www.pudn.com > 取硬盘物理序列号.zip > PORTDLL.CPP


#include  
//#include  
//#include  
//#include  
#include  
//#include  
 
#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE 
#define  IDENTIFY_BUFFER_SIZE  512 
#define  FILE_DEVICE_SCSI              0x0000001b 
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ((FILE_DEVICE_SCSI << 16) + 0x0501) 
#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition 
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI. 
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA. 
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088 
	typedef struct _IDSECTOR 
{ 
   USHORT  wGenConfig; 
   USHORT  wNumCyls; 
   USHORT  wReserved; 
   USHORT  wNumHeads; 
   USHORT  wBytesPerTrack; 
   USHORT  wBytesPerSector; 
   USHORT  wSectorsPerTrack; 
   USHORT  wVendorUnique[3]; 
   CHAR    sSerialNumber[20]; 
   USHORT  wBufferType; 
   USHORT  wBufferSize; 
   USHORT  wECCSize; 
   CHAR    sFirmwareRev[8]; 
   CHAR    sModelNumber[40]; 
   USHORT  wMoreVendorUnique; 
   USHORT  wDoubleWordIO; 
   USHORT  wCapabilities; 
   USHORT  wReserved1; 
   USHORT  wPIOTiming; 
   USHORT  wDMATiming; 
   USHORT  wBS; 
   USHORT  wNumCurrentCyls; 
   USHORT  wNumCurrentHeads; 
   USHORT  wNumCurrentSectorsPerTrack; 
   ULONG   ulCurrentSectorCapacity; 
   USHORT  wMultSectorStuff; 
   ULONG   ulTotalAddressableSectors; 
   USHORT  wSingleWordDMA; 
   USHORT  wMultiWordDMA; 
   BYTE    bReserved[128]; 
} IDSECTOR, *PIDSECTOR; 
 
