📄 gethdidinfo2.cpp
字号:
// Search for a free GDT descriptor for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++) { if (pGDTDescriptor->Type == 0 && pGDTDescriptor->System == 0 && pGDTDescriptor->DPL == 0 && pGDTDescriptor->Present == 0) { // Found one ! // Now we need to transform this descriptor into a callgate. // Note that we're using selector 0x28 since it corresponds // to a ring 0 segment which spans the entire linear address // space of the processor (0-4GB). struct CALLGATE_DESCRIPTOR *pCallgate; pCallgate = (struct CALLGATE_DESCRIPTOR *) pGDTDescriptor; pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr); pCallgate->Selector = 0x28; pCallgate->ParamCount = 0; pCallgate->Unused = 0; pCallgate->Type = 0xc; pCallgate->System = 0; pCallgate->DPL = 3; pCallgate->Present = 1; pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr); // Prepare the far call parameters CallgateAddr[0] = 0x0; CallgateAddr[1] = 0x0; CallgateAddr[2] = (wGDTIndex << 3) | 3; // Please fasten your seat belts! // We're about to make a hyperspace jump into RING 0. _asm Mov DX, [wPortAddr] _asm Mov EBX, [pdwPortVal] _asm Mov CL, [bSize] _asm Call FWORD PTR [CallgateAddr] // We have made it ! // Now free the GDT descriptor memset(pGDTDescriptor, 0, 8); // Our journey was successful. Seeya. return true; } // Advance to the next GDT descriptor pGDTDescriptor++; } // Whoops, the GDT is full return false;}bool GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize){ bool Result; DWORD dwBytesReturned; struct tagPort32Struct Port32Struct; if (IsNT) { if (!IsWinIoInitialized) return false; Port32Struct.wPortAddr = wPortAddr; Port32Struct.bSize = bSize; if (!DeviceIoControl(hDriver, IOCTL_WINIO_READPORT, &Port32Struct, sizeof(struct tagPort32Struct), &Port32Struct, sizeof(struct tagPort32Struct), &dwBytesReturned, NULL)) return false; else *pdwPortVal = Port32Struct.dwPortVal; } else { Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize); if (Result == false) return false; } return true;}bool SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize){ DWORD dwBytesReturned; struct tagPort32Struct Port32Struct; if (IsNT) { if (!IsWinIoInitialized) return false; Port32Struct.wPortAddr = wPortAddr; Port32Struct.dwPortVal = dwPortVal; Port32Struct.bSize = bSize; if (!DeviceIoControl(hDriver, IOCTL_WINIO_WRITEPORT, &Port32Struct, sizeof(struct tagPort32Struct), NULL, 0, &dwBytesReturned, NULL)) return false; } else return CallRing0((PVOID)Ring0SetPortVal, wPortAddr, &dwPortVal, bSize); return true;}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;}#define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZEint 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;}char HardDriveSerialNumber [1024];void PrintIdeInfo (int drive, DWORD diskdata [256]){ // copy the hard driver serial number to the buffer strcpy (HardDriveSerialNumber, ConvertToString (diskdata, 10, 19));#ifdef PRINTING_TO_CONSOLE_ALLOWED switch (drive / 2) { case 0: printf ("\nPrimary Controller - "); break; case 1: printf ("\nSecondary Controller - "); break; case 2: printf ("\nTertiary Controller - "); break; case 3: printf ("\nQuaternary Controller - "); break; } switch (drive % 2) { case 0: printf ("Master drive\n\n"); break; case 1: printf ("Slave drive\n\n"); break; } printf ("Drive Model Number________________: %s\n", ConvertToString (diskdata, 27, 46)); printf ("Drive Serial Number_______________: %s\n", ConvertToString (diskdata, 10, 19)); printf ("Drive Controller Revision Number__: %s\n", ConvertToString (diskdata, 23, 26)); printf ("Controller Buffer Size on Drive___: %u bytes\n", diskdata [21] * 512); printf ("Drive Type________________________: "); if (diskdata [0] & 0x0080) printf ("Removable\n"); else if (diskdata [0] & 0x0040) printf ("Fixed\n"); else printf ("Unknown\n"); printf ("Physical Geometry: " "%u Cylinders %u Heads %u Sectors per track\n", diskdata [1], diskdata [3], diskdata [6]);#else // PRINTING_TO_CONSOLE_ALLOWED // nothing to do#endif // PRINTING_TO_CONSOLE_ALLOWED}char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex){ static char string [1024]; int index = 0; int position = 0; // each integer has two characters stored in it backwards for (index = firstIndex; index <= lastIndex; index++) { // get high byte for 1st character string [position] = (char) (diskdata [index] / 256); position++; // get low byte for 2nd character string [position] = (char) (diskdata [index] % 256); position++; } // end the string string [position] = '\0'; // cut off the trailing blanks for (index = position - 1; index > 0 && ' ' == string [index]; index--) string [index] = '\0'; return string;}long getHardDriveComputerID (){ int done = FALSE; //char string [1024]; __int64 id = 0; strcpy (HardDriveSerialNumber, ""); // this works under WinNT4 or Win2K if you have admin rights done = ReadPhysicalDriveInNT (); // this should work in WinNT or Win2K if previous did not work // this is kind of a backdoor via the SCSI mini port driver into // the IDE drives if ( ! done) done = ReadIdeDriveAsScsiDriveInNT (); // this works under Win9X and calls WINIO.DLL if ( ! done) done = ReadDrivePortsInWin9X (); if (done) { char *p = HardDriveSerialNumber; //WriteConstantString ("HardDriveSerialNumber", HardDriveSerialNumber); // ignore first 5 characters from western digital hard drives if // the first four characters are WD-W if ( ! strncmp (HardDriveSerialNumber, "WD-W", 4)) p += 5; for ( ; p && *p; p++) { if ('-' == *p) continue; id *= 10; switch (*p) { case '0': id += 0; break; case '1': id += 1; break; case '2': id += 2; break; case '3': id += 3; break; case '4': id += 4; break; case '5': id += 5; break; case '6': id += 6; break; case '7': id += 7; break; case '8': id += 8; break; case '9': id += 9; break; case 'a': case 'A': id += 10; break; case 'b': case 'B': id += 11; break; case 'c': case 'C': id += 12; break; case 'd': case 'D': id += 13; break; case 'e': case 'E': id += 14; break; case 'f': case 'F': id += 15; break; case 'g': case 'G': id += 16; break; case 'h': case 'H': id += 17; break; case 'i': case 'I': id += 18; break; case 'j': case 'J': id += 19; break; case 'k': case 'K': id += 20; break; case 'l': case 'L': id += 21; break; case 'm': case 'M': id += 22; break; case 'n': case 'N': id += 23; break; case 'o': case 'O': id += 24; break; case 'p': case 'P': id += 25; break; case 'q': case 'Q': id += 26; break; case 'r': case 'R': id += 27; break; case 's': case 'S': id += 28; break; case 't': case 'T': id += 29; break; case 'u': case 'U': id += 30; break; case 'v': case 'V': id += 31; break; case 'w': case 'W': id += 32; break; case 'x': case 'X': id += 33; break; case 'y': case 'Y': id += 34; break; case 'z': case 'Z': id += 35; break; } } }#ifdef PRINTING_TO_CONSOLE_ALLOWED printf ("\nComputer ID_______________________: %I64d\n", id);#endif return (long) id;}int main (int argc, char * argv []){ long id = getHardDriveComputerID (); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -