完善DriveInfoEx源代码 获取计算机硬盘序列号

概述:

获取计算机硬盘序列号用途很多,在网上找到了一个C++的源代码DriveInfoEx(点这里查看)。非常好的一个DLL,.NET项目可以直接引用,而且源代码里有示例。

但这个DLL在Win7非管理员权限下,无法获取硬盘序列号,所以我就完善了一下这个DLL,让其支持Win7 非管理员。

源代码:

https://github.com/Xiongpq/DriveInfoExFull

编译时请注意

源代码内的一些方法,在VC90里已经被系统直接支持,所以就不用再重复定义,不然编译不过,所以如果在VC90及大于VC90平台编译的话,需要加一个“VC90”的“预处理器定义”。

代码中我做了判断,如果预定义了“VC90”就不会定义一些方法。在VC80及小于VC80平台编译的话,不用做这个设置。

DriveInfoExFull/DriveInfoEx/bin 目录下有已经编译好的DLL,这两个DLL支持.NET Framework 2.0

代码分析:

原作者的代码已经能很好支持非管理员权限下的硬盘序列号获取,我就不再分析原来的代码,只是大概说下我修改的内容。

ReadPhysicalDriveInNTWithZeroRights这个方法被原作者注释掉了,不知道什么原因,这个方法就是在没有权限的情况下获取硬盘序列号。

用这个方法如果找到的硬盘编号满足要求就添加到m_serizalNoVec中,这是一个vector<char*>

然后在Load方法中判断如果常规方法找到的硬盘个数为0,则将m_serizalNoVec中的硬盘信息添加到结果中。这个只包括硬盘的序列号,不包括大小等信息。

下面就是这个方法:

int DiskInfo::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.
      TCHAR driveName [256];

      swprintf (driveName, L"\\\\.\\PhysicalDrive%d", drive);

         //  Windows NT, Windows 2000, Windows XP - admin rights not required
      hPhysicalDriveIOCTL = CreateFile (driveName, 0,
                               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                               OPEN_EXISTING, 0, NULL);

      if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
      {
         STORAGE_PROPERTY_QUERY query;
         DWORD cbBytesReturned = 0;
         char buffer [10000];

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

         memset (buffer, 0, sizeof (buffer));

         if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
                   & query,
                   sizeof (query),
                   & buffer,
                   sizeof (buffer),
                   & cbBytesReturned, NULL) )
         {
             STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *) & buffer;
             char* serialNumber  = new char[1000];
             strcpy (serialNumber,
                     flipAndCodeBytes ( & buffer [descrip -> SerialNumberOffset]));

             int isAlnumAndSpace = TRUE;
             int isAllSpace = TRUE;
             int length=strlen(serialNumber);
             for(int i=0;i<length;i++){
                if(!isalnum(serialNumber[i]) && serialNumber[i] != ‘ ‘){
                     isAlnumAndSpace=FALSE;
                     break;
                }

                if(isAllSpace && serialNumber[i] != ‘ ‘){
                    isAllSpace=FALSE;
                }
             }
            //硬盘编号为字母、数字和空格,但不是纯空格
             if(isAlnumAndSpace && !isAllSpace){
                m_serizalNoVec.push_back(serialNumber);
             }

             done=TRUE;
         }

        CloseHandle (hPhysicalDriveIOCTL);
      }
   }
   return done;
}
INT Load()
        {
                DiskInfo& di = DiskInfo::GetDiskInfo();
                UINT cnt = di.LoadDiskInfo();
                for(UINT i=0; i < cnt; i++)
                    this->Add(gcnew DriveInfoEx(i));

                //判断如果常规方法找到的硬盘为0,则将m_serizalNoVec中的硬盘信息添加到结果中。
                //这个只包括硬盘的序列号,不包括大小等信息。
                if(cnt == 0){
                    UINT zeroRightCount = di.m_serizalNoVec.size();
                    for(UINT i=0; i < zeroRightCount; i++){
                        this->Add(gcnew DriveInfoEx(di.m_serizalNoVec[i]));
                    }
                }

                return this->Count;
        };

还有一些其他的修改就不再详细介绍,想了解的可以看看源代码。

不想了解的,下载DLL直接使用吧,哈哈~

时间: 2024-10-08 13:07:33

完善DriveInfoEx源代码 获取计算机硬盘序列号的相关文章

MFC获取电脑硬盘序列号(附源码)

