Fixed some compiler warnings.
[wine/multimedia.git] / msdos / int2f.c
blob43e7417765656e70c37cbf74b55b01180b03658f
1 /*
2 * DOS interrupt 2fh handler
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
9 #include "ldt.h"
10 #include "drive.h"
11 #include "msdos.h"
12 #include "miscemu.h"
13 #include "module.h"
14 #include "task.h"
15 #include "dosexe.h"
16 /* #define DEBUG_INT */
17 #include "debug.h"
19 /* base WPROCS.DLL ordinal number for VxDs */
20 #define VXD_BASE 400
22 static void do_int2f_16( CONTEXT *context );
24 /**********************************************************************
25 * INT_Int2fHandler
27 * Handler for int 2fh (multiplex).
29 void WINAPI INT_Int2fHandler( CONTEXT *context )
31 TRACE(int,"Subfunction 0x%X\n", AH_reg(context));
33 switch(AH_reg(context))
35 case 0x10:
36 AL_reg(context) = 0xff; /* share is installed */
37 break;
39 case 0x11: /* Network Redirector / IFSFUNC */
40 switch (AL_reg(context))
42 case 0x00: /* Install check */
43 /* not installed */
44 break;
45 case 0x80: /* Enhanced services - Install check */
46 /* not installed */
47 break;
48 default:
49 INT_BARF( context, 0x2f );
50 break;
52 break;
54 case 0x12:
55 switch (AL_reg(context))
57 case 0x2e: /* get or set DOS error table address */
58 switch (DL_reg(context))
60 /* Four tables: even commands are 'get', odd are 'set' */
61 /* DOS 5.0+ ignores "set" commands */
62 case 0x01:
63 case 0x03:
64 case 0x05:
65 case 0x07:
66 case 0x09:
67 break;
68 /* Instead of having a message table in DOS-space, */
69 /* we can use a special case for MS-DOS to force */
70 /* the secondary interface. */
71 case 0x00:
72 case 0x02:
73 case 0x04:
74 case 0x06:
75 ES_reg(context) = 0x0001;
76 DI_reg(context) = 0x0000;
77 break;
78 case 0x08:
79 FIXME(int, "No real-mode handler for errors yet! (bye!)");
80 break;
81 default:
82 INT_BARF(context, 0x2f);
84 break;
85 default:
86 INT_BARF(context, 0x2f);
88 break;
90 case 0x15: /* mscdex */
91 do_mscdex(context);
92 break;
94 case 0x16:
95 do_int2f_16( context );
96 break;
98 case 0x1a: /* ANSI.SYS / AVATAR.SYS Install Check */
99 /* Not supported yet, do nothing */
100 break;
102 case 0x43:
103 #if 1
104 switch (AL_reg(context))
106 case 0x00: /* XMS v2+ installation check */
107 WARN(int,"XMS is not fully implemented\n");
108 AL_reg(context) = 0x80;
109 break;
110 case 0x10: /* XMS v2+ get driver address */
112 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
113 NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
114 GlobalUnlock16( GetCurrentTask() );
115 #ifdef MZ_SUPPORTED
116 if (pModule && pModule->lpDosTask)
117 ES_reg(context) = pModule->lpDosTask->xms_seg;
118 else
119 #endif
120 ES_reg(context) = 0;
121 BX_reg(context) = 0;
122 break;
124 default:
125 INT_BARF( context, 0x2f );
127 #else
128 FIXME(int,"check for XMS (not supported)\n");
129 AL_reg(context) = 0x42; /* != 0x80 */
130 #endif
131 break;
133 case 0x45:
134 switch (AL_reg(context))
136 case 0x00:
137 case 0x01:
138 case 0x02:
139 case 0x03:
140 case 0x04:
141 case 0x05:
142 case 0x06:
143 case 0x07:
144 case 0x08:
145 /* Microsoft Profiler - not installed */
146 break;
147 default:
148 INT_BARF( context, 0x2f );
150 break;
152 case 0x4a:
153 switch(AL_reg(context))
155 case 0x10: /* smartdrv */
156 break; /* not installed */
157 case 0x11: /* dblspace */
158 break; /* not installed */
159 case 0x12: /* realtime compression interface */
160 break; /* not installed */
161 default:
162 INT_BARF( context, 0x2f );
164 break;
165 case 0x56: /* INTERLNK */
166 switch(AL_reg(context))
168 case 0x01: /* check if redirected drive */
169 AL_reg(context) = 0; /* not redirected */
170 break;
171 default:
172 INT_BARF( context, 0x2f );
174 break;
175 case 0x7a: /* NOVELL NetWare */
176 switch (AL_reg(context))
178 case 0x20: /* Get VLM Call Address */
179 /* return nothing -> NetWare not installed */
180 break;
181 default:
182 INT_BARF( context, 0x2f );
183 break;
185 break;
186 case 0xb7: /* append */
187 AL_reg(context) = 0; /* not installed */
188 break;
189 case 0xb8: /* network */
190 switch (AL_reg(context))
192 case 0x00: /* Install check */
193 /* not installed */
194 break;
195 default:
196 INT_BARF( context, 0x2f );
197 break;
199 break;
200 case 0xbd: /* some Novell network install check ??? */
201 AX_reg(context) = 0xa5a5; /* pretend to have Novell IPX installed */
202 break;
203 case 0xbf: /* REDIRIFS.EXE */
204 switch (AL_reg(context))
206 case 0x00: /* Install check */
207 /* not installed */
208 break;
209 default:
210 INT_BARF( context, 0x2f );
211 break;
213 break;
214 case 0xd7: /* Banyan Vines */
215 switch (AL_reg(context))
217 case 0x01: /* Install check - Get Int Number */
218 /* not installed */
219 break;
220 default:
221 INT_BARF( context, 0x2f );
222 break;
224 break;
225 case 0xfa: /* Watcom debugger check, returns 0x666 if installed */
226 break;
227 default:
228 INT_BARF( context, 0x2f );
229 break;
234 /**********************************************************************
235 * do_int2f_16
237 static void do_int2f_16( CONTEXT *context )
239 DWORD addr;
241 switch(AL_reg(context))
243 case 0x00: /* Windows enhanced mode installation check */
244 AX_reg(context) = (GetWinFlags() & WF_ENHANCED) ?
245 LOWORD(GetVersion16()) : 0;
246 break;
248 case 0x0a: /* Get Windows version and type */
249 AX_reg(context) = 0;
250 BX_reg(context) = (LOWORD(GetVersion16()) << 8) |
251 (LOWORD(GetVersion16()) >> 8);
252 CX_reg(context) = (GetWinFlags() & WF_ENHANCED) ? 3 : 2;
253 break;
255 case 0x11: /* Get Shell Parameters - (SHELL= in CONFIG.SYS) */
256 /* We can mock this up. But not today... */
257 FIXME(int, "Get Shell Parameters\n");
258 break;
260 case 0x80: /* Release time-slice */
261 AL_reg(context) = 0;
262 /* FIXME: We need to do something that lets some other process run
263 here. */
264 sleep(0);
265 break;
267 case 0x81: /* Begin critical section. */
268 /* FIXME? */
269 break;
271 case 0x82: /* End critical section. */
272 /* FIXME? */
273 break;
275 case 0x83: /* Return Current Virtual Machine ID */
276 /* Virtual Machines are usually created/destroyed when Windows runs
277 * DOS programs. Since we never do, we are always in the System VM.
278 * According to Ralf Brown's Interrupt List, never return 0. But it
279 * seems to work okay (returning 0), just to be sure we return 1.
281 BX_reg(context) = 1; /* VM 1 is probably the System VM */
282 break;
284 case 0x84: /* Get device API entry point */
285 addr = (DWORD)NE_GetEntryPoint( GetModuleHandle16("WPROCS"),
286 VXD_BASE + BX_reg(context) );
287 if (!addr) /* not supported */
289 ERR(int,"Accessing unknown VxD %04x - Expect a failure now.\n",
290 BX_reg(context) );
292 ES_reg(context) = SELECTOROF(addr);
293 DI_reg(context) = OFFSETOF(addr);
294 break;
296 case 0x86: /* DPMI detect mode */
297 AX_reg(context) = 0; /* Running under DPMI */
298 break;
300 case 0x87: /* DPMI installation check */
301 #if 1 /* DPMI still breaks pkunzip */
302 if (ISV86(context)) break; /* so bail out for now if in v86 mode */
303 #endif
305 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
306 NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
307 SYSTEM_INFO si;
309 GlobalUnlock16( GetCurrentTask() );
310 GetSystemInfo(&si);
311 AX_reg(context) = 0x0000; /* DPMI Installed */
312 BX_reg(context) = 0x0001; /* 32bits available */
313 CL_reg(context) = si.wProcessorLevel;
314 DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
315 SI_reg(context) = 0; /* # of para. of DOS extended private data */
316 #ifdef MZ_SUPPORTED /* ES:DI is DPMI switch entry point */
317 if (pModule && pModule->lpDosTask)
318 ES_reg(context) = pModule->lpDosTask->dpmi_seg;
319 else
320 #endif
321 ES_reg(context) = 0;
322 DI_reg(context) = 0;
323 break;
325 case 0x8a: /* DPMI get vendor-specific API entry point. */
326 /* The 1.0 specs say this should work with all 0.9 hosts. */
327 break;
329 default:
330 INT_BARF( context, 0x2f );
334 void do_mscdex( CONTEXT *context )
336 int drive, count;
337 char *p;
339 switch(AL_reg(context))
341 case 0x00: /* Installation check */
342 /* Count the number of contiguous CDROM drives
344 for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
346 if (DRIVE_GetType(drive) == TYPE_CDROM)
348 while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++;
349 break;
353 BX_reg(context) = count;
354 CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0;
355 break;
357 case 0x0B: /* drive check */
358 AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM);
359 BX_reg(context) = 0xADAD;
360 break;
362 case 0x0C: /* get version */
363 BX_reg(context) = 0x020a;
364 break;
366 case 0x0D: /* get drive letters */
367 p = CTX_SEG_OFF_TO_LIN(context, ES_reg(context), BX_reg(context));
368 memset( p, 0, MAX_DOS_DRIVES );
369 for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
371 if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive;
373 break;
375 #ifdef linux
376 /* FIXME: why a new linux-only CDROM drive access, for crying out loud?
377 * There are pretty complete routines in multimedia/mcicda.c already! */
378 case 0x10: /* direct driver acces */
379 FIXME(cdaudio,"mscdex should use multimedia/mcicda.c");
380 do_mscdex_dd(context,ISV86(context));
381 break;
383 #endif
385 default:
386 FIXME(int, "Unimplemented MSCDEX function 0x%02X.\n", AL_reg(context));
387 break;