在深入探讨如何通过低层设备过滤器驱动程序来区分硬盘和U盘驱动器之前,我们需要先理解几个关键概念。本文将详细介绍如何利用`IoGetDeviceProperty`函数来获取物理设备对象(Physical Device Object, PDO)的总线类型GUID,并通过一系列步骤来确定设备的具体类型。
### 关键概念介绍
#### 1. 物理设备对象 (PDO)
在Windows内核模式下,每个硬件设备都有一个与之对应的物理设备对象。PDO是驱动程序栈中的最低层对象,由系统自动创建,用于代表硬件设备。
#### 2. IoGetDeviceProperty
`IoGetDeviceProperty`是一个重要的内核API,可以用来获取设备属性。通过这个函数,我们可以查询设备的各种属性,例如设备类型、总线类型等。在本例中,我们关心的是设备的总线类型。
#### 3. 总线类型的GUID
总线类型的GUID是一种全局唯一标识符,用于表示特定类型的硬件总线。例如,对于USB总线,其GUID为 `{68e04dd0-2f4a-11cf-a229-00aa003c151e}`。通过比较PDO的总线类型GUID,我们可以判断出设备连接到的是哪种类型的总线。
### 如何区分硬盘和U盘驱动器
#### 步骤1:获取总线类型GUID
我们需要使用`IoGetDeviceProperty`函数来获取当前物理设备对象的总线类型的GUID。这一步骤可以通过以下代码实现:
```c
NTSTATUS status = IoGetDeviceProperty(
deviceExtension->PhysicalDeviceObject,
DevicePropertyBusTypeGuid,
sizeof(GUID),
&guidBusType,
&uReturn
);
```
其中`deviceExtension->PhysicalDeviceObject`是指向PDO的指针,`guidBusType`是一个用于存储总线类型GUID的变量,而`uReturn`则是返回的实际数据长度。
#### 步骤2:比较GUID
接下来,我们需要比较获取到的总线类型GUID与已知的USB和IDE总线类型的GUID。如果匹配,则可以判断设备连接到的是USB或IDE总线。
```c
if (IsEqualGUID(guidBusType, GUID_USB_BUS)) {
// 设备连接到了USB总线
} else if (IsEqualGUID(guidBusType, GUID_IDE_BUS)) {
// 设备连接到了IDE总线
}
```
#### 步骤3:检查设备类型
一旦确定了设备所连接的总线类型,下一步是确定设备的具体类型。对于硬盘和U盘,可以通过检查PDO的`DeviceType`属性来实现。如果`DeviceType`为`FILE_DEVICE_CD_ROM`,则该设备可能是CD-ROM,而非硬盘或U盘。可以通过以下方式进一步确认设备类型:
```c
if (PhysicalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) {
deviceExtension->bCdRom = TRUE;
} else {
deviceExtension->bCdRom = FALSE;
}
```
#### 步骤4:符号链接名的比较
为了更准确地判断硬盘还是U盘,还可以通过比较PDO的符号链接名来实现。通常,硬盘和U盘会有特定的符号链接名称,如`\\??\\IDE#Disk`和`\\??\\USBSTOR#Disk`。通过比较这些字符串,可以进一步确定设备的类型:
```c
if (RtlCompareMemory(deviceExtension->ifSymLinkName.Buffer, IDE_DISK_STRING, sizeof(IDE_DISK_STRING) - sizeof(WCHAR)) == sizeof(IDE_DISK_STRING) - sizeof(WCHAR)) {
deviceExtension->DeviceType = IDE_DISK;
} else if (RtlCompareMemory(deviceExtension->ifSymLinkName.Buffer, USBSTOR_DISK_STRING, sizeof(USBSTOR_DISK_STRING) - sizeof(WCHAR)) == sizeof(USBSTOR_DISK_STRING) - sizeof(WCHAR)) {
deviceExtension->DeviceType = USBSTOR_DISK;
}
```
### 结论
通过上述步骤,我们可以有效地在低层设备过滤器驱动程序中区分硬盘和U盘驱动器。这些方法基于对物理设备对象属性的查询和比较,能够确保正确地识别各种类型的存储设备。这对于开发高效且可靠的设备过滤器驱动程序至关重要。