Get the physical serial number of the hard disk under Win9XNT

xiaoxiao2021-03-30  207

#include

#include

#pragma inline

/ / -------------------------------------------------------------------------------------------- ---------------------------

// IDE NT / 2000 / XP special variable

#define getversionoutparams getVersioninparams

#define DFP_GET_VERSION SMART_GET_VERSION

#define DFP_SEND_DRIVE_COMMAND Smart_send_drive_command

#DEFINE DFP_RCV_DRIVE_DATA Smart_rcv_drive_data

Const Word IDE_ATAPI_IDENTIFY = 0xA1; // Read the command of the ATAPI device

Const Word IDE_ATA_IDENTIFY = 0xec; // Read ATA Device Command

Const int max_IDE_Drives = 4;

// SCSI special variable

Const dword file_device_scsi = 0x0000001B;

Const DWORD ioctl_scsi_miniport_identify = ((file_device_scsi << 16) 0x0501);

Const dword ioctl_scsi_miniport = 0x0004d008; // See ntddscsi.h for definition

Const dword sendidens = sizeof (sendcmdoutparams) Identify_buffer_size;

Typedef struct _srb_io_control

{

Ulong headerlength;

Uchar Signature [8];

Ulong timeout;

Ulong controlcode;

Ulong Returncode;

Ulong Length;

} SRB_IO_CONTROL, * PSRB_IO_CONTROL;

// Read the main function

Void __fastcall readphysicaldrive (tstrings * pserlist, tstrings * pmodelist);

// Auxiliary function

Char * __ fastcall convertostnow (dword dwdiskdata [256], int nfirstindex, int nlastindex);

// NT / 2000 / XP function

Void __fastcall readphysicalDriveonNT (Tstrings * pserlist, tstrings * pmodelist);

