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, §or_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, §or_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