- 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
This commit is contained in:
Filip Navara 2004-03-21 18:58:53 +00:00
parent 722728fd5c
commit bb917ce975
4 changed files with 158 additions and 23 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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
{