我使用DeviceIoControl读取,方法如下:
BOOL GetDriveSN(CHANGER_PRODUCT_DATA *pdg)
{
  HANDLE hDevice;               // handle to the drive to be examined 
  BOOL bResult;                 // results flag
  DWORD junk;                   // discard results  hDevice = CreateFile("\\\\.\\PhysicalDrive0",  // drive to open
                    0,                // no access to the drive
                    0, 
                    NULL,             // default security attributes
                    OPEN_EXISTING,    // disposition
                    0,                // file attributes
                    NULL);            // do not copy file attributes  if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
  {
    return (FALSE);
  }  bResult = DeviceIoControl(hDevice,  // device to be queried
  IOCTL_CHANGER_GET_PRODUCT_DATA,  // operation to perform
                             NULL, 0, // no input buffer
                            pdg, sizeof(*pdg),     // output buffer
                            &junk,                 // # bytes returned
                            (LPOVERLAPPED) NULL);  // synchronous I/O  CloseHandle(hDevice);  return (bResult);
}使用GetLastError得到的错误码是5,这是为什么?
MSDN的例子是IOCTL_DISK_GET_DRIVE_GEOMETRY,正确。

解决方案 »

  1.   

    看看这个例子;
    http://www.moreres.com/down/svc021405.zip
      

  2.   

    谢谢。
    不过我想知道。DeviceIoControl的使用过程中出现什么问题了?
      

  3.   

    因为我想在其他环境中,比如VB,Delphi中,也实现这个功能。
      

  4.   

    我在网吧。没有msdn,不清楚5的错误码是什么。
    不过有个主意你用vc做成dll,让vb和delphi用。我也是这么干的供pb用。
      

  5.   

    1,當返回值為5時,表示你的訪問被拒絕。主要是你的CreateFile時權限沒有開夠!
    2,將CreateFile改為如下調用:
       hDevice = ::CreateFile(
    "\\\\.\\PhysicalDrive0",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
    );我試了一下,發現ERROR返回值為 1,可能對於磁盤驅動器而言,根本就不提供這個功能調用!
      

  6.   

    IOCTL_CHANGER_GET_PRODUCT_DATA
    需要WindowsXP以上系统。
      

  7.   

    http://vip.6to23.com/NowCan1/tech/diskid.htm
    看这里。
      

  8.   

    不是啊那个源程序在win9x(通过中断门)和nt,win2k都可以运行.
    而且支持scsi硬盘.
      

  9.   

    IOCTL_CHANGER_GET_PRODUCT_DATA这个应该支持Win2K吧?
    MSDN文档:Requirements 
      Windows NT/2000/XP: Included in Windows XP and Windows .NET Server.
      Windows 95/98/Me: Unsupported.
      Header: Declared in Winioctl.h.See Also
      

  10.   

    NowCan(能量、激情、雨水、彩虹——雷雨云) 
     能不能避免汇编代码?VB不能用。
      

  11.   

    syh_17(神探柯南) 
      唉,MSDN上的文档为什么不好用啊。
      他提供的例子很正常,应该可以这样操作磁盘驱动器。#include <windows.h>
    #include <winioctl.h>BOOL
    GetDriveGeometry(DISK_GEOMETRY *pdg)
    {
      HANDLE hDevice;               // handle to the drive to be examined 
      BOOL bResult;                 // results flag
      DWORD junk;                   // discard results  hDevice = CreateFile("\\\\.\\PhysicalDrive0", // drive to open
                           0,       // don't need any access to the drive
                           FILE_SHARE_READ | FILE_SHARE_WRITE,  // share mode
                           NULL,    // default security attributes
                           OPEN_EXISTING,  // disposition
                           0,       // file attributes
                           NULL);   // don't copy any file's attributes  if (hDevice == INVALID_HANDLE_VALUE) // we can't open the drive
      {
        return (FALSE);
      }  bResult = DeviceIoControl(hDevice,  // device we are querying
          IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
                                 NULL, 0, // no input buffer, so pass zero
                                pdg, sizeof(*pdg),  // output buffer
                                &junk, // discard count of bytes returned
                                (LPOVERLAPPED) NULL);  // synchronous I/O  CloseHandle(hDevice);         // we're done with the handle  return (bResult);
    }int
    main(int argc, char *argv[])
    {
      DISK_GEOMETRY pdg;            // disk drive geometry structure
      BOOL bResult;                 // generic results flag
      ULONGLONG DiskSize;           // size of the drive, in bytes  bResult = GetDriveGeometry (&pdg);  if (bResult) 
      {
        printf("Cylinders = %I64d\n", pdg.Cylinders);
        printf("Tracks per cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder);
        printf("Sectors per track = %ld\n", (ULONG) pdg.SectorsPerTrack);
        printf("Bytes per sector = %ld\n", (ULONG) pdg.BytesPerSector);    DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
          (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
        printf("Disk size = %I64d (Bytes) = %I64d (Mb)\n", DiskSize,
               DiskSize / (1024 * 1024));
      } else {
        printf ("Attempt to get drive geometry failed. Error %ld.\n",
                GetLastError ());
      }  return ((int)bResult);
    }
      

  12.   

    这个功能在2000/XP下是可以使用的。
    这个需要Admin权限才可以进行。
      

  13.   

    另外,你使用下面的代码也可以达到效果:
       //  IOCTL commands
    #define  DFP_GET_VERSION          0x00074080
    int ReadPhysicalDriveInNT (DWORD diskdata[256])
    {
       int done = FALSE;
       int drive = 0;   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))
             {
     int ijk = 0;
     USHORT *pIdSector = (USHORT *)
                                 ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;  for (ijk = 0; ijk < 256; ijk++)
                      diskdata [ijk] = pIdSector [ijk];             done = TRUE;
        }         CloseHandle (hPhysicalDriveIOCTL);
          }
       }   return done;
    }
      

  14.   

    to :wuxuan(真心英雄):
    我的系统是Win2K,我也是Administrator。
    可是不行啊。
    谢谢你的意见。不过好像也不行。