Moved drive parameter block (DPB) routines to winedos.
This commit is contained in:
parent
f227cfaac6
commit
181a7cca2b
|
@ -58,6 +58,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(int21);
|
||||||
|
|
||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended Drive Parameter Block.
|
||||||
|
* This structure is compatible with standard DOS4+ DPB and
|
||||||
|
* extended DOS7 DPB.
|
||||||
|
*/
|
||||||
|
typedef struct _INT21_DPB {
|
||||||
|
BYTE drive; /* 00 drive number (0=A, ...) */
|
||||||
|
BYTE unit; /* 01 unit number within device driver */
|
||||||
|
WORD sector_bytes; /* 02 bytes per sector */
|
||||||
|
BYTE cluster_sectors; /* 04 highest sector number within a cluster */
|
||||||
|
BYTE shift; /* 05 shift count to convert clusters into sectors */
|
||||||
|
WORD num_reserved; /* 06 reserved sectors at beginning of drive */
|
||||||
|
BYTE num_FAT; /* 08 number of FATs */
|
||||||
|
WORD num_root_entries; /* 09 number of root directory entries */
|
||||||
|
WORD first_data_sector; /* 0b number of first sector containing user data */
|
||||||
|
WORD num_clusters1; /* 0d highest cluster number (number of data clusters + 1) */
|
||||||
|
WORD sectors_per_FAT; /* 0f number of sectors per FAT */
|
||||||
|
WORD first_dir_sector; /* 11 sector number of first directory sector */
|
||||||
|
SEGPTR driver_header; /* 13 address of device driver header */
|
||||||
|
BYTE media_ID; /* 17 media ID byte */
|
||||||
|
BYTE access_flag; /* 18 0x00 if disk accessed, 0xff if not */
|
||||||
|
SEGPTR next; /* 19 pointer to next DPB */
|
||||||
|
WORD search_cluster1; /* 1d cluster at which to start search for free space */
|
||||||
|
WORD free_clusters_lo; /* 1f number of free clusters on drive or 0xffff if unknown */
|
||||||
|
WORD free_clusters_hi; /* 21 hiword of clusters_free */
|
||||||
|
WORD mirroring_flags; /* 23 active FAT/mirroring flags */
|
||||||
|
WORD info_sector; /* 25 sector number of file system info sector or 0xffff for none */
|
||||||
|
WORD spare_boot_sector; /* 27 sector number of backup boot sector or 0xffff for none */
|
||||||
|
DWORD first_cluster_sector; /* 29 sector number of the first cluster */
|
||||||
|
DWORD num_clusters2; /* 2d maximum cluster number */
|
||||||
|
DWORD fat_clusters; /* 31 number of clusters occupied by FAT */
|
||||||
|
DWORD root_cluster; /* 35 cluster number of start of root directory */
|
||||||
|
DWORD search_cluster2; /* 39 cluster at which to start searching for free space */
|
||||||
|
} INT21_DPB;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure for DOS data that can be accessed directly from applications.
|
* Structure for DOS data that can be accessed directly from applications.
|
||||||
* Real and protected mode pointers will be returned to this structure so
|
* Real and protected mode pointers will be returned to this structure so
|
||||||
|
@ -87,7 +123,11 @@ typedef struct _INT21_HEAP {
|
||||||
WORD dbcs_size; /* Number of valid ranges in the following table */
|
WORD dbcs_size; /* Number of valid ranges in the following table */
|
||||||
BYTE dbcs_table[16]; /* Start/end bytes for N ranges and 00/00 as terminator */
|
BYTE dbcs_table[16]; /* Start/end bytes for N ranges and 00/00 as terminator */
|
||||||
|
|
||||||
BYTE misc_indos; /* Interrupt 21 nesting flag */
|
BYTE misc_indos; /* Interrupt 21 nesting flag */
|
||||||
|
WORD misc_segment; /* Real mode segment for INT21_HEAP */
|
||||||
|
WORD misc_selector; /* Protected mode selector for INT21_HEAP */
|
||||||
|
INT21_DPB misc_dpb_list[MAX_DOS_DRIVES]; /* Drive parameter blocks for all drives */
|
||||||
|
|
||||||
} INT21_HEAP;
|
} INT21_HEAP;
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,6 +393,39 @@ static void INT21_FillHeap( INT21_HEAP *heap )
|
||||||
* Initialize InDos flag.
|
* Initialize InDos flag.
|
||||||
*/
|
*/
|
||||||
heap->misc_indos = 0;
|
heap->misc_indos = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Should drive parameter blocks (DPB) be
|
||||||
|
* initialized here and linked to DOS LOL?
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_GetHeapPointer
|
||||||
|
*
|
||||||
|
* Get pointer for DOS heap (INT21_HEAP).
|
||||||
|
* Creates and initializes heap on first call.
|
||||||
|
*/
|
||||||
|
static INT21_HEAP *INT21_GetHeapPointer( void )
|
||||||
|
{
|
||||||
|
static INT21_HEAP *heap_pointer = NULL;
|
||||||
|
|
||||||
|
if (!heap_pointer)
|
||||||
|
{
|
||||||
|
WORD heap_segment;
|
||||||
|
WORD heap_selector;
|
||||||
|
|
||||||
|
heap_pointer = DOSVM_AllocDataUMB( sizeof(INT21_HEAP),
|
||||||
|
&heap_segment,
|
||||||
|
&heap_selector );
|
||||||
|
|
||||||
|
heap_pointer->misc_segment = heap_segment;
|
||||||
|
heap_pointer->misc_selector = heap_selector;
|
||||||
|
INT21_FillHeap( heap_pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
return heap_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,23 +437,94 @@ static void INT21_FillHeap( INT21_HEAP *heap )
|
||||||
*/
|
*/
|
||||||
static WORD INT21_GetHeapSelector( CONTEXT86 *context )
|
static WORD INT21_GetHeapSelector( CONTEXT86 *context )
|
||||||
{
|
{
|
||||||
static WORD heap_segment = 0;
|
INT21_HEAP *heap = INT21_GetHeapPointer();
|
||||||
static WORD heap_selector = 0;
|
|
||||||
static BOOL heap_initialized = FALSE;
|
|
||||||
|
|
||||||
if (!heap_initialized)
|
|
||||||
{
|
|
||||||
INT21_HEAP *ptr = DOSVM_AllocDataUMB( sizeof(INT21_HEAP),
|
|
||||||
&heap_segment,
|
|
||||||
&heap_selector );
|
|
||||||
INT21_FillHeap( ptr );
|
|
||||||
heap_initialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ISV86(context) && DOSVM_IsWin16())
|
if (!ISV86(context) && DOSVM_IsWin16())
|
||||||
return heap_selector;
|
return heap->misc_selector;
|
||||||
else
|
else
|
||||||
return heap_segment;
|
return heap->misc_segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_FillDrivePB
|
||||||
|
*
|
||||||
|
* Fill DOS heap drive parameter block for the specified drive.
|
||||||
|
* Return TRUE if drive was valid and there were
|
||||||
|
* no errors while reading drive information.
|
||||||
|
*/
|
||||||
|
static BOOL INT21_FillDrivePB( BYTE drive )
|
||||||
|
{
|
||||||
|
WCHAR drivespec[3] = {'A', ':', 0};
|
||||||
|
INT21_HEAP *heap = INT21_GetHeapPointer();
|
||||||
|
INT21_DPB *dpb;
|
||||||
|
UINT drivetype;
|
||||||
|
DWORD cluster_sectors;
|
||||||
|
DWORD sector_bytes;
|
||||||
|
DWORD free_clusters;
|
||||||
|
DWORD total_clusters;
|
||||||
|
|
||||||
|
if (drive >= MAX_DOS_DRIVES)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dpb = &heap->misc_dpb_list[drive];
|
||||||
|
drivespec[0] += drive;
|
||||||
|
drivetype = GetDriveTypeW( drivespec );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Does this check work correctly with floppy/cdrom drives?
|
||||||
|
*/
|
||||||
|
if (drivetype == DRIVE_NO_ROOT_DIR || drivetype == DRIVE_UNKNOWN)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Does this check work correctly with floppy/cdrom drives?
|
||||||
|
*/
|
||||||
|
if (!GetDiskFreeSpaceW( drivespec, &cluster_sectors, §or_bytes,
|
||||||
|
&free_clusters, &total_clusters ))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Most of the values listed below are incorrect.
|
||||||
|
* All values should be validated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dpb->drive = drive;
|
||||||
|
dpb->unit = 0;
|
||||||
|
dpb->sector_bytes = sector_bytes;
|
||||||
|
dpb->cluster_sectors = cluster_sectors - 1;
|
||||||
|
|
||||||
|
dpb->shift = 0;
|
||||||
|
while (cluster_sectors > 1)
|
||||||
|
{
|
||||||
|
cluster_sectors /= 2;
|
||||||
|
dpb->shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dpb->num_reserved = 0;
|
||||||
|
dpb->num_FAT = 1;
|
||||||
|
dpb->num_root_entries = 2;
|
||||||
|
dpb->first_data_sector = 2;
|
||||||
|
dpb->num_clusters1 = total_clusters;
|
||||||
|
dpb->sectors_per_FAT = 1;
|
||||||
|
dpb->first_dir_sector = 1;
|
||||||
|
dpb->driver_header = 0;
|
||||||
|
dpb->media_ID = (drivetype == DRIVE_FIXED) ? 0xF8 : 0xF0;
|
||||||
|
dpb->access_flag = 0;
|
||||||
|
dpb->next = 0;
|
||||||
|
dpb->search_cluster1 = 0;
|
||||||
|
dpb->free_clusters_lo = LOWORD(free_clusters);
|
||||||
|
dpb->free_clusters_hi = HIWORD(free_clusters);
|
||||||
|
dpb->mirroring_flags = 0;
|
||||||
|
dpb->info_sector = 0xffff;
|
||||||
|
dpb->spare_boot_sector = 0xffff;
|
||||||
|
dpb->first_cluster_sector = 0;
|
||||||
|
dpb->num_clusters2 = total_clusters;
|
||||||
|
dpb->fat_clusters = 32;
|
||||||
|
dpb->root_cluster = 0;
|
||||||
|
dpb->search_cluster2 = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2282,6 +2426,62 @@ static void INT21_Ioctl( CONTEXT86 *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_Fat32
|
||||||
|
*
|
||||||
|
* Handler for function 0x73.
|
||||||
|
*/
|
||||||
|
static BOOL INT21_Fat32( CONTEXT86 *context )
|
||||||
|
{
|
||||||
|
switch (AL_reg(context))
|
||||||
|
{
|
||||||
|
case 0x02: /* FAT32 - GET EXTENDED DPB */
|
||||||
|
{
|
||||||
|
BYTE drive = INT21_MapDrive( DL_reg(context) );
|
||||||
|
WORD *ptr = CTX_SEG_OFF_TO_LIN(context,
|
||||||
|
context->SegEs, context->Edi);
|
||||||
|
INT21_DPB *target = (INT21_DPB*)(ptr + 1);
|
||||||
|
INT21_DPB *source;
|
||||||
|
|
||||||
|
TRACE( "FAT32 - GET EXTENDED DPB %d\n", DL_reg(context) );
|
||||||
|
|
||||||
|
if ( CX_reg(context) < sizeof(INT21_DPB) + 2 || *ptr < sizeof(INT21_DPB) )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_BAD_LENGTH );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !INT21_FillDrivePB( drive ) )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_DRIVE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
source = &INT21_GetHeapPointer()->misc_dpb_list[drive];
|
||||||
|
|
||||||
|
*ptr = sizeof(INT21_DPB);
|
||||||
|
memcpy( target, source, sizeof(INT21_DPB));
|
||||||
|
|
||||||
|
if (LOWORD(context->Esi) != 0xF1A6)
|
||||||
|
{
|
||||||
|
target->driver_header = 0;
|
||||||
|
target->next = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME( "Caller requested driver and next DPB pointers!\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INT21_LongFilename
|
* INT21_LongFilename
|
||||||
*
|
*
|
||||||
|
@ -2862,7 +3062,21 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
|
case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
|
||||||
INT_Int21Handler( context );
|
{
|
||||||
|
BYTE drive = INT21_MapDrive( 0 );
|
||||||
|
TRACE( "GET DPB FOR DEFAULT DRIVE\n" );
|
||||||
|
|
||||||
|
if (INT21_FillDrivePB( drive ))
|
||||||
|
{
|
||||||
|
SET_AL( context, 0x00 ); /* success */
|
||||||
|
SET_BX( context, offsetof( INT21_HEAP, misc_dpb_list[drive] ) );
|
||||||
|
context->SegDs = INT21_GetHeapSelector( context );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_AL( context, 0xff ); /* invalid or network drive */
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x20: /* NULL FUNCTION FOR CP/M COMPATIBILITY */
|
case 0x20: /* NULL FUNCTION FOR CP/M COMPATIBILITY */
|
||||||
|
@ -3008,7 +3222,21 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
|
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
|
||||||
INT_Int21Handler( context );
|
{
|
||||||
|
BYTE drive = INT21_MapDrive( DL_reg(context) );
|
||||||
|
TRACE( "GET DPB FOR SPECIFIC DRIVE %d\n", DL_reg(context) );
|
||||||
|
|
||||||
|
if (INT21_FillDrivePB( drive ))
|
||||||
|
{
|
||||||
|
SET_AL( context, 0x00 ); /* success */
|
||||||
|
SET_DX( context, offsetof( INT21_HEAP, misc_dpb_list[drive] ) );
|
||||||
|
context->SegDs = INT21_GetHeapSelector( context );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_AL( context, 0xff ); /* invalid or network drive */
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x33: /* MULTIPLEXED */
|
case 0x33: /* MULTIPLEXED */
|
||||||
|
@ -3695,7 +3923,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x73: /* MSDOS7 - FAT32 */
|
case 0x73: /* MSDOS7 - FAT32 */
|
||||||
INT_Int21Handler( context );
|
if (!INT21_Fat32( context ))
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xdc: /* CONNECTION SERVICES - GET CONNECTION NUMBER */
|
case 0xdc: /* CONNECTION SERVICES - GET CONNECTION NUMBER */
|
||||||
|
|
198
msdos/int21.c
198
msdos/int21.c
|
@ -73,62 +73,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(int21);
|
||||||
|
|
||||||
#define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive())
|
#define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive())
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
DWORD dpbsegptr;
|
|
||||||
|
|
||||||
struct DosHeap {
|
struct DosHeap {
|
||||||
BYTE mediaID;
|
BYTE mediaID;
|
||||||
BYTE biosdate[8];
|
BYTE biosdate[8];
|
||||||
struct DPB dpb;
|
|
||||||
};
|
};
|
||||||
static struct DosHeap *heap;
|
static struct DosHeap *heap;
|
||||||
static WORD DosHeapHandle;
|
static WORD DosHeapHandle;
|
||||||
|
@ -143,7 +90,6 @@ static BOOL INT21_CreateHeap(void)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
heap = (struct DosHeap *) GlobalLock16(DosHeapHandle);
|
heap = (struct DosHeap *) GlobalLock16(DosHeapHandle);
|
||||||
dpbsegptr = MAKESEGPTR(DosHeapHandle,(int)&heap->dpb-(int)heap);
|
|
||||||
strcpy(heap->biosdate, "01/01/80");
|
strcpy(heap->biosdate, "01/01/80");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -223,60 +169,6 @@ static int INT21_GetDriveAllocInfo( CONTEXT86 *context )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FillInDrivePB( int drive )
|
|
||||||
{
|
|
||||||
if(!DRIVE_IsValid(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.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
||||||
{
|
{
|
||||||
BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
||||||
|
@ -722,20 +614,10 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||||
if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
|
if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
|
|
||||||
GetDrivePB(context, DRIVE_GetCurrentDrive());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x29: /* PARSE FILENAME INTO FCB */
|
case 0x29: /* PARSE FILENAME INTO FCB */
|
||||||
INT21_ParseFileNameIntoFCB(context);
|
INT21_ParseFileNameIntoFCB(context);
|
||||||
break;
|
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 0x36: /* GET FREE DISK SPACE */
|
case 0x36: /* GET FREE DISK SPACE */
|
||||||
TRACE("GET FREE DISK SPACE FOR DRIVE %s\n",
|
TRACE("GET FREE DISK SPACE FOR DRIVE %s\n",
|
||||||
INT21_DriveName( DL_reg(context)));
|
INT21_DriveName( DL_reg(context)));
|
||||||
|
@ -941,86 +823,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0x73: /* MULTIPLEXED: Win95 OSR2/Win98 FAT32 calls */
|
|
||||||
TRACE("windows95 function AX %04x\n",
|
|
||||||
AX_reg(context));
|
|
||||||
|
|
||||||
switch (AL_reg(context))
|
|
||||||
{
|
|
||||||
case 0x02: /* Get Extended Drive Parameter Block for specific drive */
|
|
||||||
/* ES:DI points to word with length of data (should be 0x3d) */
|
|
||||||
{
|
|
||||||
WORD *buffer;
|
|
||||||
struct EDPB *edpb;
|
|
||||||
DWORD cluster_sectors, sector_bytes, free_clusters, total_clusters;
|
|
||||||
char root[] = "A:\\";
|
|
||||||
|
|
||||||
buffer = (WORD *)CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi);
|
|
||||||
|
|
||||||
TRACE("Get Extended DPB: linear buffer address is %p\n", buffer);
|
|
||||||
|
|
||||||
/* validate passed-in buffer lengths */
|
|
||||||
if ((*buffer != 0x3d) || (context->Ecx != 0x3f))
|
|
||||||
{
|
|
||||||
WARN("Get Extended DPB: buffer lengths incorrect\n");
|
|
||||||
WARN("CX = %lx, buffer[0] = %x\n", context->Ecx, *buffer);
|
|
||||||
SET_CFLAG(context);
|
|
||||||
SET_AL( context, 0x18 ); /* bad buffer length */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* buffer checks out */
|
|
||||||
buffer++; /* skip over length word now */
|
|
||||||
if (FillInDrivePB( DX_reg(context) ) )
|
|
||||||
{
|
|
||||||
edpb = (struct EDPB *)buffer;
|
|
||||||
|
|
||||||
/* copy down the old-style DPB portion first */
|
|
||||||
memcpy(&edpb->dpb, &heap->dpb, sizeof(struct DPB));
|
|
||||||
|
|
||||||
/* now fill in the extended entries */
|
|
||||||
edpb->edpb_flags = 0;
|
|
||||||
edpb->next_edpb = 0;
|
|
||||||
edpb->free_cluster = edpb->free_cluster2 = 0;
|
|
||||||
|
|
||||||
/* determine free disk space */
|
|
||||||
*root += DOS_GET_DRIVE( DX_reg(context) );
|
|
||||||
GetDiskFreeSpaceA( root, &cluster_sectors, §or_bytes,
|
|
||||||
&free_clusters, &total_clusters );
|
|
||||||
|
|
||||||
edpb->clusters_free = (free_clusters&0xffff);
|
|
||||||
|
|
||||||
edpb->clusters_free_hi = free_clusters >> 16;
|
|
||||||
edpb->mirroring_flags = 0;
|
|
||||||
edpb->info_sector = 0xffff;
|
|
||||||
edpb->spare_boot_sector = 0xffff;
|
|
||||||
edpb->first_cluster = 0;
|
|
||||||
edpb->max_cluster = total_clusters;
|
|
||||||
edpb->fat_clusters = 32; /* made-up value */
|
|
||||||
edpb->root_cluster = 0;
|
|
||||||
|
|
||||||
RESET_CFLAG(context); /* clear carry */
|
|
||||||
SET_AX( context, 0 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SET_AX( context, 0x00ff );
|
|
||||||
SET_CFLAG(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x03: /* Get Extended free space on drive */
|
|
||||||
case 0x04: /* Set DPB for formatting */
|
|
||||||
case 0x05: /* extended absolute disk read/write */
|
|
||||||
FIXME("Unimplemented FAT32 int32 function %04x\n", AX_reg(context));
|
|
||||||
SET_CFLAG(context);
|
|
||||||
SET_AL( context, 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
INT_BARF( context, 0x21 );
|
INT_BARF( context, 0x21 );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue