M
mmww
Unregistered / Unconfirmed
GUEST, unregistred user!
我的邮箱:gold_net@163.com<br>这是一段不用vxd读取硬盘物理信息的C程序,哪位大侠能把它转换成delphi,急!谢谢!!<br><br>#include <stdafx.h><br>//#include <windows.h><br>//#include <dos.h><br>//#include <conio.h><br>#include <stdio.h><br>//#include <string.h><br><br>#define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE<br>#define IDENTIFY_BUFFER_SIZE 512<br>#define FILE_DEVICE_SCSI 0x0000001b<br>#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)<br>#define IOCTL_SCSI_MINIPORT 0x0004D008 // see NTDDSCSI.H for definition<br>#define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.<br>#define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.<br>#define DFP_RECEIVE_DRIVE_DATA 0x0007c088<br> typedef struct _IDSECTOR<br>{<br> USHORT wGenConfig;<br> USHORT wNumCyls;<br> USHORT wReserved;<br> USHORT wNumHeads;<br> USHORT wBytesPerTrack;<br> USHORT wBytesPerSector;<br> USHORT wSectorsPerTrack;<br> USHORT wVendorUnique[3];<br> CHAR sSerialNumber[20];<br> USHORT wBufferType;<br> USHORT wBufferSize;<br> USHORT wECCSize;<br> CHAR sFirmwareRev[8];<br> CHAR sModelNumber[40];<br> USHORT wMoreVendorUnique;<br> USHORT wDoubleWordIO;<br> USHORT wCapabilities;<br> USHORT wReserved1;<br> USHORT wPIOTiming;<br> USHORT wDMATiming;<br> USHORT wBS;<br> USHORT wNumCurrentCyls;<br> USHORT wNumCurrentHeads;<br> USHORT wNumCurrentSectorsPerTrack;<br> ULONG ulCurrentSectorCapacity;<br> USHORT wMultSectorStuff;<br> ULONG ulTotalAddressableSectors;<br> USHORT wSingleWordDMA;<br> USHORT wMultiWordDMA;<br> BYTE bReserved[128];<br>} IDSECTOR, *PIDSECTOR;<br><br>typedef struct _DRIVERSTATUS<br>{<br> BYTE bDriverError; // Error code from driver, or 0 if no error.<br> BYTE bIDEStatus; // Contents of IDE Error register.<br> // Only valid when bDriverError is SMART_IDE_ERROR.<br> BYTE bReserved[2]; // Reserved for future expansion.<br> DWORD dwReserved[2]; // Reserved for future expansion.<br>} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;<br><br> typedef struct _SENDCMDOUTPARAMS<br>{<br> DWORD cBufferSize; // Size of bBuffer in bytes<br> DRIVERSTATUS DriverStatus; // Driver status structure.<br> BYTE bBuffer[1]; // Buffer of arbitrary length in which to store the data read from the // drive.<br>} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;<br>typedef struct _SRB_IO_CONTROL<br>{<br> ULONG HeaderLength;<br> UCHAR Signature[8];<br> ULONG Timeout;<br> ULONG ControlCode;<br> ULONG ReturnCode;<br> ULONG Length;<br>} SRB_IO_CONTROL, *PSRB_IO_CONTROL;<br>typedef struct _IDEREGS<br>{<br> BYTE bFeaturesReg; // Used for specifying SMART "commands".<br> BYTE bSectorCountReg; // IDE sector count register<br> BYTE bSectorNumberReg; // IDE sector number register<br> BYTE bCylLowReg; // IDE low order cylinder value<br> BYTE bCylHighReg; // IDE high order cylinder value<br> BYTE bDriveHeadReg; // IDE drive/head register<br> BYTE bCommandReg; // Actual IDE command.<br> BYTE bReserved; // reserved for future use. Must be zero.<br>} IDEREGS, *PIDEREGS, *LPIDEREGS;<br><br>typedef struct _SENDCMDINPARAMS<br>{<br> DWORD cBufferSize; // Buffer size in bytes<br> IDEREGS irDriveRegs; // Structure with drive register values.<br> BYTE bDriveNumber; // Physical drive number to send <br> // command to (0,1,2,3).<br> BYTE bReserved[3]; // Reserved for future expansion.<br> DWORD dwReserved[4]; // For future use.<br> BYTE bBuffer[1]; // Input buffer.<br>} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;<br>typedef struct _GETVERSIONOUTPARAMS<br>{<br> BYTE bVersion; // Binary driver version.<br> BYTE bRevision; // Binary driver revision.<br> BYTE bReserved; // Not used.<br> BYTE bIDEDeviceMap; // Bit map of IDE devices.<br> DWORD fCapabilities; // Bit mask of driver capabilities.<br> DWORD dwReserved[4]; // For future use.<br>} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;<br><br>WORD serial[256];<br>DWORD OldInterruptAddress;<br>DWORDLONG IDTR;<br>void _stdcall ReadIdeSerialNumber();<br>static unsigned int WaitHardDiskIde() <br>{<br> BYTE xx;<br><br>Waiting:<br> __asm{<br> mov dx, 0x1f7<br> in al, dx<br> cmp al, 0x80<br> jb Endwaiting<br> jmp Waiting<br> }<br>Endwaiting:<br> __asm{<br> mov xx, al<br> }<br><br> return xx; <br>} <br>void __declspec( naked ) InterruptProcess(void)//中断服务程序<br>{<br> int xx;<br> int i;<br> WORD temp;<br> //保存寄存器值<br> __asm<br> {<br> push eax<br> push ebx<br> push ecx<br> push edx<br> push esi<br> }<br> <br> WaitHardDiskIde();//等待硬盘空闲状态<br> __asm{<br> mov dx, 0x1f6<br> mov al, 0xa0<br> out dx, al<br> }<br> xx = WaitHardDiskIde(); //若直接在Ring3级执行等待命令,会进入死循环<br> if ((xx&0x50)!=0x50)<br> {<br> __asm{<br> pop esi<br> pop edx<br> pop ecx<br> pop ebx<br> pop eax<br> iretd<br> }<br> }<br> <br> __asm{<br> mov dx, 0x1f6 //命令端口1f6,选择驱动器0<br> mov al, 0xa0<br> out dx, al<br> inc dx<br> mov al, 0xec<br> out dx, al //发送读驱动器参数命令<br> }<br><br> xx = WaitHardDiskIde(); <br> if ((xx&0x58)!=0x58) <br> {<br> __asm{<br> pop esi<br> pop edx<br> pop ecx<br> pop ebx<br> pop eax<br> iretd<br> }<br> }<br> //读取硬盘控制器的全部信息<br> for (i=0;i<256;i++) {<br> __asm{<br> mov dx, 0x1f0<br> in ax, dx<br> mov temp, ax<br> }<br> serial = temp;<br> } <br> <br> __asm{<br> pop esi<br> pop edx<br> pop ecx<br> pop ebx<br> pop eax<br> iretd<br> }<br> <br> //_asm iretd<br>}<br> <br>int Win9xHDSerialNumRead(WORD * buffer)<br>{ <br> int i; <br> for(i=0;i<256;i++) <br> buffer=0;<br> ReadIdeSerialNumber();<br> for(i=0;i<256;i++) <br> buffer=serial;<br> return 1;<br>}<br>void _stdcall ReadIdeSerialNumber()<br>{ <br> _asm<br> {<br> push eax <br> //获取修改的中断的中断描述符(中断门)地址<br> sidt IDTR <br> mov eax,dword ptr [IDTR+02h] <br> add eax,3*08h+04h<br> cli<br> //保存原先的中断入口地址<br> push ecx<br> mov ecx,dword ptr [eax]<br> mov cx,word ptr [eax-04h]<br> mov dword ptr OldInterruptAddress,ecx<br> pop ecx<br> //设置修改的中断入口地址为新的中断处理程序入口地址<br> push ebx<br> lea ebx,InterruptProcess <br> mov word ptr [eax-04h],bx<br> shr ebx,10h<br> mov word ptr [eax+02h],bx<br> pop ebx<br> //执行中断,转到Ring 0(类似CIH病毒原理)<br> int 3h<br> //恢复原先的中断入口地址<br> push ecx<br> mov ecx,dword ptr OldInterruptAddress<br> mov word ptr [eax-04h],cx<br> shr ecx,10h<br> mov word ptr [eax+02h],cx<br> pop ecx<br> sti<br> pop eax<br> }<br>}<br><br>char *ConvertToString (WORD diskdata [256], int firstIndex, int lastIndex)<br>{<br> static char string [1024];<br> int index = 0;<br> int position = 0;<br><br> // each integer has two characters stored in it backwards<br> for (index = firstIndex; index <= lastIndex; index++)<br> {<br> // get high byte for 1st character<br> string [position] = (char) (diskdata [index] / 256);<br> position++;<br><br> // get low byte for 2nd character<br> string [position] = (char) (diskdata [index] % 256);<br> position++;<br> }<br><br> // end the string<br> string [position] = '/0';<br><br> // cut off the trailing blanks<br> for (index = position - 1; index > 0 && ' ' == string [index]; index--)<br> string [index] = '/0';<br><br> return string;<br>}<br><br>char *ConvertToString2 (DWORD diskdata [256], int firstIndex, int lastIndex)<br>{<br> static char string [1024];<br> int index = 0;<br> int position = 0;<br><br> // each integer has two characters stored in it backwards<br> for (index = firstIndex; index <= lastIndex; index++)<br> {<br> // get high byte for 1st character<br> string [position] = (char) (diskdata [index] / 256);<br> position++;<br><br> // get low byte for 2nd character<br> string [position] = (char) (diskdata [index] % 256);<br> position++;<br> }<br><br> // end the string <br> string [position] = '/0';<br><br> // cut off the trailing blanks<br> for (index = position - 1; index > 0 && ' ' == string [index]; index--)<br> string [index] = '/0';<br><br> return string;<br>}<br><br>int WinNTHDSerialNumAsScsiRead (DWORD * buffer)<br>{<br><br> buffer[0]='/n';<br> int controller = 0;<br><br> // for (controller = 0; controller < 2; controller++)<br> {<br> HANDLE hScsiDriveIOCTL = 0;<br> char driveName [256];<br> // Try to get a handle to PhysicalDrive IOCTL, report failure<br> // and exit if can't.<br> sprintf (driveName, "////.//Scsi%d:", controller);<br>// driveName="////.//Scsi0";<br> // Windows NT, Windows 2000, any rights should do<br> hScsiDriveIOCTL = CreateFile (driveName,<br> GENERIC_READ | GENERIC_WRITE, <br> FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,<br> OPEN_EXISTING, 0, NULL);<br> // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)<br> // printf ("Unable to open SCSI controller %d, error code: 0x%lX/n",<br> // controller, GetLastError ());<br><br> if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)<br> {<br> int drive = 0;<br><br> for (drive = 0; drive < 2; drive++)<br> {<br> char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];<br> SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;<br> SENDCMDINPARAMS *pin =<br> (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));<br> DWORD dummy;<br> <br> memset (buffer, 0, sizeof (buffer));<br> p -> HeaderLength = sizeof (SRB_IO_CONTROL);<br> p -> Timeout = 10000;<br> p -> Length = SENDIDLENGTH;<br> p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;<br> strncpy ((char *) p -> Signature, "SCSIDISK", 8);<br> <br> pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;<br> pin -> bDriveNumber = drive;<br><br> if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, <br> buffer,<br> sizeof (SRB_IO_CONTROL) +<br> sizeof (SENDCMDINPARAMS) - 1,<br> buffer,<br> sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,<br> &dummy, NULL))<br> {<br> SENDCMDOUTPARAMS *pOut =<br> (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));<br> IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);<br> if (pId -> sModelNumber [0])<br> {<br> int ijk = 0;<br> USHORT *pIdSector = (USHORT *) pId;<br> <br> for (ijk = 0; ijk < 256; ijk++)<br> buffer[ijk] =pIdSector [ijk];<br>// PrintIdeInfo (controller * 2 + drive, diskdata);<br> return 1;<br> }<br> }<br> }<br> CloseHandle (hScsiDriveIOCTL);<br> }<br> }<br><br> return -1;<br>}<br>BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,<br> PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,<br> PDWORD lpcbBytesReturned)<br>{<br> // Set up data structures for IDENTIFY command.<br> pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;<br> pSCIP -> irDriveRegs.bFeaturesReg = 0;<br> pSCIP -> irDriveRegs.bSectorCountReg = 1;<br> pSCIP -> irDriveRegs.bSectorNumberReg = 1;<br> pSCIP -> irDriveRegs.bCylLowReg = 0;<br> pSCIP -> irDriveRegs.bCylHighReg = 0;<br><br> // Compute the drive number.<br> pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);<br><br> // The command can either be IDE identify or ATAPI identify.<br> pSCIP -> irDriveRegs.bCommandReg = bIDCmd;<br> pSCIP -> bDriveNumber = bDriveNum;<br> pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;<br><br> return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,<br> (LPVOID) pSCIP,<br> sizeof(SENDCMDINPARAMS) - 1,<br> (LPVOID) pSCOP,<br> sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,<br> lpcbBytesReturned, NULL) );<br>}<br><br>int WinNTHDSerialNumAsPhysicalRead (DWORD * buffer)<br>{<br>#define DFP_GET_VERSION 0x00074080<br>BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];<br><br> int done = FALSE;<br> int drive = 0;<br><br> // for (drive = 0; drive < MAX_IDE_DRIVES; drive++)<br> {<br> HANDLE hPhysicalDriveIOCTL = 0;<br><br> // Try to get a handle to PhysicalDrive IOCTL, report failure<br> // and exit if can't.<br> char driveName [256];<br><br> sprintf (driveName, "////.//PhysicalDrive%d", drive);<br><br> // Windows NT, Windows 2000, must have admin rights<br> hPhysicalDriveIOCTL = CreateFile (driveName,<br> GENERIC_READ | GENERIC_WRITE,<br> FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,<br> OPEN_EXISTING, 0, NULL);<br> // if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)<br> // printf ("Unable to open physical drive %d, error code: 0x%lX/n",<br> // drive, GetLastError ());<br><br> if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)<br> {<br> GETVERSIONOUTPARAMS VersionParams;<br> DWORD cbBytesReturned = 0;<br><br> // Get the version, etc of PhysicalDrive IOCTL<br> memset ((void*) &VersionParams, 0, sizeof(VersionParams));<br><br> if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,<br> NULL, <br> 0,<br> &VersionParams,<br> sizeof(VersionParams),<br> &cbBytesReturned, NULL) )<br> { <br> // printf ("DFP_GET_VERSION failed for drive %d/n", i);<br> // continue;<br> }<br><br> // If there is a IDE device at number "i" issue commands<br> // to the device<br> if (VersionParams.bIDEDeviceMap > 0)<br> {<br> BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd<br> SENDCMDINPARAMS scip;<br> //SENDCMDOUTPARAMS OutCmd;<br><br> // Now, get the ID sector for all IDE devices in the system.<br> // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,<br> // otherwise use the IDE_ATA_IDENTIFY command<br> bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? /<br> IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;<br><br> memset (&scip, 0, sizeof(scip));<br> memset (IdOutCmd, 0, sizeof(IdOutCmd));<br><br> if ( DoIDENTIFY (hPhysicalDriveIOCTL, <br> &scip, <br> (PSENDCMDOUTPARAMS)&IdOutCmd,<br> (BYTE) bIDCmd,<br> (BYTE) drive,<br> &cbBytesReturned))<br> {<br> //DWORD diskdata [256];<br> int ijk = 0;<br> USHORT *pIdSector = (USHORT *)<br> ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;<br><br> for (ijk = 0; ijk < 256; ijk++)<br> buffer[ijk] = pIdSector [ijk];<br><br> // PrintIdeInfo (drive, diskdata);<br><br> done = TRUE;<br> }<br> }<br><br> CloseHandle (hPhysicalDriveIOCTL);<br> }<br> }<br><br> return done;<br>}<br><br><br><br>LPCWSTR FAR HDSerialNumRead()<br>{ <br> char buffer[256];<br> buffer[0]='/n';<br> OSVERSIONINFO OSVersionInfo;<br> OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);<br> GetVersionEx( &OSVersionInfo);<br> if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)<br> { <br> WORD m_wSeri[256];<br> Win9xHDSerialNumRead(m_wSeri); <br> strcpy (buffer, ConvertToString (m_wSeri, 10, 19));<br> }<br> else{<br> DWORD m_wStr[256];<br> <br> if ( ! WinNTHDSerialNumAsPhysicalRead(m_wStr)) WinNTHDSerialNumAsScsiRead;<br><br> strcpy (buffer, ConvertToString2 (m_wStr, 10, 19));<br> } ;<br> <br> return LPCWSTR(LPCSTR(buffer)); <br><br>}<br><br>int WEP(int nParam)<br>{<br>return 1;<br>}<br><br>