🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #8378

Re: get disk serial number

#8378
From: Andrue Cope [TeamB]
Date: Wed, 27 Oct 2004 14:47
108 lines
4911 bytes
Ed Mulroy [TeamB] wrote:

> Do you have any hints about how one could do that or at least where
> to find the info on how to do it?

Yeah. I was waiting to see if the OP already knew how to do this. It's
a horrible area to get to grips with and very frustrating. One of those
cases where you faff around for a week trying different things until
you finally get something that seems to work. Then you vow never to
touch the code ever again :(

The following only works under true Win32 (ie;not Win9x).

The core functionality revolves around DeviceIOControl() that is one of
those functions that takes (and sometimes returns) a control structure
along with varying numbers of arguments. Get one value wrong and the
error code will be "A parameter is incorrect" :(

You call CreateFile() to the device using the appropriate device path.
This path is the first problem because there are several ways of
identifying a device. If you're familiar with Unix then think of the
\Dev\ directory but assume that most devices have at least two aliases
and that devices have paths not just names. The simplest form would be:

  \\.\PhysicalDisk0
For C:
  \\.\C:

But there are various other possibilites including SCSI specifications
and GUIDs. Basically device IDs under Win32 are classified using a
hierarchy and IIRC this even extends to files. The same parser is used
for file paths and relies on "A:" being an alias for \\.\A:

As for DeviceIOControl you can do a Google for this and find the entry
on MSDN. A section of our code for one device type is:

  MyFileHandle=CreateFile( SPTIDeviceID,
                           GENERIC_WRITE|GENERIC_READ,
                           FILE_SHARE_READ|FILE_SHARE_WRITE,
                           NULL,
                           OPEN_EXISTING,
                           0,
                           NULL );

/*
    BYTE                   MyInfoBuffer[ 2048 ];

  Why 2048? Because it seems to be enough.
*/

  if( MyFileHandle!=INVALID_HANDLE_VALUE )
  {
    DWORD returned=0;

    // Get information for this card (includes inquiry info. for all
devices)
    if( !MyIAmDriveLetterF )
    {
      if( DeviceIoControl( MyFileHandle,
                           IOCTL_SCSI_GET_INQUIRY_DATA,
                           NULL,
                           0,
                           MyInfoBuffer,
                           sizeof( MyInfoBuffer ),
                           &returned,
                           FALSE ) )
      {
        MyIAmDriveLetterF=false;
        PSCSI_ADAPTER_BUS_INFO adapterInfo=(PSCSI_ADAPTER_BUS_INFO)
MyInfoBuffer;

        if( adapterInfo&&
            adapterInfo->NumberOfBuses&&
            adapterInfo->BusData[ 0 ].InquiryDataOffset )
        {
          PSCSI_INQUIRY_DATA inquiryData=
            (PSCSI_INQUIRY_DATA)( MyInfoBuffer+adapterInfo->BusData[ 0
].InquiryDataOffset );

The fact the structure returns an array is bizarre. Sometimes there's a
good reason for it since you can open the SCSI controller as a device
and access the drives attached to it. Presumably someone at Microsoft
and probably elsewhere in the World understands all of this but I
confess to only knowing 'enough'.

You might say "I have walked in the valley of death, and yay I did turn
around and run but I grabbed some stuff as I ran" :)

PSCSI_INQUIRY_DATA gets you access the drive's inquiry data which will
then be as described by the SCSI standard:

        AnsiString sn;

        char * chAdd=( char *)&buffer[ 4 ];
        while( buffer[ 3 ] )
        {
          sn+=*chAdd;
          --buffer[ 3 ];
        }

        sn=sn.Trim();

..but note that since for IDE drives Win32 is 'faking it' the results
are sometimes a little odd.
-- 
Andrue Cope [TeamB]
[Bicester, Uk]
http://info.borland.com/newsgroups/guide.html
Technical Details
Message-ID: <417fb513@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!newsfeed-east.nntpserver.com!nntpserver.com!diablo.voicenet.com!38.119.100.83.MISMATCH!news-out1.nntp.be!propagator2-sterling!news-in-sterling.newsfeeds.com!in.nntp.be!caladan.arrakis.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <417fa0fd@newsgroups.borland.com> <417fa38f@newsgroups.borland.com> <417fa4dd@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,bdae4482adfc73e4
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Andrue Cope [TeamB]" <no.spam@not.a.valid.address>
Subject: Re: get disk serial number
Newsgroups: borland.public.cppbuilder.nativeapi
References: <417fa0fd@newsgroups.borland.com> <417fa38f@newsgroups.borland.com> <417fa4dd@newsgroups.borland.com>
User-Agent: XanaNews/1.16.4.6
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
NNTP-Posting-Host: 217.207.223.34
Message-ID: <417fb513@newsgroups.borland.com>
Date: 27 Oct 2004 07:47:47 -0700
X-Trace: newsgroups.borland.com 1098888467 217.207.223.34 (27 Oct 2004 07:47:47 -0700)
Lines: 108
X-Authenticated-User: acope
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!newsfeed-east.nntpserver.com!nntpserver.com!diablo.voicenet.com!38.119.100.83.MISMATCH!news-out1.nntp.be!propagator2-sterling!news-in-sterling.newsfeeds.com!in.nntp.be!caladan.arrakis.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail