2 * DOS interrupt 2fh handler
16 /* #define DEBUG_INT */
19 /* base WPROCS.DLL ordinal number for VxDs */
22 static void do_int2f_16( CONTEXT *context );
24 /**********************************************************************
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))
36 AL_reg(context) = 0xff; /* share is installed */
39 case 0x11: /* Network Redirector / IFSFUNC */
40 switch (AL_reg(context))
42 case 0x00: /* Install check */
45 case 0x80: /* Enhanced services - Install check */
49 INT_BARF( context, 0x2f );
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 */
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. */
75 ES_reg(context) = 0x0001;
76 DI_reg(context) = 0x0000;
79 FIXME(int, "No real-mode handler for errors yet! (bye!)");
82 INT_BARF(context, 0x2f);
86 INT_BARF(context, 0x2f);
90 case 0x15: /* mscdex */
95 do_int2f_16( context );
98 case 0x1a: /* ANSI.SYS / AVATAR.SYS Install Check */
99 /* Not supported yet, do nothing */
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;
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() );
116 if (pModule && pModule->lpDosTask)
117 ES_reg(context) = pModule->lpDosTask->xms_seg;
125 INT_BARF( context, 0x2f );
128 FIXME(int,"check for XMS (not supported)\n");
129 AL_reg(context) = 0x42; /* != 0x80 */
134 switch (AL_reg(context))
145 /* Microsoft Profiler - not installed */
148 INT_BARF( context, 0x2f );
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 case 0x32: /* patch IO.SYS (???) */
162 break; /* we have no IO.SYS, so we can't patch it :-/ */
164 INT_BARF( context, 0x2f );
167 case 0x56: /* INTERLNK */
168 switch(AL_reg(context))
170 case 0x01: /* check if redirected drive */
171 AL_reg(context) = 0; /* not redirected */
174 INT_BARF( context, 0x2f );
177 case 0x7a: /* NOVELL NetWare */
178 switch (AL_reg(context))
180 case 0x20: /* Get VLM Call Address */
181 /* return nothing -> NetWare not installed */
184 INT_BARF( context, 0x2f );
188 case 0xb7: /* append */
189 AL_reg(context) = 0; /* not installed */
191 case 0xb8: /* network */
192 switch (AL_reg(context))
194 case 0x00: /* Install check */
198 INT_BARF( context, 0x2f );
202 case 0xbd: /* some Novell network install check ??? */
203 AX_reg(context) = 0xa5a5; /* pretend to have Novell IPX installed */
205 case 0xbf: /* REDIRIFS.EXE */
206 switch (AL_reg(context))
208 case 0x00: /* Install check */
212 INT_BARF( context, 0x2f );
216 case 0xd7: /* Banyan Vines */
217 switch (AL_reg(context))
219 case 0x01: /* Install check - Get Int Number */
223 INT_BARF( context, 0x2f );
227 case 0xfa: /* Watcom debugger check, returns 0x666 if installed */
230 INT_BARF( context, 0x2f );
236 /**********************************************************************
239 static void do_int2f_16( CONTEXT *context )
243 switch(AL_reg(context))
245 case 0x00: /* Windows enhanced mode installation check */
246 AX_reg(context) = (GetWinFlags() & WF_ENHANCED) ?
247 LOWORD(GetVersion16()) : 0;
250 case 0x0a: /* Get Windows version and type */
252 BX_reg(context) = (LOWORD(GetVersion16()) << 8) |
253 (LOWORD(GetVersion16()) >> 8);
254 CX_reg(context) = (GetWinFlags() & WF_ENHANCED) ? 3 : 2;
257 case 0x0b: /* Identify Windows-aware TSRs */
258 /* we don't have any pre-Windows TSRs */
261 case 0x11: /* Get Shell Parameters - (SHELL= in CONFIG.SYS) */
262 /* We can mock this up. But not today... */
263 FIXME(int, "Get Shell Parameters\n");
266 case 0x80: /* Release time-slice */
268 /* FIXME: We need to do something that lets some other process run
273 case 0x81: /* Begin critical section. */
277 case 0x82: /* End critical section. */
281 case 0x83: /* Return Current Virtual Machine ID */
282 /* Virtual Machines are usually created/destroyed when Windows runs
283 * DOS programs. Since we never do, we are always in the System VM.
284 * According to Ralf Brown's Interrupt List, never return 0. But it
285 * seems to work okay (returning 0), just to be sure we return 1.
287 BX_reg(context) = 1; /* VM 1 is probably the System VM */
290 case 0x84: /* Get device API entry point */
291 addr = (DWORD)NE_GetEntryPoint( GetModuleHandle16("WPROCS"),
292 VXD_BASE + BX_reg(context) );
293 if (!addr) /* not supported */
295 ERR(int,"Accessing unknown VxD %04x - Expect a failure now.\n",
298 ES_reg(context) = SELECTOROF(addr);
299 DI_reg(context) = OFFSETOF(addr);
302 case 0x86: /* DPMI detect mode */
303 AX_reg(context) = 0; /* Running under DPMI */
306 case 0x87: /* DPMI installation check */
307 #if 1 /* DPMI still breaks pkunzip */
308 if (ISV86(context)) break; /* so bail out for now if in v86 mode */
311 TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
312 NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
315 GlobalUnlock16( GetCurrentTask() );
317 AX_reg(context) = 0x0000; /* DPMI Installed */
318 BX_reg(context) = 0x0001; /* 32bits available */
319 CL_reg(context) = si.wProcessorLevel;
320 DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
321 SI_reg(context) = 0; /* # of para. of DOS extended private data */
322 #ifdef MZ_SUPPORTED /* ES:DI is DPMI switch entry point */
323 if (pModule && pModule->lpDosTask)
324 ES_reg(context) = pModule->lpDosTask->dpmi_seg;
331 case 0x8a: /* DPMI get vendor-specific API entry point. */
332 /* The 1.0 specs say this should work with all 0.9 hosts. */
336 INT_BARF( context, 0x2f );
340 void do_mscdex( CONTEXT *context )
345 switch(AL_reg(context))
347 case 0x00: /* Installation check */
348 /* Count the number of contiguous CDROM drives
350 for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
352 if (DRIVE_GetType(drive) == TYPE_CDROM)
354 while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++;
359 BX_reg(context) = count;
360 CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0;
363 case 0x0B: /* drive check */
364 AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM);
365 BX_reg(context) = 0xADAD;
368 case 0x0C: /* get version */
369 BX_reg(context) = 0x020a;
372 case 0x0D: /* get drive letters */
373 p = CTX_SEG_OFF_TO_LIN(context, ES_reg(context), EBX_reg(context));
374 memset( p, 0, MAX_DOS_DRIVES );
375 for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
377 if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive;
382 /* FIXME: why a new linux-only CDROM drive access, for crying out loud?
383 * There are pretty complete routines in multimedia/mcicda.c already! */
384 case 0x10: /* direct driver acces */
385 FIXME(cdaudio,"mscdex should use multimedia/mcicda.c");
386 do_mscdex_dd(context,ISV86(context));
392 FIXME(int, "Unimplemented MSCDEX function 0x%02X.\n", AL_reg(context));