From bb917ce9752819ad7cff2fd64b0fbd6f65035ee5 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sun, 21 Mar 2004 18:58:53 +0000 Subject: [PATCH] - Support for upper level filter drivers. NOTE: Although the support for lower level filter driver is very similar, it's practically impossible to incorporate it with the current design without avoiding bugs such as #262 or #263. I don't want to extend the current mess beyond it's borders, so I ommited the call for initializing lower level filter drivers. The code needs a major cleanup and simplification on some places to make this support possible while maintaining a reasonable stable system. svn path=/trunk/; revision=8830 --- reactos/ntoskrnl/include/internal/io.h | 16 +++- reactos/ntoskrnl/io/device.c | 128 ++++++++++++++++++++++++- reactos/ntoskrnl/io/driver.c | 25 +++-- reactos/ntoskrnl/io/pnpmgr.c | 12 ++- 4 files changed, 158 insertions(+), 23 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 7aa02e4bb15..082f9202512 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: io.h,v 1.39 2004/03/14 17:10:48 navaraf Exp $ +/* $Id: io.h,v 1.40 2004/03/21 18:58:52 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -386,6 +386,19 @@ NTSTATUS PnpRootCreateDevice( PDEVICE_OBJECT *PhysicalDeviceObject); +/* device.c */ + +NTSTATUS +IopAttachFilterDrivers( + PDEVICE_NODE DeviceNode, + BOOLEAN Lower); + +NTSTATUS +IopInitializeService( + PDEVICE_NODE DeviceNode, + PUNICODE_STRING ServiceName, + PUNICODE_STRING ImagePath); + /* driver.c */ VOID @@ -399,6 +412,7 @@ IopInitializeSystemDrivers( NTSTATUS IopInitializeDeviceNodeService( PDEVICE_NODE DeviceNode, + PUNICODE_STRING ServiceName, BOOLEAN BootDriverOnly); VOID diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index ecfee43cd38..5b9cfeb120f 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -1,4 +1,4 @@ -/* $Id: device.c,v 1.67 2004/03/14 17:10:48 navaraf Exp $ +/* $Id: device.c,v 1.68 2004/03/21 18:58:53 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -345,13 +345,130 @@ IopCreateDriverObject(PDRIVER_OBJECT *DriverObject, return STATUS_SUCCESS; } -NTSTATUS -IopAttachFilterDrivers(PDEVICE_NODE DeviceNode, - BOOLEAN Lower) + +NTSTATUS STDCALL +IopAttachFilterDriversCallback( + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) { + PDEVICE_NODE DeviceNode = Context; + UNICODE_STRING ServiceName; + PWCHAR Filters; + + Filters = ValueData; + while (((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength && + *Filters != 0) + { + DPRINT1("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath); + ServiceName.Buffer = Filters; + ServiceName.MaximumLength = + ServiceName.Length = wcslen(Filters) * sizeof(WCHAR); + IopInitializeDeviceNodeService( + DeviceNode, + &ServiceName, + FALSE); + Filters += (ServiceName.Length / sizeof(WCHAR)) + 1; + } + return STATUS_SUCCESS; } + +NTSTATUS +IopAttachFilterDrivers( + PDEVICE_NODE DeviceNode, + BOOLEAN Lower) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + PWCHAR KeyBuffer; + UNICODE_STRING Class; + WCHAR ClassBuffer[40]; + NTSTATUS Status; + + /* + * First load the device filters + */ + + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].EntryContext = NULL; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[1].QueryRoutine = NULL; + QueryTable[1].Name = NULL; + + KeyBuffer = ExAllocatePool( + PagedPool, + (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length); + wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); + wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); + + RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + /* + * Now get the class GUID + */ + + Class.Length = 0; + Class.MaximumLength = 40 * sizeof(WCHAR); + Class.Buffer = ClassBuffer; + QueryTable[0].QueryRoutine = NULL; + QueryTable[0].Name = L"ClassGUID"; + QueryTable[0].EntryContext = &Class; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + ExFreePool(KeyBuffer); + + /* + * Load the class filter driver + */ + + if (NT_SUCCESS(Status)) + { + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].EntryContext = NULL; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + + KeyBuffer = ExAllocatePool(PagedPool, (58 * sizeof(WCHAR)) + Class.Length); + wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"); + wcscat(KeyBuffer, ClassBuffer); + + RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + ExFreePool(KeyBuffer); + } + + return STATUS_SUCCESS; +} + + NTSTATUS IopInitializeDevice(PDEVICE_NODE DeviceNode, BOOLEAN BootDriver) @@ -443,12 +560,13 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, NTSTATUS IopInitializeService( PDEVICE_NODE DeviceNode, + PUNICODE_STRING ServiceName, PUNICODE_STRING ImagePath) { PMODULE_OBJECT ModuleObject; NTSTATUS Status; - ModuleObject = LdrGetModuleObject(&DeviceNode->ServiceName); + ModuleObject = LdrGetModuleObject(ServiceName); if (ModuleObject == NULL) { /* The module is currently not loaded, so load it now */ diff --git a/reactos/ntoskrnl/io/driver.c b/reactos/ntoskrnl/io/driver.c index e46b6ca5950..b5f7973b1c3 100644 --- a/reactos/ntoskrnl/io/driver.c +++ b/reactos/ntoskrnl/io/driver.c @@ -1,4 +1,4 @@ -/* $Id: driver.c,v 1.37 2004/03/19 17:37:57 navaraf Exp $ +/* $Id: driver.c,v 1.38 2004/03/21 18:58:53 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,11 +33,6 @@ /* ke/main.c */ extern LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock; -NTSTATUS -IopInitializeService( - PDEVICE_NODE DeviceNode, - PUNICODE_STRING ImagePath); - NTSTATUS LdrProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING ModuleName, @@ -799,13 +794,16 @@ IopGetDriverNameFromServiceKey( */ NTSTATUS -IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) +IopInitializeDeviceNodeService( + PDEVICE_NODE DeviceNode, + PUNICODE_STRING ServiceName, + BOOLEAN BootDriverOnly) { NTSTATUS Status; ULONG ServiceStart; RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - if (DeviceNode->ServiceName.Buffer == NULL) + if (ServiceName == NULL || ServiceName->Buffer == NULL) { return STATUS_UNSUCCESSFUL; } @@ -819,7 +817,7 @@ IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].EntryContext = &ServiceStart; Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, - DeviceNode->ServiceName.Buffer, QueryTable, NULL, NULL); + ServiceName->Buffer, QueryTable, NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); @@ -840,8 +838,7 @@ IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) ULONG ModuleStart, ModuleSize; PCHAR ModuleName; - /* FIXME: Guard for buffer overflow */ - sprintf(SearchName, "%S.sys", DeviceNode->ServiceName.Buffer); + _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName); for (i = 1; i < KeLoaderBlock.ModsCount; i++) { ModuleStart = KeLoaderModules[i].ModStart; @@ -869,7 +866,7 @@ IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) * Get service path */ Status = IopGetDriverNameFromServiceKey(RTL_REGISTRY_SERVICES, - DeviceNode->ServiceName.Buffer, &ImagePath); + ServiceName->Buffer, &ImagePath); if (!NT_SUCCESS(Status)) { DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); @@ -879,12 +876,12 @@ IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) /* * Display loading message */ - IopDisplayLoadingMessage(DeviceNode->ServiceName.Buffer); + IopDisplayLoadingMessage(ServiceName->Buffer); /* * Load the service */ - Status = IopInitializeService(DeviceNode, &ImagePath); + Status = IopInitializeService(DeviceNode, ServiceName, &ImagePath); /* * Free the service path diff --git a/reactos/ntoskrnl/io/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr.c index cad12813c67..5f5da1a80a2 100644 --- a/reactos/ntoskrnl/io/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr.c @@ -1,4 +1,4 @@ -/* $Id: pnpmgr.c,v 1.26 2004/03/20 17:34:25 navaraf Exp $ +/* $Id: pnpmgr.c,v 1.27 2004/03/21 18:58:53 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -897,7 +897,9 @@ IopActionInterrogateDeviceStack( * Create registry key for the instance id, if it doesn't exist yet */ - KeyBuffer = ExAllocatePool(PagedPool, (49 + DeviceNode->InstancePath.Length) * sizeof(WCHAR)); + KeyBuffer = ExAllocatePool( + PagedPool, + (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length); wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); IopCreateDeviceKeyPath(KeyBuffer); @@ -1066,9 +1068,13 @@ IopActionInitChildServices( !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) { - Status = IopInitializeDeviceNodeService(DeviceNode, BootDrivers); + Status = IopInitializeDeviceNodeService( + DeviceNode, + &DeviceNode->ServiceName, + BootDrivers); if (NT_SUCCESS(Status)) { + IopAttachFilterDrivers(DeviceNode, FALSE); IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); } else {