📄 diskinfo.c
字号:
{
fSkipSizeTest = TRUE;
/* Bump the number of floppies */
++wNmbrFloppies;
}
/* Free space isn't checked on CD-ROM drives, either */
if (wDriveType == DISK_CD_ROM_DRIVE)
fSkipSizeTest = TRUE;
if (wDriveType == DISK_FIXED_DISK)
{
/* Determine CMOS characteristics */
GetCmosDiskInfo (wNmbrFixedDisks, pDisk, wDriveIndex);
/* Bump the number of fixed disks */
++wNmbrFixedDisks;
}
if (fSkipSizeTest == FALSE)
{
/* Determine the size of the drive, */
/* and the amount of free space */
inregs.h.ah = 0x36;
inregs.h.dl = (BYTE) (i + 1);
int86 (0x21, &inregs, &outregs);
if (outregs.x.ax != 0xFFFF)
{
/* Free space is AX * BX * CX */
pDisk->asdi[wDriveIndex].dwFreeBytes = (DWORD) outregs.x.ax *
(DWORD) outregs.x.bx *
(DWORD) outregs.x.cx;
/* Total space (size of drive) is AX * CX * DX */
pDisk->asdi[wDriveIndex].dwTotalBytes = (DWORD) outregs.x.ax *
(DWORD) outregs.x.cx *
(DWORD) outregs.x.dx;
/* If it has not already been determined, set the number */
/* of bytes per sector. */
if (pDisk->asdi[wDriveIndex].wBytesPerSector == 0)
pDisk->asdi[wDriveIndex].wBytesPerSector = outregs.x.cx;
}
}
}
/* Restore the current drive */
DosSetCurrentDrive (bCurrentDrive);
return (FALSE);
}
/*********************************************************************
* GetCmosDiskInfo - Obtains the CMOS drive parameters.
*
* wHardDriveNmbr - Hard disk number (0 or 1).
* pDisk - Structure for storing disk information.
* wDriveIndex - Index to pDisk.
*
* Returns: TRUE if this is a valid drive number. FALSE if not.
*********************************************************************/
VOID _cdecl GetCmosDiskInfo (WORD wHardDriveNmbr,
DISK_STRUCT *pDisk,
WORD wDriveIndex)
{
WORD i; /* Looping variable */
WORD wCmosIndex = 0; /* Value to obtain */
WORD wCmosValue; /* Value from CMOS */
/* Obtain the drive type appropriate for this drive */
outp (0x70, 0x12);
/* Wait */
for (i = 0; i < 1; ++i)
;
/* Input the drive type */
wCmosValue = inp (0x71);
/* First HD type is in bits 4-7, second is in bits 0-3 */
if (wHardDriveNmbr == 0)
wCmosValue = (wCmosValue & 0xF0) >> 4;
else
wCmosValue = (wCmosValue & 0x0F);
/* If the HD type is 15 (0Fh), look elsewhere */
if (wCmosValue == 0x0F)
{
/* Choose the appropriate value for the hard drive number */
if (wHardDriveNmbr == 0)
wCmosIndex = 0x19;
else
wCmosIndex = 0x1A;
outp (0x70, wCmosIndex);
/* Wait */
for (i = 0; i < 1; ++i)
;
/* Get the hard drive type */
wCmosValue = inp (0x71);
}
/* Set the CMOS Drive Type */
pDisk->asdi[wDriveIndex].wCmosDriveType = wCmosValue;
/* Get the drive parameters */
/* Is this a user defined drive type (48 or 49) */
if (pDisk->asdi[wDriveIndex].wCmosDriveType == 48 ||
pDisk->asdi[wDriveIndex].wCmosDriveType == 49)
{
/* Set the base index for the drive paramter table */
if (wHardDriveNmbr == 0)
wCmosIndex = 0x20;
else
wCmosIndex = 0x35;
/* Cylinders */
outp (0x70, wCmosIndex + 1);
for (i = 0; i < 1; ++i)
;
wCmosValue = inp (0x71);
wCmosValue = wCmosValue << 8;
outp (0x70, wCmosIndex + 1);
for (i = 0; i < 1; ++i)
;
wCmosValue = wCmosValue + inp (0x70);
pDisk->asdi[wDriveIndex].wCmosCylinders = wCmosValue;
/* Heads */
outp (0x70, wCmosIndex + 2);
for (i = 0; i < 1; ++i)
;
pDisk->asdi[wDriveIndex].wCmosHeads = inp (0x71);
/* Sectors per track */
outp (0x70, wCmosIndex + 7);
for (i = 0; i < 1; ++i)
;
pDisk->asdi[wDriveIndex].wCmosSectorsPerTrack = inp (0x71);
}
else
{
CMOS_DRIVE_TYPE FAR *pCmosInfo = NULL; /* CMOS Info in BIOS */
WORD wTableNmbr; /* Drive Table Number */
union REGS regs; /* int86x registers */
struct SREGS sregs; /* int86x segments */
/* This is a predefined drive type -- located in the BIOS */
/* Use the appropriate lookup table */
if (wHardDriveNmbr == 0)
wTableNmbr = 0x41;
else
wTableNmbr = 0x46;
/* Get the table's address */
regs.h.ah = 0x35;
regs.h.al = (BYTE) wTableNmbr;
int86x (0x21, ®s, ®s, &sregs);
pCmosInfo = (CMOS_DRIVE_TYPE FAR *)
(((DWORD) sregs.es << 16) + regs.x.bx);
/* Get the information */
pDisk->asdi[wDriveIndex].wCmosCylinders =
pCmosInfo->wNmbrCylinders;
pDisk->asdi[wDriveIndex].wCmosHeads =
pCmosInfo->bNmbrHeads;
pDisk->asdi[wDriveIndex].wCmosSectorsPerTrack =
pCmosInfo->bSectorsPerTrack;
}
/* Set the CMOS type on the "Fixed Disk" line */
sprintf (pDisk->asdi[wDriveIndex].szDriveType,
"Fixed Disk, CMOS Type %d",
pDisk->asdi[wDriveIndex].wCmosDriveType);
}
/*********************************************************************
* ValidDrive - Determines if this drive number is a valid drive.
*
* bDrive - Drive letter to test.
*
* Returns: TRUE if this is a valid drive number. FALSE if not.
*********************************************************************/
BOOL ValidDrive (BYTE bDrive)
{
/* Attempt to make this drive number the current drive */
DosSetCurrentDrive (bDrive);
/* Return success or failure */
if (DosGetCurrentDrive() == bDrive)
return (TRUE);
else
return (FALSE);
}
/*********************************************************************
* DosGetCurrentDrive - Obtain drive number of the current drive.
*
* Returns: Current drive number.
*********************************************************************/
BYTE DosGetCurrentDrive (VOID)
{
union REGS inregs, outregs; /* Register structures for int86() */
/* DOS call to return the current drive number */
inregs.h.ah = 0x19;
int86 (0x21, &inregs, &outregs);
/* Return the current drive letter */
return (outregs.h.al);
}
/*********************************************************************
* DosSetCurrentDrive - Sets the current drive to the given drive
* number.
*
* bDrive - Drive number to set as the current drive.
* wDosVersion - DOS Version (ie 3.20 == 320).
*
* Returns: The highest potentially valid drive letter. The highest
* of 5, LASTDRIVE in CONFIG.SYS, or the highest drive
* number in the system.
*********************************************************************/
BYTE DosSetCurrentDrive (BYTE bDrive)
{
union REGS inregs, outregs; /* Register structures for int86() */
/* DOS call to return the current drive number */
inregs.h.ah = 0x0e;
inregs.h.dl = bDrive;
int86 (0x21, &inregs, &outregs);
return (outregs.h.al);
}
/*********************************************************************
* GetDiskProgList - Gets the list of disk related programs installed
* in memory (JOIN, ASSIGN, MSCDEX, etc).
*
* pDisk - Pointer to disk information structure.
*********************************************************************/
VOID GetDiskProgList (DISK_STRUCT *pDisk, WORD wDosVersion)
{
union REGS inregs, outregs; /* Register structures for int86() calls */
struct SREGS sregs; /* Segment registers for int86x() calls */
BYTE FAR *fbByte = NULL; /* Far pointer to a BYTE */
WORD i; /* Looping variable */
/* Determine if JOIN.EXE is being used */
if (wDosVersion >= 310)
{
inregs.h.ah = 0x52;
int86x (0x21, &inregs, &outregs, &sregs);
fbByte = (BYTE FAR *) ((DWORD) sregs.es << 16) + outregs.x.bx;
if (fbByte[0x34] != 0)
pDisk->fJoinInstalled = TRUE;
}
/* Determine if SHARE.EXE is installed */
inregs.x.ax = 0x1000;
int86 (0x2F, &inregs, &outregs);
if (outregs.h.al == 0xFF)
pDisk->fShareInstalled = TRUE;
/* Determine if ASSIGN.EXE installed */
inregs.x.ax = 0x0600;
int86 (0x2F, &inregs, &outregs);
if (outregs.h.al == 0xFF)
{
pDisk->fAssignInstalled = TRUE;
/* Load up the ASSIGN drive table */
inregs.x.ax = 0x0601;
int86x (0x2F, &inregs, &outregs, &sregs);
if (sregs.es > 0x0000)
{
WORD wAssignIndex; /* Index to the AssignTable */
/* Point to the drive assignment table */
fbByte = (BYTE FAR *) ((DWORD) sregs.es << 16) + 0x0102;
/* Loop through, looking for assignments */
/* (ASSIGN reserves room for A:-Z:, no */
/* matter what LASTDRIVE is set to). */
for (i = 1, wAssignIndex = 0; i < MAX_ASSIGN_TABLE; ++i)
if (fbByte[i] != (BYTE) i)
{
pDisk->atAssignTable[wAssignIndex].chAssignTo = (CHAR) i;
pDisk->atAssignTable[wAssignIndex].chAssignFrom = fbByte[i];
++wAssignIndex;
}
}
}
/* Determine if APPEND.EXE installed */
inregs.x.ax = 0xB700;
int86 (0x2F, &inregs, &outregs);
if (outregs.h.al == 0xFF)
{
CHAR FAR * fpszAppendPath = NULL; /* Far pointer to the APPEND path */
pDisk->fAppendInstalled = TRUE;
/* Locate the APPEND path */
inregs.x.ax = 0xB704;
int86x (0x2f, &inregs, &outregs, &sregs);
/* Place it into the Disk Info structure */
fpszAppendPath = (CHAR FAR *) ((DWORD) sregs.es << 16) + outregs.x.di;
_fstrncpy ((CHAR FAR *) pDisk->szAppendPath, fpszAppendPath,
MAX_APPEND_PATH - 1);
pDisk->szAppendPath[MAX_APPEND_PATH - 1] = '\0';
}
/* Determine if MSCDEX.EXE is installed */
inregs.x.ax = 0x1500;
inregs.x.bx = 0x0000;
int86 (0x2F, &inregs, &outregs);
if (outregs.x.bx != 0x0000)
{
/* MSCDEX is installed -- Determine version number */
inregs.x.ax = 0x150C;
inregs.x.bx = 0x0000;
int86 (0x2F, &inregs, &outregs);
if (outregs.x.bx == 0)
{
/* Set the version to 1.x */
pDisk->wMscdexMajor = 1;
pDisk->wMscdexMinor = 0xFF;
}
else
{
pDisk->wMscdexMajor = outregs.h.bh;
pDisk->wMscdexMinor = outregs.h.bl;
}
}
}
/*********************************************************************
* SprintDiskInfo - Put disk information into a set of strings to be
* printed or displayed.
*
* Returns: NULL if an error occured.
*********************************************************************/
QSZ * SprintDiskInfo (DISK_STRUCT *pDisk,
CHAR szSumStrings[][MAX_SUMM_INFO + 5])
{
WORD wNmbrStrings; /* Number of strings */
WORD wNmbrChars; /* Number of characters in the strings */
WORD wUnderlineLength; /* Length of the underline string */
WORD wDriveIndex; /* Index to the structure of disk data */
WORD i; /* Looping variables */
QSZ *pqszStrings = NULL; /* Location for storing string pointers */
CHAR chBuffer[80]; /* Buffer for string data */
/* Summary Strings */
if (szSumStrings != NULL)
{
WORD wDrivesThisLine = 0; /* Current number of drive letters */
/* on this line. */
i = 0;
szSumStrings[i][0] = '\0';
for (wDriveIndex = 0; wDriveIndex < pDisk->wNmbrDrives; ++wDriveIndex)
{
/* Drive Letter */
sprintf (chBuffer, "%c: ", pDisk->asdi[wDriveIndex].chDriveLetter);
/* Is there room for it on this line */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -