int21 handling

Eric Pouech pouech-eric at wanadoo.fr
Sun Nov 9 12:28:22 CST 2003


this patch moves a few more int21 requests from msdos/ to dlls/winedos/
it's mainly a rewrite without using kernel32 internals
the most important modification is that modifying a drive serial number 
is no longer possible. there's no exported function from kernel32 to do 
so. Anyway, I don't think it's a big deal (it was only useful on 
floppies, which are less and less used).
If needed we could copy the existing kernel32 code to dlls/winedos if needed
only the find{first|next} functions remain in msdos/int21.c which will 
be (soon) history.

A+
-- 
Eric Pouech
-------------- next part --------------
Name:          int21
ChangeLog:
	-t moved a few more int21 calls to dlls/winedos (setting drive serial# has been disabled)
	-t added volume management prototypes to include/winebase.h
	-t started DefineDosDevice (needed by first item in this list)
License:       X11
GenDate:       2003/11/09 18:21:10 UTC
ModifiedFiles: dlls/winedos/int21.c files/drive.c include/winbase.h msdos/int21.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winedos/int21.c,v
retrieving revision 1.45
diff -u -u -r1.45 int21.c
--- dlls/winedos/int21.c	3 Nov 2003 22:13:25 -0000	1.45
+++ dlls/winedos/int21.c	9 Nov 2003 18:16:12 -0000
@@ -26,6 +26,10 @@
 #include "config.h"
 
 #include <stdarg.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -58,6 +62,13 @@
 
 #include "pshpack1.h"
 
+struct DosHeap {
+       BYTE mediaID;
+	BYTE biosdate[8];
+};
+static struct DosHeap *heap;
+static WORD DosHeapHandle;
+
 /*
  * Extended Drive Parameter Block.
  * This structure is compatible with standard DOS4+ DPB and 
@@ -161,13 +172,40 @@
 #include "poppack.h"
 
 
+static BOOL INT21_CreateHeap(void)
+{
+    if (!(DosHeapHandle = GlobalAlloc16(GMEM_FIXED,sizeof(struct DosHeap))))
+    {
+        WARN("Out of memory\n");
+        return FALSE;
+    }
+    heap = (struct DosHeap *) GlobalLock16(DosHeapHandle);
+    strcpy(heap->biosdate, "01/01/80");
+    return TRUE;
+}
+
+/* Many calls translate a drive argument like this:
+   drive number (00h = default, 01h = A:, etc)
+   */
+/******************************************************************
+ *		INT21_DriveName
+ *
+ * Many calls translate a drive argument like this:
+ * drive number (00h = default, 01h = A:, etc)
+ */
+static const char *INT21_DriveName(int drive)
+{
+    if (drive > 0) return wine_dbg_sprintf( "%c:", 'A' + drive - 1 );
+    return "default";
+}
+
 /***********************************************************************
  *           INT21_GetCurrentDrive
  *
  * Return current drive using scheme (0=A:, 1=B:, 2=C:, ...) or
  * MAX_DOS_DRIVES on error.
  */
-static BYTE INT21_GetCurrentDrive()
+static BYTE INT21_GetCurrentDrive(void)
 {
     WCHAR current_directory[MAX_PATH];
 
@@ -2092,6 +2130,50 @@
         SET_BX( context, DOSVM_psp );
 }
 
+static void CreateBPB(int drive, BYTE *data, BOOL16 limited)
+/* limited == TRUE is used with INT 0x21/0x440d */
+{
+    if (drive > 1) 
+    {
+        setword(data, 512);
+        data[2] = 2;
+        setword(&data[3], 0);
+        data[5] = 2;
+        setword(&data[6], 240);
+        setword(&data[8], 64000);
+        data[0x0a] = 0xf8;
+        setword(&data[0x0b], 40);
+        setword(&data[0x0d], 56);
+        setword(&data[0x0f], 2);
+        setword(&data[0x11], 0);
+        if (!limited) 
+        {
+            setword(&data[0x1f], 800);
+            data[0x21] = 5;
+            setword(&data[0x22], 1);
+        }
+    }
+    else
+    { /* 1.44mb */
+        setword(data, 512);
+        data[2] = 2;
+        setword(&data[3], 0);
+        data[5] = 2;
+        setword(&data[6], 240);
+        setword(&data[8], 2880);
+        data[0x0a] = 0xf8;
+        setword(&data[0x0b], 6);
+        setword(&data[0x0d], 18);
+        setword(&data[0x0f], 2);
+        setword(&data[0x11], 0);
+        if (!limited) 
+        {
+            setword(&data[0x1f], 80);
+            data[0x21] = 7;
+            setword(&data[0x22], 2);
+        }
+    }
+}
 
 /***********************************************************************
  *           INT21_Ioctl_Block
@@ -2176,7 +2258,24 @@
             break;
 
         case 0x0860: /* get device parameters */
-            INT_Int21Handler( context );
+            /* used by w4wgrp's winfile */
+            memset(dataptr, 0, 0x20); /* DOS 6.22 uses 0x20 bytes */
+            dataptr[0] = 0x04;
+            dataptr[6] = 0; /* media type */
+            if (drive > 1)
+            {
+                dataptr[1] = 0x05; /* fixed disk */
+                setword(&dataptr[2], 0x01); /* non removable */
+                setword(&dataptr[4], 0x300); /* # of cylinders */
+            }
+            else
+            {
+                dataptr[1] = 0x07; /* block dev, floppy */
+                setword(&dataptr[2], 0x02); /* removable */
+                setword(&dataptr[4], 80); /* # of cylinders */
+            }
+            CreateBPB(drive, &dataptr[7], TRUE);
+            RESET_CFLAG(context);
             break;
 
         case 0x0861: /* read logical device track */
@@ -2198,7 +2297,18 @@
             break;
 
         case 0x0866: /* get volume serial number */
-            INT_Int21Handler( context );
+            {
+                char	label[12],fsname[9],path[4];
+                DWORD	serial;
+
+                path[0] = drive+'A';
+                strcpy(path + 1, ":\\");
+                GetVolumeInformationA(path,label,12,&serial,NULL,NULL,fsname,9);
+                *(WORD*)dataptr	= 0;
+                memcpy(dataptr+2,&serial,4);
+                memcpy(dataptr+6,label	,11);
+                memcpy(dataptr+17,fsname,8);
+            }
             break;
 
         case 0x086a: /* unlock logical volume */
@@ -2207,11 +2317,16 @@
             break;
 
         case 0x086f: /* get drive map information */
-            INT_Int21Handler( context );
+            memset(dataptr+1, '\0', dataptr[0]-1);
+            dataptr[1] = dataptr[0];
+            dataptr[2] = 0x07; /* protected mode driver; no eject; no notification */
+            dataptr[3] = 0xFF; /* no physical drive */
             break;
 
         case 0x0872:
-            INT_Int21Handler( context );
+            /* Trail on error implementation */
+            SET_AX( context, drivetype == DRIVE_UNKNOWN ? 0x0f : 0x01 );
+            SET_CFLAG(context);	/* Seems to be set all the time */
             break;
 
         default:
@@ -2227,7 +2342,19 @@
         break;
 
     case 0x0f: /* SET LOGICAL DRIVE MAP */
-        INT_Int21Handler( context );
+	{
+            char dev[3], target[4];
+
+            TRACE("IOCTL - SET LOGICAL DRIVE MAP for drive %s\n",
+		  INT21_DriveName( BL_reg(context)));
+            sprintf(dev, "%c:", 'A' + drive);
+            sprintf(target, "%c:\\", 'A' + drive + 1);
+            if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH, dev, target))
+	    {
+		SET_CFLAG(context);
+		SET_AX( context, 0x000F );  /* invalid drive */
+	    }
+        }
         break;
 
     case 0x11: /* QUERY GENERIC IOCTL CAPABILITY */
