// 此函数类似于WDM中的PNP_MN_START_DEVICE函数,紧接着PnpAdd之后被调用。 // 此时PNP管理器经过甄别之后,已经决定将那些系统资源分配给当前设备。 // 参数ResourceList和ResourceListTranslated代表了这些系统资源。 // 当个函数被调用时候,设备已经进入了D0电源状态;函数完成后,设备即正式进入工作状态。 NTSTATUS DrvClass::PnpPrepareHardware(IN WDFCMRESLIST ResourceList, IN WDFCMRESLIST ResourceListTranslated) { NTSTATUS status; PDEVICE_CONTEXT pContext = NULL; ULONG ulNumRes = 0; ULONG ulIndex; CM_PARTIAL_RESOURCE_DESCRIPTOR* pResDes = NULL; KDBG(DPFLTR_INFO_LEVEL, "[PnpPrepareHardware]"); pContext = GetDeviceContext(m_hDevice); // 配置设备 status = ConfigureUsbDevice(); if(!NT_SUCCESS(status)) return status; // 获取Pipe句柄 status = GetUsbPipes(); if(!NT_SUCCESS(status)) return status; // 初始电源策略, status = InitPowerManagement(); // 获取USB总线驱动接口。总线接口中包含总线驱动提供的回调函数和其他信息。 // 总线接口由系统共用GUID标识。 status = WdfFdoQueryForInterface( m_hDevice, &USB_BUS_INTERFACE_USBDI_GUID1, // 总线接口ID (PINTERFACE)&m_busInterface, // 保存在设备环境块中 sizeof(USB_BUS_INTERFACE_USBDI_V1), 1, NULL); // 调用接口函数,判断USB版本。 if(NT_SUCCESS(status) && m_busInterface.IsDeviceHighSpeed){ if(m_busInterface.IsDeviceHighSpeed(m_busInterface.BusContext)) KDBG(DPFLTR_INFO_LEVEL, "USB 2.0"); else KDBG(DPFLTR_INFO_LEVEL, "USB 1.1"); } // 对系统资源列表,我们不做实质性的操作,仅仅打印一些信息。 // 读者完全可以把下面的这些代码都注释掉。 ulNumRes = WdfCmResourceListGetCount(ResourceList); KDBG(DPFLTR_INFO_LEVEL, "ResourceListCount:%d\n", ulNumRes); // 下面我们饶有兴致地枚举这些系统资源,并打印出它们的相关名称信息。 for(ulIndex = 0; ulIndex < ulNumRes; ulIndex++) { pResDes = WdfCmResourceListGetDescriptor(ResourceList, ulIndex); if(!pResDes)continue; // 取得失败,则跳到下一个 switch (pResDes->Type) { case CmResourceTypeMemory: KDBG(DPFLTR_INFO_LEVEL, "System Resource:CmResourceTypeMemory\n"); break; case CmResourceTypePort: KDBG(DPFLTR_INFO_LEVEL, "System Resource:CmResourceTypePort\n"); break; case CmResourceTypeInterrupt: KDBG(DPFLTR_INFO_LEVEL, "System Resource:CmResourceTypeInterrupt\n"); break; default: KDBG(DPFLTR_INFO_LEVEL, "System Resource:Others %d\n", pResDes->Type); break; } } return STATUS_SUCCESS; }
/********************************************************************* Function: DevicePollMedia Description: Detect media change, this is used in particular to detect when a USB memory stick is removed.or inserted. *********************************************************************/ u32 DevicePollMedia(ADI_USB_DEF *pDevice) { u32 Result = ADI_DEV_RESULT_FAILED; u32 DeviceEnumerated = FALSE; u32 FSSValue = 0; /* initiate the value to be sent to FSS as 0 (USB Device number in use) */ if( pDevice->MediaPresent == FALSE ) { /* The following callback to the FSS will result in any previously mounted file system * being unmounted; if first time the call is benign. This has to be done at thread level * as it may involve memory allocation tasks. */ if (FSSDirectCallbackFunction) { (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, &FSSValue ); } else { (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, &FSSValue ); } adi_dev_Control( pDevice->ClassDriverHandle, ADI_USB_MSD_CMD_IS_DEVICE_ENUMERATED, &DeviceEnumerated ); if ( DeviceEnumerated ) { /* Perform additional communications with device to establish * the connection and inform the FSS of media insertion. */ ConfigureUsbDevice(pDevice); /* Use Result to pass the device number */ Result = 0; /* call back to FSS to inform it of media insertion. The FSS will unmount any previous mount, and will * instruct this PID to detect volumes by reading the MBR. On successful return to FSS the Result value * will be set accordingly. If successful the MediaPresent flag is set to true. */ if (FSSDirectCallbackFunction) { (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_INSERTED, &Result ); } else { (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_INSERTED, &Result ); } if ( Result==ADI_FSS_RESULT_SUCCESS ) { pDevice->MediaPresent = TRUE; } else { pDevice->MediaPresent = FALSE; } Result = ADI_DEV_RESULT_SUCCESS; } else { Result=ADI_DEV_RESULT_FAILED; } } /* otherwise if media was already present then this call successfully resulted * in nothing to do */ else if (pDevice->MediaPresent) { Result = ADI_DEV_RESULT_SUCCESS; } return Result; }