mirror of
https://github.com/reactos/reactos.git
synced 2024-08-31 15:55:41 +00:00
- Minor cleanup and fixed few memory leaks on driver unload.
svn path=/trunk/; revision=8896
This commit is contained in:
parent
5c7330b4d4
commit
c734759964
|
@ -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.41 2004/03/27 19:41:31 navaraf Exp $
|
||||
/* $Id: io.h,v 1.42 2004/03/28 09:48:13 navaraf Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -57,6 +57,12 @@ typedef struct _DEVOBJ_EXTENSION {
|
|||
struct _DEVICE_NODE *DeviceNode;
|
||||
} DEVOBJ_EXTENSION, *PDEVOBJ_EXTENSION;
|
||||
|
||||
typedef struct _PRIVATE_DRIVER_EXTENSIONS {
|
||||
struct _PRIVATE_DRIVER_EXTENSIONS *Link;
|
||||
PVOID ClientIdentificationAddress;
|
||||
CHAR Extension[1];
|
||||
} PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS;
|
||||
|
||||
typedef struct _DEVICE_NODE
|
||||
{
|
||||
struct _DEVICE_NODE *Parent;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: driver.c,v 1.39 2004/03/27 19:41:32 navaraf Exp $
|
||||
/* $Id: driver.c,v 1.40 2004/03/28 09:48:13 navaraf Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -85,24 +85,19 @@ POBJECT_TYPE EXPORTED IoDriverObjectType = NULL;
|
|||
|
||||
#define DRIVER_REGISTRY_KEY_BASENAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
/* DECLARATIONS ***************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IopCreateDriver(
|
||||
PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||
{
|
||||
DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
|
||||
ObjectBody, Parent, RemainingPath);
|
||||
POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
VOID STDCALL
|
||||
IopDeleteDriver(PVOID ObjectBody);
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
VOID INIT_FUNCTION
|
||||
IopInitDriverImplementation(VOID)
|
||||
|
@ -119,7 +114,7 @@ IopInitDriverImplementation(VOID)
|
|||
IoDriverObjectType->Dump = NULL;
|
||||
IoDriverObjectType->Open = NULL;
|
||||
IoDriverObjectType->Close = NULL;
|
||||
IoDriverObjectType->Delete = NULL;
|
||||
IoDriverObjectType->Delete = IopDeleteDriver;
|
||||
IoDriverObjectType->Parse = NULL;
|
||||
IoDriverObjectType->Security = NULL;
|
||||
IoDriverObjectType->QueryName = NULL;
|
||||
|
@ -136,7 +131,7 @@ IopInitDriverImplementation(VOID)
|
|||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IopDefaultDispatchFunction(
|
||||
IopInvalidDeviceRequest(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
|
@ -146,6 +141,68 @@ IopDefaultDispatchFunction(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IopCreateDriver(
|
||||
PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||
{
|
||||
PDRIVER_OBJECT Object = ObjectBody;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("IopCreateDriver(ObjectBody %x, Parent %x, RemainingPath %S)\n",
|
||||
ObjectBody, Parent, RemainingPath);
|
||||
|
||||
if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Create driver extension */
|
||||
Object->DriverExtension = (PDRIVER_EXTENSION)
|
||||
ExAllocatePoolWithTag(
|
||||
NonPagedPool,
|
||||
sizeof(DRIVER_EXTENSION),
|
||||
TAG_DRIVER_EXTENSION);
|
||||
|
||||
if (Object->DriverExtension == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
|
||||
|
||||
Object->Type = InternalDriverType;
|
||||
|
||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||
Object->MajorFunction[i] = IopInvalidDeviceRequest;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IopDeleteDriver(PVOID ObjectBody)
|
||||
{
|
||||
PDRIVER_OBJECT Object = ObjectBody;
|
||||
KIRQL OldIrql;
|
||||
PPRIVATE_DRIVER_EXTENSIONS DriverExtension, NextDriverExtension;
|
||||
|
||||
DPRINT("IopDeleteDriver(ObjectBody %x)\n", ObjectBody);
|
||||
|
||||
ExFreePool(Object->DriverExtension);
|
||||
|
||||
OldIrql = KeRaiseIrqlToDpcLevel();
|
||||
|
||||
for (DriverExtension = Object->DriverSection;
|
||||
DriverExtension != NULL;
|
||||
DriverExtension = NextDriverExtension)
|
||||
{
|
||||
NextDriverExtension = DriverExtension->Link;
|
||||
ExFreePool(DriverExtension);
|
||||
}
|
||||
|
||||
KfLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
IopCreateDriverObject(
|
||||
PDRIVER_OBJECT *DriverObject,
|
||||
|
@ -155,7 +212,6 @@ IopCreateDriverObject(
|
|||
ULONG DriverImageSize)
|
||||
{
|
||||
PDRIVER_OBJECT Object;
|
||||
ULONG i;
|
||||
WCHAR NameBuffer[MAX_PATH];
|
||||
UNICODE_STRING DriverName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
@ -208,28 +264,9 @@ IopCreateDriverObject(
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Create driver extension */
|
||||
Object->DriverExtension = (PDRIVER_EXTENSION)
|
||||
ExAllocatePoolWithTag(
|
||||
NonPagedPool,
|
||||
sizeof(DRIVER_EXTENSION),
|
||||
TAG_DRIVER_EXTENSION);
|
||||
|
||||
if (Object->DriverExtension == NULL)
|
||||
{
|
||||
ExFreePool(Object);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
|
||||
|
||||
Object->Type = InternalDriverType;
|
||||
Object->DriverStart = DriverImageStart;
|
||||
Object->DriverSize = DriverImageSize;
|
||||
|
||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||
Object->MajorFunction[i] = IopDefaultDispatchFunction;
|
||||
|
||||
*DriverObject = Object;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -552,7 +589,6 @@ IopAttachFilterDriversCallback(
|
|||
PDRIVER_OBJECT DriverObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
for (Filters = ValueData;
|
||||
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
|
||||
*Filters != 0;
|
||||
|
@ -681,13 +717,6 @@ IopAttachFilterDrivers(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
IopCreateGroupListEntry(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
|
@ -966,7 +995,7 @@ MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
|
|||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++)
|
||||
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
|
||||
{
|
||||
MmDeleteVirtualMapping(NULL, (char*)StartAddress + i * PAGE_SIZE, TRUE, NULL, NULL);
|
||||
}
|
||||
|
@ -999,12 +1028,14 @@ IopInitializeBuiltinDriver(
|
|||
/*
|
||||
* Display 'Initializing XXX...' message
|
||||
*/
|
||||
|
||||
sprintf(TextBuffer, "Initializing %s...\n", FileName);
|
||||
HalDisplayString(TextBuffer);
|
||||
|
||||
/*
|
||||
* Determine the right device object
|
||||
*/
|
||||
|
||||
if (ModuleDeviceNode == NULL)
|
||||
{
|
||||
/* Use IopRootDeviceNode for now */
|
||||
|
@ -1022,6 +1053,7 @@ IopInitializeBuiltinDriver(
|
|||
/*
|
||||
* Generate filename without path (not needed by freeldr)
|
||||
*/
|
||||
|
||||
FileNameWithoutPath = strrchr(FileName, '\\');
|
||||
if (FileNameWithoutPath == NULL)
|
||||
{
|
||||
|
@ -1031,6 +1063,7 @@ IopInitializeBuiltinDriver(
|
|||
/*
|
||||
* Load the module
|
||||
*/
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&DeviceNode->ServiceName,
|
||||
FileNameWithoutPath);
|
||||
Status = LdrProcessModule(ModuleLoadBase, &DeviceNode->ServiceName,
|
||||
|
@ -1046,6 +1079,7 @@ IopInitializeBuiltinDriver(
|
|||
/*
|
||||
* Strip the file extension from ServiceName
|
||||
*/
|
||||
|
||||
FileExtension = wcsrchr(DeviceNode->ServiceName.Buffer, '.');
|
||||
if (FileExtension != NULL)
|
||||
{
|
||||
|
@ -1056,6 +1090,7 @@ IopInitializeBuiltinDriver(
|
|||
/*
|
||||
* Initialize the driver
|
||||
*/
|
||||
|
||||
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE,
|
||||
&DriverObject);
|
||||
|
||||
|
@ -1112,6 +1147,7 @@ IopInitializeBootDrivers(VOID)
|
|||
/*
|
||||
* Pass symbol files to kernel debugger
|
||||
*/
|
||||
|
||||
if (!_stricmp(Extension, ".sym"))
|
||||
{
|
||||
KDB_SYMBOLFILE_HOOK((PVOID)ModuleStart, ModuleName, ModuleSize);
|
||||
|
@ -1120,6 +1156,7 @@ IopInitializeBootDrivers(VOID)
|
|||
/*
|
||||
* Load builtin driver
|
||||
*/
|
||||
|
||||
if (!_stricmp(Extension, ".sys"))
|
||||
{
|
||||
if (!ModuleLoaded)
|
||||
|
@ -1133,6 +1170,7 @@ IopInitializeBootDrivers(VOID)
|
|||
/*
|
||||
* Free memory for all boot files, except ntoskrnl.exe and hal.dll
|
||||
*/
|
||||
|
||||
#ifdef KDBG
|
||||
/*
|
||||
* Do not free the memory from symbol files, if the kernel debugger
|
||||
|
@ -1371,215 +1409,6 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/*
|
||||
* NtLoadDriver
|
||||
*
|
||||
* Loads a device driver.
|
||||
*
|
||||
* Parameters
|
||||
* DriverServiceName
|
||||
* Name of the service to load (registry key).
|
||||
*
|
||||
* Return Value
|
||||
* Status
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
||||
UNICODE_STRING ImagePath;
|
||||
UNICODE_STRING ServiceName;
|
||||
NTSTATUS Status;
|
||||
ULONG Type;
|
||||
PDEVICE_NODE DeviceNode;
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
LPWSTR Start;
|
||||
|
||||
DPRINT("NtLoadDriver('%wZ')\n", DriverServiceName);
|
||||
|
||||
/*
|
||||
* Check security privileges
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, KeGetPreviousMode()))
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
#endif
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/*
|
||||
* Get the service name from the registry key name.
|
||||
*/
|
||||
|
||||
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
||||
if (Start == NULL)
|
||||
Start = DriverServiceName->Buffer;
|
||||
else
|
||||
Start++;
|
||||
|
||||
RtlInitUnicodeString(&ServiceName, Start);
|
||||
|
||||
/*
|
||||
* Get service type.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
QueryTable[0].Name = L"Type";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &Type;
|
||||
|
||||
QueryTable[1].Name = L"ImagePath";
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
QueryTable[1].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
DriverServiceName->Buffer, QueryTable, NULL, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize the image path for all later processing.
|
||||
*/
|
||||
|
||||
Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("FullImagePath: '%S'\n", ImagePath.Buffer);
|
||||
DPRINT("Type: %lx\n", Type);
|
||||
|
||||
/*
|
||||
* See, if the driver module isn't already loaded
|
||||
*/
|
||||
ModuleObject = LdrGetModuleObject(&ImagePath);
|
||||
if (ModuleObject != NULL)
|
||||
{
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create device node
|
||||
*/
|
||||
|
||||
/* Use IopRootDeviceNode for now */
|
||||
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the driver module
|
||||
*/
|
||||
|
||||
Status = LdrLoadModule(&ImagePath, &ModuleObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("LdrLoadModule() failed (Status %lx)\n", Status);
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a service name for the device node
|
||||
*/
|
||||
|
||||
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
||||
if (Start == NULL)
|
||||
Start = DriverServiceName->Buffer;
|
||||
else
|
||||
Start++;
|
||||
RtlCreateUnicodeString(&DeviceNode->ServiceName, Start);
|
||||
|
||||
/*
|
||||
* Initialize the driver module
|
||||
*/
|
||||
|
||||
Status = IopInitializeDriverModule(
|
||||
DeviceNode,
|
||||
ModuleObject,
|
||||
(Type == 2 /*SERVICE_FILE_SYSTEM_DRIVER*/ ||
|
||||
Type == 8 /*SERVICE_RECOGNIZER_DRIVER*/),
|
||||
&DriverObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
|
||||
LdrUnloadModule(ModuleObject);
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
return Status;
|
||||
}
|
||||
|
||||
IopInitializeDevice(DeviceNode, DriverObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUnloadDriver
|
||||
*
|
||||
* Unloads a legacy device driver.
|
||||
*
|
||||
* Parameters
|
||||
* DriverServiceName
|
||||
* Name of the service to unload (registry key).
|
||||
*
|
||||
* Return Value
|
||||
* Status
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
|
||||
{
|
||||
return IopUnloadDriver(DriverServiceName, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
|
||||
PDRIVER_REINITIALIZE ReinitRoutine,
|
||||
PVOID Context)
|
||||
{
|
||||
PDRIVER_REINIT_ITEM ReinitItem;
|
||||
|
||||
ReinitItem = ExAllocatePool(NonPagedPool,
|
||||
sizeof(DRIVER_REINIT_ITEM));
|
||||
if (ReinitItem == NULL)
|
||||
return;
|
||||
|
||||
ReinitItem->DriverObject = DriverObject;
|
||||
ReinitItem->ReinitRoutine = ReinitRoutine;
|
||||
ReinitItem->Context = Context;
|
||||
|
||||
ExInterlockedInsertTailList(&DriverReinitListHead,
|
||||
&ReinitItem->ItemEntry,
|
||||
&DriverReinitListLock);
|
||||
}
|
||||
|
||||
|
||||
VOID FASTCALL
|
||||
IopMarkLastReinitializeDriver(VOID)
|
||||
{
|
||||
|
@ -1645,11 +1474,229 @@ IopReinitializeDrivers(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct _PRIVATE_DRIVER_EXTENSIONS {
|
||||
struct _PRIVATE_DRIVER_EXTENSIONS *Link;
|
||||
PVOID ClientIdentificationAddress;
|
||||
CHAR Extension[1];
|
||||
} PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS;
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
* NtLoadDriver
|
||||
*
|
||||
* Loads a device driver.
|
||||
*
|
||||
* Parameters
|
||||
* DriverServiceName
|
||||
* Name of the service to load (registry key).
|
||||
*
|
||||
* Return Value
|
||||
* Status
|
||||
*
|
||||
* Status
|
||||
* implemented
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
||||
UNICODE_STRING ImagePath;
|
||||
UNICODE_STRING ServiceName;
|
||||
NTSTATUS Status;
|
||||
ULONG Type;
|
||||
PDEVICE_NODE DeviceNode;
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
LPWSTR Start;
|
||||
|
||||
DPRINT("NtLoadDriver('%wZ')\n", DriverServiceName);
|
||||
|
||||
/*
|
||||
* Check security privileges
|
||||
*/
|
||||
|
||||
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, KeGetPreviousMode()))
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/*
|
||||
* Get the service name from the registry key name.
|
||||
*/
|
||||
|
||||
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
||||
if (Start == NULL)
|
||||
Start = DriverServiceName->Buffer;
|
||||
else
|
||||
Start++;
|
||||
|
||||
RtlInitUnicodeString(&ServiceName, Start);
|
||||
|
||||
/*
|
||||
* Get service type.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
QueryTable[0].Name = L"Type";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &Type;
|
||||
|
||||
QueryTable[1].Name = L"ImagePath";
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
QueryTable[1].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
DriverServiceName->Buffer, QueryTable, NULL, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize the image path for all later processing.
|
||||
*/
|
||||
|
||||
Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("FullImagePath: '%S'\n", ImagePath.Buffer);
|
||||
DPRINT("Type: %lx\n", Type);
|
||||
|
||||
/*
|
||||
* See, if the driver module isn't already loaded
|
||||
*/
|
||||
|
||||
ModuleObject = LdrGetModuleObject(&ImagePath);
|
||||
if (ModuleObject != NULL)
|
||||
{
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create device node
|
||||
*/
|
||||
|
||||
/* Use IopRootDeviceNode for now */
|
||||
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the driver module
|
||||
*/
|
||||
|
||||
Status = LdrLoadModule(&ImagePath, &ModuleObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("LdrLoadModule() failed (Status %lx)\n", Status);
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a service name for the device node
|
||||
*/
|
||||
|
||||
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
||||
if (Start == NULL)
|
||||
Start = DriverServiceName->Buffer;
|
||||
else
|
||||
Start++;
|
||||
RtlCreateUnicodeString(&DeviceNode->ServiceName, Start);
|
||||
|
||||
/*
|
||||
* Initialize the driver module
|
||||
*/
|
||||
|
||||
Status = IopInitializeDriverModule(
|
||||
DeviceNode,
|
||||
ModuleObject,
|
||||
(Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
|
||||
Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
|
||||
&DriverObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status);
|
||||
LdrUnloadModule(ModuleObject);
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
return Status;
|
||||
}
|
||||
|
||||
IopInitializeDevice(DeviceNode, DriverObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUnloadDriver
|
||||
*
|
||||
* Unloads a legacy device driver.
|
||||
*
|
||||
* Parameters
|
||||
* DriverServiceName
|
||||
* Name of the service to unload (registry key).
|
||||
*
|
||||
* Return Value
|
||||
* Status
|
||||
*
|
||||
* Status
|
||||
* implemented
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
|
||||
{
|
||||
return IopUnloadDriver(DriverServiceName, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* IoRegisterDriverReinitialization
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
VOID STDCALL
|
||||
IoRegisterDriverReinitialization(
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PDRIVER_REINITIALIZE ReinitRoutine,
|
||||
PVOID Context)
|
||||
{
|
||||
PDRIVER_REINIT_ITEM ReinitItem;
|
||||
|
||||
ReinitItem = ExAllocatePool(NonPagedPool, sizeof(DRIVER_REINIT_ITEM));
|
||||
if (ReinitItem == NULL)
|
||||
return;
|
||||
|
||||
ReinitItem->DriverObject = DriverObject;
|
||||
ReinitItem->ReinitRoutine = ReinitRoutine;
|
||||
ReinitItem->Context = Context;
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DriverReinitListHead,
|
||||
&ReinitItem->ItemEntry,
|
||||
&DriverReinitListLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* IoAllocateDriverObjectExtension
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IoAllocateDriverObjectExtension(
|
||||
|
@ -1699,6 +1746,13 @@ IoAllocateDriverObjectExtension(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* IoGetDriverObjectExtension
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
PVOID STDCALL
|
||||
IoGetDriverObjectExtension(
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
|
|
Loading…
Reference in a new issue