@@ -2729,6 +2861,128 @@
 
 
 /***********************************************************************
+ *           INT21_NetworkFunc
+ *
+ * Handler for:
+ * - function 0x5e
+ */
+static BOOL INT21_NetworkFunc (CONTEXT86 *context)
+{
+    switch (AL_reg(context)) 
+    {
+    case 0x00: /* Get machine name. */
+        {
+            char *dst = CTX_SEG_OFF_TO_LIN (context,context->SegDs,context->Edx);
+            TRACE("getting machine name to %p\n", dst);
+            if (gethostname (dst, 15))
+            {
+                WARN("failed!\n");
+                SetLastError( ER_NoNetwork );
+                return TRUE;
+            }
+            else 
+            {
+                int len = strlen (dst);
+                while (len < 15)
+		    dst[len++] = ' ';
+                dst[15] = 0;
+                SET_CH( context, 1 ); /* Valid */
+                SET_CL( context, 1 ); /* NETbios number??? */
+                TRACE("returning %s\n", debugstr_an (dst, 16));
+                return FALSE;
+            }
+        }
+
+    default:
+        SetLastError( ER_NoNetwork );
+        return TRUE;
+    }
+}
+
+/******************************************************************
+ *		INT21_GetDiskSerialNumber
+ *
+ */
+static int INT21_GetDiskSerialNumber( CONTEXT86 *context )
+{
+    BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
+    char path[] = {'A',':',0};
+
+    path[0] += BL_reg(context) ? BL_reg(context) - 1 : INT21_GetCurrentDrive();
+    if (!GetVolumeInformationA( path, (char *)(dataptr + 6), 11, 
+                                (DWORD *)(dataptr + 2),
+                                NULL, NULL, NULL, 0))
+    {
+        SetLastError( ERROR_INVALID_DRIVE );
+        return 0;
+    }
+
+    *(WORD *)dataptr = 0;
+    strncpy(dataptr + 0x11, "FAT16   ", 8);
+    return 1;
+}
+
+
+/******************************************************************
+ *		INT21_SetDiskSerialNumber
+ *
+ */
+static int INT21_SetDiskSerialNumber( CONTEXT86 *context )
+{
+#if 0
+    BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
+    int drive = BL_reg(context) ? BL_reg(context) - 1 : INT21_GetCurrentDrive();
+
+    if (!is_valid_drive(drive))
+    {
+        SetLastError( ERROR_INVALID_DRIVE );
+        return 0;
+    }
+
+    DRIVE_SetSerialNumber( drive, *(DWORD *)(dataptr + 2) );
+    return 1;
+#else
+    FIXME("Setting drive serial number is no longer supported\n");
+    SetLastError( ERROR_NOT_SUPPORTED );
+    return 0;
+#endif
+}
+
+
+/******************************************************************
+ *		INT21_GetFreeDiskSpace
+ *
+ */
+static int INT21_GetFreeDiskSpace( CONTEXT86 *context )
+{
+    DWORD cluster_sectors, sector_bytes, free_clusters, total_clusters;
+    char root[] = "A:\\";
+
+    *root += BL_reg(context) ? BL_reg(context) - 1 : INT21_GetCurrentDrive();
+    if (!GetDiskFreeSpaceA( root, &cluster_sectors, &sector_bytes,
+                              &free_clusters, &total_clusters )) return 0;
+    SET_AX( context, cluster_sectors );
+    SET_BX( context, free_clusters );
+    SET_CX( context, sector_bytes );
+    SET_DX( context, total_clusters );
+    return 1;
+}
+
+/******************************************************************
+ *		INT21_GetDriveAllocInfo
+ *
+ */
+static int INT21_GetDriveAllocInfo( CONTEXT86 *context )
+{
+    if (!INT21_GetFreeDiskSpace( context )) return 0;
+    if (!heap && !INT21_CreateHeap()) return 0;
+    heap->mediaID = 0xf0;
+    context->SegDs = DosHeapHandle;
+    SET_BX( context, (int)&heap->mediaID - (int)heap );
+    return 1;
+}
+
+/***********************************************************************
  *           INT21_GetExtendedError
  */
 static void INT21_GetExtendedError( CONTEXT86 *context )
