Announcement

Collapse
No announcement yet.

Physical HD Manuf,Model,Serial C++

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Physical HD Manuf,Model,Serial C++

    The VXD and the source code can be found at: http://www.winsim.com/diskid32/diskid32.html

    Can this be converted to PB? I am not good at C++ so I am posting the code in case someone wants to convert it and post it.

    Thank you,

    Pedro


    // diskid32.cpp

    // for displaying the details of hard drives in

    // 06/11/2000 Lynn McGuire written with many contributions from others,
    // IDE drives only under Windows NT/2K and 9X,
    // maybe SCSI drives later


    #define PRINTING_TO_CONSOLE_ALLOWED


    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <windows.h>

    #define TITLE "DiskId32"


    // Required to ensure correct PhysicalDrive IOCTL structure setup
    #pragma pack(1)


    // Max number of drives assuming primary/secondary, master/slave topology
    #define MAX_IDE_DRIVES 4
    #define IDENTIFY_BUFFER_SIZE 512


    // IOCTL commands
    #define DFP_GET_VERSION 0x00074080
    #define DFP_SEND_DRIVE_COMMAND 0x0007c084
    #define DFP_RECEIVE_DRIVE_DATA 0x0007c088

    #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

    // GETVERSIONOUTPARAMS contains the data returned from the
    // Get Driver Version function.
    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;


    // Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
    #define CAP_IDE_ID_FUNCTION 1 // ATA ID command supported
    #define CAP_IDE_ATAPI_ID 2 // ATAPI ID command supported
    #define CAP_IDE_EXECUTE_SMART_FUNCTION 4 // SMART commannds supported


    // IDE registers
    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;


    // SENDCMDINPARAMS contains the input parameters for the
    // Send Command to Drive function.
    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;


    // Valid values for the bCommandReg member of IDEREGS.
    #define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.
    #define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.


    // Status returned from driver
    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;


    // Structure returned by PhysicalDrive IOCTL for several commands
    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;


    // The following struct defines the interesting part of the IDENTIFY
    // buffer:
    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 _SRB_IO_CONTROL
    {
    ULONG HeaderLength;
    UCHAR Signature[8];
    ULONG Timeout;
    ULONG ControlCode;
    ULONG ReturnCode;
    ULONG Length;
    } SRB_IO_CONTROL, *PSRB_IO_CONTROL;


    // Define global buffers.
    BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];


    char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex);
    void PrintIdeInfo (int drive, DWORD diskdata [256]);
    BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,
    PDWORD);


    int ReadPhysicalDriveInNT (void)
    {
    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++)
    diskdata [ijk] = pIdSector [ijk];

    PrintIdeInfo (drive, diskdata);

    done = TRUE;
    }
    }

    CloseHandle (hPhysicalDriveIOCTL);
    }
    }

    return done;
    }


    // DoIDENTIFY
    // FUNCTION: Send an IDENTIFY command to the drive
    // bDriveNum = 0-3
    // bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
    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) );
    }


    // ---------------------------------------------------

    // (* Output Bbuffer for the VxD (rt_IdeDinfo record) *)
    typedef struct _rt_IdeDInfo_
    {
    BYTE IDEExists[4];
    BYTE DiskExists[8];
    WORD DisksRawInfo[8*256];
    } rt_IdeDInfo, *pt_IdeDInfo;


    // (* IdeDinfo "data fields" *)
    typedef struct _rt_DiskInfo_
    {
    BOOL DiskExists;
    BOOL ATAdevice;
    BOOL RemovableDevice;
    WORD TotLogCyl;
    WORD TotLogHeads;
    WORD TotLogSPT;
    char SerialNumber[20];
    char FirmwareRevision[8];
    char ModelNumber[40];
    WORD CurLogCyl;
    WORD CurLogHeads;
    WORD CurLogSPT;
    } rt_DiskInfo;


    #define m_cVxDFunctionIdesDInfo 1


    // ---------------------------------------------------


    int ReadDrivePortsInWin9X (void)
    {
    int done = FALSE;

    HANDLE VxDHandle = 0;
    pt_IdeDInfo pOutBufVxD = 0;
    DWORD lpBytesReturned = 0;

    // set the thread priority high so that we get exclusive access to the disk
    BOOL status =
    // SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS);
    // SetPriorityClass (GetCurrentProcess (), HIGH_PRIORITY_CLASS);
    #ifdef PRINTING_TO_CONSOLE_ALLOWED

    if (0 == status)
    // printf ("\nERROR: Could not SetThreadPriority, LastError: %d\n", GetLastError ());
    printf ("\nERROR: Could not SetPriorityClass, LastError: %d\n", GetLastError ());

    #endif

    // 1. Make an output buffer for the VxD
    rt_IdeDInfo info;
    pOutBufVxD = &info;

    // *****************
    // KLUDGE WARNING!!!
    // HAVE to zero out the buffer space for the IDE information!
    // If this is NOT done then garbage could be in the memory
    // locations indicating if a disk exists or not.
    ZeroMemory (&info, sizeof(info));

    // 1. Try to load the VxD
    // must use the short file name path to open a VXD file
    //char StartupDirectory [2048];
    //char shortFileNamePath [2048];
    //char *p = NULL;
    //char vxd [2048];
    // get the directory that the exe was started from
    //GetModuleFileName (hInst, (LPSTR) StartupDirectory, sizeof (StartupDirectory));
    // cut the exe name from string
    //p = &(StartupDirectory [strlen (StartupDirectory) - 1]);
    //while (p >= StartupDirectory && *p && '\\' != *p) p--;
    //*p = '\0';
    //GetShortPathName (StartupDirectory, shortFileNamePath, 2048);
    //sprintf (vxd, "\\\\.\\%s\\IDE21201.VXD", shortFileNamePath);
    //VxDHandle = CreateFile (vxd, 0, 0, 0,
    // 0, FILE_FLAG_DELETE_ON_CLOSE, 0);
    VxDHandle = CreateFile ("\\\\.\\IDE21201.VXD", 0, 0, 0,
    0, FILE_FLAG_DELETE_ON_CLOSE, 0);

    if (VxDHandle != INVALID_HANDLE_VALUE)
    {
    // 2. Run VxD function
    DeviceIoControl (VxDHandle, m_cVxDFunctionIdesDInfo,
    0, 0, pOutBufVxD, sizeof(pt_IdeDInfo), &lpBytesReturned, 0);

    // 3. Unload VxD
    CloseHandle (VxDHandle);
    }
    else
    MessageBox (NULL, "ERROR: Could not open IDE21201.VXD file",
    TITLE, MB_ICONSTOP);

    // 4. Translate and store data
    unsigned long int i = 0;
    for (i=0; i<8; i++)
    {
    if((pOutBufVxD->DiskExists[i]) && (pOutBufVxD->IDEExists[i/2]))
    {
    DWORD diskinfo [256];
    for (int j = 0; j < 256; j++)
    diskinfo [j] = pOutBufVxD -> DisksRawInfo [i * 256 + j];

    // process the information for this buffer
    PrintIdeInfo (i, diskinfo);
    done = TRUE;
    }
    }

    // reset the thread priority back to normal
    // SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_NORMAL);
    SetPriorityClass (GetCurrentProcess (), NORMAL_PRIORITY_CLASS);

    return done;
    }


    #define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE


    int ReadIdeDriveAsScsiDriveInNT (void)
    {
    int done = FALSE;
    int controller = 0;

    for (controller = 0; controller < 16; 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;
    }


    char HardDriveSerialNumber [1024];


    void PrintIdeInfo (int drive, DWORD diskdata [256])
    {
    char string1 [1024];
    __int64 sectors = 0;
    __int64 bytes = 0;

    // copy the hard drive serial number to the buffer
    strcpy (string1, ConvertToString (diskdata, 10, 19));
    if (0 == HardDriveSerialNumber [0] &&
    // serial number must be alphanumeric
    // (but there can be leading spaces on IBM drives)
    (isalnum (string1 [0]) &#0124; &#0124; isalnum (string1 [19])))
    strcpy (HardDriveSerialNumber, string1);

    #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));
    printf ("Drive Serial Number_______________: %s\n",
    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");

    // calculate size based on 28 bit or 48 bit addressing
    // 48 bit addressing is reflected by bit 10 of word 83
    if (diskdata [83] & 0x400)
    sectors = diskdata [103] * 65536I64 * 65536I64 * 65536I64 +
    diskdata [102] * 65536I64 * 65536I64 +
    diskdata [101] * 65536I64 +
    diskdata [100];
    else
    sectors = diskdata [61] * 65536 + diskdata [60];
    // there are 512 bytes in a sector
    bytes = sectors * 512;
    printf ("Drive Size________________________: %I64d bytes\n",
    bytes);

    #else // PRINTING_TO_CONSOLE_ALLOWED

    // nothing to do

    #endif // PRINTING_TO_CONSOLE_ALLOWED

    }


    char *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 getHardDriveComputerID ()
    {
    int done = FALSE;
    // char string [1024];
    __int64 id = 0;
    OSVERSIONINFO version;

    strcpy (HardDriveSerialNumber, "");

    memset (&version, 0, sizeof (version));
    version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    GetVersionEx (&version);
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
    // this works under WinNT4 or Win2K if you have admin rights
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
    printf ("\nTrying to read the drive IDs using physical access\n");
    #endif
    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
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
    printf ("\nTrying to read the drive IDs using the SCSI back door\n");
    #endif
    // if ( ! done)
    done = ReadIdeDriveAsScsiDriveInNT ();
    }
    else
    {
    // this works under Win9X and calls a VXD
    int attempt = 0;

    // try this up to 10 times to get a hard drive serial number
    for (attempt = 0;
    attempt < 10 && ! done && 0 == HardDriveSerialNumber [0];
    attempt++)
    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;
    }
    }
    }

    #ifdef PRINTING_TO_CONSOLE_ALLOWED

    printf ("\nComputer ID_______________________: %I64d\n", id);

    #endif

    return (long) id;
    }


    int main (int argc, char * argv [])
    {
    long id = getHardDriveComputerID ();

    return 0;
    }



    ------------------

  • #2
    hmm... why not use standard windows API's to get harddisk serials and more?

    Check these:

    GetDiskFreeSpace()
    GetVolumeInformation()

    Cheers

    ------------------
    Balt
    bi at inside dot net
    "It's not the end, not even the beginning of the end, but, it might be the end of the beginning!"

    Comment


    • #3
      Originally posted by Balthasar Indermuehle:
      hmm... why not use standard windows API's to get harddisk serials and more?

      Check these:

      GetDiskFreeSpace()
      GetVolumeInformation()

      Cheers


      Those APIs will give you the VOLUMR serial not the physical HD serail, Model and Manufacturer.

      Thank you,

      Pedro



      ------------------

      Comment


      • #4
        Conversions only work if you post the original code using Code Tags

        MCM


        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Sorry here is the code in code tag.

          Code:
          //  diskid32.cpp
          
          //  for displaying the details of hard drives in 
          
          //  06/11/2000  Lynn McGuire  written with many contributions from others,
          //                            IDE drives only under Windows NT/2K and 9X,
          //                            maybe SCSI drives later
          
          
          #define PRINTING_TO_CONSOLE_ALLOWED
          
          
          #include <stdlib.h>
          #include <stdio.h>
          #include <string.h>
          #include <windows.h>
          
          #define  TITLE   "DiskId32"
          
          
             //  Required to ensure correct PhysicalDrive IOCTL structure setup
          #pragma pack(1)
          
          
             //  Max number of drives assuming primary/secondary, master/slave topology
          #define  MAX_IDE_DRIVES  4
          #define  IDENTIFY_BUFFER_SIZE  512
          
          
             //  IOCTL commands
          #define  DFP_GET_VERSION          0x00074080
          #define  DFP_SEND_DRIVE_COMMAND   0x0007c084
          #define  DFP_RECEIVE_DRIVE_DATA   0x0007c088
          
          #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
          
             //  GETVERSIONOUTPARAMS contains the data returned from the 
             //  Get Driver Version function.
          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;
          
          
             //  Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS 
          #define  CAP_IDE_ID_FUNCTION             1  // ATA ID command supported
          #define  CAP_IDE_ATAPI_ID                2  // ATAPI ID command supported
          #define  CAP_IDE_EXECUTE_SMART_FUNCTION  4  // SMART commannds supported
          
          
             //  IDE registers
          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;
          
          
             //  SENDCMDINPARAMS contains the input parameters for the 
             //  Send Command to Drive function.
          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;
          
          
             //  Valid values for the bCommandReg member of IDEREGS.
          #define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
          #define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
          
          
             // Status returned from driver
          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;
          
          
             // Structure returned by PhysicalDrive IOCTL for several commands
          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;
          
          
             // The following struct defines the interesting part of the IDENTIFY
             // buffer:
          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 _SRB_IO_CONTROL
          {
             ULONG HeaderLength;
             UCHAR Signature[8];
             ULONG Timeout;
             ULONG ControlCode;
             ULONG ReturnCode;
             ULONG Length;
          } SRB_IO_CONTROL, *PSRB_IO_CONTROL;
          
          
             // Define global buffers.
          BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
          
          
          char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex);
          void PrintIdeInfo (int drive, DWORD diskdata [256]);
          BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,
                           PDWORD);
          
          
          int ReadPhysicalDriveInNT (void)
          {
             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++)
                            diskdata [ijk] = pIdSector [ijk];
          
                         PrintIdeInfo (drive, diskdata);
          
                         done = TRUE;
                      }
          	    }
          
                   CloseHandle (hPhysicalDriveIOCTL);
                }
             }
          
             return done;
          }
          
          
             // DoIDENTIFY
             // FUNCTION: Send an IDENTIFY command to the drive
             // bDriveNum = 0-3
             // bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
          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) );
          }
          
          
          //  ---------------------------------------------------
          
             // (* Output Bbuffer for the VxD (rt_IdeDinfo record) *)
          typedef struct _rt_IdeDInfo_
          {
              BYTE IDEExists[4];
              BYTE DiskExists[8];
              WORD DisksRawInfo[8*256];
          } rt_IdeDInfo, *pt_IdeDInfo;
          
          
             // (* IdeDinfo "data fields" *)
          typedef struct _rt_DiskInfo_
          {
             BOOL DiskExists;
             BOOL ATAdevice;
             BOOL RemovableDevice;
             WORD TotLogCyl;
             WORD TotLogHeads;
             WORD TotLogSPT;
             char SerialNumber[20];
             char FirmwareRevision[8];
             char ModelNumber[40];
             WORD CurLogCyl;
             WORD CurLogHeads;
             WORD CurLogSPT;
          } rt_DiskInfo;
          
          
          #define  m_cVxDFunctionIdesDInfo  1
          
          
          //  ---------------------------------------------------
          
          
          int ReadDrivePortsInWin9X (void)
          {
          	int done = FALSE;
          
             HANDLE VxDHandle = 0;
             pt_IdeDInfo pOutBufVxD = 0;
             DWORD lpBytesReturned = 0;
          
          		//  set the thread priority high so that we get exclusive access to the disk
             BOOL status =
          		// SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
          		SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS);
          		// SetPriorityClass (GetCurrentProcess (), HIGH_PRIORITY_CLASS);
          #ifdef PRINTING_TO_CONSOLE_ALLOWED
          
             if (0 == status) 
          	   // printf ("\nERROR: Could not SetThreadPriority, LastError: %d\n", GetLastError ());
          	   printf ("\nERROR: Could not SetPriorityClass, LastError: %d\n", GetLastError ());
          
          #endif
          
                // 1. Make an output buffer for the VxD
             rt_IdeDInfo info;
             pOutBufVxD = &info;
          
                // *****************
                // KLUDGE WARNING!!!
                // HAVE to zero out the buffer space for the IDE information!
                // If this is NOT done then garbage could be in the memory
                // locations indicating if a disk exists or not.
             ZeroMemory (&info, sizeof(info));
          
                // 1. Try to load the VxD
                 //  must use the short file name path to open a VXD file
             //char StartupDirectory [2048];
             //char shortFileNamePath [2048];
             //char *p = NULL;
             //char vxd [2048];
                //  get the directory that the exe was started from
             //GetModuleFileName (hInst, (LPSTR) StartupDirectory, sizeof (StartupDirectory));
                //  cut the exe name from string
             //p = &(StartupDirectory [strlen (StartupDirectory) - 1]);
             //while (p >= StartupDirectory && *p && '\\' != *p) p--;
             //*p = '\0';   
             //GetShortPathName (StartupDirectory, shortFileNamePath, 2048);
             //sprintf (vxd, "\\\\.\\%s\\IDE21201.VXD", shortFileNamePath);
             //VxDHandle = CreateFile (vxd, 0, 0, 0,
             //               0, FILE_FLAG_DELETE_ON_CLOSE, 0);   
             VxDHandle = CreateFile ("\\\\.\\IDE21201.VXD", 0, 0, 0,
          							0, FILE_FLAG_DELETE_ON_CLOSE, 0);
          
             if (VxDHandle != INVALID_HANDLE_VALUE)
             {
                   // 2. Run VxD function
                DeviceIoControl (VxDHandle, m_cVxDFunctionIdesDInfo,
          					0, 0, pOutBufVxD, sizeof(pt_IdeDInfo), &lpBytesReturned, 0);
          
                   // 3. Unload VxD
                CloseHandle (VxDHandle);
             }
             else
          		MessageBox (NULL, "ERROR: Could not open IDE21201.VXD file", 
          					TITLE, MB_ICONSTOP);
          
                // 4. Translate and store data
             unsigned long int i = 0;
             for (i=0; i<8; i++)
             {
                if((pOutBufVxD->DiskExists[i]) && (pOutBufVxD->IDEExists[i/2]))
                {
          			DWORD diskinfo [256];
          			for (int j = 0; j < 256; j++) 
          				diskinfo [j] = pOutBufVxD -> DisksRawInfo [i * 256 + j];
          
                      // process the information for this buffer
          		   PrintIdeInfo (i, diskinfo);
          			done = TRUE;
                }
             }
          
          		//  reset the thread priority back to normal
             // SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_NORMAL);
             SetPriorityClass (GetCurrentProcess (), NORMAL_PRIORITY_CLASS);
          
             return done;
          }
          
          
          #define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
          
          
          int ReadIdeDriveAsScsiDriveInNT (void)
          {
             int done = FALSE;
             int controller = 0;
          
             for (controller = 0; controller < 16; 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;
          }
          
          
          char HardDriveSerialNumber [1024];
          
          
          void PrintIdeInfo (int drive, DWORD diskdata [256])
          {
             char string1 [1024];
             __int64 sectors = 0;
             __int64 bytes = 0;
          
                //  copy the hard drive serial number to the buffer
             strcpy (string1, ConvertToString (diskdata, 10, 19));
             if (0 == HardDriveSerialNumber [0] &&
                      //  serial number must be alphanumeric
                      //  (but there can be leading spaces on IBM drives)
                 (isalnum (string1 [0]) &#0124; &#0124; isalnum (string1 [19])))
                strcpy (HardDriveSerialNumber, string1);
          
          #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));
             printf ("Drive Serial Number_______________: %s\n",
                     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");
                     
          		//  calculate size based on 28 bit or 48 bit addressing
          		//  48 bit addressing is reflected by bit 10 of word 83
          	if (diskdata [83] & 0x400) 
          		sectors = diskdata [103] * 65536I64 * 65536I64 * 65536I64 + 
          					diskdata [102] * 65536I64 * 65536I64 + 
          					diskdata [101] * 65536I64 + 
          					diskdata [100];
          	else
          		sectors = diskdata [61] * 65536 + diskdata [60];
          		//  there are 512 bytes in a sector
          	bytes = sectors * 512;
          	printf ("Drive Size________________________: %I64d bytes\n",
          			bytes);
          
          #else   //  PRINTING_TO_CONSOLE_ALLOWED
          
             //  nothing to do
          
          #endif  // PRINTING_TO_CONSOLE_ALLOWED
          
          }
          
          
          char *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 getHardDriveComputerID ()
          {
             int done = FALSE;
             // char string [1024];
             __int64 id = 0;
          	OSVERSIONINFO version;
          
             strcpy (HardDriveSerialNumber, "");
          
          	memset (&version, 0, sizeof (version));
          	version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
          	GetVersionEx (&version);
          	if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
          	{
          		  //  this works under WinNT4 or Win2K if you have admin rights
          #ifdef PRINTING_TO_CONSOLE_ALLOWED
          		printf ("\nTrying to read the drive IDs using physical access\n");
          #endif
          		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
          #ifdef PRINTING_TO_CONSOLE_ALLOWED
          		printf ("\nTrying to read the drive IDs using the SCSI back door\n");
          #endif
          		// if ( ! done) 
          			done = ReadIdeDriveAsScsiDriveInNT ();
          	}
          	else
              {
                   //  this works under Win9X and calls a VXD
                int attempt = 0;
          
                   //  try this up to 10 times to get a hard drive serial number
                for (attempt = 0;
                     attempt < 10 && ! done && 0 == HardDriveSerialNumber [0];
                     attempt++)
                   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;
                   }                            
                }
             }
          
          #ifdef PRINTING_TO_CONSOLE_ALLOWED
          
             printf ("\nComputer ID_______________________: %I64d\n", id);
          
          #endif
          
             return (long) id;
          }
          
          
          int main (int argc, char * argv [])
          {
             long id = getHardDriveComputerID ();
          
             return 0;
          }


          ------------------

          Comment


          • #6
            It's just straightforward C code. Pretty easy to convert but takes time, and time = money. So I can't help with this one, sorry

            ------------------
            Kev Peel
            KGP Software
            http://www.kgpsoftware.com
            kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

            Comment


            • #7
              Code:
              switch (*p) 
                {            case '0': id += 0; break;
                             case '1': id += 1; break;
                             case '2': id += 2; break; 
                             case '3': id += 3; break;
                             .....
                             case 'z': id += 35; break;
              The author must have quoted this job per line of source code.

              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                I know this is an old, but could not find the answer here and
                had to convert some VB code, so here it is and hope it helps
                someone else.

                Code:
                'this is a hacked version of some VB code I found.
                'it works on XP to get the REAL drive serial number and model
                'but as for the other information, I will leave that up to you
                
                
                #COMPILE EXE
                #DIM ALL
                #INCLUDE "win32api.inc"
                
                %GENERIC_READ = &H80000000
                %GENERIC_WRITE = &H40000000
                %FILE_SHARE_READ = &H1
                %FILE_SHARE_WRITE = &H2
                %OPEN_EXISTING = 3
                %CREATE_NEW = 1
                %VER_PLATFORM_WIN32_NT = 2
                %IDENTIFY_BUFFER_SIZE = 512
                %OUTPUT_DATA_SIZE = %IDENTIFY_BUFFER_SIZE + 16
                
                TYPE GETVERSIONOUTPARAMS
                    bVersion       AS BYTE 'Binary driver version.
                    bRevision      AS BYTE 'Binary driver revision
                    bReserved      AS BYTE 'Not used
                    bIDEDeviceMap  AS BYTE 'Bit map of IDE devices
                    fCapabilities  AS LONG 'Bit mask of driver capabilities
                    dwReserved(3)  AS LONG 'For future use
                END TYPE
                
                TYPE IDEREGS
                    bFeaturesReg     AS BYTE 'Used for specifying SMART "commands"
                    bSectorCountReg  AS BYTE 'IDE sector count register
                    bSectorNumberReg AS BYTE 'IDE sector number register
                    bCylLowReg       AS BYTE 'IDE low order cylinder value
                    bCylHighReg      AS BYTE 'IDE high order cylinder value
                    bDriveHeadReg    AS BYTE 'IDE drive/head register
                    bCommandReg      AS BYTE 'Actual IDE command
                    bReserved        AS BYTE 'reserved for future use - must be zero
                END TYPE
                
                TYPE SENDCMDINPARAMS
                    cBufferSize     AS LONG     'Buffer size in bytes
                    irDriveRegs     AS IDEREGS  'Structure with drive register values.
                    bDriveNumber    AS BYTE     'Physical drive number to send command to (0,1,2,3).
                    bReserved(2)    AS BYTE     'Bytes reserved
                    dwReserved(3)   AS LONG     'DWORDS reserved
                    bBuffer(0)      AS BYTE      'Input buffer.
                END TYPE
                
                'Valid values for the bCommandReg member of IDEREGS.
                %IDE_ID_FUNCTION = &HEC            'Returns ID sector for ATA.
                %IDE_EXECUTE_SMART_FUNCTION = &HB0 'Performs SMART cmd.
                                                                'Requires valid bFeaturesReg,
                                                                'bCylLowReg, and bCylHighReg
                
                'Cylinder register values required when issuing SMART command
                %SMART_CYL_LOW = &H4F
                %SMART_CYL_HI = &HC2
                
                'Status returned from driver
                TYPE DRIVERSTATUS
                    bDriverError  AS BYTE          'Error code from driver, or 0 if no error
                    bIDEStatus    AS BYTE          'Contents of IDE Error register
                                                   'Only valid when bDriverError is SMART_IDE_ERROR
                    bReserved(1)  AS BYTE
                    dwReserved(1) AS LONG
                END TYPE
                
                TYPE IDSECTOR
                    wGenConfig                 AS INTEGER
                    wNumCyls                   AS INTEGER
                    wReserved                  AS INTEGER
                    wNumHeads                  AS INTEGER
                    wBytesPerTrack             AS INTEGER
                    wBytesPerSector            AS INTEGER
                    wSectorsPerTrack           AS INTEGER
                    wVendorUnique(2)           AS INTEGER
                    sSerialNumber(19)          AS BYTE
                    wBufferType                AS INTEGER
                    wBufferSize                AS INTEGER
                    wECCSize                   AS INTEGER
                    sFirmwareRev(7)            AS BYTE
                    sModelNumber(39)           AS BYTE
                    wMoreVendorUnique          AS INTEGER
                    wDoubleWordIO              AS INTEGER
                    wCapabilities              AS INTEGER
                    wReserved1                 AS INTEGER
                    wPIOTiming                 AS INTEGER
                    wDMATiming                 AS INTEGER
                    wBS                        AS INTEGER
                    wNumCurrentCyls            AS INTEGER
                    wNumCurrentHeads           AS INTEGER
                    wNumCurrentSectorsPerTrack AS INTEGER
                    ulCurrentSectorCapacity    AS LONG
                    wMultSectorStuff           AS INTEGER
                    ulTotalAddressableSectors  AS LONG
                    wSingleWordDMA             AS INTEGER
                    wMultiWordDMA              AS INTEGER
                    bReserved(127)             AS BYTE
                END TYPE
                
                'Structure returned by SMART IOCTL commands
                TYPE SENDCMDOUTPARAMS
                    cBufferSize   AS LONG         'Size of Buffer in bytes
                    DRIVERSTATUS  AS DRIVERSTATUS 'Driver status structure
                    bBuffer(1)    AS BYTE          'Buffer of arbitrary length for data read from drive
                END TYPE
                
                'Vendor specific feature register defines
                'for SMART "sub commands"
                %SMART_ENABLE_SMART_OPERATIONS = &HD8
                
                'Status Flags Values
                'Enum STATUS_FLAGS
                %PRE_FAILURE_WARRANTY = &H1
                %ON_LINE_COLLECTION = &H2
                %PERFORMANCE_ATTRIBUTE = &H4
                %ERROR_RATE_ATTRIBUTE = &H8
                %EVENT_COUNT_ATTRIBUTE = &H10
                %SELF_PRESERVING_ATTRIBUTE = &H20
                'End Enum
                
                'IOCTL commands
                %DFP_GET_VERSION = &H74080
                %DFP_SEND_DRIVE_COMMAND = &H7C084
                %DFP_RECEIVE_DRIVE_DATA = &H7C088
                
                TYPE ATTR_DATA
                    AttrID AS BYTE
                    AttrName(7) AS BYTE ' **** not sure about this size ****
                    AttrValue AS BYTE
                    ThresholdValue AS BYTE
                    WorstValue AS BYTE
                    StatusFlags AS BYTE
                END TYPE
                
                TYPE DRIVE_INFO
                    bDriveType AS BYTE
                    SerialNumber(19) AS BYTE' As String * 20
                    Model(39) AS BYTE ' As String * 40
                    FirmWare(7) AS BYTE ' As String * 8
                    Cilinders AS LONG
                    Heads AS LONG
                    SecPerTrack AS LONG
                    BytesPerSector AS LONG
                    BytesperTrack AS LONG
                    NumAttributes AS BYTE
                    Attributes(1) AS ATTR_DATA
                END TYPE
                
                DECLARE FUNCTION CloseHandle LIB "kernel32" _
                    ALIAS "CloseHandle" _
                  (BYVAL hObject AS LONG) AS LONG
                
                
                DECLARE FUNCTION IdentifyDrive(BYVAL hDrive AS LONG, _
                                               BYVAL IDCmd AS BYTE, _
                                               BYVAL drvNumber AS BYTE, _
                                               ddi AS DRIVE_INFO) AS LONG
                DECLARE FUNCTION IsWinNT4Plus() AS LONG
                DECLARE FUNCTION SmartCheckEnabled(BYVAL hDrive AS LONG, _
                                                   drvNumber AS BYTE) AS LONG
                DECLARE FUNCTION SmartGetVersion(BYVAL hDrive AS LONG) AS LONG
                DECLARE FUNCTION SmartOpen(drvNumber AS BYTE) AS LONG
                DECLARE FUNCTION SwapBytes(b() AS BYTE) AS LONG'Byte()
                DECLARE FUNCTION GetDriveInfo(drvNumber AS BYTE, ddi AS drive_info) AS LONG ' As DRIVE_INFO
                
                
                FUNCTION GetDriveInfo(drvNumber AS BYTE, ddi AS drive_info) AS LONG ' As DRIVE_INFO
                
                    DIM hDrive AS LONG
                    DIM retvl AS LONG
                    DIM retv AS BYTE
                
                    hDrive = SmartOpen(drvNumber)
                    IF hdrive <> %invalid_handle_value THEN
                        retv = SmartGetVersion(hDrive)
                        IF retv = %True THEN
                            ddi.bDriveType = 0
                            ddi.NumAttributes = 0
                            retv = SmartCheckEnabled(hDrive, drvNumber) 'seems to return false must be doing something wrong
                            IF retv = %true THEN
                                retv = IdentifyDrive(hDrive, %IDE_ID_FUNCTION, drvNumber, ddi)
                                IF retv = %True THEN
                                     getdriveinfo = %true
                                END IF   'IdentifyDrive
                            END IF   'SmartCheckEnabled
                        END IF   'SmartGetVersion
                    END IF   'hDrive <> INVALID_HANDLE_VALUE
                    CloseHandle hDrive
                
                END FUNCTION
                
                FUNCTION IdentifyDrive(BYVAL hDrive AS LONG, _
                                               BYVAL IDCmd AS BYTE, _
                                               BYVAL drvNumber AS BYTE, _
                                               ddi AS DRIVE_INFO) AS LONG
                
                    'Function: Send an IDENTIFY command to the drive
                    'drvNumber = 0-3
                    'IDCmd = IDE_ID_FUNCTION or IDE_ATAPI_ID
                    DIM SCIP AS SENDCMDINPARAMS
                    DIM IDSEC AS IDSECTOR
                    DIM bArrOut(%OUTPUT_DATA_SIZE - 1) AS BYTE
                    DIM cbBytesReturned AS LONG
                    DIM i AS LONG
                    DIM tstr AS STRING
                    DIM bTemp AS BYTE
                    DIM cnt AS LONG
                
                    SCIP.cBufferSize = %IDENTIFY_BUFFER_SIZE
                    SCIP.bDriveNumber = drvNumber
                    SCIP.irDriveRegs.bFeaturesReg = 0
                    SCIP.irDriveRegs.bSectorCountReg = 1
                    SCIP.irDriveRegs.bSectorNumberReg = 1
                    SCIP.irDriveRegs.bCylLowReg = 0
                    SCIP.irDriveRegs.bCylHighReg = 0
                    SCIP.irDriveRegs.bDriveHeadReg = &HA0 'compute the drive number
                    IF NOT IsWinNT4Plus THEN
                        SCIP.irDriveRegs.bDriveHeadReg = SCIP.irDriveRegs.bDriveHeadReg OR ((drvNumber AND 1) * 16)
                    END IF
                    'the command can either be IDE
                    'identify or ATAPI identify.
                    SCIP.irDriveRegs.bCommandReg = IDCmd
                    IF DeviceIoControl(hDrive, _
                                          %DFP_RECEIVE_DRIVE_DATA, _
                                          SCIP, _
                                          SIZEOF(SCIP) - 1, _
                                          bArrOut(0), _
                                          %OUTPUT_DATA_SIZE, _
                                          cbBytesReturned, _
                                          BYVAL 0&) THEN
                        FOR i = 0 TO SIZEOF(idsec)
                            tstr = tstr & CHR$(barrout(i))
                        NEXT i
                
                        'ddi.Model = StrConv(SwapBytes(IDSEC.sModelNumber), vbUnicode)
                        'ddi.SerialNumber = StrConv(SwapBytes(IDSEC.sSerialNumber), vbUnicode)
                        FOR i = 0 TO 20
                            ddi.SerialNumber(i) = ASC(MID$(tstr,i+37,1))
                        NEXT i
                
                        FOR cnt = 0 TO 19 STEP 2
                            bTemp = ddi.serialnumber(cnt)
                            ddi.serialnumber(cnt) = ddi.serialnumber(cnt + 1)
                            ddi.serialnumber(cnt + 1) = bTemp
                        NEXT cnt
                
                
                        FOR i = 0 TO 40
                            ddi.Model(i) = ASC(MID$(tstr,i+71,1))
                        NEXT i
                        FOR cnt = 0 TO 39 STEP 2
                            bTemp = ddi.Model(cnt)
                            ddi.Model(cnt) = ddi.Model(cnt + 1)
                            ddi.Model(cnt + 1) = bTemp
                        NEXT cnt
                        IdentifyDrive = %True
                
                    END IF
                
                END FUNCTION
                
                
                FUNCTION IsWinNT4Plus() AS LONG
                
                    'returns True if running Windows NT4 or later
                    DIM osv AS OSVERSIONINFO
                    osv.dwOSVersionInfoSize = SIZEOF(osv)
                    IF GetVersionEx(osv) = 1 THEN
                
                       IsWinNT4Plus = (osv.dwPlatformId = %VER_PLATFORM_WIN32_NT) AND _
                                      (osv.dwMajorVersion >= 4)
                
                    END IF
                
                END FUNCTION
                
                
                FUNCTION SmartCheckEnabled(BYVAL hDrive AS LONG, _
                                                   drvNumber AS BYTE) AS LONG
                
                    'SmartCheckEnabled - Check if SMART enable
                    'FUNCTION: Send a SMART_ENABLE_SMART_OPERATIONS command to the drive
                    'bDriveNum = 0-3
                    DIM SCIP AS SENDCMDINPARAMS
                    DIM SCOP AS SENDCMDOUTPARAMS
                    DIM cbBytesReturned AS LONG
                    DIM retv AS LONG
                
                    SCIP.cBufferSize = 0
                    SCIP.irDriveRegs.bFeaturesReg = %SMART_ENABLE_SMART_OPERATIONS
                    SCIP.irDriveRegs.bSectorCountReg = 1
                    SCIP.irDriveRegs.bSectorNumberReg = 1
                    SCIP.irDriveRegs.bCylLowReg = %SMART_CYL_LOW
                    SCIP.irDriveRegs.bCylHighReg = %SMART_CYL_HI
                    SCIP.irDriveRegs.bDriveHeadReg = &HA0
                    IF NOT IsWinNT4Plus THEN
                        SCIP.irDriveRegs.bDriveHeadReg = SCIP.irDriveRegs.bDriveHeadReg OR ((drvNumber AND 1) * 16)
                    END IF
                    SCIP.irDriveRegs.bCommandReg = %IDE_EXECUTE_SMART_FUNCTION
                    SCIP.bDriveNumber = drvNumber
                '    msgbox str$(sizeof(scip))
                '    msgbox str$(len(scip))
                    retv = DeviceIoControl(hDrive, _
                                                          %DFP_SEND_DRIVE_COMMAND, _
                                                          SCIP, _
                                                          SIZEOF(SCIP) - 1, _
                                                          SCOP, _
                                                          SIZEOF(SCOP) - 1, _
                                                          cbBytesReturned, _
                                                          BYVAL 0&)
                    smartcheckenabled = retv
                END FUNCTION
                
                
                FUNCTION SmartGetVersion(BYVAL hDrive AS LONG) AS LONG 'Boolean
                
                    DIM cbBytesReturned AS LONG
                    DIM GVOP AS GETVERSIONOUTPARAMS
                
                    SmartGetVersion = DeviceIoControl(hDrive, _
                                                         %DFP_GET_VERSION, _
                                                         BYVAL 0&, 0, _
                                                         GVOP, _
                                                         SIZEOF(GVOP), _
                                                         cbBytesReturned, _
                                                         BYVAL 0&)
                
                END FUNCTION
                
                
                FUNCTION SmartOpen(drvNumber AS BYTE) AS LONG
                
                    'Open SMART to allow DeviceIoControl
                    'communications and return SMART handle
                
                    IF IsWinNT4Plus() THEN
                        SmartOpen = CreateFile("\\.\PhysicalDrive" & TRIM$(STR$(drvNumber)), _
                                                 %GENERIC_READ OR %GENERIC_WRITE, _
                                                 %FILE_SHARE_READ OR %FILE_SHARE_WRITE, _
                                                 BYVAL 0&, _
                                                 %OPEN_EXISTING, _
                                                 0&, _
                                                 0&)
                
                    ELSE
                        SmartOpen = CreateFile("\\.\SMARTVSD", _
                                                  0&, 0&, _
                                                  BYVAL 0&, _
                                                  %CREATE_NEW, _
                                                  0&, _
                                                  0&)
                    END IF
                
                END FUNCTION
                
                FUNCTION PBMAIN () AS LONG
                
                    DIM ddi AS DRIVE_INFO
                    DIM drvNumber AS BYTE
                    DIM retv AS LONG
                    DIM i AS LONG
                    DIM tstr AS STRING
                
                    FOR drvnumber = 0 TO 7
                        tstr = ""
                        retv = getdriveinfo( drvnumber,ddi)
                        IF retv = 1 THEN '        msgbox str$(retv)
                            FOR i = 0 TO 39
                                tstr = tstr & CHR$(ddi.model(i))
                            NEXT i
                            MSGBOX "Model:" &  TRIM$(tstr)
                            tstr = ""
                            FOR i = 0 TO 19
                                tstr = tstr & CHR$(ddi.SerialNumber(i))
                            NEXT i
                            MSGBOX "Serial No:" &  TRIM$(tstr)
                        END IF
                    NEXT drvnumber
                END FUNCTION
                ------------------
                Frank H. Crowder
                RoxBox, Inc.
                Frank H. Crowder
                RoxBox, Inc.

                Comment


                • #9
                  Originally posted by Frank Crowder:
                  I know this is an old ...
                  Frank, this is a good code!

                  I made a few modifications to the PBMAIN function - I hope you like

                  Code:
                  FUNCTION PBMAIN () AS LONG
                  
                      DIM ddi AS DRIVE_INFO
                      DIM drvNumber AS BYTE
                      DIM retv AS LONG
                      DIM i AS LONG
                      DIM tstr AS STRING
                      LOCAL Text AS STRING
                      
                      FOR drvnumber = 0 TO 7
                          tstr = ""
                          retv = getdriveinfo( drvnumber,ddi)
                          IF retv = 1 THEN '        msgbox str$(retv)
                              FOR i = 0 TO 39
                                  tstr = tstr & CHR$(ddi.model(i))
                              NEXT i
                              Text = Text & _
                                      "Phisical Drive" & STR$(drvnumber) & " - " & _
                                      "Usually " & CHOOSE$(drvnumber+1,"C","D","E","F","G","H","I","J") & $CRLF
                              Text = Text & "Model: " & TRIM$(tstr) & $CRLF
                              tstr = ""
                              FOR i = 0 TO 19
                                  tstr = tstr & CHR$(ddi.SerialNumber(i))
                              NEXT i
                              Text = Text & "Serial No: " & TRIM$(tstr) & $CRLF & $CRLF
                          END IF
                      NEXT drvnumber
                  
                      MSGBOX Text
                      
                  END FUNCTION
                  ------------------
                  Arthur Gomide
                  Como diria nosso profeta da bola, Dadá Maravilha: "Para toda Problemática existe uma Solucionática!"

                  [This message has been edited by Arthur Gomide (edited December 19, 2006).]
                  "The trouble with quotes on the Internet is that you can never know if they are genuine." - Abraham Lincoln.

                  Comment


                  • #10
                    I use this routine in PB DOS, and it function good.
                    Can you transform it in PB WIN?



                    Code:
                     $COMPILE EXE
                    
                     GOSUB SERIAL
                     ? "Serial Number: ";DiskID.SerialNr
                     ? "File System  : ";DiskID.FileSystem
                     K$=INPUT$(1)
                     
                     END
                    
                    SERIAL:
                          TYPE Bufstruc
                             Drive 	      AS STRING*1
                             SerialNr     AS STRING*9
                             FileSystem AS STRING*8
                          END TYPE
                          
                          DIM DiskID AS SHARED Bufstruc
                          
                          DiskInfo "C:"
                    
                    RETURN
                    
                    SUB DiskInfo (BYVAL drive$)
                       DIM Drivename AS STRING * 4
                       DIM Filesysname AS STRING * 8
                       DIM rax  AS WORD
                       DIM rbx  AS WORD
                       DIM rcx  AS WORD
                       DIM rdx  AS WORD
                       DIM seg1 AS WORD
                       DIM off1 AS WORD
                       DIM seg2 AS WORD
                       DIM off2 AS WORD
                    
                       Drive$   =UCASE$(LEFT$(drive$,1))
                       Drivename=LEFT$(drive$,1) +":\"+CHR$(0)
                       DiskID.SerialNr=""
                    
                       seg1=VARSEG(drivename)
                       off1=VARPTR(drivename)
                       seg2=VARSEG(filesysname)
                       off2=VARPTR(filesysname)
                    
                    	! MOV AX,&H71A0
                    	! MOV DS,seg1
                    	! MOV DX,off1
                    	! MOV ES,seg2
                    	! MOV DI,off2
                    	! MOV CX,&HFF
                    	! INT &H21
                    	! MOV RAX,AX
                    	! MOV RBX,BX
                    
                       ' Obtain Serial
                    
                       Driv%=ASC(LEFT$(drive$,1))-64
                       DIM buffr2 AS STRING*25
                       REG 1, &H6900
                       REG 2, driv%            ' 0= Current Drive
                       REG 8, VARSEG(buffr2)
                       REG 4, VARPTR(buffr2)
                       CALL INTERRUPT &H21
                    
                       IF (REG(0) AND 1)=0 THEN
                    	   DiskID.SerialNr="0000-0000"
                    	   ser1$=HEX$(CVI(MID$(buffr2,5,2)))
                    	   MID$(DiskID.SerialNr,5-LEN(ser1$))=ser1$
                    	   ser1$=HEX$(CVI(MID$(buffr2,3,2)))
                    	   MID$(DiskID.SerialNr,10-LEN(ser1$))=ser1$
                    	   IF LEFT$(MID$(buffr2,18,8),2)<>"CD" THEN 
                    	      DiskID.FileSystem=RTRIM$(MID$(buffr2,18,8))
                    	   END IF
                       END IF
                    END SUB
                    Last edited by Giuseppe Belziti; 10 May 2008, 01:28 PM.
                    mailto:[email protected]
                    From Italy.

                    Comment


                    • #11
                      Hi Giuseppe,

                      "interupt 21" won't do under modern Windows

                      Api approach by Peter Lameijn...

                      http://www.powerbasic.com/support/pb...ad.php?t=23071

                      Comment

                      Working...
                      X