int2f.c 10.9 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * DOS interrupt 2fh handler
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
5
#include <stdlib.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
6
#include <string.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
7
#include <unistd.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
8

Alexandre Julliard's avatar
Alexandre Julliard committed
9 10
#include "ldt.h"
#include "drive.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
11
#include "msdos.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
12
#include "miscemu.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
13
#include "module.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
14 15
#include "task.h"
#include "dosexe.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
16 17
/* #define DEBUG_INT */
#include "debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
18

Alexandre Julliard's avatar
Alexandre Julliard committed
19
  /* base WPROCS.DLL ordinal number for VxDs */
Alexandre Julliard's avatar
Alexandre Julliard committed
20 21
#define VXD_BASE 400

Alexandre Julliard's avatar
Alexandre Julliard committed
22
static void do_int2f_16( CONTEXT *context );
Alexandre Julliard's avatar
Alexandre Julliard committed
23

Alexandre Julliard's avatar
Alexandre Julliard committed
24 25 26 27 28
/**********************************************************************
 *	    INT_Int2fHandler
 *
 * Handler for int 2fh (multiplex).
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
29
void WINAPI INT_Int2fHandler( CONTEXT *context )
Alexandre Julliard's avatar
Alexandre Julliard committed
30
{
Alexandre Julliard's avatar
Alexandre Julliard committed
31 32
    TRACE(int,"Subfunction 0x%X\n", AH_reg(context));

Alexandre Julliard's avatar
Alexandre Julliard committed
33
    switch(AH_reg(context))
Alexandre Julliard's avatar
Alexandre Julliard committed
34
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
35
    case 0x10:
Alexandre Julliard's avatar
Alexandre Julliard committed
36
        AL_reg(context) = 0xff; /* share is installed */
Alexandre Julliard's avatar
Alexandre Julliard committed
37 38
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    case 0x11:  /* Network Redirector / IFSFUNC */
        switch (AL_reg(context))
        {
        case 0x00:  /* Install check */
            /* not installed */
            break;
        case 0x80:  /* Enhanced services - Install check */
            /* not installed */
            break;
        default:
	    INT_BARF( context, 0x2f );
            break;
        }
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    case 0x12:
        switch (AL_reg(context))
        {
        case 0x2e: /* get or set DOS error table address */
            switch (DL_reg(context))
            {
            /* Four tables: even commands are 'get', odd are 'set' */
            /* DOS 5.0+ ignores "set" commands */
            case 0x01:
            case 0x03:
            case 0x05:
            case 0x07:
            case 0x09:
                break; 
            /* Instead of having a message table in DOS-space, */
            /* we can use a special case for MS-DOS to force   */
            /* the secondary interface.			       */
            case 0x00:
            case 0x02:
            case 0x04:
            case 0x06: 
                ES_reg(context) = 0x0001;
                DI_reg(context) = 0x0000;
                break;
            case 0x08:
                FIXME(int, "No real-mode handler for errors yet! (bye!)");
                break;
            default:
                INT_BARF(context, 0x2f);
            }
            break;
        default:
           INT_BARF(context, 0x2f);
        }  
        break;
   
Alexandre Julliard's avatar
Alexandre Julliard committed
90
    case 0x15: /* mscdex */
Alexandre Julliard's avatar
Alexandre Julliard committed
91
        do_mscdex(context);
Alexandre Julliard's avatar
Alexandre Julliard committed
92 93 94
        break;

    case 0x16:
Alexandre Julliard's avatar
Alexandre Julliard committed
95
        do_int2f_16( context );
Alexandre Julliard's avatar
Alexandre Julliard committed
96
        break;
97 98 99 100 101

    case 0x1a: /* ANSI.SYS / AVATAR.SYS Install Check */
        /* Not supported yet, do nothing */
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
102
    case 0x43:
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
#if 1
	switch (AL_reg(context))
	{
	case 0x00:   /* XMS v2+ installation check */
	    WARN(int,"XMS is not fully implemented\n");
	    AL_reg(context) = 0x80;
	    break;
	case 0x10:   /* XMS v2+ get driver address */
	{
            TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
            NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
            GlobalUnlock16( GetCurrentTask() );
#ifdef MZ_SUPPORTED
            if (pModule && pModule->lpDosTask)
                ES_reg(context) = pModule->lpDosTask->xms_seg;
            else
#endif
                ES_reg(context) = 0;
            BX_reg(context) = 0;
            break;
	}
	default:
	    INT_BARF( context, 0x2f );
	}
