我在windows中写了一个驱动程序,我需要磁盘驱动器序列号,对于用户模式,我找到this ansver . 我的问题是可以将上面的代码转换为内核模式,以及如何? WMI查询在筛选器驱动程序中是否可用?示例代码可以大大帮助 .
EDIT:
我发现here这段代码,但我是如何重写他获取序列号的?
void GetSmbios()
{
NTSTATUS status;
GUID smbiosGUID = SMBIOS_DATA_GUID; // defined in wmiguid.h
PVOID wmiObject = NULL;
PWNODE_ALL_DATA dataBuffer;
ULONG bufferSize;
int TAG_SMBIOS = 'smbi';
//
// Get a WMI block handle to the SMBIOS_DATA_GUID
//
status = IoWMIOpenBlock((GUID *)&smbiosGUID, WMIGUID_QUERY,
&wmiObject);
if (!NT_SUCCESS(status))
{
return status;
}
//
// Determine how much space is required for the data
//
status = IoWMIQueryAllData(wmiObject, &bufferSize, NULL);
if (status != STATUS_BUFFER_TOO_SMALL)
{
ObDereferenceObject(wmiObject);
return status;
}
//
// Allocate the necessary storage. This space must come out of NP-pool
//
dataBuffer = ExAllocatePoolWithTag(
NonPagedPool,
bufferSize,
TAG_SMBIOS);
if (dataBuffer == NULL)
{
ObDereferenceObject(wmiObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
}
2 回答
分配内存后,我相信你需要再次调用
IoWMIQueryAllData()
,这次传递dataBuffer .SMBIOS不希望将另一个GUID传递给
IoWMIOpenBlock()
. 也许this one({BF253431-1E4D-4F57-00E7-64B2CACC801E}
),因为你的用户模式示例和others查询Win32_PhysicalMedia来获取SerialNumber .但是,this引用了一个(可能是用户模式)DLL,它是Win32_PhysicalMedia的提供者 . 因此,在内核模式下可能无法访问 .
但它也提示如何从内核模式获取信息:IOCTL . 它提到了IOCTL_SMART_GET_VERSION,它应该只是SMART_GET_VERSION,而here's an example :(在用户模式下,但你应该可以使用
ZwDeviceIoControlFile()
从内核模式做类似的事情) . 请注意,它会使用另一个ioctl命令SMART_RCV_DRIVE_DATA来获取序列号 .另一个听起来很有希望(更通用)的ioctl是IOCTL_STORAGE_QUERY_PROPERTY,输入STORAGE_PROPERTY_QUERY.PropertyId设置为StorageDeviceProperty,因此输出将是STORAGE_DEVICE_DESCRIPTOR结构,其结构为SerialNumberOffset字段:
FILE_FS_VOLUME_INFORMATION包含字段
VolumeSerialNumber
. 可以使用ZwQueryVolumeInformationFile(... FileFsVolumeInformation)检索此数据结构 .这需要卷的句柄或卷中的文件/目录 . 如果这不可行,但你有一个
DEVICE_OBJECT
,你可以尝试使用IRP_MJ_QUERY_VOLUME_INFORMATION Build 你自己的IRP并发送IoCallDriver(),虽然我没有受到制裁 - 文件说这样的"request is sent by the I/O Manager."