Bool __fastcall doidentify (Handle HphysicalDriveioctl, Psendcmdinparams PSCIP,

Psendcmdoutparams Pscop, Byte Btidcmd,

Byte Btdrivenum, PDWORD LPCBBYTESRETURNED;

// windows 9x function

Void __fastcall readphysicaldriveonw9x (tstrings * pserlist, tstrings * pmodelist);

Void __fastcall readphysicalDriveonw9x_ring0 (Bool IsFirst, Word Baseaddress,

Byte Mos, Bool & IsideExist, Bool & Isdiskexist, Word * Outdata; // SCSI Reading Function (for NT / 2000 / XP)

String __fastcall readidedriveasscsidriveonnt ();

/ / -------------------------------------------------------------------------------------------- ---------------------------

// readphysicalDrive

Void __fastcall readphysicaldrive (tstrings * pserlist, tstrings * pmodelist)

{

Switch (Win32Platform)

{

Case Ver_Platform_Win32_Windows:

ReadphysicalDriveonW9X (Pserlist, Pmodelist);

Break;

Case Ver_Platform_WIN32_NT:

ReadphysicalDriveonNT (Pserlist, Pmodelist);

Break;

DEFAULT:

Break;

}

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// ConvertToString

Char * __ fastcall convertostring (DWord DwdiskData [256], INT NFIRSDEX, INT NLASTINDEX)

{

Static Char Szresbuf [1024];

INT NINDEX = 0;

INT nPosition = 0;

// Each Integer Has Two Characters Stored In It Backwards

For (nindex = nfirstindex; nindex <= nlastindex; NINDEX )

{

// Get High byte for 1st Character

Szresbuf [nposition] = (char) (DWDiskData [NINDEX] / 256);

NPOSITION ;

// Get Low byte for 2nd Character

SzResbuf [nposition] = (char) (DWDiskData [NINDEX]% 256);

NPOSITION ;

}

// end the string

SzResbuf [nposition] = '/ 0';

// Cut Off The Trailing Blanks

For (Nindex = nPosition - 1; NINDEX> 0 && '' == SzResbuf [NINDEX]; NINDEX -)

SzResbuf [NINDEX] = '/ 0';

Return SzResbuf;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// WinNDOWS NT4 / 2000 / XP code

/ / -------------------------------------------------------------------------------------------- ---------------------------

// readphysicalDriveonNT

Void __fastcall readphysicalDriveonNT (Tstrings * pserlist, tstrings * pmodelist)

{

// Output parameters

BYTE BTIDOUTCMD [SIZEOF (Sendcmdoutparams) Identify_buffer_size - 1];

For (int NDRIVE = 0; ndrive

{

Handle HphysicalDriveiocTl;

Char szdrivename [32];

Sprintf (szdrivename, ".//physicaldrive%D", ndrive);

HphysicalDriveiocTl = CREATEFILE (SzdriveName,

Generic_read | generic_write,

File_share_read | file_share_write, null,

Open_EXISTING, 0, NULL

IF (hphysicaldriveioctl! = invalid_handle_value)

{

DWORD DWBYTESRETURNED = 0;

GetversionOutparams gvopVersionparams;

// Get The Version, ETC of PhysicalDrive ioctl

ZeromeMory (& gvopVersionParams, Sizeof (GetVersionOutparams);

IF (! DeviceioControl (HphysicalDriveiOctl, DFP_GET_VERSION,

NULL, 0, & GVOPVERSIONPARAMS, SIZEOF (GVOPVersionParams),

& dwbytesreturned, NULL))

{

CONTINUE;

}

IF (gvopVersionparams.bidedEDeviceMap> 0)

{

// IDE or atapi identify cmd

BYTE BTIDCMD = 0;

Sendcmdinparams INPARAMS;

// now, get the id sector for all my devices in the system.

// if the device is atapi us ie_atapi_identify command,

// OtherWise Use the IDE_ATA_IDENTIFY COMMAND

/ / Please refer to the description of the header file for the result of the specific result.

BTIDCMD = (gvopVersionParams.BidedEDeviceMap >> NDrive & 0x10)?

IDE_ATAPI_IDENTIFY: IDE_ATA_IDENTIFY;

ZeromeMory (& INPARAMS, SIZEOF (Sendcmdinparams);

ZeromeMory (BTIDOUTCMD, SIZEOF (BTIDOUTCMD));

IF (HphysicalDriveiocTl,

& INPARAMS, (psendcmdoutparams) BTIDOUTCMD,

(Byte) BTIDCMD, (Byte) NDrive, & DWBYTESRETURNED))

{

DWORD DWDiskData [256];

Ushort * pidsector; // correspondence structure idsector, see head file

Char szserialnumber [21];

Char szmodelnumber [41];

Pidsector = (usHort *) (Sendcmdoutparams *) btidoutcmd) -> bbuffer;

For (int i = 0; i <256; i )

DWDiskData [i] = pidsector [i]; // Take a series

ZeromeMory (SizserialNumber, Sizeof (SZSerialNumber);

STRCPY (SZSerialnumber, ConvertToString (DWDiskData, 10, 19);

// Timing model

ZeromeMory (Szmodelnumber, Sizeof (Szmodelnumber);

STRCPY (Szmodelnumber, ConvertToString (DWDiskData, 27, 46));

PSerlist-> Add (SZSerialnumber);

Pmodelist-> add (szmodelnumber);

}

}

CloseHandle (HPHYSICALDRIVEIOCTL);

}

}

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// doidentify

Bool __fastcall doidentify (Handle HphysicalDriveioctl, Psendcmdinparams PSCIP,

Psendcmdoutparams Pscop, Byte Btidcmd, Byte Btdrivenum,

PDWORD PDWBYTESRETURNED)

{

// SET UP DATA STRUCTURES for Identify Command.

PSCIP-> CBuffersize = Identify_buffer_size;

Pscip-> IrDriveRegs.BfeaturesReg = 0;

Pscip-> IrDriveRegs.bsectorcountreg = 1;

Pscip-> IrDriveRegs.bsectorNumberReg = 1;

Pscip-> IrDriveRegs.bcyllowreg = 0;

Pscip-> IrDriveRegs.bcylhighReg = 0;

// compute the drive number. (The value corresponding to the main disc and slave "is not the same)

Pscip-> irdriveRegs.bdriveheadreg = (BTDrivenum & 1)? 0xB0: 0xA0;

// The Command CAN Either Be Ide Identify or atapi Identify.

Pscip-> IrDriveRegs.bcommandreg = btidcmd;

Pscip-> bdrivenumber = btdrivenu;

PSCIP-> CBuffersize = Identify_buffer_size;

Return DeviceioControl (HphysicalDriveiocTl, DFP_RCV_DRIVE_DATA,

(LPVOID) PSCIP,

Sizeof (Sendcmdinparams) - 1,

(LPVOID) PSCOP,

Sizeof (Sendcmdoutparams) Identify_buffer_size - 1,

PDWBYTESRETURNED, NULL);

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Windows 95/98 / ME code

/ / -------------------------------------------------------------------------------------------- ---------------------------

// readphysicalDriveonw9xvoid __fastcall readphysicalDriveonw9x (tstrings * pserlist, tstrings * pmodelist)

{

Word woutdata [256];

SetPriorityClass (GetCurrentProcess (), realtime_priority_class;

// After testing, it is found that the first call and DRIVE> = 2 will occur in the RING0 code, resulting in a blue screen.

// After the N (n> 15), it still can't find the reason after the blue screen: (, there is no additional useless code here.

// Avoid the appearance of the blue screen. (I look forward to a high person to point out the reason)

For (int NDRIVE = 0; NDRIVE <8; NDRIVE )

{

Word dwbaseaddress;

Byte btmasterslave; // master or slave

Bool bisideexist;

Bool isdiskexist;

Switch (ndrive / 2)

{

Case 0: dwbaseaddress = 0x01f0; Break;

Case 1: dwbaseaddress = 0x0170; Break;

Case 2: dwbaseaddress = 0x01e8; Break;

Case 3: DWBaseAddress = 0x0168; Break;

}

BTMASTERSLAVE = (Byte) ((nDrive% 2) == 0)? 0xA0: 0xB0);

// Enter RING0

ReadphysicalDriveonW9x_ring0 (True, Dwbaseaddress, Btmasterslave,

Bisideexist, ISDISKEXIST, WOUTDATA

}

// Start reading

For (int NDRIVE = 0; NDRIVE <8; NDRIVE )

{

Word dwbaseaddress;

Byte btmasterslave; // master or slave

Bool bisideexist;

Bool bisdiskexist;

Switch (ndrive / 2)

{

Case 0: dwbaseaddress = 0x01f0; Break;

Case 1: dwbaseaddress = 0x0170; Break;

Case 2: dwbaseaddress = 0x01e8; Break;

Case 3: DWBaseAddress = 0x0168; Break;

}

BTMASTERSLAVE = (Byte) ((nDrive% 2) == 0)? 0xA0: 0xB0);

// Enter RING0

Bisideexist = FALSE;

Bisdiskexist = false;

ZeromeMory (Woutdata);

ReadphysicalDriveonW9x_ring0 (False, Dwbaseaddress, BtmasterSlave,

Bisideexist, Bisdiskexist, Woutdata;

IF (bisideexist && bisdiskexist)

{

DWORD DWDiskData [256];

Char szserialnumber [21];

Char szmodelnumber [41];

For (int K = 0; k <256; k ) dwdiskdata [k] = woutdata [k];

// Take a series

ZeromeMory (SizserialNumber, Sizeof (SZSerialNumber);

STRCPY (SZSerialnumber, ConvertToString (DWDiskData, 10, 19);

// Timing model

ZeromeMory (Szmodelnumber, Sizeof (Szmodelnumber);

STRCPY (Szmodelnumber, ConvertToString (DWDiskData, 27, 46));

PSerlist-> Add (SZSerialnumber);

Pmodelist-> add (szmodelnumber);

}

}

SetPriorityClass (GetCurrentProcess (), Normal_Priority_Class;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// readphysicalDriveonw9x_ring0 ()

//

// dwbaseaddress = IDE (0, 1, 2, 3): 1F0H, 170H, 1E8H, 168H

// btmasterslave = master (0xA0) OR slave (0xB0)

/ / -------------------------------------------------------------------------------------------- ---------------------------

Void __fastcall readphysicalDriveonw9x_ring0 (Bool Bisfirst, Word Dwbaseaddress,

BYTE BTMASTERSLAVE, BOOL & Bisideexist, Bool & Bisdiskexist, Word * Poutdata)

{

Byte btidtr1 [6];

DWORD DWOLDEXCEPTIONHOK;

Const int nhookedXceptionNO = 5;

Byte btisideexist = 0;

BYTE BTISDISKEXIST = 0;

Word woutdatabuf [256];

Byte btisfirst = (byte) bisfirst;

Const byte btbit00 = 0x01;

// const byte btbit02 = 0x04;

Const byte btbit06 = 0x40;

Const byte btbit07 = 0x80;

// const byte bterr = btbit00;

Const byte btbusy = btbit07;

Const byte btatacmd = 0xec;

Const byte btatapicmd = 0xa1;

__ASM

{

// must implement this statement first

JMP Enterring0

// Define the process

// Waiting for the IDE device until it is not busy

Waitwhilebusy Proc

MOV EBX, 100000

MOV DX, DWBaseAddress

Add dx, 7

LoopWhilebusy:

Dec EBX

CMP EBX, 0

JZ Timeout

IN Al, DX

Test Al, BTBUSY

Jnz loopwhilebusy

JMP DriveReady

// Timeout, directly exit

TIMEOUT:

JMP Leavering0

DriveReady:

RET

Endp // end of waitwhilebusy procedure // Set the primary disc and slave

SelectDevice Proc

MOV DX, DWBaseAddress

Add dx, 6

Mov Al, BtMasterslave

Out dx, al

RET

Endp // end of selectdevice procedure

/ / Send an access command to the IDE device

Sendcmd Proc

MOV DX, DWBaseAddress

Add dx, 7

MOV Al, BL // BL is the main slave dish identifier, outside the process

Out dx, al

RET

Endp // end of sendcmd procedure

// Ring0 code

Ring0Proc:

Pushhad

// Query if the IDE device exists

MOV DX, DWBaseAddress

Add dx, 7

IN Al, DX

// When the value of Al is 0xff or 0x7f, the IDE device does not exist, and then it is directly returned.

CMP Al, 0xFF

JZ Leavering0

CMP Al, 0x7f

JZ Leavering0

/ / Set an IDE device exists

Mov btisideexist, 1

/ / Query if the drive on the IDE device exists (with the IDE slot on the motherboard, but not necessarily a hard disk inserted above)

Call Waitwhilebusy

Call SelectDevice

// If it is called, then it is returned directly, otherwise it will appear blue screen when performing a downlist.

CMP BTISFIRST, 1

JZ Leavering0

// When calling, if you do this, you can cause Blue Screen, why? ? ?

Call Waitwhilebusy

// Al is equal to CBIT06, there is no drive, directly return

Test al, btbit06

JZ Leavering0

/ / Set the drive existence flag

Mov btisdiskexist, 1

// Send an access port command

// Cannot be like NT / 2000 / XP can be used to get the value of the Version to get the type of drive,

// So I can only test one step by step. If it is not an ATA device, try using the ATAPI device command.

Call Waitwhilebusy

Call selectDevice // Set the primary slam sign

MOV BL, BTATACMD / / Send Read Command

Call sendcmd

Call Waitwhilebusy

/ / Check if an error

MOV DX, DWBaseAddress

Add dx, 7

IN Al, DX

Test al, btbit00

JZ RETRIEVEINFO / / read data when there is no error

// If an error, further try to use the ATAPI device command

Call Waitwhilebusy

Call SelectDevice

MOV BL, BTATAPICMD

Call sendcmd

Call Waitwhilebusy

/ / Check if it is still wrong

MOV DX, DWBaseAddress

Add dx, 7

IN Al, DX

Test al, btbit00

JZ RETRIEVEINFO / / read data when there is no error

JMP Leavering0 // If it is still an error, return directly

// read data

RetrieveInfo:

Lea Edi, WoutdataBuf

Mov ECX, 256

MOV DX, DWBaseAddress

CLD

Rep Insw

// Exit Ring0 code

Leavering0:

PopadiRetd

// activate Ring0 code

ENTERRING0:

/ / Modify the interrupt gate

SIDT FWORD PTR BTIDTR1

MOV EAX, DWORD PTR BTIDTR1 02H

Add Eax, NHOOKEXCENO * 08H 04H

CLI

/ / Preserve the original exception handling routine entry

MOV ECX, DWORD PTR [EAX]

MOV CX, Word PTR [EAX-04H]

Mov DwoldExceptionHook, ECX

/ / Specify new entry

Lea EBX, RING0PROC

MOV Word PTR [EAX-04H], BX

SHR EBX, 10H

MOV Word PTR [EAX 02H], BX

// activate Ring0 code

Int nhokexceptionno

// Restore the entrance

MOV ECX, DwoldExceptionHOK

Mov Word PTR [EAX-04H], CX

SHR ECX, 10H

MOV Word PTR [EAX 02H], CX

STI

}

IF (! bisfirst)

{

Bisideexist = (BOOL) btisideexist;

BiSDISKEXIST = (BOOL) btisdiskexist;

CopyMemory (poutdata, woutdatabuf, sizeof (woutdatabuf);

}

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Call method:

Void __fastcall tform1 :: button1click (Tobject * Sender)

{

ReadphysicalDrive (Memo1-> Lines, Memo2-> lines);

}

转载请注明原文地址:https://www.9cbs.com/read-130651.html

New Post(0)