#else
Alexandre Julliard's avatar
Alexandre Julliard committed
128 129
    	FIXME(int,"check for XMS (not supported)\n");
	AL_reg(context) = 0x42; /* != 0x80 */
130
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
131
    	break;
Alexandre Julliard's avatar
Alexandre Julliard committed
132

Alexandre Julliard's avatar
Alexandre Julliard committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    case 0x45:
       switch (AL_reg(context)) 
       {
       case 0x00:
       case 0x01:
       case 0x02:
       case 0x03:
       case 0x04:
       case 0x05:
       case 0x06:
       case 0x07:
       case 0x08:
           /* Microsoft Profiler - not installed */
           break;
       default:
            INT_BARF( context, 0x2f );
       }
       break;

Alexandre Julliard's avatar
Alexandre Julliard committed
152
    case 0x4a:
Alexandre Julliard's avatar
Alexandre Julliard committed
153
        switch(AL_reg(context))
Alexandre Julliard's avatar
Alexandre Julliard committed
154
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
155 156
	case 0x10:  /* smartdrv */
	    break;  /* not installed */
Alexandre Julliard's avatar
Alexandre Julliard committed
157 158
        case 0x11:  /* dblspace */
            break;  /* not installed */
Alexandre Julliard's avatar
Alexandre Julliard committed
159 160
        case 0x12:  /* realtime compression interface */
            break;  /* not installed */
161 162
        case 0x32:  /* patch IO.SYS (???) */
            break;  /* we have no IO.SYS, so we can't patch it :-/ */
Alexandre Julliard's avatar
Alexandre Julliard committed
163
        default:
Alexandre Julliard's avatar
Alexandre Julliard committed
164
            INT_BARF( context, 0x2f );
Alexandre Julliard's avatar
Alexandre Julliard committed
165 166
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
167 168 169 170 171 172 173 174 175 176
    case 0x56:  /* INTERLNK */
	switch(AL_reg(context))
	{
	case 0x01:  /* check if redirected drive */
	    AL_reg(context) = 0; /* not redirected */
	    break;
	default:
	    INT_BARF( context, 0x2f );
	}
	break;