@@ -2843,6 +3097,34 @@
     SET_CH( context, locus );
 }
 
+static BOOL INT21_CreateTempFile( CONTEXT86 *context )
+{
+    static int counter = 0;
+    char *name = CTX_SEG_OFF_TO_LIN(context,  context->SegDs, context->Edx );
+    char *p = name + strlen(name);
+
+    /* despite what Ralf Brown says, some programs seem to call without
+     * ending backslash (DOS accepts that, so we accept it too) */
+    if ((p == name) || (p[-1] != '\\')) *p++ = '\\';
+
+    for (;;)
+    {
+        sprintf( p, "wine%04x.%03d", (int)getpid(), counter );
+        counter = (counter + 1) % 1000;
+
+        SET_AX( context, 
+                Win32HandleToDosFileHandle( 
+                    CreateFileA( name, GENERIC_READ | GENERIC_WRITE,
+                                 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                                 CREATE_NEW, 0, 0 ) ) );
+        if (AX_reg(context) != HFILE_ERROR16)
+        {
+            TRACE("created %s\n", name );
+            return TRUE;
+        }
+        if (GetLastError() != ERROR_FILE_EXISTS) return FALSE;
+    }
+}
 
 /***********************************************************************
  *           DOSVM_Int21Handler
@@ -3101,8 +3383,12 @@
         break;
 
     case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
+        SET_DL( context, 0 );
+        if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
+        break;
+
     case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
-        INT_Int21Handler( context );
+        if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
         break;
 
     case 0x1d: /* NULL FUNCTION FOR CP/M COMPATIBILITY */
@@ -3356,7 +3642,9 @@
         break;
 
     case 0x36: /* GET FREE DISK SPACE */
-        INT_Int21Handler( context );
+	TRACE("GET FREE DISK SPACE FOR DRIVE %s\n",
+	      INT21_DriveName( DL_reg(context)));
+        if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
         break;
 
     case 0x37: /* SWITCHAR */
@@ -3834,7 +4122,8 @@
         break;
 
     case 0x5a: /* CREATE TEMPORARY FILE */
-        INT_Int21Handler( context );
+        TRACE("CREATE TEMPORARY FILE\n");
+        bSetDOSExtendedError = !INT21_CreateTempFile(context);
         break;
 
     case 0x5b: /* CREATE NEW FILE */ 
@@ -3881,11 +4170,26 @@
         break;
 
     case 0x5e: /* NETWORK 5E */
+        bSetDOSExtendedError = INT21_NetworkFunc( context);
+        break;
+
     case 0x5f: /* NETWORK 5F */
-    case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
         INT_Int21Handler( context );
         break;
 
+    case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
+        TRACE("TRUENAME %s\n",
+	      (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Esi));
+        {
+            if (!GetFullPathNameA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
+                                                      context->Esi), 128,
+                                   CTX_SEG_OFF_TO_LIN(context, context->SegEs,
+                                                      context->Edi),NULL))
+		bSetDOSExtendedError = TRUE;
+            else SET_AX( context, 0 );
+        }
+        break;
+
     case 0x61: /* UNUSED */
         SET_AL( context, 0 );
         break;
