Если ты открыл какой-то девайс, то имеешь указатель на FileObject. FileObject->DeviceObject это самый нижний девайс в стеке, DeviceObject->AttachedDevice это следующий, и так до последнего, у которого AttachedDevice = NULL. Раскручивай стек и ищи тот девайс, который тебе нужен.
Если сверху-вниз, но под ХР+ есть IoGetLowerDeviceObject, которая, впрочем, легко эмулируется руками.
pDeviceObject->DeviceObjectExtension->AttachedTo; А для гурманов вот: Код (Text): ////////////////////////////////////////////////////////////////////// /////// // // Undocumented definition of DEVOBJ_EXTENSION // struct _DEVICE_OBJECT_POWER_EXTENSION; typedef struct _DEVOBJ_EXTENSION_EX { CSHORT Type; USHORT Size; PDEVICE_OBJECT DeviceObject; ULONG PowerFlags; struct _DEVICE_OBJECT_POWER_EXTENSION *Dope; ULONG ExtensionFlags; PVOID DeviceNode; PDEVICE_OBJECT AttachedTo; LIST_ENTRY FileObjectList; } DEVOBJ_EXTENSION_EX, *PDEVOBJ_EXTENSION_EX; // // Undocumented definition of ExtensionFlags // #ifndef DOE_UNLOAD_PENDING #define DOE_UNLOAD_PENDING 0x00000001 #define DOE_DELETE_PENDING 0x00000002 #define DOE_REMOVE_PENDING 0x00000004 #define DOE_REMOVE_PROCESSED 0x00000008 #define DOE_START_PENDING 0x00000010 #endif ////////////////////////////////////////////////////////////////////// /////// // GetNextLowerDeviceObject ////////////////////////////////////////////////////////////////////// /////// PDEVICE_OBJECT GetNextLowerDeviceObject( IN PDEVICE_OBJECT i_pDeviceObject ) /*++ Routine Description: This routine returns a pointer to the next-lower-level device object on the driver stack. Parameters: i_pDeviceObject - Pointer to the device object in the stack for which the next-lower-level device object is to be returned. Return Value: A pointer to the next-lower-level device object on the device stack. Comments: THIS CODE WORKS FINE BUT SHOULD BE USED UNDER W2K ONLY. ON XP OR LATER SYSTEMS THERE IS DOCUMENTED IoGetLowerDeviceObject. This routine increments the reference count on the next-lower-level device object. Thus every successful call to it must be matched by a subsequent call ObDereferenceObject. --*/ { PDEVOBJ_EXTENSION_EX pdoex; PDEVICE_OBJECT r_pNextLowerDO = NULL; ASSERT( i_pDeviceObject && i_pDeviceObject->Type == IO_TYPE_DEVICE ); if ( i_pDeviceObject && i_pDeviceObject->Type == IO_TYPE_DEVICE ) { pdoex = (PDEVOBJ_EXTENSION_EX) i_pDeviceObject->DeviceObjectExtension; ASSERT( pdoex->Type == IO_TYPE_DEVICE_OBJECT_EXTENSION ); if ( 0 == (pdoex->ExtensionFlags & (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING | \ DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED)) ) { r_pNextLowerDO = pdoex->AttachedTo; if ( r_pNextLowerDO && r_pNextLowerDO->Type == IO_TYPE_DEVICE ) { // // This routine should bahave exactly like IoGetLowerDeviceObject, // because the caller will use IoGetLowerDeviceObject under XP or later. // So we must increment the reference count on the next-lower-level // device object. Thus every successful call to this routine must be // matched by a subsequent call ObDereferenceObject. // ObReferenceObject( r_pNextLowerDO ); return r_pNextLowerDO; } } } return NULL; }
Не понятно, ведь это все работает на основе : "pDeviceObject->DeviceObjectExtension->AttachedTo" Но структура расширения устройства для каждого драйвера индивидуальна.(ИМХО) Как я понял из доков... Этого мембера может и вовсе не быть или он может иметь совсем другое имя. У меня например "NextDriver". Или "AttachedTo" - это что-то другое?