在新建的工程里面添加一个类 即:以下一个类 GetHDSerial.cpp // GetHDSerial.cpp: implementation of the CGetHDSerial class. // Download by http://www.newxing.com/ ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "

C# 获取CPU序列号、网卡MAC地址、硬盘序列号封装类,用于软件绑定电脑

1 using System.Management; 2 3 namespace GLaLa 4 { 5 /// <summary> 6 /// hardware_mac 的摘要说明. 7 /// </summary> 8 class HardwareInfo 9 { 10 /// <summary> 11 /// 取机器名 12 /// </summary> 13 /// <returns></returns> 14 public

java通过jni方式获取硬盘序列号(windows,linux)

linux系统java通过jni方式获取硬盘序列号 http://blog.csdn.net/starter110/article/details/8186788 使用jni在windows下读取硬盘序列号 http://www.iflym.com/index.php/code/201109070001.html 通常做java程序的开发人员都想过想要通过某种手段来保护自己的程序.一般的方式是通过授权,采取软件授权的方式.这个时间就需要读取客户机器上的一些关键信息,比如硬盘序列号,网卡,cpu信

(转)通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号

最近由于项目的需要,需要在程序中获取机器的硬盘序列号和MAC地址等信息,在C#下,可以很容易的获得这些信息,但是在C++程序中感觉比较麻烦.经过百度,发现很多大虾都是通过WMI来获取这些硬件信息的,网上也有相关的代码,通过实际调试,也发现确实可以通过WMI来获取这些信息.前两天,在网上突然搜到一位大牛写的比较完整的程序,为了以后使用方便,就转载记录一下.同时,也会在大牛的代码中增加一些自己的注释,都是自己在实际使用过程中遇到的问题. #define _WIN32_DCOM #include "s

c/c++获取硬盘序列号

最近在接触软件注册模块,需要获取硬盘序列号来生成注册码. 硬盘序列号,英文名:Hard Disk Serial Number,该号是硬盘厂家为区别产品而设置的,是唯一的.网上搜索一下,发现获取硬盘序列号的代码遍地都是,但很多是错误的.典型代表就是使用GetVolumeInformation函数获取序列号.这种方法获取的是卷的序列号,即Volume Serial Number.硬盘格式化后,这种序列号将发生变化.本文描述的是获取硬盘唯一的物理序列号的方法. 获取硬盘序列号的方法:https://w

JAVA获取计算机CPU、硬盘、主板、网络等信息

通过使用第三方开源jar包sigar.jar我们可以获得本地的信息 1.下载sigar.jar sigar官方主页 sigar-1.6.4.zip 2.按照主页上的说明解压包后将相应的文件copy到java路径.比如windows32位操作系统需要将lib中sigar-x86-winnt.dll文件拷贝到java SDK目录的bin内 参考官方主页上的配置项. File Language Description Required sigar.jar Java Java API Yes (for

vc 获取 硬盘序列号 和 cpu

vc 获取 硬盘序列号 和 cpu 唯一iD的方法?如题---------网上找来很多资料 也没找到, 要支持xp win7 32/64 系统下都能获取 硬盘序列号 和cpu ID 哪位朋友帮帮忙:------解决方案--------------------不是很确定 没有测试64位的 http://blog.sina.com.cn/s/blog_612b382d0100efdt.html------解决方案--------------------CString cpu_id(){ int s1

获取网卡MAC、硬盘序列号、CPU_ID、BIOS编号

抄来的 获取网卡MAC.硬盘序列号.CPU ID.BIOS编号 本文中所有原理及思想均取自网络,有修改.其中获取硬盘序列号.获取CPU编号.获取BIOS编号的原始代码的著作权归各自作者所有. 以下代码可以取得系统特征码(网卡MAC.硬盘序列号.CPU ID.BIOS编号) BYTE szSystemInfo[4096]; // 在程序执行完毕后,此处存储取得的系统特征码 UINT uSystemInfoLen = 0; // 在程序执行完毕后,此处存储取得的系统特征码的长度 // 网卡 MAC

在windows下获取硬盘序列号(win7 32位,Windows Server 64位测试,希望在其他平台测试,遇到问题的网友留言分享)

#include <Windows.h> #include <stdio.h> // IOCTL控制码 // #define DFP_SEND_DRIVE_COMMAND CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // #define DFP_RECEIVE_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022,