@@ -3942,7 +4246,22 @@
         break;
 
     case 0x69: /* DISK SERIAL NUMBER */
-        INT_Int21Handler( context );
+        switch (AL_reg(context))
+        {
+        case 0x00:
+	    TRACE("GET DISK SERIAL NUMBER for drive %s\n",
+		  INT21_DriveName(BL_reg(context)));
+            if (!INT21_GetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
+            else SET_AX( context, 0 );
+            break;
+
+        case 0x01:
+	    TRACE("SET DISK SERIAL NUMBER for drive %s\n",
+		  INT21_DriveName(BL_reg(context)));
+            if (!INT21_SetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
+            else SET_AX( context, 1 );
+            break;
+        }
         break;
 
     case 0x6a: /* COMMIT FILE */
Index: files/drive.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/files/drive.c,v
retrieving revision 1.100
diff -u -u -r1.100 drive.c
--- files/drive.c	15 Oct 2003 03:47:53 -0000	1.100
+++ files/drive.c	9 Nov 2003 16:06:43 -0000
@@ -1283,21 +963,28 @@
 
 
 /***********************************************************************
- *           DRIVE_SetLogicalMapping
+ *           DefineDosDeviceA       (KERNEL32.@)
  */
-int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
+BOOL WINAPI DefineDosDeviceA(DWORD flags,LPCSTR devname,LPCSTR targetpath) 
 {
- /* If new_drive is already valid, do nothing and return 0
-    otherwise, copy DOSDrives[existing_drive] to DOSDrives[new_drive] */
-
     DOSDRIVE *old, *new;
 
-    old = DOSDrives + existing_drive;
-    new = DOSDrives + new_drive;
+    /* this is a temporary hack for int21 support. better implementation has to be done */
+    if (flags != DDD_RAW_TARGET_PATH ||
+        !(toupper(devname[0]) >= 'A' && toupper(devname[0]) <= 'Z') ||
+        devname[1] != ':' || devname[2] != 0 ||
+        !(toupper(targetpath[0]) >= 'A' && toupper(targetpath[0]) <= 'Z') ||
+        targetpath[1] != ':' || targetpath[2] != '\\' || targetpath[3] != 0)
+    {
+        FIXME("(0x%08lx,%s,%s),stub!\n", flags, devname, targetpath);
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        return FALSE;
+    }
+
+    old = DOSDrives + devname[0] - 'A';
+    new = DOSDrives + targetpath[0] - 'A';
 
-    if ((existing_drive < 0) || (existing_drive >= MAX_DOS_DRIVES) ||
-        !old->root ||
-	(new_drive < 0) || (new_drive >= MAX_DOS_DRIVES))
+    if (!old->root)
     {
         SetLastError( ERROR_INVALID_DRIVE );
         return 0;
@@ -1306,7 +993,7 @@
     if ( new->root )
     {
         TRACE("Can't map drive %c: to already existing drive %c:\n",
-              'A' + existing_drive, 'A' + new_drive );
+              devname[0], targetpath[0] );
 	/* it is already mapped there, so return success */
 	if (!strcmp(old->root,new->root))
 	    return 1;
@@ -1327,7 +1014,7 @@
     new->ino = old->ino;
 
     TRACE("Drive %c: is now equal to drive %c:\n",
-          'A' + new_drive, 'A' + existing_drive );
+          targetpath[0], devname[0] );
 
     return 1;
 }
@@ -2126,8 +1781,8 @@
 /***********************************************************************
  *           GetVolumeNameForVolumeMountPointW   (KERNEL32.@)
  */
-DWORD WINAPI GetVolumeNameForVolumeMountPointW(LPWSTR str, DWORD a, DWORD b)
+BOOL WINAPI GetVolumeNameForVolumeMountPointW(LPCWSTR str, LPWSTR dst, DWORD size)
 {
-    FIXME("(%s, %lx, %lx): stub\n", debugstr_w(str), a, b);
+    FIXME("(%s, %p, %lx): stub\n", debugstr_w(str), dst, size);
     return 0;
 }
Index: include/winbase.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/include/winbase.h,v
retrieving revision 1.199
diff -u -u -r1.199 winbase.h
--- include/winbase.h	4 Nov 2003 04:52:54 -0000	1.199
+++ include/winbase.h	9 Nov 2003 15:53:06 -0000
@@ -1090,6 +1090,13 @@
 BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType );
 #define GetBinaryType WINELIB_NAME_AW(GetBinaryType)
 
+/* flags for DefineDosDevice */
+#define DDD_RAW_TARGET_PATH         0x00000001
+#define DDD_REMOVE_DEFINITION       0x00000002
+#define DDD_EXACT_MATCH_ON_REMOVE   0x00000004
+#define DDD_NO_BROADCAST_SYSTEM     0x00000008
+#define DDD_LUID_BROADCAST_DRIVE    0x00000010
+
 BOOL        WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID);
 PVOID       WINAPI AddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTION_HANDLER);
 BOOL        WINAPI AttachThreadInput(DWORD,DWORD,BOOL);
