Searching for SATA serial number - why DeviceIoControl failed?

I use the following code to get hard disk serial number. But with some disks (SATA)this code failed. Do you know why?
What should I use instead of DFP_GET_VERSION?
1.First way:


#define  DFP_GET_VERSION          0x00074080
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;

char driveName [256];
sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
hPhysicalDriveIOCTL = CreateFile (driveName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,
                              OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
    GETVERSIONOUTPARAMS VersionParams;
    DWORD              cbBytesReturned = 0;
    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;
        }
...


2. Second way:


typedef enum _STORAGE_QUERY_TYPE {
    PropertyStandardQuery = 0,
    PropertyExistsQuery,
PropertyMaskQuery,   
PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;


typedef enum _STORAGE_PROPERTY_ID {
    StorageDeviceProperty = 0,
    StorageAdapterProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;

typedef struct _STORAGE_PROPERTY_QUERY {
    STORAGE_PROPERTY_ID PropertyId;
    STORAGE_QUERY_TYPE QueryType;
    UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
#define IOCTL_STORAGE_QUERY_PROPERTY  CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

char driveName [256];
sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
hPhysicalDriveIOCTL = CreateFile (driveName, 0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                              OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
STORAGE_PROPERTY_QUERY query;
      DWORD cbBytesReturned = 0;
char buffer [10000];

      memset ((void *) & query, 0, sizeof (query));
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
      memset (buffer, 0, sizeof (buffer));

if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof (query), &buffer,    sizeof (buffer), & cbBytesReturned, NULL) )
      {       
STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *) &buffer;
.

3. Third way


char  driveName [256];
sprintf (driveName, "\\\\.\\Scsi%d:", controller);
hScsiDriveIOCTL = CreateFile (driveName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                              OPEN_EXISTING, 0, NULL);
if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
{
  int drive = 0;
  for (drive = 0; drive < 2; drive++)
  {
      char buffer ;
      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))
}
...


I know that my device has got serial number because other program (aida) find it.
Posted on 2006-05-18 05:21:06 by adamrogoz
There are people here proficient in c/c++ code.But since this is an ASM board, I would tend to think that you would be better off posting your code and questions about it on a C/C++ board.
Rags
Posted on 2006-05-18 07:42:06 by rags
It's a fine enough question to post on this board, considering it's low-level nature. But since the code is C, I've moved the topic to The Heap.

The closest I've come with a quick google search was this: http://forums.wugnet.com/windows/DiskId32-SATA-drives-ftopict435387.html . Perhaps you can email Lynn and ask how he got it to work? (And post your results here :) )
Posted on 2006-05-18 07:53:36 by f0dder