Fixed an infinite loop in ChildWindowFromPointEx.
[wine.git] / msdos / devices.c
blob72684258b82e780cec21e69b7f8addac3378e467
1 /*
2 * DOS devices
4 * Copyright 1999 Ove Kåven
5 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include "wine/winbase16.h"
10 #include "msdos.h"
11 #include "miscemu.h"
12 #include "debug.h"
14 #include "pshpack1.h"
16 typedef struct {
17 DOS_DEVICE_HEADER hdr;
18 BYTE ljmp1;
19 RMCBPROC strategy;
20 BYTE ljmp2;
21 RMCBPROC interrupt;
22 } WINEDEV;
24 #include "poppack.h"
26 DOS_LISTOFLISTS * DOS_LOL;
27 DWORD DOS_LOLSeg;
29 #define NONEXT ((DWORD)-1)
31 #define ATTR_STDIN 0x0001
32 #define ATTR_STDOUT 0x0002
33 #define ATTR_NUL 0x0004
34 #define ATTR_CLOCK 0x0008
35 #define ATTR_FASTCON 0x0010
36 #define ATTR_REMOVABLE 0x0800
37 #define ATTR_NONIBM 0x2000 /* block devices */
38 #define ATTR_UNTILBUSY 0x2000 /* char devices */
39 #define ATTR_IOCTL 0x4000
40 #define ATTR_CHAR 0x8000
42 #define LJMP 0x9a
44 static void WINAPI nul_strategy(CONTEXT*ctx)
48 static void WINAPI nul_interrupt(CONTEXT*ctx)
52 static void WINAPI con_strategy(CONTEXT*ctx)
56 static void WINAPI con_interrupt(CONTEXT*ctx)
60 #define STRATEGY_OFS sizeof(DOS_DEVICE_HEADER)
61 #define INTERRUPT_OFS STRATEGY_OFS+5
63 static DOS_DEVICE_HEADER dev_nul_hdr={
64 NONEXT,
65 ATTR_CHAR|ATTR_NUL,
66 STRATEGY_OFS,INTERRUPT_OFS,
67 "NUL "
70 static WINEDEV devs={
71 {NONEXT,
72 ATTR_CHAR|ATTR_STDIN|ATTR_STDOUT|ATTR_FASTCON,
73 STRATEGY_OFS,INTERRUPT_OFS,
74 "CON "},
75 LJMP,con_strategy,
76 LJMP,con_interrupt
78 #define nr_devs (sizeof(devs)/sizeof(WINEDEV))
80 static void InitListOfLists()
83 Output of DOS 6.22:
85 0133:0020 6A 13-33 01 CC 00 33 01 59 00 j.3...3.Y.
86 0133:0030 70 00 00 00 72 02 00 02-6D 00 33 01 00 00 2E 05 p...r...m.3.....
87 0133:0040 00 00 FC 04 00 00 03 08-92 21 11 E0 04 80 C6 0D .........!......
88 0133:0050 CC 0D 4E 55 4C 20 20 20-20 20 00 00 00 00 00 00 ..NUL ......
89 0133:0060 00 4B BA C1 06 14 00 00-00 03 01 00 04 70 CE FF .K...........p..
90 0133:0070 FF 00 00 00 00 00 00 00-00 01 00 00 0D 05 00 00 ................
91 0133:0080 00 FF FF 00 00 00 00 FE-00 00 F8 03 FF 9F 70 02 ..............p.
92 0133:0090 D0 44 C8 FD D4 44 C8 FD-D4 44 C8 FD D0 44 C8 FD .D...D...D...D..
93 0133:00A0 D0 44 C8 FD D0 44 .D...D
95 DOS_LOL->CX_Int21_5e01 = 0x0;
96 DOS_LOL->LRU_count_FCB_cache = 0x0;
97 DOS_LOL->LRU_count_FCB_open = 0x0;
98 DOS_LOL->OEM_func_handler = -1; /* not available */
99 DOS_LOL->INT21_offset = 0x0;
100 DOS_LOL->sharing_retry_count = 3;
101 DOS_LOL->sharing_retry_delay = 1;
102 DOS_LOL->ptr_disk_buf = 0x0;
103 DOS_LOL->offs_unread_CON = 0x0;
104 DOS_LOL->seg_first_MCB = 0x0;
105 DOS_LOL->ptr_first_DPB = 0x0;
106 DOS_LOL->ptr_first_SysFileTable = 0x0;
107 DOS_LOL->ptr_clock_dev_hdr = 0x0;
108 DOS_LOL->ptr_CON_dev_hdr = 0x0;
109 DOS_LOL->max_byte_per_sec = 512;
110 DOS_LOL->ptr_disk_buf_info = 0x0;
111 DOS_LOL->ptr_array_CDS = 0x0;
112 DOS_LOL->ptr_sys_FCB = 0x0;
113 DOS_LOL->nr_protect_FCB = 0x0;
114 DOS_LOL->nr_block_dev = 0x0;
115 DOS_LOL->nr_avail_drive_letters = 26; /* A - Z */
116 DOS_LOL->nr_drives_JOINed = 0x0;
117 DOS_LOL->ptr_spec_prg_names = 0x0;
118 DOS_LOL->ptr_SETVER_prg_list = 0x0; /* no SETVER list */
119 DOS_LOL->DOS_HIGH_A20_func_offs = 0x0;
120 DOS_LOL->PSP_last_exec = 0x0;
121 DOS_LOL->BUFFERS_val = 99; /* maximum: 99 */
122 DOS_LOL->BUFFERS_nr_lookahead = 8; /* maximum: 8 */
123 DOS_LOL->boot_drive = 3; /* C: */
124 DOS_LOL->flag_DWORD_moves = 0x01; /* i386+ */
125 DOS_LOL->size_extended_mem = 0xf000; /* very high value */
128 void DOSDEV_InstallDOSDevices(void)
130 WINEDEV *dev;
131 DOS_DEVICE_HEADER *pdev;
132 UINT16 seg;
133 int n;
134 WORD ofs = sizeof(DOS_LISTOFLISTS)-sizeof(DOS_DEVICE_HEADER);
136 /* allocate DOS data segment or something */
137 DOS_LOLSeg = GlobalDOSAlloc16(ofs+sizeof(WINEDEV)+sizeof(devs));
138 seg = HIWORD(DOS_LOLSeg);
139 DOS_LOL = PTR_SEG_OFF_TO_LIN(LOWORD(DOS_LOLSeg), 0);
141 InitListOfLists();
143 /* copy first device (NUL) */
144 pdev = &(DOS_LOL->NUL_dev);
145 memcpy(pdev,&dev_nul_hdr,sizeof(DOS_DEVICE_HEADER));
146 pdev->strategy += ofs;
147 pdev->interrupt += ofs;
148 /* set up dev so we can copy over the rest */
149 dev = (WINEDEV*)(((char*)DOS_LOL)+ofs);
150 dev[0].ljmp1 = LJMP;
151 dev[0].strategy = (RMCBPROC)DPMI_AllocInternalRMCB(nul_strategy);
152 dev[0].ljmp2 = LJMP;
153 dev[0].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(nul_interrupt);
155 dev++;
156 ofs += sizeof(WINEDEV);
158 memcpy(dev,&devs,sizeof(devs));
159 for (n=0; n<nr_devs; n++) {
160 pdev->next_dev = PTR_SEG_OFF_TO_SEGPTR(seg, ofs);
161 dev[n].hdr.strategy += ofs;
162 dev[n].hdr.interrupt += ofs;
163 dev[n].strategy = (RMCBPROC)DPMI_AllocInternalRMCB(dev[n].strategy);
164 dev[n].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(dev[n].interrupt);
165 ofs += sizeof(WINEDEV);
166 pdev = &(dev[n].hdr);