Alexandre Julliard's avatar
Alexandre Julliard committed
177 178 179 180 181 182 183
    case 0x7a:  /* NOVELL NetWare */
        switch (AL_reg(context))
        {
        case 0x20:  /* Get VLM Call Address */
            /* return nothing -> NetWare not installed */
            break;
        default:
Alexandre Julliard's avatar
Alexandre Julliard committed
184
	    INT_BARF( context, 0x2f );
Alexandre Julliard's avatar
Alexandre Julliard committed
185 186 187
            break;
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
188
    case 0xb7:  /* append */
Alexandre Julliard's avatar
Alexandre Julliard committed
189
        AL_reg(context) = 0; /* not installed */
Alexandre Julliard's avatar
Alexandre Julliard committed
190
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
191 192 193 194 195 196 197 198 199 200 201
    case 0xb8:  /* network */
        switch (AL_reg(context))
        {
        case 0x00:  /* Install check */
            /* not installed */
            break;
        default:
	    INT_BARF( context, 0x2f );
            break;
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
202 203 204
    case 0xbd:  /* some Novell network install check ??? */
        AX_reg(context) = 0xa5a5; /* pretend to have Novell IPX installed */
	break;
Alexandre Julliard's avatar
Alexandre Julliard committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
    case 0xbf:  /* REDIRIFS.EXE */
        switch (AL_reg(context))
        {
        case 0x00:  /* Install check */
            /* not installed */
            break;
        default:
	    INT_BARF( context, 0x2f );
            break;
        }
        break;
    case 0xd7:  /* Banyan Vines */
        switch (AL_reg(context))
        {
        case 0x01:  /* Install check - Get Int Number */
            /* not installed */
            break;
        default:
	    INT_BARF( context, 0x2f );
            break;
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
227 228
    case 0xfa:  /* Watcom debugger check, returns 0x666 if installed */
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
229
    default:
Alexandre Julliard's avatar
Alexandre Julliard committed
230
        INT_BARF( context, 0x2f );
Alexandre Julliard's avatar
Alexandre Julliard committed
231 232
        break;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
233
}
Alexandre Julliard's avatar
Alexandre Julliard committed
234 235


Alexandre Julliard's avatar
Alexandre Julliard committed
236 237 238
/**********************************************************************
 *	    do_int2f_16
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
239
static void do_int2f_16( CONTEXT *context )
Alexandre Julliard's avatar
Alexandre Julliard committed
240
{
Alexandre Julliard's avatar
Alexandre Julliard committed
241 242
    DWORD addr;

Alexandre Julliard's avatar
Alexandre Julliard committed
243
    switch(AL_reg(context))
Alexandre Julliard's avatar
Alexandre Julliard committed
244 245
    {
    case 0x00:  /* Windows enhanced mode installation check */
Alexandre Julliard's avatar
Alexandre Julliard committed
246 247
        AX_reg(context) = (GetWinFlags() & WF_ENHANCED) ?
                                                  LOWORD(GetVersion16()) : 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
248
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
249
	
Alexandre Julliard's avatar
Alexandre Julliard committed
250
    case 0x0a:  /* Get Windows version and type */
Alexandre Julliard's avatar
Alexandre Julliard committed
251
        AX_reg(context) = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
252 253 254
        BX_reg(context) = (LOWORD(GetVersion16()) << 8) |
                          (LOWORD(GetVersion16()) >> 8);
        CX_reg(context) = (GetWinFlags() & WF_ENHANCED) ? 3 : 2;
Alexandre Julliard's avatar
Alexandre Julliard committed
255 256
        break;

257 258 259 260
    case 0x0b:  /* Identify Windows-aware TSRs */
        /* we don't have any pre-Windows TSRs */
        break;

261 262 263 264 265
    case 0x11:  /* Get Shell Parameters - (SHELL= in CONFIG.SYS) */
        /* We can mock this up. But not today... */ 
        FIXME(int, "Get Shell Parameters\n");       
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
266
    case 0x80:  /* Release time-slice */
Alexandre Julliard's avatar
Alexandre Julliard committed
267 268 269 270 271
	AL_reg(context) = 0;
	/* FIXME: We need to do something that lets some other process run
	   here.  */
	sleep(0);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
272

Alexandre Julliard's avatar
Alexandre Julliard committed
273 274 275 276 277 278 279 280
    case 0x81: /* Begin critical section.  */
        /* FIXME? */
        break;

    case 0x82: /* End critical section.  */
        /* FIXME? */
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
281 282 283 284 285 286 287 288 289 290
    case 0x83:  /* Return Current Virtual Machine ID */
        /* Virtual Machines are usually created/destroyed when Windows runs
         * DOS programs. Since we never do, we are always in the System VM.
         * According to Ralf Brown's Interrupt List, never return 0. But it
         * seems to work okay (returning 0), just to be sure we return 1.
         */
	BX_reg(context) = 1; /* VM 1 is probably the System VM */
	break;

    case 0x84:  /* Get device API entry point */
Alexandre Julliard's avatar
Alexandre Julliard committed
291 292
        addr = (DWORD)NE_GetEntryPoint( GetModuleHandle16("WPROCS"),
                                        VXD_BASE + BX_reg(context) );
Alexandre Julliard's avatar
Alexandre Julliard committed
293 294
        if (!addr)  /* not supported */
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
295
	    ERR(int,"Accessing unknown VxD %04x - Expect a failure now.\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
296 297 298 299 300
                     BX_reg(context) );
        }
	ES_reg(context) = SELECTOROF(addr);
	DI_reg(context) = OFFSETOF(addr);
	break;
Alexandre Julliard's avatar
Alexandre Julliard committed
301

Alexandre Julliard's avatar
Alexandre Julliard committed
302
    case 0x86:  /* DPMI detect mode */
Alexandre Julliard's avatar
Alexandre Julliard committed
303
        AX_reg(context) = 0;  /* Running under DPMI */
Alexandre Julliard's avatar
Alexandre Julliard committed
304 305
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
306
    case 0x87: /* DPMI installation check */
Alexandre Julliard's avatar
Alexandre Julliard committed
307
#if 1   /* DPMI still breaks pkunzip */
Alexandre Julliard's avatar
Alexandre Julliard committed
308
        if (ISV86(context)) break; /* so bail out for now if in v86 mode */
Alexandre Julliard's avatar
Alexandre Julliard committed
309
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
310
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
311 312
            TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
            NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
313 314
	    SYSTEM_INFO si;

Alexandre Julliard's avatar
Alexandre Julliard committed
315
            GlobalUnlock16( GetCurrentTask() );
Alexandre Julliard's avatar
Alexandre Julliard committed
316 317 318 319 320 321
	    GetSystemInfo(&si);
	    AX_reg(context) = 0x0000; /* DPMI Installed */
            BX_reg(context) = 0x0001; /* 32bits available */
            CL_reg(context) = si.wProcessorLevel;
            DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
            SI_reg(context) = 0;      /* # of para. of DOS extended private data */
Alexandre Julliard's avatar
Alexandre Julliard committed
322 323 324 325 326 327
#ifdef MZ_SUPPORTED                   /* ES:DI is DPMI switch entry point */
            if (pModule && pModule->lpDosTask)
                ES_reg(context) = pModule->lpDosTask->dpmi_seg;
            else
#endif
                ES_reg(context) = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
328 329 330
            DI_reg(context) = 0;
            break;
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
331 332 333 334
    case 0x8a:  /* DPMI get vendor-specific API entry point. */
	/* The 1.0 specs say this should work with all 0.9 hosts.  */
	break;

Alexandre Julliard's avatar
Alexandre Julliard committed
335
    default:
Alexandre Julliard's avatar
Alexandre Julliard committed
336
        INT_BARF( context, 0x2f );
Alexandre Julliard's avatar
Alexandre Julliard committed
337
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
338
}
Alexandre Julliard's avatar
Alexandre Julliard committed
339

