user-0 提问: 如何用c语言编一段程序，实现读取硬盘序列号？

回复:
user: user-1
content: linux怎么获取

user: user-0
content: 引用 2 楼 菜是一种姿态 的回复：void CDiskTool::AdjustString(const char * str, int pos, char * buf) {     int i = 0, nStart, nEnd;      nStart = pos;     while ((str[nStart] == ' '))         nStart++;      nEnd = nStart;     while (str[nEnd])     {         buf[i++] = str[nEnd];         nEnd++;     }     buf[i] = '\0'; }  std::string CDiskTool::getDiskId(int nID /*= 0*/) {     char caDriveSerial[20] = {0};     int nlen = 20;     std::string strTmp; #ifdef _WIN32     HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;      int SerialLen = 0;     char DriveName[32];      // 要检索设备句柄，必须使用设备名称或与设备关联的驱动程序名称来调用CreateFile函数。     // DeviceIoControl可以接受特定设备的句柄。 对于硬盘来说，可能为以下几种形式：     // 对于物理驱动器x，形式为 \\.\PhysicalDriveX ，编号从0开始     sprintf(DriveName, TEXT("\\\\.\\PhysicalDrive%d"), nID);      hPhysicalDrive = CreateFile(DriveName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);      if (hPhysicalDrive == INVALID_HANDLE_VALUE)     {         return "";     }      struct _STORAGE_PROPERTY_QUERY query;      DWORD cbBytesReturned = 0;      static 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(hPhysicalDrive, IOCTL_STORAGE_QUERY_PROPERTY,         &query, sizeof(query), &local_buffer[0], sizeof(local_buffer), &cbBytesReturned, NULL))     {         struct _STORAGE_DEVICE_DESCRIPTOR * descrip = (struct _STORAGE_DEVICE_DESCRIPTOR *)& local_buffer;          char serialNumber[1000];          AdjustString(local_buffer, descrip->SerialNumberOffset, serialNumber);          if (isalnum(serialNumber[0]))         {             ULONG ulSerialLenTemp = (ULONG)strnlen(serialNumber, nlen - 1);             memcpy(caDriveSerial, serialNumber, ulSerialLenTemp);             caDriveSerial[ulSerialLenTemp] = '\0';             SerialLen = ulSerialLenTemp;         }     }      if (hPhysicalDrive != INVALID_HANDLE_VALUE)     {         CloseHandle(hPhysicalDrive);     } #elif _LINUX     int fd = 0;     hd_driveid hid;     FILE *fp;     char line[10000], *disk, *root;     char *p = NULL;     char cTmp = 97 + nID;     char fileName[20] = {0};      if(nID > 25)         return "";      sprintf(fileName, TEXT("/etc/sd%c"), cTmp);     fp = fopen(fileName, "r");     if (fp == NULL){         fprintf(stderr, "NO %s.\n", fileName);         return "";      }     fd = -1;     while (fgets(line, sizeof(line), fp) != NULL){         disk = strtok(line, " ");         if (disk == NULL) continue;         root = strtok(NULL, " ");         if (root == NULL) continue;         if (strcmp(root, "/") == 0){             for (p = disk + strlen(disk) - 1; isdigit(*p); p--){                 *p = '\0';             }             fd = open(disk, O_RDONLY);             break;         }     }     fclose(fp);      if (fd < 0){         fprintf(stderr, "open hard disk device failed.\n");         return "";      }     if (ioctl(fd, HDIO_GET_IDENTITY, &hid) < 0){         fprintf(stderr, "ioctlerror.\n");         return "";     }     close(fd);     snprintf(caDriveSerial, nlen, "%s", hid.serial_no); #endif     strTmp = caDriveSerial;     return strTmp;   }报错了

user: user-2
content: void CDiskTool::AdjustString(const char * str, int pos, char * buf) {     int i = 0, nStart, nEnd;      nStart = pos;     while ((str[nStart] == ' '))         nStart++;      nEnd = nStart;     while (str[nEnd])     {         buf[i++] = str[nEnd];         nEnd++;     }     buf[i] = '\0'; }  std::string CDiskTool::getDiskId(int nID /*= 0*/) {     char caDriveSerial[20] = {0};     int nlen = 20;     std::string strTmp; #ifdef _WIN32     HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;      int SerialLen = 0;     char DriveName[32];      // 要检索设备句柄，必须使用设备名称或与设备关联的驱动程序名称来调用CreateFile函数。     // DeviceIoControl可以接受特定设备的句柄。 对于硬盘来说，可能为以下几种形式：     // 对于物理驱动器x，形式为 \\.\PhysicalDriveX ，编号从0开始     sprintf(DriveName, TEXT("\\\\.\\PhysicalDrive%d"), nID);      hPhysicalDrive = CreateFile(DriveName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);      if (hPhysicalDrive == INVALID_HANDLE_VALUE)     {         return "";     }      struct _STORAGE_PROPERTY_QUERY query;      DWORD cbBytesReturned = 0;      static 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(hPhysicalDrive, IOCTL_STORAGE_QUERY_PROPERTY,         &query, sizeof(query), &local_buffer[0], sizeof(local_buffer), &cbBytesReturned, NULL))     {         struct _STORAGE_DEVICE_DESCRIPTOR * descrip = (struct _STORAGE_DEVICE_DESCRIPTOR *)& local_buffer;          char serialNumber[1000];          AdjustString(local_buffer, descrip->SerialNumberOffset, serialNumber);          if (isalnum(serialNumber[0]))         {             ULONG ulSerialLenTemp = (ULONG)strnlen(serialNumber, nlen - 1);             memcpy(caDriveSerial, serialNumber, ulSerialLenTemp);             caDriveSerial[ulSerialLenTemp] = '\0';             SerialLen = ulSerialLenTemp;         }     }      if (hPhysicalDrive != INVALID_HANDLE_VALUE)     {         CloseHandle(hPhysicalDrive);     } #elif _LINUX     int fd = 0;     hd_driveid hid;     FILE *fp;     char line[10000], *disk, *root;     char *p = NULL;     char cTmp = 97 + nID;     char fileName[20] = {0};      if(nID > 25)         return "";      sprintf(fileName, TEXT("/etc/sd%c"), cTmp);     fp = fopen(fileName, "r");     if (fp == NULL){         fprintf(stderr, "NO %s.\n", fileName);         return "";      }     fd = -1;     while (fgets(line, sizeof(line), fp) != NULL){         disk = strtok(line, " ");         if (disk == NULL) continue;         root = strtok(NULL, " ");         if (root == NULL) continue;         if (strcmp(root, "/") == 0){             for (p = disk + strlen(disk) - 1; isdigit(*p); p--){                 *p = '\0';             }             fd = open(disk, O_RDONLY);             break;         }     }     fclose(fp);      if (fd < 0){         fprintf(stderr, "open hard disk device failed.\n");         return "";      }     if (ioctl(fd, HDIO_GET_IDENTITY, &hid) < 0){         fprintf(stderr, "ioctlerror.\n");         return "";     }     close(fd);     snprintf(caDriveSerial, nlen, "%s", hid.serial_no); #endif     strTmp = caDriveSerial;     return strTmp;   }

user: user-3
content: Windows DeviceIoControl Linux ioctl