@@ -1182,9 +1189,15 @@
 void        WINAPI DebugBreak(void);
 BOOL        WINAPI DebugBreakProcess(HANDLE);
 BOOL        WINAPI DebugSetProcessKillOnExit(BOOL);
+BOOL        WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR);
+BOOL        WINAPI DefineDosDeviceW(DWORD,LPCSTR,LPCSTR);
+#define     DefineDosDevice WINELIB_NAME_AW(DefineDosDevice)
 void        WINAPI DeleteFiber(LPVOID);
 BOOL        WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
 BOOL        WINAPI DeleteTimerQueueTimer(HANDLE,HANDLE,HANDLE);
+BOOL        WINAPI DeleteVolumeMountPointA(LPCSTR);
+BOOL        WINAPI DeleteVolumeMountPointW(LPCWSTR);
+#define     DeleteVolumeMountPoint WINELIB_NAME_AW(DeleteVolumeMountPoint)
 BOOL        WINAPI DeregisterEventSource(HANDLE);
 BOOL        WINAPI DeviceIoControl(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
 BOOL        WINAPI DisableThreadLibraryCalls(HMODULE);
@@ -1223,6 +1236,20 @@
 HRSRC       WINAPI FindResourceExA(HMODULE,LPCSTR,LPCSTR,WORD);
 HRSRC       WINAPI FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
 #define     FindResourceEx WINELIB_NAME_AW(FindResourceEx)
+HANDLE      WINAPI FindFirstVolumeA(LPSTR,DWORD);
+HANDLE      WINAPI FindFirstVolumeW(LPWSTR,DWORD);
+#define     FindFirstVolume WINELIB_NAME_AW(FindFirstVolume)
+HANDLE      WINAPI FindFirstVolumeMountPointA(LPCSTR,LPSTR,DWORD);
+HANDLE      WINAPI FindFirstVolumeMountPointW(LPCWSTR,LPWSTR,DWORD);
+#define     FindFirstVolumeMountPoint WINELIB_NAME_AW(FindFirstVolumeMountPoint)
+BOOL        WINAPI FindNextVolumeA(HANDLE,LPSTR,DWORD);
+BOOL        WINAPI FindNextVolumeW(HANDLE,LPWSTR,DWORD);
+#define     FindNextVolume WINELIB_NAME_AW(FindNextVolume)
+BOOL        WINAPI FindNextVolumeMountPointA(HANDLE,LPSTR,DWORD);
+BOOL        WINAPI FindNextVolumeMountPointW(HANDLE,LPWSTR,DWORD);
+#define     FindNextVolumeMountPoint WINELIB_NAME_AW(FindNextVolumeMountPoint)
+BOOL        WINAPI FindVolumeClose(HANDLE);
+BOOL        WINAPI FindVolumeMountPointClose(HANDLE);
 BOOL        WINAPI FlushFileBuffers(HANDLE);
 BOOL        WINAPI FlushViewOfFile(LPCVOID,SIZE_T);
 DWORD       WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*);
@@ -1322,6 +1349,15 @@
 BOOL        WINAPI GetUserNameA(LPSTR,LPDWORD);
 BOOL        WINAPI GetUserNameW(LPWSTR,LPDWORD);
 #define     GetUserName WINELIB_NAME_AW(GetUserName)
+BOOL        WINAPI GetVolumeNameForVolumeMountPointA(LPCSTR,LPSTR,DWORD);
+BOOL        WINAPI GetVolumeNameForVolumeMountPointW(LPCWSTR,LPWSTR,DWORD);
+#define     GetVolumeNameForVolumeMountPoint WINELIB_NAME_AW(GetVolumeNameForVolumeMountPoint)
+BOOL        WINAPI GetVolumePathNameA(LPCSTR,LPSTR,DWORD);
+BOOL        WINAPI GetVolumePathNameW(LPCWSTR,LPWSTR,DWORD);
+#define     GetVolumePathName WINELIB_NAME_AW(GetVolumePathName)
+BOOL        WINAPI GetVolumePathNamesForVolumeNameA(LPCSTR,LPSTR,DWORD,PDWORD);
+BOOL        WINAPI GetVolumePathNamesForVolumeNameW(LPCWSTR,LPWSTR,DWORD,PDWORD);
+#define     GetVolumePathNamesForVolumeName WINELIB_NAME_AW(GetVolumePathNamesForVolumeName)
 VOID        WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
 LPVOID      WINAPI HeapAlloc(HANDLE,DWORD,SIZE_T);
 SIZE_T      WINAPI HeapCompact(HANDLE,DWORD);
@@ -1470,6 +1506,9 @@
 BOOL        WINAPI SetThreadPriorityBoost(HANDLE,BOOL);
 BOOL        WINAPI SetThreadToken(PHANDLE,HANDLE);
 BOOL        WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