Alexandre Julliard's avatar
Alexandre Julliard committed
340
void do_mscdex( CONTEXT *context )
Alexandre Julliard's avatar
Alexandre Julliard committed
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
{
    int drive, count;
    char *p;

    switch(AL_reg(context))
    {
        case 0x00: /* Installation check */
            /* Count the number of contiguous CDROM drives
             */
            for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
            {
                if (DRIVE_GetType(drive) == TYPE_CDROM)
                {
                    while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++;
                    break;
                }
            }

            BX_reg(context) = count;
            CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0;
            break;

        case 0x0B: /* drive check */
            AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM);
            BX_reg(context) = 0xADAD;
            break;

        case 0x0C: /* get version */
            BX_reg(context) = 0x020a;
            break;

        case 0x0D: /* get drive letters */
373
	    p = CTX_SEG_OFF_TO_LIN(context, ES_reg(context), EBX_reg(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
374 375 376 377 378 379 380
            memset( p, 0, MAX_DOS_DRIVES );
            for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
            {
                if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive;
            }
            break;

Alexandre Julliard's avatar
Alexandre Julliard committed
381
#ifdef linux
Alexandre Julliard's avatar
Alexandre Julliard committed
382 383
        /* FIXME: why a new linux-only CDROM drive access, for crying out loud?
         * There are pretty complete routines in multimedia/mcicda.c already! */
Alexandre Julliard's avatar
Alexandre Julliard committed
384
	case 0x10: /* direct driver acces */
Alexandre Julliard's avatar
Alexandre Julliard committed
385 386
            FIXME(cdaudio,"mscdex should use multimedia/mcicda.c");
	    do_mscdex_dd(context,ISV86(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
387 388 389 390
	    break;

#endif

Alexandre Julliard's avatar
Alexandre Julliard committed
391
        default:
Alexandre Julliard's avatar
Alexandre Julliard committed
392
            FIXME(int, "Unimplemented MSCDEX function 0x%02X.\n", AL_reg(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
393 394 395
            break;
    }
}