如何在过滤器驱动程序中获取磁盘驱动器序列号?
How do I get the disk drive serial number in filter driver?
我在windows中写了一个驱动程序,我需要磁盘驱动器序列号,对于用户模式我找到了this答案。
我的问题是可以将上面的代码转换为内核模式吗?如何转换? WMI 查询在筛选器驱动程序中是否可用?示例代码可以提供很大帮助。
编辑:
我找到了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;
}
}
FILE_FS_VOLUME_INFORMATION
contains field VolumeSerialNumber
. This data structure might be retrieved with ZwQueryVolumeInformationFile(... FileFsVolumeInformation)
.
这需要卷的句柄或卷中的 file/directory。如果那不可行,但您有一个 DEVICE_OBJECT
,您可以尝试使用 IRP_MJ_QUERY_VOLUME_INFORMATION
and sending it with IoCallDriver()
构建您自己的 IRP,尽管我不知道这是否被批准——文档说这样一个 "request is sent by the I/O Manager."
分配内存后,我相信你需要再次调用IoWMIQueryAllData()
,这次传递的是dataBuffer。
SMBIOS 似乎与磁盘驱动器无关,因此您需要将不同的 GUID 传递给 IoWMIOpenBlock()
。也许 this one ({BF253431-1E4D-4F57-00E7-64B2CACC801E}
), since your user-mode example and 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 结构,它有字段序列号偏移量:
Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's serial number. If the device has no serial number, this member is zero.
我在windows中写了一个驱动程序,我需要磁盘驱动器序列号,对于用户模式我找到了this答案。 我的问题是可以将上面的代码转换为内核模式吗?如何转换? WMI 查询在筛选器驱动程序中是否可用?示例代码可以提供很大帮助。
编辑:
我找到了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;
}
}
FILE_FS_VOLUME_INFORMATION
contains field VolumeSerialNumber
. This data structure might be retrieved with ZwQueryVolumeInformationFile(... FileFsVolumeInformation)
.
这需要卷的句柄或卷中的 file/directory。如果那不可行,但您有一个 DEVICE_OBJECT
,您可以尝试使用 IRP_MJ_QUERY_VOLUME_INFORMATION
and sending it with IoCallDriver()
构建您自己的 IRP,尽管我不知道这是否被批准——文档说这样一个 "request is sent by the I/O Manager."
分配内存后,我相信你需要再次调用IoWMIQueryAllData()
,这次传递的是dataBuffer。
SMBIOS 似乎与磁盘驱动器无关,因此您需要将不同的 GUID 传递给 IoWMIOpenBlock()
。也许 this one ({BF253431-1E4D-4F57-00E7-64B2CACC801E}
), since your user-mode example and 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 结构,它有字段序列号偏移量:
Specifies the byte offset from the beginning of the structure to a null-terminated ASCII string that contains the device's serial number. If the device has no serial number, this member is zero.