+BOOL        WINAPI SetVolumeMountPointA(LPCSTR,LPCSTR);
+BOOL        WINAPI SetVolumeMountPointW(LPCSTR,LPCSTR);
+#define     SetVolumeMountPoint WINELIB_NAME_AW(SetVolumeMountPoint)
 BOOL        WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,BOOL);
 BOOL        WINAPI SetupComm(HANDLE,DWORD,DWORD);
 DWORD       WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL);
Index: msdos/int21.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/msdos/int21.c,v
retrieving revision 1.100
diff -u -u -r1.100 int21.c
--- msdos/int21.c	27 Oct 2003 22:06:10 -0000	1.100
+++ msdos/int21.c	9 Nov 2003 18:20:26 -0000
@@ -70,30 +70,10 @@
 #define LOCK_NB  8
 #endif
 
-
 #define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive())
 
-struct DosHeap {
-        BYTE mediaID;
-	BYTE biosdate[8];
-};
-static struct DosHeap *heap;
-static WORD DosHeapHandle;
-
 extern char TempDirectory[];
 
-static BOOL INT21_CreateHeap(void)
-{
-    if (!(DosHeapHandle = GlobalAlloc16(GMEM_FIXED,sizeof(struct DosHeap))))
-    {
-        WARN("Out of memory\n");
-        return FALSE;
-    }
-    heap = (struct DosHeap *) GlobalLock16(DosHeapHandle);
-    strcpy(heap->biosdate, "01/01/80");
-    return TRUE;
-}
-
 static BYTE *GetCurrentDTA( CONTEXT86 *context )
 {
     TDB *pTask = GlobalLock16(GetCurrentTask());
@@ -104,146 +84,6 @@
 }
 
 
-static void CreateBPB(int drive, BYTE *data, BOOL16 limited)
-/* limited == TRUE is used with INT 0x21/0x440d */
-{
-	if (drive > 1) {
-		setword(data, 512);
-		data[2] = 2;
-		setword(&data[3], 0);
-		data[5] = 2;
-		setword(&data[6], 240);
-		setword(&data[8], 64000);
-		data[0x0a] = 0xf8;
-		setword(&data[0x0b], 40);
-		setword(&data[0x0d], 56);
-		setword(&data[0x0f], 2);
-		setword(&data[0x11], 0);
-		if (!limited) {
-		    setword(&data[0x1f], 800);
-		    data[0x21] = 5;
-		    setword(&data[0x22], 1);
-		}
-	} else { /* 1.44mb */
-		setword(data, 512);
-		data[2] = 2;
-		setword(&data[3], 0);
-		data[5] = 2;
-		setword(&data[6], 240);
-		setword(&data[8], 2880);
-		data[0x0a] = 0xf8;
-		setword(&data[0x0b], 6);
-		setword(&data[0x0d], 18);
-		setword(&data[0x0f], 2);
-		setword(&data[0x11], 0);
-		if (!limited) {
-		    setword(&data[0x1f], 80);
-		    data[0x21] = 7;
-		    setword(&data[0x22], 2);
-		}
-	}
-}
-
-static int INT21_GetFreeDiskSpace( CONTEXT86 *context )
-{
-    DWORD cluster_sectors, sector_bytes, free_clusters, total_clusters;
-    char root[] = "A:\\";
-
-    *root += DOS_GET_DRIVE( DL_reg(context) );
-    if (!GetDiskFreeSpaceA( root, &cluster_sectors, &sector_bytes,
-                              &free_clusters, &total_clusters )) return 0;
-    SET_AX( context, cluster_sectors );
-    SET_BX( context, free_clusters );
-    SET_CX( context, sector_bytes );
-    SET_DX( context, total_clusters );
-    return 1;
-}
-
-static int INT21_GetDriveAllocInfo( CONTEXT86 *context )
-{
-    if (!INT21_GetFreeDiskSpace( context )) return 0;
-    if (!heap && !INT21_CreateHeap()) return 0;
-    heap->mediaID = 0xf0;
-    context->SegDs = DosHeapHandle;
-    SET_BX( context, (int)&heap->mediaID - (int)heap );
-    return 1;
-}
-
-static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
-{
-	BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
-	int drive = DOS_GET_DRIVE( BL_reg(context) );
-
-	if (!DRIVE_IsValid(drive))
-        {
-            SetLastError( ERROR_FILE_NOT_FOUND );
-            return TRUE;
-	}
-
-	if (CH_reg(context) != 0x08)
-        {
-            INT_BARF( context, 0x21 );
-            return FALSE;
-	}
-
-	switch (CL_reg(context))
-	{
-		case 0x60: /* get device parameters */
-			   /* used by w4wgrp's winfile */
-			memset(dataptr, 0, 0x20); /* DOS 6.22 uses 0x20 bytes */
-			dataptr[0] = 0x04;
-			dataptr[6] = 0; /* media type */
-			if (drive > 1)
-			{
-				dataptr[1] = 0x05; /* fixed disk */
-				setword(&dataptr[2], 0x01); /* non removable */
-				setword(&dataptr[4], 0x300); /* # of cylinders */
-			}
-			else
-			{
-				dataptr[1] = 0x07; /* block dev, floppy */
-				setword(&dataptr[2], 0x02); /* removable */
-				setword(&dataptr[4], 80); /* # of cylinders */
-			}
-			CreateBPB(drive, &dataptr[7], TRUE);
-			RESET_CFLAG(context);
-			break;
-
-		case 0x66:/*  get disk serial number */
-			{
-				char	label[12],fsname[9],path[4];
-				DWORD	serial;
-
-				strcpy(path,"x:\\");path[0]=drive+'A';
-				GetVolumeInformationA(
-					path,label,12,&serial,NULL,NULL,fsname,9
-				);
-				*(WORD*)dataptr		= 0;
-				memcpy(dataptr+2,&serial,4);
-				memcpy(dataptr+6,label	,11);
-				memcpy(dataptr+17,fsname,8);
-			}
-			break;
-
-		case 0x6f:
-			memset(dataptr+1, '\0', dataptr[0]-1);
-			dataptr[1] = dataptr[0];
-			dataptr[2] = 0x07; /* protected mode driver; no eject; no notification */
-			dataptr[3] = 0xFF; /* no physical drive */
-			break;
-
-		case 0x72:
-			/* Trail on error implementation */
-			SET_AX( context, GetDriveType16(BL_reg(context)) == DRIVE_UNKNOWN ? 0x0f : 0x01 );
-			SET_CFLAG(context);	/* Seems to be set all the time */
-			break;
-
-		default:
-                        INT_BARF( context, 0x21 );
-	}
-	return FALSE;
-}
-
 static void INT21_ParseFileNameIntoFCB( CONTEXT86 *context )
 {
     char *filename =
@@ -289,25 +129,6 @@
 }
 
 
