如何在过滤器驱动程序中获取磁盘驱动器序列号?

时间:2016-10-13 08:39:30

标签: c driver wmi kernel-mode filter-driver

我在Windows中编写驱动程序,我需要磁盘驱动器序列号,对于用户模式,我找到了this ansver。 我的问题是可以将上面的代码转换为内核模式,以及如何? 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;
    }

}

2 个答案:

答案 0 :(得分:1)

分配内存后,我相信你需要再次调用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:

  

指定从结构开头到包含设备序列号的以null结尾的ASCII字符串的字节偏移量。如果设备没有序列号,则该成员为零。

答案 1 :(得分:0)

FILE_FS_VOLUME_INFORMATION包含字段VolumeSerialNumber。可以使用ZwQueryVolumeInformationFile(... FileFsVolumeInformation)检索此数据结构。

这需要卷的句柄或卷中的文件/目录。如果这不可行,但您有DEVICE_OBJECT,则可以尝试使用IRP_MJ_QUERY_VOLUME_INFORMATION构建自己的IRP并使用IoCallDriver()发送,但我不知道是否已经批准了 - docs说这样的“请求是由I / O管理器发送的。”