hardinfo.cpp

来自「“取CPU和硬盘ID值” 在Windows 98平台下编译成功」· C++ 代码 · 共 733 行 · 第 1/2 页

CPP
733
字号
    Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize);

    if (Result == false)
      return false;
  }

  return true;
}


bool CHardInfo::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 CHardInfo::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;
}

int CHardInfo::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;
}

void CHardInfo::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));
   strcpy(Hard_Info.Drive_Model,ConvertToString (diskdata, 27, 46));
//   printf ("Drive Serial Number_______________: %s\n",
//           ConvertToString (diskdata, 10, 19));
   strcpy(Hard_Info.Disk_Serial,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]);
Hard_Info.Cylinders=diskdata [1];
Hard_Info.Heads=diskdata [3];
Hard_Info.Sectors_per_track=diskdata [6];

#else   //  PRINTING_TO_CONSOLE_ALLOWED

   //  nothing to do

#endif  // PRINTING_TO_CONSOLE_ALLOWED

}


char *CHardInfo::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 CHardInfo::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;
         }                            
      }
   }

      //   make sure no bigger than 16^7
   if (id > 268435455) id %= 268435456;

#ifdef PRINTING_TO_CONSOLE_ALLOWED

   //printf ("\nComputer ID_______________________: %d\n", id);
   Hard_Info.Cpu_Id=id;

#endif

   return (long) id;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?