-/* Many calls translate a drive argument like this:
-   drive number (00h = default, 01h = A:, etc)
-   */
-static const char *INT21_DriveName(int drive)
-{
-    if (drive > 0) return wine_dbg_sprintf( "%c:", 'A' + drive - 1 );
-    return "default";
-}
-
-static HFILE16 _lcreat16_uniq( LPCSTR path, INT attr )
-{
-    /* Mask off all flags not explicitly allowed by the doc */
-    attr &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
-    return Win32HandleToDosFileHandle( CreateFileA( path, GENERIC_READ | GENERIC_WRITE,
-                                             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                                             CREATE_NEW, attr, 0 ));
-}
-
-
 static int INT21_FindFirst( CONTEXT86 *context )
 {
     char *p;
@@ -392,68 +213,6 @@
     return 1;
 }
 
-
-static BOOL INT21_CreateTempFile( CONTEXT86 *context )
-{
-    static int counter = 0;
-    char *name = CTX_SEG_OFF_TO_LIN(context,  context->SegDs, context->Edx );
-    char *p = name + strlen(name);
-
-    /* despite what Ralf Brown says, some programs seem to call without
-     * ending backslash (DOS accepts that, so we accept it too) */
-    if ((p == name) || (p[-1] != '\\')) *p++ = '\\';
-
-    for (;;)
-    {
-        sprintf( p, "wine%04x.%03d", (int)getpid(), counter );
-        counter = (counter + 1) % 1000;
-
-        SET_AX( context, _lcreat16_uniq( name, 0 ) );
-        if (AX_reg(context) != HFILE_ERROR16)
-        {
-            TRACE("created %s\n", name );
-            return TRUE;
-        }
-        if (GetLastError() != ERROR_FILE_EXISTS) return FALSE;
-    }
-}
-
-
-static int INT21_GetDiskSerialNumber( CONTEXT86 *context )
-{
-    BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
-    int drive = DOS_GET_DRIVE( BL_reg(context) );
-
-    if (!DRIVE_IsValid(drive))
-    {
-        SetLastError( ERROR_INVALID_DRIVE );
-        return 0;
-    }
-
-    *(WORD *)dataptr = 0;
-    *(DWORD *)(dataptr + 2) = DRIVE_GetSerialNumber( drive );
-    memcpy( dataptr + 6, DRIVE_GetLabel( drive ), 11 );
-    strncpy(dataptr + 0x11, "FAT16   ", 8);
-    return 1;
-}
-
-
-static int INT21_SetDiskSerialNumber( CONTEXT86 *context )
-{
-    BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
-    int drive = DOS_GET_DRIVE( BL_reg(context) );
-
-    if (!DRIVE_IsValid(drive))
-    {
-        SetLastError( ERROR_INVALID_DRIVE );
-        return 0;
-    }
-
-    DRIVE_SetSerialNumber( drive, *(DWORD *)(dataptr + 2) );
-    return 1;
-}
-
-
 /* microsoft's programmers should be shot for using CP/M style int21
    calls in Windows for Workgroup's winfile.exe */
 
