驱动下如何获取硬盘序列号

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

#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;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值