最近公司有个项目,需要在驱动模式及用户模式下,获取硬盘的序列号,在网上找了半天,大多是用户模式的代码,而且许多已经过时,于是参照了一下,改写成内核模式下的代码,本人是驱动的菜鸟,希望此代码能对那些和我一样的菜鸟有所帮助。

#include < ntdddisk.h>
#include <ntstrsafe.h>

#define _in
#define _out

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;

typedef struct _HardDiskInfo
{
char szSerialNumber[21];
char szModelNumber[41];
char szRevision[21];
}HardDiskInfo,*PHardDiskInfo;

typedef enum 
{
HDSERIALNO = 1,
HDMODELNO = 1<<1,
HDREVISION = 1<<2,
HDALLINFO = HDSERIALNO | HDMODELNO | HDREVISION
} HDInfoRequest;

int ConvertToString(_in PUSHORT pData, _in int iFirstIndex, _in int iLastIndex, _out char* szOutBuf )
{
int iIndex = 0;
int iPosition = 0;
BOOL bNoneSpace = FALSE;

if(iFirstIndex > iLastIndex)
{
int iTmp = iFirstIndex;
iFirstIndex = iLastIndex;
iLastIndex = iTmp;
}

if(iLastIndex > 0xFF)
return 0;
//memset(szOutBuf,0,iLastIndex-iFirstIndex+1);

for(iIndex = iFirstIndex; iIndex<= iLastIndex;++iIndex)
{
char ch = pData[iIndex] >> 8;

if(ch != ' ')
{
bNoneSpace = TRUE;
}
if(bNoneSpace)
szOutBuf[iPosition++] = ch;

ch = pData[iIndex] & 0xFF;
if(ch != ' ')
{
bNoneSpace = TRUE;
}
if(bNoneSpace)
szOutBuf[iPosition++] = ch;
}

iPosition--;
while(szOutBuf[iPosition] == ' ')
iPosition--;
szOutBuf[++iPosition] = 0;

return iPosition;
}

NTSTATUS ReadPhysicalDriveInNTUsingSmart( _in int iDrive,_out PHardDiskInfo pHDInfo,_in HDInfoRequest hdRequest )
{
HANDLE hPhysicalDriveIOCTL = 0;
wchar_t szDriveName [40];
NTSTATUS ret = STATUS_UNSUCCESSFUL;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uDrivePath;
IO_STATUS_BLOCK iosb;

#ifdef DBG
__asm int 3
#endif
ret = RtlStringCchPrintfW(szDriveName,sizeof(szDriveName)/sizeof(wchar_t), L"\\DosDevices\\PhysicalDrive%d", iDrive);
if(!NT_SUCCESS(ret))
return ret;

RtlInitUnicodeString(&uDrivePath,szDriveName);

InitializeObjectAttributes(&oa, &uDrivePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,(HANDLE)NULL, NULL);

ret = ZwCreateFile( &hPhysicalDriveIOCTL,
FILE_READ_DATA | FILE_READ_ATTRIBUTES |FILE_WRITE_DATA,
&oa,
&iosb,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if(NT_SUCCESS(ret))
{
ULONG ulCommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;
DWORD BytesReturned = 0;
PSENDCMDINPARAMS pCmdParam;

DbgPrint(("Open Disk file succeded!"));
pCmdParam = (PSENDCMDINPARAMS) ExAllocatePoolWithTag (NonPagedPool,ulCommandSize, (ULONG)"_EL_");
if(pCmdParam != NULL)
{
pCmdParam -> irDriveRegs.bCommandReg =  0xEC; // Returns ID sector for ATA

ret = ZwDeviceIoControlFile( hPhysicalDriveIOCTL,
NULL,
NULL,
NULL,
&iosb,
SMART_RCV_DRIVE_DATA,
pCmdParam,sizeof(SENDCMDINPARAMS),
pCmdParam,ulCommandSize
);
if(NT_SUCCESS(ret))
{
// Print the IDENTIFY data
USHORT *punIdSector = (USHORT *)(PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) pCmdParam) -> bBuffer;
if(hdRequest & HDSERIALNO)
ConvertToString (punIdSector, 10, 19, pHDInfo->szSerialNumber);
if(hdRequest & HDMODELNO)
ConvertToString (punIdSector, 27, 46, pHDInfo->szModelNumber);
if(hdRequest & HDREVISION)
ConvertToString (punIdSector, 23, 26, pHDInfo->szRevision);
}

ExFreePoolWithTag(pCmdParam, (ULONG)"_EL_");
}
ZwClose(hPhysicalDriveIOCTL);
}
else
{
DbgPrint(("Open Disk file failed!"));
}
return ret;
}