@@ -550,38 +309,6 @@
 }
 
 
-static BOOL
-INT21_networkfunc (CONTEXT86 *context)
-{
-     switch (AL_reg(context)) {
-     case 0x00: /* Get machine name. */
-     {
-	  char *dst = CTX_SEG_OFF_TO_LIN (context,context->SegDs,context->Edx);
-	  TRACE("getting machine name to %p\n", dst);
-	  if (gethostname (dst, 15))
-	  {
-	       WARN("failed!\n");
-	       SetLastError( ER_NoNetwork );
-	       return TRUE;
-	  } else {
-	       int len = strlen (dst);
-	       while (len < 15)
-		    dst[len++] = ' ';
-	       dst[15] = 0;
-	       SET_CH( context, 1 ); /* Valid */
-	       SET_CL( context, 1 ); /* NETbios number??? */
-	       TRACE("returning %s\n", debugstr_an (dst, 16));
-	       return FALSE;
-	  }
-     }
-
-     default:
-	  SetLastError( ER_NoNetwork );
-	  return TRUE;
-     }
-}
-
-
 /***********************************************************************
  *           INT_Int21Handler
  */
@@ -605,50 +332,10 @@
         SET_AL( context, INT21_FindNextFCB(context) ? 0x00 : 0xff );
         break;
 
-    case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
-        SET_DL( context, 0 );
-        if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
-        break;
-
-    case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
-        if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
-        break;
-
     case 0x29: /* PARSE FILENAME INTO FCB */
         INT21_ParseFileNameIntoFCB(context);
         break;
 
-    case 0x36: /* GET FREE DISK SPACE */
-	TRACE("GET FREE DISK SPACE FOR DRIVE %s\n",
-	      INT21_DriveName( DL_reg(context)));
-        if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
-        break;
-
-    case 0x44: /* IOCTL */
-        switch (AL_reg(context))
-        {
-        case 0x0d:
-            TRACE("IOCTL - GENERIC BLOCK DEVICE REQUEST %s\n",
-		  INT21_DriveName( BL_reg(context)));
-            bSetDOSExtendedError = ioctlGenericBlkDevReq(context);
-            break;
-
-        case 0x0F:   /* Set logical drive mapping */
-	    {
-	    int drive;
-            TRACE("IOCTL - SET LOGICAL DRIVE MAP for drive %s\n",
-		  INT21_DriveName( BL_reg(context)));
-	    drive = DOS_GET_DRIVE ( BL_reg(context) );
-	    if ( ! DRIVE_SetLogicalMapping ( drive, drive+1 ) )
-	    {
-		SET_CFLAG(context);
-		SET_AX( context, 0x000F );  /* invalid drive */
-	    }
-            break;
-	    }
-        }
-        break;
-
     case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
         TRACE("FINDFIRST mask 0x%04x spec %s\n",CX_reg(context),
 	      (LPCSTR)CTX_SEG_OFF_TO_LIN(context,  context->SegDs, context->Edx));
@@ -666,15 +353,6 @@
         else SET_AX( context, 0 );  /* OK */
         break;
 
-    case 0x5a: /* CREATE TEMPORARY FILE */
-        TRACE("CREATE TEMPORARY FILE\n");
-        bSetDOSExtendedError = !INT21_CreateTempFile(context);
-        break;
-
-    case 0x5e:
-	bSetDOSExtendedError = INT21_networkfunc (context);
-        break;
-
     case 0x5f: /* NETWORK */
         switch (AL_reg(context))
         {
@@ -696,47 +374,6 @@
             }
             break;
 
-        default:
-            /* network software not installed */
-            TRACE("NETWORK function AX=%04x not implemented\n",AX_reg(context));
-            SetLastError( ER_NoNetwork );
-	    bSetDOSExtendedError = TRUE;
-            break;
-        }
-        break;
-
-    case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
-        TRACE("TRUENAME %s\n",
-	      (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Esi));
-        {
-            if (!GetFullPathNameA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
-                                                        context->Esi), 128,
-                                     CTX_SEG_OFF_TO_LIN(context, context->SegEs,
-                                                        context->Edi),NULL))
-		bSetDOSExtendedError = TRUE;
-            else SET_AX( context, 0 );
-        }
-        break;
-
-    case 0x69: /* DISK SERIAL NUMBER */
-        switch (AL_reg(context))
-        {
-        case 0x00:
-	    TRACE("GET DISK SERIAL NUMBER for drive %s\n",
-		  INT21_DriveName(BL_reg(context)));
-            if (!INT21_GetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
-            else SET_AX( context, 0 );
-            break;
-
-        case 0x01:
-	    TRACE("SET DISK SERIAL NUMBER for drive %s\n",
-		  INT21_DriveName(BL_reg(context)));
-            if (!INT21_SetDiskSerialNumber(context)) bSetDOSExtendedError = TRUE;
-            else SET_AX( context, 1 );
-            break;
-        }
-        break;
-
     case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
         switch(AL_reg(context))
         {


More information about the wine-patches mailing list