Code:
int ReadPhysicalDriveInNT (void)
{
int done = FALSE;
int drive = 0;

for (drive = 0; drive < MAX_IDE_DRIVES; drive++)
{
HANDLE hPhysicalDriveIOCTL = 0;

// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
char driveName [256];

sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);

// Windows NT, Windows 2000, must have admin rights
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
// if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
// printf ("Unable to open physical drive %d, error code: 0x%lX\n",
// drive, GetLastError ());

if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
GETVERSIONOUTPARAMS VersionParams;
DWORD cbBytesReturned = 0;

// Get the version, etc of PhysicalDrive IOCTL
memset ((void*) &VersionParams, 0, sizeof(VersionParams));

if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,
NULL,
0,
&VersionParams,
sizeof(VersionParams),
&cbBytesReturned, NULL) )
{
// printf ("DFP_GET_VERSION failed for drive %d\n", i);
// continue;
}

// If there is a IDE device at number "i" issue commands
// to the device
if (VersionParams.bIDEDeviceMap > 0)
{
BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd
SENDCMDINPARAMS scip;
//SENDCMDOUTPARAMS OutCmd;

// Now, get the ID sector for all IDE devices in the system.
// If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
// otherwise use the IDE_ATA_IDENTIFY command
bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? \
IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

memset (&scip, 0, sizeof(scip));
memset (IdOutCmd, 0, sizeof(IdOutCmd));

if ( DoIDENTIFY (hPhysicalDriveIOCTL,
&scip,
(PSENDCMDOUTPARAMS)&IdOutCmd,
(BYTE) bIDCmd,
(BYTE) drive,
&cbBytesReturned))
{
DWORD diskdata [256];
int ijk = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

for (ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];

PrintIdeInfo (drive, diskdata);

done = TRUE;
}
}

CloseHandle (hPhysicalDriveIOCTL);
}
}

return done;
}
int ReadIdeDriveAsScsiDriveInNT (void)
{
int done = FALSE;
int controller = 0;

for (controller = 0; controller < 2; controller++)
{
HANDLE hScsiDriveIOCTL = 0;
char driveName [256];

// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
sprintf (driveName, "\\\\.\\Scsi%d:", controller);

// Windows NT, Windows 2000, any rights should do
hScsiDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
// if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
// printf ("Unable to open SCSI controller %d, error code: 0x%lX\n",
// controller, GetLastError ());

if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
{
int drive = 0;

for (drive = 0; drive < 2; drive++)
{
char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
SENDCMDINPARAMS *pin =
(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
DWORD dummy;

memset (buffer, 0, sizeof (buffer));
p -> HeaderLength = sizeof (SRB_IO_CONTROL);
p -> Timeout = 10000;
p -> Length = SENDIDLENGTH;
p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy ((char *) p -> Signature, "SCSIDISK", 8);

pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
pin -> bDriveNumber = drive;

if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
buffer,
sizeof (SRB_IO_CONTROL) +
sizeof (SENDCMDINPARAMS) - 1,
buffer,
sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
&dummy, NULL))
{
SENDCMDOUTPARAMS *pOut =
(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
if (pId -> sModelNumber [0])
{
DWORD diskdata [256];
int ijk = 0;
USHORT *pIdSector = (USHORT *) pId;

for (ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];

PrintIdeInfo (controller * 2 + drive, diskdata);

done = TRUE;
}
}
}
CloseHandle (hScsiDriveIOCTL);
}
}

return done;
}
int ReadDrivePortsInWin9X (void)
{
int done = FALSE;
int drive = 0;

InitializeWinIo ();

// Get IDE Drive info from the hardware ports
// loop thru all possible drives
for (drive = 0; drive < 8; drive++)
{
DWORD diskdata [256];
WORD baseAddress = 0; // Base address of drive controller
DWORD portValue = 0;
int waitLoop = 0;
int index = 0;

switch (drive / 2)
{
case 0: baseAddress = 0x1f0; break;
case 1: baseAddress = 0x170; break;
case 2: baseAddress = 0x1e8; break;
case 3: baseAddress = 0x168; break;
}

// Wait for controller not busy
waitLoop = 100000;
while (--waitLoop > 0)
{
GetPortVal ((WORD) (baseAddress + 7), &portValue, (BYTE) 1);
// drive is ready
if ((portValue & 0x40) == 0x40) break;
// previous drive command ended in error
if ((portValue & 0x01) == 0x01) break;
}

if (waitLoop < 1) continue;

// Set Master or Slave drive
if ((drive % 2) == 0)
SetPortVal ((WORD) (baseAddress + 6), 0xA0, 1);
else
SetPortVal ((WORD) (baseAddress + 6), 0xB0, 1);

// Get drive info data
SetPortVal ((WORD) (baseAddress + 7), 0xEC, 1);

// Wait for data ready
waitLoop = 100000;
while (--waitLoop > 0)
{
GetPortVal ((WORD) (baseAddress + 7), &portValue, 1);
// see if the drive is ready and has it's info ready for us
if ((portValue & 0x48) == 0x48) break;
// see if there is a drive error
if ((portValue & 0x01) == 0x01) break;
}

// check for time out or other error
if (waitLoop < 1 || portValue & 0x01) continue;

// read drive id information
for (index = 0; index < 256; index++)
{
diskdata [index] = 0; // init the space
GetPortVal (baseAddress, &(diskdata [index]), 2);
}

PrintIdeInfo (drive, diskdata);
done = TRUE;
}

ShutdownWinIo ();

return done;
}

Last edited by shabbir; 13May2010 at 11:34.. Reason: Code blocks