/* GLOBALS ********************************************************************/
+ERESOURCE IopDriverLoadResource;
+
LIST_ENTRY DriverReinitListHead;
KSPIN_LOCK DriverReinitListLock;
PLIST_ENTRY DriverReinitTailEntry;
DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
DriverObject, ServiceName, FileSystem);
+ ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
*DriverObject = NULL;
/* Create ModuleName string */
DriverName.Length = 0;
DriverName.MaximumLength = sizeof(NameBuffer);
- if (FileSystem == TRUE)
+ if (FileSystem != FALSE)
RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME);
else
RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME);
*/
VOID
FASTCALL
-INIT_FUNCTION
IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
{
CHAR TextBuffer[256];
PUNICODE_STRING ImagePath,
_In_ PUNICODE_STRING ServiceName)
{
+ UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
+ UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
+ UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
UNICODE_STRING InputImagePath;
DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
- RtlCopyMemory(&InputImagePath,
- ImagePath,
- sizeof(UNICODE_STRING));
-
+ InputImagePath = *ImagePath;
if (InputImagePath.Length == 0)
{
ImagePath->Length = 0;
- ImagePath->MaximumLength =
- (33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL);
- ImagePath->Buffer = ExAllocatePool(NonPagedPool,
- ImagePath->MaximumLength);
+ ImagePath->MaximumLength = DriversPathString.Length +
+ ServiceName->Length +
+ DotSysString.Length +
+ sizeof(UNICODE_NULL);
+ ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ ImagePath->MaximumLength,
+ TAG_IO);
if (ImagePath->Buffer == NULL)
return STATUS_NO_MEMORY;
- RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\");
+ RtlCopyUnicodeString(ImagePath, &DriversPathString);
RtlAppendUnicodeStringToString(ImagePath, ServiceName);
- RtlAppendUnicodeToString(ImagePath, L".sys");
+ RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
}
else if (InputImagePath.Buffer[0] != L'\\')
{
ImagePath->Length = 0;
- ImagePath->MaximumLength =
- 12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL);
- ImagePath->Buffer = ExAllocatePool(NonPagedPool,
- ImagePath->MaximumLength);
+ ImagePath->MaximumLength = SystemRootString.Length +
+ InputImagePath.Length +
+ sizeof(UNICODE_NULL);
+ ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ ImagePath->MaximumLength,
+ TAG_IO);
if (ImagePath->Buffer == NULL)
return STATUS_NO_MEMORY;
- RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\");
+ RtlCopyUnicodeString(ImagePath, &SystemRootString);
RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
/* Free caller's string */
HANDLE CCSKey, ServiceKey;
PVOID BaseAddress;
+ ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
ASSERT(ServiceName->Length);
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
ServiceStart = 0;
/* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
- ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0;
- ServiceImagePath.Buffer = NULL;
+ RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
}
else
{
/* Create ModuleName string */
if (ServiceName && ServiceName->Length > 0)
{
- if (FileSystemDriver == TRUE)
+ if (FileSystemDriver != FALSE)
wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
else
wcscpy(NameBuffer, DRIVER_ROOT_NAME);
ServiceName.MaximumLength =
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
Status = IopGetDriverObject(&DriverObject,
&ServiceName,
FALSE);
/* Load and initialize the filter driver */
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
if (!NT_SUCCESS(Status))
+ {
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
return Status;
+ }
Status = IopInitializeDriverModule(DeviceNode,
ModuleObject,
FALSE,
&DriverObject);
if (!NT_SUCCESS(Status))
+ {
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
return Status;
+ }
}
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
+
Status = IopInitializeDevice(DeviceNode, DriverObject);
/* Remove extra reference */
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry;
UNICODE_STRING ServiceName;
+ BOOLEAN Success;
/*
* Display 'Loading XXX...' message
/*
* Strip the file extension from ServiceName
*/
- RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
+ Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
+ if (!Success)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
FileExtension = wcsrchr(ServiceName.Buffer, '.');
if (FileExtension != NULL)
{
NextEntry = NextEntry->Flink;
}
- NT_ASSERT(NextEntry != &PsLoadedModuleList);
+ ASSERT(NextEntry != &PsLoadedModuleList);
/*
* Initialize the driver
if (!NT_SUCCESS(Status))
{
- IopFreeDeviceNode(DeviceNode);
return Status;
}
if (!NT_SUCCESS(Status))
{
/* Fail */
- IopFreeDeviceNode(DeviceNode);
return;
}
if (!NT_SUCCESS(Status))
{
/* Fail */
- IopFreeDeviceNode(DeviceNode);
ObDereferenceObject(DriverObject);
return;
}
if (!NT_SUCCESS(Status))
{
/* Fail */
- IopFreeDeviceNode(DeviceNode);
ObDereferenceObject(DriverObject);
return;
}
/* Set the unload invoked flag and call the unload routine */
DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
Status = IopLoadUnloadDriver(NULL, &DriverObject);
- NT_ASSERT(Status == STATUS_SUCCESS);
+ ASSERT(Status == STATUS_SUCCESS);
/* Mark the driver object temporary, so it could be deleted later */
ObMakeTemporaryObject(DriverObject);
/* Create a random name and set up the string*/
NameLength = (USHORT)swprintf(NameBuffer,
DRIVER_ROOT_NAME L"%08u",
- KeTickCount);
+ KeTickCount.LowPart);
LocalDriverName.Length = NameLength * sizeof(WCHAR);
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
LocalDriverName.Buffer = NameBuffer;
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
InitializeObjectAttributes(&ObjectAttributes,
&LocalDriverName,
- OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
+ OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
{
PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
- NT_ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess);
+ ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess);
LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
&LoadParams->DriverObject);
KeSetEvent(&LoadParams->Event, 0, FALSE);
DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
DPRINT("Type: %lx\n", Type);
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
/*
* Get existing DriverObject pointer (in case the driver
* has already been loaded and initialized).
*/
Status = IopGetDriverObject(DriverObject,
&ServiceName,
- (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
- Type == 8 /* SERVICE_RECOGNIZER_DRIVER */));
+ (Type == SERVICE_FILE_SYSTEM_DRIVER ||
+ Type == SERVICE_RECOGNIZER_DRIVER));
if (!NT_SUCCESS(Status))
{
if (!NT_SUCCESS(Status))
{
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
return Status;
}
if (!NT_SUCCESS(Status))
{
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
MmUnloadSystemImage(ModuleObject);
return Status;
}
Status = IopInitializeDriverModule(DeviceNode,
ModuleObject,
&DeviceNode->ServiceName,
- (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
- Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
+ (Type == SERVICE_FILE_SYSTEM_DRIVER ||
+ Type == SERVICE_RECOGNIZER_DRIVER),
DriverObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
MmUnloadSystemImage(ModuleObject);
- IopFreeDeviceNode(DeviceNode);
return Status;
}
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
+
/* Initialize and start device */
IopInitializeDevice(DeviceNode, *DriverObject);
Status = IopStartDevice(DeviceNode);
}
else
{
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
+
DPRINT("DriverObject already exist in ObjectManager\n");
Status = STATUS_IMAGE_ALREADY_LOADED;