BOOL GetHardDiskSerial( char* szSerial )
{
HardDiskInfo hdInfo;
BOOL iRet = FALSE;

strcpy(szSerial,"");

if(NT_SUCCESS(ReadPhysicalDriveInNTUsingSmart(0,&hdInfo,HDALLINFO)))
{
strcat(szSerial,hdInfo.szSerialNumber);
strcat(szSerial,"  ");
/*strcat(szSerial,"  ");
strcat(szSerial,hdInfo.szModelNumber);
strcat(szSerial,"  ");
strcat(szSerial,hdInfo.szRevision);*/
DbgPrint(("Hard disk serial is %s\n",szSerial));
iRet = TRUE;
}

return iRet;
}

驱动下如何获取硬盘序列号相关推荐

  1. 用C#获取硬盘序列号,CPU序列号,网卡MAC地址

    这个问题首先得考虑的就是你的硬盘是不是SCSI硬盘 如果是,那么根本不存在"物理序列号",只可能取得卷标的序列号 如果是卷标序列号,要注意的是每次格式化硬盘的时候这个序列号都会变 ...

  2. VC6获取硬盘序列号、型号、修订版本号

    因为要做个读取硬盘参数信息的控件,所以在网上找了不少代码,但是自己作为一个初学者在使用别人代码时,总会发现有各种各样的问题: 1. 需要的头文件未写明 2. 有些定义未给出 3. 代码的开发环境未明, ...

  3. 使用java获取硬盘序列号

    使用java获取硬盘序列号 使用java获取硬盘的序列号呢,涉及了跨平台的问题,不同的操作系统的查看命令不一样,可以使用oshi获取. oshi(Native Operating System and ...

  4. MFC 获取硬盘序列号、IP地址、MAC地址

    1)获取本地硬盘序列号 调出cmd 输入wmic diskdrive get serialnumber 或 wmic diskdrive get Name, Manufacturer, Model, ...

  5. .NET获取硬盘序列号的几个方法

    最近作软件注册,收集了很多.NET相关的获取硬盘物理序列号的方法,主要分为使用WMI方式和API方式.但这些方法均可能有问题. 1,使用WMI方式,有的机器根本取不到硬盘序列号,有的方式在Vista下 ...

  6. java获取硬盘序列号_Win7 64+Python3.7获取计算机硬盘信息初探

    一.需求 由于最近负责电脑资产清查的工作,有100多台分散的电脑需要获得用户名.MAC地址.硬盘序列号.硬盘品牌 一般方法: (1)查看系统用户名 (2) 获取MAC地址 windos命令行使用ipc ...

  7. 获取硬盘序列号、CPU序列号

    public class SerialUtils {private static Properties props = System.getProperties();private static St ...

  8. 获取硬盘序列号的方法总结

    硬盘有多种牌子,型号... 接口有IDE, SCSI, SATA...... 操作系统有win98, 2000, xp, vista...... 在网上找了好几天,多数都是抄来抄去的,或者是八九年以前 ...

  9. 转另一个获取硬盘序列号的方法

    原谅转自:http://blog.sina.com.cn/s/blog_57dff12f0100d5so.html #define  DFP_GET_VERSION                   ...

最新文章

  1. XML文件读取数据绑定到DropDownList
  2. 计算机的好处和坏处的英语作文,《电脑的好处和坏处》英语作文 80词以上 谢谢...
  3. 图 深度优先遍历 广度优先遍历 非递归遍历 图解算法过程
  4. 心得14-hibernate的优化2-抓取(fetch)
  5. python 笔记 haversine (两个经纬度坐标之间的距离)
  6. asp.net三层结构
  7. 怎么做逆向geocoding?
  8. MongoDB数据库(了解MongoDB及基础命令,备份数据库)
  9. MFC透明桌面flash金鱼
  10. atitit.orm的缺点与orm框架市场占有率,选型attilax总结
  11. 【java】java的Jaas授权与鉴权
  12. FreeSwitch双轨录音
  13. 通过IIS安装包安装IIS
  14. ACO 蚁群算法(算法流程,TSP例子解析)
  15. Jetson 系列——Jetson Nano使用sudo命令免输入密码方法
  16. python 图片抓取
  17. react 的样式写法
  18. EventBus的理解和使用
  19. 用CSS实现段落前面缩进两个字
  20. 新能源汽车行业资讯-2022-9-15

热门文章

  1. Java能够长盛不衰20年的秘密
  2. 关闭血条上显示的服务器名字,魔兽世界怀旧服姓名血条修改宏 远处看不到血条名字解决方法...
  3. 【Python-1】总算是开始了
  4. 万利达歌王DVD:两万首歌的储存方式
  5. 论Java技术在因特网平台上的应用—论文1:ERP开发的应用
  6. 学python学了一年,都做了啥东西
  7. javascript对指定元素添加父元素
  8. 关于采访面馆的一些思考
  9. 简洁UI自带稳定接口去水印小程序源码
  10. Python实现基于3σ原则的异常值检测