精华内容
下载资源
问答
  • 获取硬盘序列号 CPU MAC win7 可用

    热门讨论 2014-11-13 11:20:02
    来自国外牛人的代码,兼容win7 。可获取硬盘序列号,CPU,Mac 地址,等信息。
  • // diskid32.cpp // for displaying the details of hard drives in a command window // 06/11/00 Lynn McGuire written with many contributions from others, // IDE drives only
    
    //  diskid32.cpp
    
    
    //  for displaying the details of hard drives in a command window
    
    
    //  06/11/00  Lynn McGuire  written with many contributions from others,
    //                            IDE drives only under Windows NT/2K and 9X,
    //                            maybe SCSI drives later
    //  11/20/03  Lynn McGuire  added ReadPhysicalDriveInNTWithZeroRights
    //  10/26/05  Lynn McGuire  fix the flipAndCodeBytes function
    //  01/22/08  Lynn McGuire  incorporate changes from Gonzalo Diethelm,
    //                             remove media serial number code since does 
    //                             not work on USB hard drives or thumb drives
    //  01/29/08  Lynn McGuire  add ReadPhysicalDriveInNTUsingSmart
    //  10/01/13  Lynn Mcguire  fixed reference of buffer address per Torsten Eschner email
    
    
    #define PRINTING_TO_CONSOLE_ALLOWED
    
    #pragma warning(disable: 4121)
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <string.h>
    #include <windows.h>
    #include <winioctl.h>
    
    
    //  special include from the MS DDK
    //#include "c:\win2kddk\inc\ddk\ntddk.h"
    //#include "c:\win2kddk\inc\ntddstor.h"
    
    
    #define  TITLE   "DiskId32"
    
    
    char HardDriveSerialNumber[1024];
    char HardDriveModelNumber[1024];
    int PRINT_DEBUG = false;
    
    
    static void dump_buffer(const char* title,
        const unsigned char* buffer,
        int len);
    
    
    void WriteConstantString(char *entry, char *string)
    {
    }
    
    
    
    //  Required to ensure correct PhysicalDrive IOCTL structure setup
    #pragma pack(1)
    
    
    #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
    
    #define SMART_GET_VERSION               CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
    #define SMART_SEND_DRIVE_COMMAND        CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    #define SMART_RCV_DRIVE_DATA            CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    
    
    // Define global buffers.
    BYTE IdOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
    //  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;
    
    char *ConvertToString(DWORD diskdata[256],
        int firstIndex,
        int lastIndex,
        char* buf);
    void PrintIdeInfo(int drive, DWORD diskdata[256]);
    BOOL DoIDENTIFY(HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,
        PDWORD);
    
    
    //  Max number of drives assuming primary/secondary, master/slave topology
    #define  MAX_IDE_DRIVES  16
    #define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
    #define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
    
    int ReadPhysicalDriveInNTWithAdminRights(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_s(driveName, "\\\\.\\PhysicalDrive%d", drive);
    
            //  Windows NT, Windows 2000, must have admin rights
            hPhysicalDriveIOCTL = CreateFileA(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)
            {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                if (PRINT_DEBUG)
                    printf("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR"
                    "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n",
                    __LINE__, driveName);
    #endif
            }
            else
            {
                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))
                {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    if (PRINT_DEBUG)
                    {
                        DWORD err = GetLastError();
                        printf("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR"
                            "\nDeviceIoControl(%d, DFP_GET_VERSION) returned 0, error is %d\n",
                            __LINE__, (int)hPhysicalDriveIOCTL, (int)err);
                    }
    #endif
                }
    
                // If there is a IDE device at number "i" issue commands
                // to the device
                if (VersionParams.bIDEDeviceMap <= 0)
                {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    if (PRINT_DEBUG)
                        printf("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR"
                        "\nNo device found at position %d (%d)\n",
                        __LINE__, (int)drive, (int)VersionParams.bIDEDeviceMap);
    #endif
                }
                else
                {
                    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;
    }
    
    
    
    //
    // IDENTIFY data (from ATAPI driver source)
    //
    
    #pragma pack(1)
    
    typedef struct _IDENTIFY_DATA {
        USHORT GeneralConfiguration;            // 00 00
        USHORT NumberOfCylinders;               // 02  1
        USHORT Reserved1;                       // 04  2
        USHORT NumberOfHeads;                   // 06  3
        USHORT UnformattedBytesPerTrack;        // 08  4
        USHORT UnformattedBytesPerSector;       // 0A  5
        USHORT SectorsPerTrack;                 // 0C  6
        USHORT VendorUnique1[3];                // 0E  7-9
        USHORT SerialNumber[10];                // 14  10-19
        USHORT BufferType;                      // 28  20
        USHORT BufferSectorSize;                // 2A  21
        USHORT NumberOfEccBytes;                // 2C  22
        USHORT FirmwareRevision[4];             // 2E  23-26
        USHORT ModelNumber[20];                 // 36  27-46
        UCHAR  MaximumBlockTransfer;            // 5E  47
        UCHAR  VendorUnique2;                   // 5F
        USHORT DoubleWordIo;                    // 60  48
        USHORT Capabilities;                    // 62  49
        USHORT Reserved2;                       // 64  50
        UCHAR  VendorUnique3;                   // 66  51
        UCHAR  PioCycleTimingMode;              // 67
        UCHAR  VendorUnique4;                   // 68  52
        UCHAR  DmaCycleTimingMode;              // 69
        USHORT TranslationFieldsValid : 1;        // 6A  53
        USHORT Reserved3 : 15;
        USHORT NumberOfCurrentCylinders;        // 6C  54
        USHORT NumberOfCurrentHeads;            // 6E  55
        USHORT CurrentSectorsPerTrack;          // 70  56
        ULONG  CurrentSectorCapacity;           // 72  57-58
        USHORT CurrentMultiSectorSetting;       //     59
        ULONG  UserAddressableSectors;          //     60-61
        USHORT SingleWordDMASupport : 8;        //     62
        USHORT SingleWordDMAActive : 8;
        USHORT MultiWordDMASupport : 8;         //     63
        USHORT MultiWordDMAActive : 8;
        USHORT AdvancedPIOModes : 8;            //     64
        USHORT Reserved4 : 8;
        USHORT MinimumMWXferCycleTime;          //     65
        USHORT RecommendedMWXferCycleTime;      //     66
        USHORT MinimumPIOCycleTime;             //     67
        USHORT MinimumPIOCycleTimeIORDY;        //     68
        USHORT Reserved5[2];                    //     69-70
        USHORT ReleaseTimeOverlapped;           //     71
        USHORT ReleaseTimeServiceCommand;       //     72
        USHORT MajorRevision;                   //     73
        USHORT MinorRevision;                   //     74
        USHORT Reserved6[50];                   //     75-126
        USHORT SpecialFunctionsEnabled;         //     127
        USHORT Reserved7[128];                  //     128-255
    } IDENTIFY_DATA, *PIDENTIFY_DATA;
    
    #pragma pack()
    
    
    
    int ReadPhysicalDriveInNTUsingSmart(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_s(driveName, "\\\\.\\PhysicalDrive%d", drive);
    
            //  Windows NT, Windows 2000, Windows Server 2003, Vista
            hPhysicalDriveIOCTL = CreateFileA(driveName,
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_DELETE | 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)
            {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                if (PRINT_DEBUG)
                    printf("\n%d ReadPhysicalDriveInNTUsingSmart ERROR"
                    "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n"
                    "Error Code %d\n",
                    __LINE__, driveName, GetLastError());
    #endif
            }
            else
            {
                GETVERSIONINPARAMS GetVersionParams;
                DWORD cbBytesReturned = 0;
    
                // Get the version, etc of PhysicalDrive IOCTL
                memset((void*)& GetVersionParams, 0, sizeof(GetVersionParams));
    
                if (!DeviceIoControl(hPhysicalDriveIOCTL, SMART_GET_VERSION,
                    NULL,
                    0,
                    &GetVersionParams, sizeof(GETVERSIONINPARAMS),
                    &cbBytesReturned, NULL))
                {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    if (PRINT_DEBUG)
                    {
                        DWORD err = GetLastError();
                        printf("\n%d ReadPhysicalDriveInNTUsingSmart ERROR"
                            "\nDeviceIoControl(%d, SMART_GET_VERSION) returned 0, error is %d\n",
                            __LINE__, (int)hPhysicalDriveIOCTL, (int)err);
                    }
    #endif
                }
                else
                {
                    // Print the SMART version
                    // PrintVersion (& GetVersionParams);
                    // Allocate the command buffer
                    ULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;
                    PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS)malloc(CommandSize);
                    // Retrieve the IDENTIFY data
                    // Prepare the command
    #define ID_CMD          0xEC            // Returns ID sector for ATA
                    Command->irDriveRegs.bCommandReg = ID_CMD;
                    DWORD BytesReturned = 0;
                    if (!DeviceIoControl(hPhysicalDriveIOCTL,
                        SMART_RCV_DRIVE_DATA, Command, sizeof(SENDCMDINPARAMS),
                        Command, CommandSize,
                        &BytesReturned, NULL))
                    {
                        // Print the error
                        //PrintError ("SMART_RCV_DRIVE_DATA IOCTL", GetLastError());
                    }
                    else
                    {
                        // Print the IDENTIFY data
                        DWORD diskdata[256];
                        USHORT *pIdSector = (USHORT *)
                            (PIDENTIFY_DATA)((PSENDCMDOUTPARAMS)Command)->bBuffer;
    
                        for (int ijk = 0; ijk < 256; ijk++)
                            diskdata[ijk] = pIdSector[ijk];
    
                        PrintIdeInfo(drive, diskdata);
                        done = TRUE;
                    }
                    // Done
                    CloseHandle(hPhysicalDriveIOCTL);
                    free(Command);
                }
            }
        }
    
        return done;
    }
    
    
    
    //  Required to ensure correct PhysicalDrive IOCTL structure setup
    #pragma pack(4)
    
    
    //
    // IOCTL_STORAGE_QUERY_PROPERTY
    //
    // Input Buffer:
    //      a STORAGE_PROPERTY_QUERY structure which describes what type of query
    //      is being done, what property is being queried for, and any additional
    //      parameters which a particular property query requires.
    //
    //  Output Buffer:
    //      Contains a buffer to place the results of the query into.  Since all
    //      property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER,
    //      the IOCTL can be called once with a small buffer then again using
    //      a buffer as large as the header reports is necessary.
    //
    
    
    //
    // Types of queries
    //
    
    
    #define IOCTL_STORAGE_QUERY_PROPERTY   CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
    
    
    //
    // Device property descriptor - this is really just a rehash of the inquiry
    // data retrieved from a scsi device
    //
    // This may only be retrieved from a target device.  Sending this to the bus
    // will result in an error
    //
    
    #pragma pack(4)
    
    //  function to decode the serial numbers of IDE hard drives
    //  using the IOCTL_STORAGE_QUERY_PROPERTY command 
    char * flipAndCodeBytes(const char * str,
        int pos,
        int flip,
        char * buf)
    {
        int i;
        int j = 0;
        int k = 0;
    
        buf[0] = '\0';
        if (pos <= 0)
            return buf;
    
        if (!j)
        {
            char p = 0;
    
            // First try to gather all characters representing hex digits only.
            j = 1;
            k = 0;
            buf[k] = 0;
            for (i = pos; j && str[i] != '\0'; ++i)
            {
                char c = tolower(str[i]);
    
                if (isspace(c))
                    c = '0';
    
                ++p;
                buf[k] <<= 4;
    
                if (c >= '0' && c <= '9')
                    buf[k] |= (unsigned char)(c - '0');
                else if (c >= 'a' && c <= 'f')
                    buf[k] |= (unsigned char)(c - 'a' + 10);
                else
                {
                    j = 0;
                    break;
                }
    
                if (p == 2)
                {
                    if (buf[k] != '\0' && !isprint(buf[k]))
                    {
                        j = 0;
                        break;
                    }
                    ++k;
                    p = 0;
                    buf[k] = 0;
                }
    
            }
        }
    
        if (!j)
        {
            // There are non-digit characters, gather them as is.
            j = 1;
            k = 0;
            for (i = pos; j && str[i] != '\0'; ++i)
            {
                char c = str[i];
    
                if (!isprint(c))
                {
                    j = 0;
                    break;
                }
    
                buf[k++] = c;
            }
        }
    
        if (!j)
        {
            // The characters are not there or are not printable.
            k = 0;
        }
    
        buf[k] = '\0';
    
        if (flip)
            // Flip adjacent characters
            for (j = 0; j < k; j += 2)
            {
                char t = buf[j];
                buf[j] = buf[j + 1];
                buf[j + 1] = t;
            }
    
        // Trim any beginning and end space
        i = j = -1;
        for (k = 0; buf[k] != '\0'; ++k)
        {
            if (!isspace(buf[k]))
            {
                if (i < 0)
                    i = k;
                j = k;
            }
        }
    
        if ((i >= 0) && (j >= 0))
        {
            for (k = i; (k <= j) && (buf[k] != '\0'); ++k)
                buf[k - i] = buf[k];
            buf[k - i] = '\0';
        }
    
        return buf;
    }
    
    
    
    #define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)
    
    
    
    int ReadPhysicalDriveInNTWithZeroRights(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_s(driveName, "\\\\.\\PhysicalDrive%d", drive);
    
            //  Windows NT, Windows 2000, Windows XP - admin rights not required
            hPhysicalDriveIOCTL = CreateFileA(driveName, 0,
                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                OPEN_EXISTING, 0, NULL);
            if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
            {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                if (PRINT_DEBUG)
                    printf("\n%d ReadPhysicalDriveInNTWithZeroRights ERROR"
                    "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n",
                    __LINE__, driveName);
    #endif
            }
            else
            {
                STORAGE_PROPERTY_QUERY query;
                DWORD cbBytesReturned = 0;
                char local_buffer[10000];
    
                memset((void *)& query, 0, sizeof(query));
                query.PropertyId = StorageDeviceProperty;
                query.QueryType = PropertyStandardQuery;
    
                memset(local_buffer, 0, sizeof(local_buffer));
    
                if (DeviceIoControl(hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
                    &query,
                    sizeof(query),
                    &local_buffer[0],
                    sizeof(local_buffer),
                    &cbBytesReturned, NULL))
                {
                    STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *)& local_buffer;
                    char serialNumber[1000];
                    char modelNumber[1000];
                    char vendorId[1000];
                    char productRevision[1000];
    
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    if (PRINT_DEBUG)
                    {
                        printf("\n%d STORAGE_DEVICE_DESCRIPTOR contents for drive %d\n"
                            "                Version: %ld\n"
                            "                   Size: %ld\n"
                            "             DeviceType: %02x\n"
                            "     DeviceTypeModifier: %02x\n"
                            "         RemovableMedia: %d\n"
                            "        CommandQueueing: %d\n"
                            "         VendorIdOffset: %4ld (0x%02lx)\n"
                            "        ProductIdOffset: %4ld (0x%02lx)\n"
                            "  ProductRevisionOffset: %4ld (0x%02lx)\n"
                            "     SerialNumberOffset: %4ld (0x%02lx)\n"
                            "                BusType: %d\n"
                            "    RawPropertiesLength: %ld\n",
                            __LINE__, drive,
                            (unsigned long)descrip->Version,
                            (unsigned long)descrip->Size,
                            (int)descrip->DeviceType,
                            (int)descrip->DeviceTypeModifier,
                            (int)descrip->RemovableMedia,
                            (int)descrip->CommandQueueing,
                            (unsigned long)descrip->VendorIdOffset,
                            (unsigned long)descrip->VendorIdOffset,
                            (unsigned long)descrip->ProductIdOffset,
                            (unsigned long)descrip->ProductIdOffset,
                            (unsigned long)descrip->ProductRevisionOffset,
                            (unsigned long)descrip->ProductRevisionOffset,
                            (unsigned long)descrip->SerialNumberOffset,
                            (unsigned long)descrip->SerialNumberOffset,
                            (int)descrip->BusType,
                            (unsigned long)descrip->RawPropertiesLength);
    
                        dump_buffer("Contents of RawDeviceProperties",
                            (unsigned char*)descrip->RawDeviceProperties,
                            descrip->RawPropertiesLength);
    
                        dump_buffer("Contents of first 256 bytes in buffer",
                            (unsigned char*)local_buffer, 256);
                    }
    #endif
                    flipAndCodeBytes(local_buffer,
                        descrip->VendorIdOffset,
                        0, vendorId);
                    flipAndCodeBytes(local_buffer,
                        descrip->ProductIdOffset,
                        0, modelNumber);
                    flipAndCodeBytes(local_buffer,
                        descrip->ProductRevisionOffset,
                        0, productRevision);
                    flipAndCodeBytes(local_buffer,
                        descrip->SerialNumberOffset,
                        1, serialNumber);
    
                    if (0 == HardDriveSerialNumber[0] &&
                        //  serial number must be alphanumeric
                        //  (but there can be leading spaces on IBM drives)
                        (isalnum(serialNumber[0]) || isalnum(serialNumber[19])))
                    {
                        strcpy_s(HardDriveSerialNumber, serialNumber);
                        strcpy_s(HardDriveModelNumber, modelNumber);
                        done = TRUE;
                    }
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    printf("\n**** STORAGE_DEVICE_DESCRIPTOR for drive %d ****\n"
                        "Vendor Id = [%s]\n"
                        "Product Id = [%s]\n"
                        "Product Revision = [%s]\n"
                        "Serial Number = [%s]\n",
                        drive,
                        vendorId,
                        modelNumber,
                        productRevision,
                        serialNumber);
    #endif
                    // Get the disk drive geometry.
                    memset(local_buffer, 0, sizeof(local_buffer));
                    if (!DeviceIoControl(hPhysicalDriveIOCTL,
                        IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                        NULL,
                        0,
                        &local_buffer[0],
                        sizeof(local_buffer),
                        &cbBytesReturned,
                        NULL))
                    {
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                        if (PRINT_DEBUG)
                            printf("\n%d ReadPhysicalDriveInNTWithZeroRights ERROR"
                            "|nDeviceIoControl(%s, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) returned 0",
                            driveName);
    #endif
                    }
                    else
                    {
                        DISK_GEOMETRY_EX * geom = (DISK_GEOMETRY_EX *)& local_buffer[0];
                        int fixed = (geom->Geometry.MediaType == FixedMedia);
                        __int64 size = geom->DiskSize.QuadPart;
    
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                        printf("\n**** DISK_GEOMETRY_EX for drive %d ****\n"
                            "Disk is%s fixed\n"
                            "DiskSize = %I64d\n",
                            drive,
                            fixed ? "" : " NOT",
                            size);
    #endif
                    }
                }
                else
                {
                    DWORD err = GetLastError();
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
                    printf("\nDeviceIOControl IOCTL_STORAGE_QUERY_PROPERTY error = %d\n", err);
    #endif
                }
    
                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;
        unsigned long int i = 0;
    
        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 = CreateFileA (vxd, 0, 0, 0,
        //               0, FILE_FLAG_DELETE_ON_CLOSE, 0);   
        VxDHandle = CreateFileA("\\\\.\\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
            MessageBoxA(NULL, "ERROR: Could not open IDE21201.VXD file",
            TITLE, MB_ICONSTOP);
    
        // 4. Translate and store data
        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
    
    
    typedef struct _SRB_IO_CONTROL
    {
        ULONG HeaderLength;
        UCHAR Signature[8];
        ULONG Timeout;
        ULONG ControlCode;
        ULONG ReturnCode;
        ULONG Length;
    } SRB_IO_CONTROL, *PSRB_IO_CONTROL;
    
    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;
    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_s(driveName, "\\\\.\\Scsi%d:", controller);
    
            //  Windows NT, Windows 2000, any rights should do
            hScsiDriveIOCTL = CreateFileA(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_s((char *)p->Signature, 8, "SCSIDISK", 8);
    
                    pin->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
                    pin->bDriveNumber = drive;
    
                    if (DeviceIoControl(hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
                        buffer,
                        sizeof(SRB_IO_CONTROL) +
                        sizeof(SENDCMDINPARAMS) - 1,
                        buffer,
                        sizeof(SRB_IO_CONTROL) + SENDIDLENGTH,
                        &dummy, NULL))
                    {
                        SENDCMDOUTPARAMS *pOut =
                            (SENDCMDOUTPARAMS *)(buffer + sizeof(SRB_IO_CONTROL));
                        IDSECTOR *pId = (IDSECTOR *)(pOut->bBuffer);
                        if (pId->sModelNumber[0])
                        {
                            DWORD diskdata[256];
                            int ijk = 0;
                            USHORT *pIdSector = (USHORT *)pId;
    
                            for (ijk = 0; ijk < 256; ijk++)
                                diskdata[ijk] = pIdSector[ijk];
    
                            PrintIdeInfo(controller * 2 + drive, diskdata);
    
                            done = TRUE;
                        }
                    }
                }
                CloseHandle(hScsiDriveIOCTL);
            }
        }
    
        return done;
    }
    
    
    void PrintIdeInfo(int drive, DWORD diskdata[256])
    {
        char serialNumber[1024];
        char modelNumber[1024];
        char revisionNumber[1024];
        char bufferSize[32];
    
        __int64 sectors = 0;
        __int64 bytes = 0;
    
        //  copy the hard drive serial number to the buffer
        ConvertToString(diskdata, 10, 19, serialNumber);
        ConvertToString(diskdata, 27, 46, modelNumber);
        ConvertToString(diskdata, 23, 26, revisionNumber);
        sprintf_s(bufferSize, "%u", diskdata[21] * 512);
    
        if (0 == HardDriveSerialNumber[0] &&
            //  serial number must be alphanumeric
            //  (but there can be leading spaces on IBM drives)
            (isalnum(serialNumber[0]) || isalnum(serialNumber[19])))
        {
            strcpy_s(HardDriveSerialNumber, serialNumber);
            strcpy_s(HardDriveModelNumber, modelNumber);
        }
    
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
    
        printf("\nDrive %d - ", drive);
    
        switch (drive / 2)
        {
        case 0: printf("Primary Controller - ");
            break;
        case 1: printf("Secondary Controller - ");
            break;
        case 2: printf("Tertiary Controller - ");
            break;
        case 3: printf("Quaternary 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",
            modelNumber);
        printf("Drive Serial Number_______________: [%s]\n",
            serialNumber);
        printf("Drive Controller Revision Number__: [%s]\n",
            revisionNumber);
    
        printf("Controller Buffer Size on Drive___: %s bytes\n",
            bufferSize);
    
        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);
    
    #endif  // PRINTING_TO_CONSOLE_ALLOWED
    
        char string1[1000];
        sprintf_s(string1, "Drive%dModelNumber", drive);
        WriteConstantString(string1, modelNumber);
    
        sprintf_s(string1, "Drive%dSerialNumber", drive);
        WriteConstantString(string1, serialNumber);
    
        sprintf_s(string1, "Drive%dControllerRevisionNumber", drive);
        WriteConstantString(string1, revisionNumber);
    
        sprintf_s(string1, "Drive%dControllerBufferSize", drive);
        WriteConstantString(string1, bufferSize);
    
        sprintf_s(string1, "Drive%dType", drive);
        if (diskdata[0] & 0x0080)
            WriteConstantString(string1, "Removable");
        else if (diskdata[0] & 0x0040)
            WriteConstantString(string1, "Fixed");
        else
            WriteConstantString(string1, "Unknown");
    }
    
    
    
    char *ConvertToString(DWORD diskdata[256],
        int firstIndex,
        int lastIndex,
        char* buf)
    {
        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
            buf[position++] = (char)(diskdata[index] / 256);
    
            //  get low byte for 2nd character
            buf[position++] = (char)(diskdata[index] % 256);
        }
    
        //  end the string 
        buf[position] = '\0';
    
        //  cut off the trailing blanks
        for (index = position - 1; index > 0 && isspace(buf[index]); index--)
            buf[index] = '\0';
    
        return buf;
    }
    
    
    
    long getHardDriveComputerID()
    {
        int done = FALSE;
        // char string [1024];
        __int64 id = 0;
        OSVERSIONINFO version;
    
        strcpy_s(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 with admin rights\n");
    #endif
            done = ReadPhysicalDriveInNTWithAdminRights();
    
            //  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();
    
            //  this works under WinNT4 or Win2K or WinXP if you have any rights
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
            printf("\nTrying to read the drive IDs using physical access with zero rights\n");
    #endif
            //if ( ! done)
            done = ReadPhysicalDriveInNTWithZeroRights();
    
            //  this works under WinNT4 or Win2K or WinXP or Windows Server 2003 or Vista if you have any rights
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
            printf("\nTrying to read the drive IDs using Smart\n");
    #endif
            //if ( ! done)
            done = ReadPhysicalDriveInNTUsingSmart();
        }
        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 (HardDriveSerialNumber[0] > 0)
        {
            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;
                }
            }
        }
    
        id %= 100000000;
        if (strstr(HardDriveModelNumber, "IBM-"))
            id += 300000000;
        else if (strstr(HardDriveModelNumber, "MAXTOR") ||
            strstr(HardDriveModelNumber, "Maxtor"))
            id += 400000000;
        else if (strstr(HardDriveModelNumber, "WDC "))
            id += 500000000;
        else
            id += 600000000;
    
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
    
        printf("\nHard Drive Serial Number__________: %s\n",
            HardDriveSerialNumber);
        printf("\nHard Drive Model Number___________: %s\n",
            HardDriveModelNumber);
        printf("\nComputer ID_______________________: %I64d\n", id);
    
    #endif
    
        return (long)id;
    }
    
    
    
    // GetMACAdapters.cpp : Defines the entry point for the console application.
    //
    // Author:  Khalid Shaikh [Shake@ShakeNet.com]
    // Date:    April 5th, 2002
    //
    // This program fetches the MAC address of the localhost by fetching the 
    // information through GetAdapatersInfo.  It does not rely on the NETBIOS
    // protocol and the ethernet adapter need not be connect to a network.
    //
    // Supported in Windows NT/2000/XP
    // Supported in Windows 95/98/Me
    //
    // Supports multiple NIC cards on a PC.
    
    #include <Iphlpapi.h>
    #include <Assert.h>
    #pragma comment(lib, "iphlpapi.lib")
    
    
    
    // Prints the MAC address stored in a 6 byte array to stdout
    static void PrintMACaddress(unsigned char MACData[])
    {
    
    #ifdef PRINTING_TO_CONSOLE_ALLOWED
    
        printf("\nMAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
            MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
    
    #endif
    
        char string[256];
        sprintf_s(string, "%02X-%02X-%02X-%02X-%02X-%02X", MACData[0], MACData[1],
            MACData[2], MACData[3], MACData[4], MACData[5]);
        WriteConstantString("MACaddress", string);
    }
    
    
    
    // Fetches the MAC address and prints it
    DWORD GetMACaddress(void)
    {
        DWORD MACaddress = 0;
        IP_ADAPTER_INFO AdapterInfo[16];       // Allocate information
        // for up to 16 NICs
        DWORD dwBufLen = sizeof(AdapterInfo);  // Save memory size of buffer
    
        DWORD dwStatus = GetAdaptersInfo(      // Call GetAdapterInfo
            AdapterInfo,                 // [out] buffer to receive data
            &dwBufLen);                  // [in] size of receive data buffer
        assert(dwStatus == ERROR_SUCCESS);  // Verify return value is
        // valid, no buffer overflow
    
        PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo; // Contains pointer to
        // current adapter info
        do {
            if (MACaddress == 0)
                MACaddress = pAdapterInfo->Address[5] + pAdapterInfo->Address[4] * 256 +
                pAdapterInfo->Address[3] * 256 * 256 +
                pAdapterInfo->Address[2] * 256 * 256 * 256;
            PrintMACaddress(pAdapterInfo->Address); // Print MAC address
            pAdapterInfo = pAdapterInfo->Next;    // Progress through linked list
        } while (pAdapterInfo);                    // Terminate if last adapter
    
        return MACaddress;
    }
    
    
    
    static void dump_buffer(const char* title,
        const unsigned char* buffer,
        int len)
    {
        int i = 0;
        int j;
    
        printf("\n-- %s --\n", title);
        if (len > 0)
        {
            printf("%8.8s ", " ");
            for (j = 0; j < 16; ++j)
            {
                printf(" %2X", j);
            }
            printf("  ");
            for (j = 0; j < 16; ++j)
            {
                printf("%1X", j);
            }
            printf("\n");
        }
        while (i < len)
        {
            printf("%08x ", i);
            for (j = 0; j < 16; ++j)
            {
                if ((i + j) < len)
                    printf(" %02x", (int)buffer[i + j]);
                else
                    printf("   ");
            }
            printf("  ");
            for (j = 0; j < 16; ++j)
            {
                if ((i + j) < len)
                    printf("%c", isprint(buffer[i + j]) ? buffer[i + j] : '.');
                else
                    printf(" ");
            }
            printf("\n");
            i += 16;
        }
        printf("-- DONE --\n");
    }
    
    
    
    int main(int argc, char * argv[])
    {
        printf("To get all details use \"diskid32 /d\"\n");
    
        if (argc > 1 && strstr(argv[1], "/d"))
            PRINT_DEBUG = true;
        else
            PRINT_DEBUG = false;
    
        long id = getHardDriveComputerID();
        id = id;
        GetMACaddress();
    
        return 0;
    }
    

    https://www.winsim.com/diskid32/diskid32.cpp

    展开全文
  • 获取mac地址,硬盘序列号,经过64位win7,32位win7测试。在虚拟机下可以正常运行,返回默认值,不会崩溃
  • 随着固态硬盘成本的降低,用固态移动硬盘的人越来越多。固态移动硬盘的重量轻巧,抗摔防震,而且传输速度比机械式移动硬盘快出很多。刚子最近收到了当贝优选发来的迅龙固态硬盘(H100-128GB)+2.5英寸硬盘盒(2179U3),...

    随着固态硬盘成本的降低,用固态移动硬盘的人越来越多。固态移动硬盘的重量轻巧,抗摔防震,而且传输速度比机械式移动硬盘快出很多。刚子最近收到了当贝优选发来的迅龙固态硬盘(H100-128GB)+2.5英寸硬盘盒(2179U3),正好用它来组装一个固态移动硬盘,让我们一起来看看性能如何吧!

    包装:

    352acdeac5011654034f290fbdabb322.png

    迅龙固态硬盘(H100-128GB)+2.5英寸硬盘盒(2179U3)均采用奥睿科常用的白蓝搭配的包装风格,左上角是品牌名称、产品名称及型号,中间印有产品渲染图,右下角是产品的规格。

    895064bb1f9b7ebf12bb101266f60cf6.png

    包装盒的顶部有挂孔,方便实体店挂在货架上。包装背面印有产品的规格参数,从这里我们可以很方面的掌握两个产品的性能参数。2.5英寸硬盘盒(2179U3)支持SATA3.0协议的硬盘,通过USB3.0 Micro-B转USB A 线连接电脑后,可实现最大5Gbps的传输速率。

    c322528486067060d4af4e4603deaf3a.png

    抽出两个产品的封套,我们可以看到硬盘和硬盘盒都牢固的固定在塑料托盘支架中,起到防震抗摔的作用。迅龙固态硬盘(H100)是一款2.5英寸固态硬盘,它采用64层 3D NAND 闪存,支持SATA3.0协议,可以用在笔记本电脑和台式机中,当然也可以搭配移动硬盘盒组装成为固态移动硬盘。

    feab505c63ce1c223b735729ca6074fa.png

    迅龙固态硬盘(H100)包装盒内除了硬盘之外,还有四颗安装螺钉、一个十字螺丝批,还有说明书等文档。硬盘外壳正面中心处印有奥睿科的图文LOGO,铝合金外壳经过阳极氧化处理后又喷涂了灰色磨砂涂层,看上去非常有质感。外壳边缘利用CNC切割倒角,平整光滑,灰色的壳体加上银白色的边缘,让整个产品的品质感提升很多。

    4f6227f378d5d6341ecef54d268fd74f.png

    在硬盘的底部我们可以看到硬盘的接口以及一些重要参数。硬盘背面贴有产品信息标签,上面详细的标注了产品型号、系列、功耗、容量、防伪二维码和产品序列号等内容。ORICO迅龙系列采用荣慧SM2259XT主控,具有LDPC智能纠错机制,优化TRIM指令,NQC智能队列管理等功能,随机读取能力大大提升;64层3D NAND 闪存TLC 颗粒,无论是容量密度还是寿命、耐久度都大大提高了。

    b0ddfc52e6e9b31085047c4871fcea95.png

    2.5英寸硬盘盒(2179U3)采用透明塑料外壳,我们可以很清楚的看到内部的电路板。除了硬盘盒外,包装内还有USB3.0 Micro-B转USB A 数据线、说明书等文档。

    cebf72560f86cba030cdbb4a4b2b8b23.png

    令人意外的是这款硬盘盒背部设计了大面积的铝合金散热片,奥睿科的透明硬盘盒刚子用过好几款了,不过像2179U3这样自带散热片的SATA硬盘盒还是首次看到。

    f47b086876bab2b10f16d7c3904634d8.png

    我们现来单独测试一下硬盘的性能,将硬盘装入台式电脑中,开机第一次连接电脑时硬盘需要进行初始化,也就是在磁盘管理器中选择一些硬盘分区形式。MBR格式适用于WIN7以前的系统,WIN10一般都用GPT了,所以在这里我们选择GPT格式。之后创建分区,先选择NTFS格式。

    73c55bf7c97c933a77386e68aac7434e.png

    创建完成后使用硬盘测试软件CrystalDiskMark进行速度测试,直装SATA口测的连续读取速度为487MB/S,持续写入速度为454MB/S,远远超过了机械硬盘100MB/s的读写速度。

    8b5e6afcc4527ec3949ed643dc8b6b74.png

    苹果的macOS也是常用的电脑系统,它和Windows有所区别,我们在Win10中格式化为NTFS格式的硬盘Mac上可以读取却不能写入。这是因为两个操作系统对于硬盘格式的要求不同,macOS需要安装收费插件后才能正常读写NTFS,所以需要将移动硬盘格式化为两个系统通用的格式才行。

    a1f2b73ed29a29e0e3cf0bb9f47b954d.png

    ExFAT格式是专门为移动硬盘创造的格式,它解决了FAT32不能存4G以上大文件的问题,也解决了NTFS格式下固态硬盘寿命的问题。更重要是,在WIN7以上系统和Mac系统中都能完美兼容,所以将硬盘格式化为exFAT格式最为方便。

    1c485abebb633e73363561489138ddcc.png

    直插SATA模式下,在黑苹果系统中使用DiskSpeed Test来测试读写速度,测试结果为连续读写速度:455MB/s,写入速度420MB/s,比Win模式下速度略降,考虑是黑苹果系统性能可能有所影响,所以这个速度也可以接受了。

    3845e12ae1baea77c26af2a36b38e607.png

    硬盘盒的硬盘仓部分采用全透明设计,舱盖采用卡扣连接,无工具拆装设计,安装拆卸都很方便。组装过程非常简单,掀开硬盘盒透明上盖,将固态硬盘对准接口插入硬盘盒,扣上上盖即可。整个安装过程用不了半分钟。安装完成后发现硬盘硬盘壳体和散热片并没有接触,这意味着我们需要自己加上一层导热硅胶垫才能发挥最大的散热效果。

    f7337f7dc3feadd45aa22c59d1cc2e89.png

    通过自带的USB3.0线缆,将组装好的固态移动硬盘插到电脑的USB3.0口进行测试,依旧上使用CrystalDiskMark,移动硬盘模式下测的的连续读取速度为460MB/S,持续写入速度为404MB/S,比直插SATA口性能差了一些,但是已经接近5Gbps的理论速度,比起普通的机械移动硬盘的几十兆秒的读写速度更是快了近十倍。

    8f34a92fe352f443b201dcc1a5406098.png

    移动硬盘模式下,使用黑苹果系统进行读写速度测试,最终结果连续读写速度为426MB/s,连续写入速度为374MB/s,比起WIN模式下也是有些降低,但是比机械式的移动硬盘要好处数十倍。

    好了,这样就完成了迅龙固态硬盘(H100-128GB)+2.5英寸硬盘盒(2179U3)的组装测试过程,看到这里,大家是不是有想组装一套自己的固态硬动硬盘呢?快来试试吧, 一分钟就能完成组装,将来还能方便拆卸更换更大容量的硬盘,千万不要忘记选格式哦!

    展开全文
  • 其实NVMe接口的固态硬盘目前来说性价比是最高的,但是很多老笔记本不支持这个接口。就像刚子的这款笔记本电脑,它本身预留了SSD位置,但是只能使用M.2 NGFF 固态,这种固态比较小众,性价比不高,因此只能暂时...

    16年的时候淘汰了用了8年的老笔记本,入手了一款游戏本-华硕飞行堡垒FX-PRO,越来越感觉这款老本的性能有点跟不上了, 正赶上去年开始SSD全线降价,于是准备给它加装一个SSD。

    ff5652540cf107a06558ac0378485ad7.png

    其实NVMe接口的固态硬盘目前来说性价比是最高的,但是很多老笔记本不支持这个接口。就像刚子的这款笔记本电脑,它本身预留了SSD位置,但是只能使用M.2 NGFF 固态,这种固态比较小众,性价比不高,因此只能暂时加了一个240G NGFF 固态用来装系统,再加上自带的一块1T机械硬盘继续使用。

    开箱和外观:

    d977d7fe9a03d7acea0236d1fbfc7250.png

    加装NGFF固态后,开机速度和软件启动速度都有了很大的提升,但是由于容量限制,大容量的游戏还是需要放在机械硬盘里,每次启动游戏都需要漫长的等待过程。年前固态硬盘又降价了,所以一咬牙准备将原来的机械硬盘换掉。由于机械硬盘接口为SATA,所以选购固态也要这种协议的,选来选去,找到了这款性价比比较高的雷克沙 NS100 1T SSD。

    44ee59521b9ae87213ec11fb62785525.png

    雷克沙NS100采用标准的2.5英寸硬盘壳体,厚度仅为7mm,可以适应大多数笔记本电脑的安装空间。盘体外壳采用磨砂质感的塑料材质构成,正面印有Lexar 英文LOGO。

    ac4a3f9e57a2af4ab07c6fd83db29c96.png

    雷克沙NS100采用了SATA 3.0接口,理论接口速度为6Gb/s,有128G、256G、512G、1TB四种容量可选,刚子入手的是1TB版本,根据包装上注明的速度来看,这款固态的传输速度在520MB/s以上,如果能够达到这个速度,和之前速度仅为110M/s的机械硬盘相比,将会有非常大的性能提升。

    ea1598d9424b0f44fea67454946b2c58.png

    笔记本追求的就是轻盈便携,每部分的重量减轻对整机的便携性都会有提升。雷克沙NS100实测重量仅为32g,是传统2.5英寸机械硬盘的三分之一左右,更换后对笔记本减重很有帮助。

    安装:

    1c882716cc37f2bcf9283515cb47c988.png

    更换笔记本硬盘时,建议先去搜索一下自己电脑机型对应的拆解教程,对内部结构了解后再拆,这样既能防止出错,又能节省更换安装的时间。记住SATA接口的方向,然后取下原来的机械硬盘,将雷克沙NS100放入硬盘支架上固定好。

    39b361bdddd7a568457900c86ad47cf0.png

    将装好的雷克沙NS100的硬盘支架一起放入硬盘仓中,将固定螺丝装好,然后将笔记本的后盖装好,这样就完成了安装过程。

    功能测试:

    cc7491667a0e3b490f9d65de0ac1b6b4.png

    安装好雷克沙NS100固态硬盘后,初次使用时需要进行硬盘初始化,由于当前运行的系统是win10所以选择GPT分区模式,后面要安装的Mac系统也是需要这种硬盘模式。

    03ade969fb72826f72419b39eaab0a1d.png

    选择好硬盘模式,就要进行分区和格式化了。我们主要想用这块硬盘来存储游戏和一些临时文件,所以直接做成一个分区即可。使用机械硬盘时,我们经常选择NTFS格式,在win10中使用很完美,但是在Mac系统中需要安装插件才能读写,读写性能也很差。所以文件系统这里建议选择 exFAT格式,这是一个专为U盘和固态硬盘设计的文件格式,在win10和Mac系统中都能实现完美兼容。初始化完成后,我们可以看到雷克沙NS100的可用空间为953GB,根据硬盘容量计算方法我们可以看出这款硬盘的空间是足够的。

    win10系统下测速:

    fd72d7424f9c2364b08bb3619e00f132.png

    首先使用CrystalDiskMark这个常用的硬盘测速软件,来测试雷克沙NS100的性能。从测试结果来看,雷克沙NS100 固态硬盘的顺序读取速度为545MB/s左右,写入在500MB/s左右,和官方标注的大于520MB/s基本一致,远远大于普通机械硬盘的读取150MB/s,写入110MB/s的速度,4K随机方面也是远远超过机械硬盘的性能。

    94ec877d066bb3ff7c74e07483a778b0.png

    为了避免单一软件测试造成误差,我们又采用TxBENCH来进行了速度测试,从测试结果来看,这款软件测试的顺序读取速度为544MB/s左右,写入在507MB/s左右,和CrystalDiskMark测试结果一致,能够达到官方的速度标称值。

    游戏文件复制测试:

    afda26cfbcf764b8405a3b779e6a95e0.png

    《Gears.5》的游戏安装资源约为65GB,我们将它复制到雷克沙NS100里面,从测速曲线来看,向雷克沙NS100里写入文件的速度基本稳定在370MB/s左右,65GB的大文件只用了三分钟左右就完成了复制。之后我们又复制了《GTA5》的游戏资源,测试的速度和上面的速度基本一致。

    6c2bea2bea120b212247aa8ef4a8bed3.png

    我们测试的这几个游戏基本都占用几十个G的存储空间,启动游戏时需要从硬盘中加载资源数据,使用机械硬盘时,每次都需要漫长的加载才能使用。在更换雷克沙NS100之后,加载速度有了非常明显的提升。以《GTA5》故事模式为例,机械硬盘下加载游戏资源需要80多秒,使用雷克沙NS100后直接降到20秒左右,提升了游戏体验。

    Mac安装:

    bb5aba8ac5548f5d6de384bb82894eb5.png

    Mac是苹果电脑专用的系统,很多程序员和设计师喜欢使用这种系统做开发,但是苹果的电脑价格实在昂贵,所以就有了黑苹果一说。普通电脑安装黑苹果非常的麻烦,对于普通用户来说,有两条捷径:一个是花钱找人装,另一种就是在网上找大神们分享的EFI文件包,选择和自己电脑配置一致的拿来用就行了。找一个16G以上的U盘,从网上下载Mac OS镜像、TransMac(刻录工具)、DiskGenius(分区工具)、EasyUEFI(引导工区)、EFI驱动文件,然后按照教程一步步操作即可。

    9e1975be851426e1e3555c1a8c833b33.png

    Mac系统安装完成后,再将EFI文件替换相应分区中的文件,实现win10+Mac双系统的Clover引导,最终实现双系统的完美结合。

    5be3cae380eed77e9d561f346ebad86e.png

    在Mac系统中,雷克沙NS100也能正确识别,使用 Disk Speed Test 进行测速,最终得到的结果为:读取速度503MB/s,写入速度为482MB/s,比win10系统中略低。这样我们就完成了双系统共享雷克沙NS100存储空间的全过程。

    5244bb3f6af005eeb64947203e6550c2.png

    我们还可以将雷克沙NS100放入移动硬盘盒中,将它变为一个不怕摔的超轻便携移动硬盘。

    f1adf12822f9266bddd402c403a744ae.png

    在移动硬盘模式下,在win10系统中使用测速软件进行测试,得到的测试结果为 读取速度 453MB/s,写入速度为 422MB/s。

    d87594c2fa4816eb64bcb1fbd1adcd5b.png

    在移动硬盘模式下,在Mac系统中使用测速软件进行测试,得到的测试结果为读取速度 419MB/s,写入速度为 423MB/s。由于受到硬盘盒USB3.0接口速度的限制,移动硬盘模式的雷克沙NS100读写速度相比之前使用的机械式移动硬盘速度快了四倍,使用体验提升也很明显。

    总结:

    总的来说,雷克沙NS100作为一款SATA3.0 接口的固态硬盘,适合用来改造升级老款不带NVMe接口的笔记本电脑,替换掉速度慢的机械硬盘,作为游戏仓库或者下载盘使用。官方提供3年质保,可以放心尽情用。

    展开全文
  • 删除休眠文件对硬盘吃紧的同学很有帮助,我的MAC才128装win10分一半才60G,装系统发现就用了20G多。 发现这个办法获取了3G多的可用硬盘
  • ExFAT格式硬盘Mac上和win上未能识别

    千次阅读 2020-04-17 13:01:30
    如果你有Mac系统下,那么有个问题是逃不过去的,怎么让自己的硬盘win下和mac下都能读取。 我们先来看下各种磁盘格式在mac下的支持情况: Fat32:Win读写,Mac OS X读写,4G单文件限制 NTFS:Win读写,Mac OS X...

    如果你有Mac系统下,那么有个问题是逃不过去的,怎么让自己的硬盘在win下和mac下都能读取。

    我们先来看下各种磁盘格式在mac下的支持情况:
    Fat32:Win读写,Mac OS X读写,4G单文件限制
    NTFS:Win读写,Mac OS X只读,无4G单文件限制
    Exfat:Win读写,Mac OS X读写,无4G单文件限制
    HFS+:Win不认,Mac OS X读写,无4G单文件限制

    随着现在文件越来越大,所以最佳选择即把移动硬盘格式化为Exfat。可是也有很多小伙伴发现,格式化了Exfat格式之后,硬盘在mac下经常读不出来。

    解决硬盘在Mac下的读取:

    1. 在磁盘工具中,选择硬盘名称,选择装载
    2. 退出硬盘的时候,选择右键退出,非正常拔出会致使下次打开要全盘扫描。如果硬盘很大很很久。。。

    解决硬盘在win下的读取问题:

    1. 用CMD打开命令提示符
    2. 输入:chkdsk空格H:空格/f

    上面的H就是你损坏的硬盘符,等待它扫描完成,把错误的标识符都替换掉,硬盘就能正常读取了

     

     



     

    展开全文
  • mac读取pc硬盘Windows can’t normally read Mac-formatted drives, and will offer to erase them instead. But third-party tools fill the gap and provide access to drives formatted with Apple’s HFS+ file ...
  • WIN/MAC使用exFat格式共用移动硬盘

    万次阅读 2016-11-18 23:59:29
    最近呢,因为需要windows、mac都可以读写这个移动硬盘,方便使用。 由于两个系统不同父,也不同母,所以共用需求不是说要就行的(当然,笔者不考虑fat格式哟) 所幸,这事也不是不可能实现的,还是有方法
  • C++获取计算机的CPU序列号,硬盘序列号(无需管理权限),网卡MAC地址,在vs2005环境下编译通过,已在win10,win7系统测试通过。
  • win 7下获取硬盘序列号,CPU,MAC地址等信息  下载地址 http://download.csdn.net/detail/iloveyouleehuijie/8152611 这篇是我引用 http://aigudao.net/?post=107 的。比较高兴,win32控制太程序,创建一...
  • 先上我的格式: FAT32可以同时使用,但是单个文件不能超过4G; 推荐: ExFAT 格式用在Win上;...基于以上需求,我把硬盘分了3个区:Mac(MacOS)、Win(ExFAT)、Time Machine(MacOS 日志式备份专用)
  • vc获取硬盘序列号、网卡MAC

    热门讨论 2012-04-18 19:05:44
    win7 64位下编译通过 获取硬盘序列号,分多种获取方式,本机测试UAC打开时无管理员权限也可获取
  • 其实NVMe接口的固态硬盘目前来说性价比是最高的,但是很多老笔记本不支持这个接口。就像刚子的这款笔记本电脑,它本身预留了SSD位置,但是只能使用M.2 NGFF 固态,这种固态比较小众,性价比不高,因此只能暂时加了一...
  • win/mac辅助接口实现

    2018-02-28 00:21:57
    1.Mac terminal commands[codesign 签名及查看/查看dylib依赖/删除工程某类型...2.mac 辅助接口[打开系统网络设置/获取plist属性值系统挂载数及挂载盘符信息等] 3.mac监听Dock激活程序 4.mac系统读写NTFS格式的移动硬盘
  • 1. private string[] GetMoc()2. {3. string[] str = new string...4. ManagementClass mcCpu = new ManagementClass(win32_Processor);5. ManagementObjectCollection mocCpu = mcCpu.GetInstances();6. foreach(M...
  • 获取MAC地址和硬盘序列号

    千次阅读 2019-03-18 14:44:13
    1.获取MAC地址 from psutil import net_if_addrs for k,v in net_if_addrs().items(): for item in v: address=item[1] if '-' in address and len(address) == 17: print(address) 2...
  • WinMac NTFS exFat等格式 兼容问题

    千次阅读 2018-08-30 21:46:00
    日常有摄影照片整理的需要,目前硬盘使用ntfs格式,mac使用mounty软件进行硬盘挂载进行读写,出现图片无法读取,并且无法读取等文件夹图片被删除问题。 参考: 干货:WinMac中NTFS和exFat格式读写速度对比 ...
  • c#获取MAC地址 硬盘序列号

    千次阅读 2009-03-13 10:53:00
    using System.Management;/// /// 获取MAC地址/// /// public string GetNetCardMacAddress(){ ManagementClass mc; ManagementObjectCollection moc; mc = new ManagementClass("Win32_Netwo
  • windows读取mac格式移动硬盘的方法

    千次阅读 2015-11-04 17:33:00
    家里有一台mac电脑,限于硬盘空间比较小,需要定期备份一些数据。 由于备份数据大小在20G左右,并且并没有压缩为一个压缩文件,有许多小文件和文件夹,不方便采用网络传输 所以采用了移动硬盘拷贝方式。 二、...
  • mac换装ssd,由于ssd容量比原来的硬盘小,所以不能简单备份转移数据,只好重装系统。 先在mac app store里下载10.11,然后把ssd用usb接到mac上,执行安装,安装目的地选择ssd即可。安装完成后关机拔电换硬件,就ok...
  • c#读取mac硬盘

    2009-06-24 10:13:00
     str = mo["MacAddress"].ToString();  }  return str;  }  /**////  /// C盘序列号  ///  /// <returns></returns>  public string GetDiskVolumeSerialNumber()  ...{  ManagementObject disk;...
  • C++获取硬盘序列号和型号 MAC地址,多种环境下测试通过
  • 该类已在win10,win7,xp等Windows环境中测试,均可正常取到硬盘的序列号和MAC地址,使用方便简单。
  • 首先需要添加一个system.management的引用,在添加引用选项卡。 using System.Management;.../// 获取MAC地址 /// </summary> /// <returns></returns> public string GetNetCardMacAddre...
  • WIN7识别苹果硬盘

    2014-04-19 20:54:23
    这是一款可以再WIN7操作系统下读取MAC硬盘的工具,非常好用!
  • 目录1 Win安装1.1 获取安装包1.2 安装步骤1.3 配置环境变量2 Win卸载3 Mac安装3.1 获取安装包3.2 安装步骤3.3 配置环境变量4 Mac卸载5 MySQL8.0数据类型 1 Win安装 1.1 获取安装包 官网下载链接:...
  • using System.Management;.../// 获取MAC地址/// </summary>/// <returns></returns>public string GetNetCardMacAddress(){ ManagementClass mc; ManagementObjectCollection mo...
  • win xp 读写 mac 的时间机器移动硬盘

    千次阅读 2014-03-12 11:32:02
    我的移动硬盘做成了时间机器盘,再接win xp 上识别不出来了? 想想原因: 时间机器什么类型文件系统的?hfs+ windows 读不出来。安装个读写驱动。 在网上搜索: Paragon_HFS+_for_Windows_9.0_Special_Edition_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,614
精华内容 3,845
关键字:

win读取mac硬盘