typedef struct _DRIVERSTATUS 
{ 
   BYTE  bDriverError;  //  Error code from driver, or 0 if no error. 
   BYTE  bIDEStatus;    //  Contents of IDE Error register. 
                        //  Only valid when bDriverError is SMART_IDE_ERROR. 
   BYTE  bReserved[2];  //  Reserved for future expansion. 
   DWORD  dwReserved[2];  //  Reserved for future expansion. 
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS; 
 
	typedef struct _SENDCMDOUTPARAMS 
{ 
   DWORD         cBufferSize;   //  Size of bBuffer in bytes 
   DRIVERSTATUS  DriverStatus;  //  Driver status structure. 
   BYTE          bBuffer[1];    //  Buffer of arbitrary length in which to store the data read from the                                                       // drive. 
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS; 
typedef struct _SRB_IO_CONTROL 
{ 
   ULONG HeaderLength; 
   UCHAR Signature[8]; 
   ULONG Timeout; 
   ULONG ControlCode; 
   ULONG ReturnCode; 
   ULONG Length; 
} SRB_IO_CONTROL, *PSRB_IO_CONTROL; 
typedef struct _IDEREGS 
{ 
   BYTE bFeaturesReg;       // Used for specifying SMART "commands". 
   BYTE bSectorCountReg;    // IDE sector count register 
   BYTE bSectorNumberReg;   // IDE sector number register 
   BYTE bCylLowReg;         // IDE low order cylinder value 
   BYTE bCylHighReg;        // IDE high order cylinder value 
   BYTE bDriveHeadReg;      // IDE drive/head register 
   BYTE bCommandReg;        // Actual IDE command. 
   BYTE bReserved;          // reserved for future use.  Must be zero. 
} IDEREGS, *PIDEREGS, *LPIDEREGS; 
 
typedef struct _SENDCMDINPARAMS 
{ 
   DWORD     cBufferSize;   //  Buffer size in bytes 
   IDEREGS   irDriveRegs;   //  Structure with drive register values. 
   BYTE bDriveNumber;       //  Physical drive number to send  
                            //  command to (0,1,2,3). 
   BYTE bReserved[3];       //  Reserved for future expansion. 
   DWORD     dwReserved[4]; //  For future use. 
   BYTE      bBuffer[1];    //  Input buffer. 
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; 
typedef struct _GETVERSIONOUTPARAMS 
{ 
   BYTE bVersion;      // Binary driver version. 
   BYTE bRevision;     // Binary driver revision. 
   BYTE bReserved;     // Not used. 
   BYTE bIDEDeviceMap; // Bit map of IDE devices. 
   DWORD fCapabilities; // Bit mask of driver capabilities. 
   DWORD dwReserved[4]; // For future use. 
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; 
 
WORD serial[256]; 
DWORD OldInterruptAddress; 
DWORDLONG IDTR; 
void _stdcall ReadIdeSerialNumber(); 
static unsigned int WaitHardDiskIde()  
{  
	BYTE xx; 
 
Waiting: 
	__asm{ 
		mov dx, 0x1f7 
		in al, dx 
		cmp al, 0x80 
		jb Endwaiting 
		jmp Waiting 
	} 
Endwaiting: 
	__asm{ 
		mov xx, al 
	} 
 
	return xx;  
}  
void __declspec( naked ) InterruptProcess(void)//中断服务程序 
{ 
	int   xx; 
    int   i; 
	WORD temp; 
	//保存寄存器值 
     __asm 
      { 
        push eax 
        push ebx 
        push ecx 
        push edx 
        push esi 
      } 
       
      WaitHardDiskIde();//等待硬盘空闲状态 
      __asm{ 
		mov dx, 0x1f6 
		mov al, 0xa0 
		out dx, al 
	} 
	xx = WaitHardDiskIde(); //若直接在Ring3级执行等待命令,会进入死循环 
	if ((xx&0x50)!=0x50)  
	{ 
		__asm{ 
        pop esi 
        pop edx 
        pop ecx 
        pop ebx 
        pop eax 
		iretd 
		} 
	} 
		 
	__asm{ 
		mov dx, 0x1f6 //命令端口1f6,选择驱动器0 
		mov al, 0xa0 
		out dx, al 
		inc dx 
		mov al, 0xec 
		out dx, al //发送读驱动器参数命令 
	} 
	 
	xx = WaitHardDiskIde();  
	if ((xx&0x58)!=0x58)  
    { 
		__asm{ 
        pop esi 
        pop edx 
        pop ecx 
        pop ebx 
        pop eax 
		iretd 
		} 
	} 
    //读取硬盘控制器的全部信息 
	for (i=0;i<256;i++) { 
		__asm{ 
			mov dx, 0x1f0 
			in ax, dx 
			mov temp, ax 
		} 
		serial[i] = temp;  
	}  
                                
	__asm{ 
        pop esi 
        pop edx 
        pop ecx 
        pop ebx 
        pop eax 
		iretd 
    } 
	 
       //_asm iretd 
} 
	 
int Win9xHDSerialNumRead(WORD * buffer) 
{	 
	int i;		 
	for(i=0;i<256;i++)  
		buffer[i]=0; 
	ReadIdeSerialNumber(); 
	for(i=0;i<256;i++)		 
		buffer[i]=serial[i]; 
	return 1; 
} 
void _stdcall ReadIdeSerialNumber() 
{       
      _asm 
      { 
      	push eax         
        //获取修改的中断的中断描述符(中断门)地址 
        sidt IDTR	 
        mov eax,dword ptr [IDTR+02h]         
        add eax,3*08h+04h 
        cli 
        //保存原先的中断入口地址 
        push ecx 
        mov ecx,dword ptr [eax] 
        mov cx,word ptr [eax-04h] 
        mov dword ptr OldInterruptAddress,ecx 
        pop ecx 
        //设置修改的中断入口地址为新的中断处理程序入口地址 
        push ebx 
        lea ebx,InterruptProcess		 
        mov word ptr [eax-04h],bx 
        shr ebx,10h 
        mov word ptr [eax+02h],bx 
        pop ebx 
        //执行中断,转到Ring 0(类似CIH病毒原理) 
		int 3h 
        //恢复原先的中断入口地址 
        push ecx 
        mov ecx,dword ptr OldInterruptAddress 
        mov word ptr [eax-04h],cx 
        shr ecx,10h 
        mov word ptr [eax+02h],cx 
        pop ecx 
        sti 
        pop eax 
       } 
} 
 
char *ConvertToString (WORD 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; 
} 
 
char *ConvertToString2 (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; 
} 
 
 
 
 
 
 
 
 
 
int WinNTHDSerialNumAsScsiRead (DWORD * buffer) 
{ 
	 
       buffer[0]='\n'; 
   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); 
//      driveName="\\\\.\\Scsi0"; 
         //  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]) 
               { 
                  int ijk = 0; 
                  USHORT *pIdSector = (USHORT *) pId; 
           
                  for (ijk = 0; ijk < 256; ijk++) 
                      buffer[ijk] =pIdSector [ijk]; 
//                  PrintIdeInfo (controller * 2 + drive, diskdata); 
         return 1; 
                               } 
            } 
         } 
         CloseHandle (hScsiDriveIOCTL); 
      } 
   } 
 
   return -1; 
} 
BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, 
                 PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, 
                 PDWORD lpcbBytesReturned) 
{ 
      // 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. 
   pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4); 
 
      // The command can either be IDE identify or ATAPI identify. 
   pSCIP -> irDriveRegs.bCommandReg = bIDCmd; 
   pSCIP -> bDriveNumber = bDriveNum; 
   pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE; 
 
   return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA, 
               (LPVOID) pSCIP, 
               sizeof(SENDCMDINPARAMS) - 1, 
               (LPVOID) pSCOP, 
               sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, 
               lpcbBytesReturned, NULL) ); 
} 
 
int WinNTHDSerialNumAsPhysicalRead (DWORD * buffer) 
{ 
#define  DFP_GET_VERSION          0x00074080 
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; 
 
   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++) 
                 buffer[ijk] = pIdSector [ijk]; 
 
            //   PrintIdeInfo (drive, diskdata); 
 
               done = TRUE; 
            } 
	    } 
 
         CloseHandle (hPhysicalDriveIOCTL); 
      } 
   } 
 
   return done; 
} 
 
 
 
LPCWSTR FAR HDSerialNumRead() 
{	 
	char  buffer[256];	 
 buffer[0]='\n'; 
  OSVERSIONINFO OSVersionInfo; 
  OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
  GetVersionEx( &OSVersionInfo); 
  if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) 
  {    
	  WORD m_wSeri[256]; 
	  Win9xHDSerialNumRead(m_wSeri);   
      strcpy (buffer, ConvertToString (m_wSeri, 10, 19)); 
  } 
  else{ 
  DWORD m_wStr[256]; 
   
  if ( ! WinNTHDSerialNumAsPhysicalRead(m_wStr)) WinNTHDSerialNumAsScsiRead; 
   
  strcpy (buffer, ConvertToString2 (m_wStr, 10, 19)); 
  }	; 
   
  return LPCWSTR(LPCSTR(buffer));	   
 
} 
 
int WEP(int nParam) 
{ 
return 1; 
}