final int21 move (5/11)
György 'Nog' Jeney
nog at sdf.lonestar.org
Wed Nov 27 12:06:19 CST 2002
ChangeLog:
* dlls/winedos/int21.c
* msdos/int21.c
Move drive functions to winedos.
nog.
-------------- next part --------------
--- msdos/int21.c.4 2002-11-27 15:52:16.000000000 +0200
+++ msdos/int21.c 2002-11-27 15:52:41.000000000 +0200
@@ -199,31 +199,6 @@
}
}
-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 int FillInDrivePB( int drive )
{
if(!DRIVE_IsValid(drive))
@@ -263,21 +238,6 @@
return 0;
}
-static void GetDrivePB( CONTEXT86 *context, int drive )
-{
- if (FillInDrivePB( drive ))
- {
- SET_AL( context, 0x00 );
- context->SegDs = SELECTOROF(dpbsegptr);
- SET_BX( context, OFFSETOF(dpbsegptr) );
- }
- else
- {
- SET_AX( context, 0x00ff );
- }
-}
-
-
static void ioctlGetDeviceInfo( CONTEXT86 *context )
{
int curr_drive;
@@ -574,22 +534,6 @@
return TRUE;
}
-
-static void INT21_GetDBCSLeadTable( CONTEXT86 *context )
-{
- if (heap || INT21_CreateHeap())
- { /* return an empty table just as DOS 4.0+ does */
- context->SegDs = DosHeapHandle;
- SET_SI( context, (int)&heap->DummyDBCSLeadTable - (int)heap );
- }
- else
- {
- SET_AX( context, 0x1 ); /* error */
- SET_CFLAG(context);
- }
-}
-
-
static int INT21_GetDiskSerialNumber( CONTEXT86 *context )
{
BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
@@ -783,19 +727,6 @@
}
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 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
- GetDrivePB(context, DRIVE_GetCurrentDrive());
- break;
-
case 0x2a: /* GET SYSTEM DATE */
INT21_GetSystemDate(context);
break;
@@ -843,12 +774,6 @@
FIXME("TERMINATE AND STAY RESIDENT stub\n");
break;
- case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
- TRACE("GET DOS DRIVE PARAMETER BLOCK FOR DRIVE %s\n",
- INT21_DriveName( DL_reg(context)));
- GetDrivePB(context, DOS_GET_DRIVE( DL_reg(context) ) );
- break;
-
case 0x33: /* MULTIPLEXED */
switch (AL_reg(context))
{
@@ -898,13 +823,6 @@
}
break;
- case 0x34: /* GET ADDRESS OF INDOS FLAG */
- TRACE("GET ADDRESS OF INDOS FLAG\n");
- if (!heap) INT21_CreateHeap();
- context->SegEs = DosHeapHandle;
- SET_BX( context, (int)&heap->InDosFlag - (int)heap );
- break;
-
case 0x37:
{
unsigned char switchchar='/';
@@ -1189,14 +1107,6 @@
}
break;
- case 0x61: /* UNUSED */
- case 0x63: /* misc. language support */
- switch (AL_reg(context)) {
- case 0x00: /* GET DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */
- INT21_GetDBCSLeadTable(context);
- break;
- }
- break;
case 0x64: /* OS/2 DOS BOX */
INT_BARF( context, 0x21 );
SET_CFLAG(context);
--- dlls/winedos/int21.c.4 2002-11-27 15:52:24.000000000 +0200
+++ dlls/winedos/int21.c 2002-11-27 15:52:41.000000000 +0200
@@ -41,6 +41,94 @@
WINE_DEFAULT_DEBUG_CHANNEL(int21);
+/* Define the drive parameter block, as used by int21/1F
+ * and int21/32. This table can be accessed through the
+ * global 'dpb' pointer, which points into the local dos
+ * heap.
+ */
+struct DPB
+{
+ BYTE drive_num; /* 0=A, etc. */
+ BYTE unit_num; /* Drive's unit number (?) */
+ WORD sector_size; /* Sector size in bytes */
+ BYTE high_sector; /* Highest sector in a cluster */
+ BYTE shift; /* Shift count (?) */
+ WORD reserved; /* Number of reserved sectors at start */
+ BYTE num_FAT; /* Number of FATs */
+ WORD dir_entries; /* Number of root dir entries */
+ WORD first_data; /* First data sector */
+ WORD high_cluster; /* Highest cluster number */
+ WORD sectors_in_FAT; /* Number of sectors per FAT */
+ WORD start_dir; /* Starting sector of first dir */
+ DWORD driver_head; /* Address of device driver header (?) */
+ BYTE media_ID; /* Media ID */
+ BYTE access_flag; /* Prev. accessed flag (0=yes,0xFF=no) */
+ DWORD next; /* Pointer to next DPB in list */
+ WORD free_search; /* Free cluster search start */
+ WORD free_clusters; /* Number of free clusters (0xFFFF=unknown) */
+};
+
+struct EDPB /* FAT32 extended Drive Parameter Block */
+{ /* from Ralf Brown's Interrupt List */
+ struct DPB dpb; /* first 24 bytes = original DPB */
+
+ BYTE edpb_flags; /* undocumented/unknown flags */
+ DWORD next_edpb; /* pointer to next EDPB */
+ WORD free_cluster; /* cluster to start search for free space on write,
+ * typically the last cluster allocated */
+ WORD clusters_free; /* number of free clusters on drive or
+ * FFFF = unknown */
+ WORD clusters_free_hi; /* hiword of clusters_free */
+ WORD mirroring_flags; /* mirroring flags: bit 7 set = do not mirror active * FAT */
+ /* bits 0-3 = 0-based number of the active FAT */
+ WORD info_sector; /* sector number of file system info sector, or FFFF * for none */
+ WORD spare_boot_sector; /* sector number of backup boot sector, or FFFF for
+ * none */
+ DWORD first_cluster; /* sector number of the first cluster */
+ DWORD max_cluster; /* sector number of the last cluster */
+ DWORD fat_clusters; /* number of clusters occupied by FAT */
+ DWORD root_cluster; /* cluster number of start of root directory */
+ DWORD free_cluster2; /* same as free_cluster: cluster at which to start
+ * search for free space when writing */
+};
+
+struct DosHeap {
+ BYTE InDosFlag;
+ BYTE mediaID;
+ BYTE biosdate[8];
+ struct DPB dpb;
+ BYTE DummyDBCSLeadTable[6];
+};
+static struct DosHeap *heap;
+static WORD DosHeapHandle;
+
+DWORD dpbsegptr;
+
+/***********************************************************************
+ * INT21_CreateHeap [internal]
+ *
+ * Allocates a heap for us to use internally.
+ *
+ * PARAMS:
+ * None.
+ *
+ * RETURNS
+ * Handle to heap.
+ */
+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);
+ dpbsegptr = MAKESEGPTR(DosHeapHandle, (int)&heap->dpb - (int)heap);
+ heap->InDosFlag = 0;
+ strcpy(heap->biosdate, "01/01/80");
+ memset(heap->DummyDBCSLeadTable, 0, 6);
+ return TRUE;
+}
+
/***********************************************************************
* GetDosDrive [internal]
*
@@ -362,6 +450,122 @@
}
/***********************************************************************
+ * INT21_GetDriveAllocInfo [internal]
+ *
+ * Returns drive allocation info.
+ *
+ * PARAMS:
+ * context [I]: Pointer to structure holding registers.
+ *
+ * RETURNS:
+ * 1: Success.
+ */
+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;
+}
+
+/***********************************************************************
+ * FillInDrivePB [internal]
+ *
+ * Initializes a Drive Parameter Block.
+ *
+ * PARAMS:
+ * context [I]: Pointer to structure holding registers.
+ *
+ * RETURNS:
+ * 0: Failure.
+ * 1: Success.
+ */
+static int FillInDrivePB(int drive)
+{
+ if(!IsDriveValid(drive)) {
+ SetLastError(ERROR_INVALID_DRIVE);
+ return 0;
+ } else if (heap || INT21_CreateHeap()) {
+ /* FIXME: I have no idea what a lot of this information should
+ * say or whether it even really matters since we're not allowing
+ * direct block access. However, some programs seem to depend on
+ * getting at least _something_ back from here. The 'next' pointer
+ * does worry me, though. Should we have a complete table of
+ * separate DPBs per drive? Probably, but I'm lazy. :-) -CH
+ */
+ heap->dpb.drive_num = heap->dpb.unit_num = drive; /* The same? */
+ heap->dpb.sector_size = 512;
+ heap->dpb.high_sector = 1;
+ heap->dpb.shift = drive < 2 ? 0 : 6; /* 6 for HD, 0 for floppy */
+ heap->dpb.reserved = 0;
+ heap->dpb.reserved = 0;
+ heap->dpb.num_FAT = 1;
+ heap->dpb.dir_entries = 2;
+ heap->dpb.first_data = 2;
+ heap->dpb.high_cluster = 64000;
+ heap->dpb.sectors_in_FAT = 1;
+ heap->dpb.start_dir = 1;
+ heap->dpb.driver_head = 0;
+ heap->dpb.media_ID = (drive > 1) ? 0xF8 : 0xF0;
+ heap->dpb.access_flag = 0;
+ heap->dpb.next = 0;
+ heap->dpb.free_search = 0;
+ heap->dpb.free_clusters = 0xFFFF; /* unknown */
+ return 1;
+ }
+
+ return 0;
+}
+
+/***********************************************************************
+ * GetDrivePB [internal]
+ *
+ * Returns a drive parameter block for a certain drive.
+ *
+ * PARAMS:
+ * context [I]: Pointer to structure holding registers.
+ * drive [I]: Drive who's DPB to retrieve.
+ *
+ * RETURNS:
+ * Nothing.
+ */
+static void GetDrivePB(CONTEXT86 *context, int drive)
+{
+ if (FillInDrivePB(drive)) {
+ SET_AL(context, 0x00);
+ context->SegDs = SELECTOROF(dpbsegptr);
+ SET_BX(context, OFFSETOF(dpbsegptr));
+ } else {
+ SET_AX(context, 0x00ff);
+ }
+}
+
+/***********************************************************************
+ * INT21_GetDBCSLeadTable [internal]
+ *
+ * Returns a DBCS Table.
+ *
+ * PARAMS:
+ * context [I]: Pointer to structure holding registers.
+ *
+ * RETURNS:
+ * Nothing.
+ */
+static void INT21_GetDBCSLeadTable(CONTEXT86 *context)
+{
+ if(heap || INT21_CreateHeap()) {
+ /* return an empty table just as DOS 4.0+ does */
+ context->SegDs = DosHeapHandle;
+ SET_SI(context, (int)&heap->DummyDBCSLeadTable - (int)heap);
+ } else {
+ SET_AX(context, 0x1); /* error */
+ SET_CFLAG(context);
+ }
+}
+
+/***********************************************************************
* GetCurrentDTA [internal]
*
* Returns a pointer to the current DTA.
@@ -1070,6 +1274,19 @@
SET_AL(context, GetDosDrive(0));
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 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
+ GetDrivePB(context, GetDosDrive(0));
+ break;
+
case 0x25: /* SET INTERRUPT VECTOR */
if(DOSVM_IsWin16()) DOSVM_SetPMHandler16(AL_reg(context),
(FARPROC16)MAKESEGPTR(context->SegDs,
@@ -1094,6 +1311,19 @@
}
break;
+ case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
+ TRACE("GET DOS DRIVE PARAMETER BLOCK FOR DRIVE %s\n",
+ INT21_DriveName(DL_reg(context)));
+ GetDrivePB(context, GetDosDrive(DL_reg(context)));
+ break;
+
+ case 0x34: /* GET ADDRESS OF INDOS FLAG */
+ TRACE("GET ADDRESS OF INDOS FLAG\n");
+ if(!heap) INT21_CreateHeap();
+ context->SegEs = DosHeapHandle;
+ SET_BX(context, (int)&heap->InDosFlag - (int)heap);
+ break;
+
case 0x35: /* GET INTERRUPT VECTOR */
{
FARPROC16 addr;
@@ -1502,6 +1732,14 @@
else SET_BX(context, DOSVM_psp);
break;
+ case 0x63: /* misc. language support */
+ switch (AL_reg(context)) {
+ case 0x00: /* GET DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE */
+ INT21_GetDBCSLeadTable(context);
+ break;
+ }
+ break;
+
case 0x68: /* "FFLUSH" - COMMIT FILE */
TRACE("FFLUSH/COMMIT handle %d\n",BX_reg(context));
bSetDOSExtendedError = (!FlushFileBuffers(DosFileHandleToWin32Handle(
More information about the wine-patches
mailing list