ReactOS  0.4.15-dev-2536-g90b3a9c
driver.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/iomgr/driver.c
5  * PURPOSE: Driver Object Management
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Filip Navara (navaraf@reactos.org)
8  * Hervé Poussineau (hpoussin@reactos.org)
9  */
10 
11 /* INCLUDES *******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS ********************************************************************/
18 
20 
24 
28 
30  RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
31 static const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
32 
34 
35 #define TAG_RTLREGISTRY 'vrqR'
36 
38 extern BOOLEAN PnpSystemInit;
41 
44 
45 /* TYPES *********************************************************************/
46 
47 // Parameters packet for Load/Unload work item's context
48 typedef struct _LOAD_UNLOAD_PARAMS
49 {
57 
62 
63 /* PRIVATE FUNCTIONS **********************************************************/
64 
66 NTAPI
69  PIRP Irp)
70 {
71  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
72  Irp->IoStatus.Information = 0;
75 }
76 
77 VOID
78 NTAPI
80 {
81  PDRIVER_OBJECT DriverObject = ObjectBody;
82  PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
83  PAGED_CODE();
84 
85  DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
86 
87  /* There must be no device objects remaining at this point */
88  ASSERT(!DriverObject->DeviceObject);
89 
90  /* Get the extension and loop them */
91  DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
92  while (DriverExtension)
93  {
94  /* Get the next one */
95  NextDriverExtension = DriverExtension->NextExtension;
97 
98  /* Move on */
99  DriverExtension = NextDriverExtension;
100  }
101 
102  /* Check if the driver image is still loaded */
103  if (DriverObject->DriverSection)
104  {
105  /* Unload it */
106  MmUnloadSystemImage(DriverObject->DriverSection);
107  }
108 
109  /* Check if it has a name */
110  if (DriverObject->DriverName.Buffer)
111  {
112  /* Free it */
113  ExFreePool(DriverObject->DriverName.Buffer);
114  }
115 
116  /* Check if it has a service key name */
117  if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
118  {
119  /* Free it */
120  ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
121  }
122 }
123 
124 NTSTATUS
126  _In_ HANDLE ServiceHandle,
127  _Out_ PUNICODE_STRING DriverName,
129 {
130  UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
133 
134  PAGED_CODE();
135 
136  // 1. Check the "ObjectName" field in the driver's registry key (it has the priority)
137  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
138  if (NT_SUCCESS(status))
139  {
140  // we're got the ObjectName. Use it to create the DRIVER_OBJECT
141  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
142  {
143  ExFreePool(kvInfo);
145  }
146 
147  driverName.Length = kvInfo->DataLength - sizeof(WCHAR),
148  driverName.MaximumLength = kvInfo->DataLength,
149  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
150  if (!driverName.Buffer)
151  {
152  ExFreePool(kvInfo);
154  }
155 
156  RtlMoveMemory(driverName.Buffer,
157  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
158  driverName.Length);
159  ExFreePool(kvInfo);
160  }
161 
162  // check if we need to get ServiceName as well
163  PKEY_BASIC_INFORMATION basicInfo;
164  if (!NT_SUCCESS(status) || ServiceName != NULL)
165  {
166  ULONG infoLength;
167  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
169  {
170  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
171  if (!basicInfo)
172  {
174  }
175 
176  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
177  if (!NT_SUCCESS(status))
178  {
179  ExFreePoolWithTag(basicInfo, TAG_IO);
180  return status;
181  }
182 
183  serviceName.Length = basicInfo->NameLength;
184  serviceName.MaximumLength = basicInfo->NameLength;
185  serviceName.Buffer = basicInfo->Name;
186  }
187  else
188  {
190  }
191  }
192 
193  // 2. there is no "ObjectName" - construct it ourselves. Depending on a driver type,
194  // it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>"
195  if (driverName.Buffer == NULL)
196  {
197  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
198  if (!NT_SUCCESS(status))
199  {
200  ExFreePoolWithTag(basicInfo, TAG_IO);
201  return status;
202  }
203  if (kvInfo->Type != REG_DWORD)
204  {
205  ExFreePool(kvInfo);
206  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
208  }
209 
210  UINT32 driverType;
211  RtlMoveMemory(&driverType, (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), sizeof(UINT32));
212  ExFreePool(kvInfo);
213 
214  driverName.Length = 0;
215  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
216  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME) + serviceName.Length;
217  else
218  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME) + serviceName.Length;
219  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
220  if (!driverName.Buffer)
221  {
222  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
224  }
225 
226  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
228  else
230 
232  }
233 
234  if (ServiceName)
235  {
237  if (!buf)
238  {
239  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
240  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
242  }
243  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
244  ServiceName->MaximumLength = serviceName.Length;
245  ServiceName->Length = serviceName.Length;
246  ServiceName->Buffer = buf;
247  }
248  ExFreePoolWithTag(basicInfo, TAG_IO); // container for ServiceName
249 
250  *DriverName = driverName;
251 
252  return STATUS_SUCCESS;
253 }
254 
255 /*
256  * RETURNS
257  * TRUE if String2 contains String1 as a suffix.
258  */
259 BOOLEAN
260 NTAPI
262  IN PCUNICODE_STRING String1,
264 {
265  PWCHAR pc1;
266  PWCHAR pc2;
267  ULONG Length;
268 
269  if (String2->Length < String1->Length)
270  return FALSE;
271 
272  Length = String1->Length / 2;
273  pc1 = String1->Buffer;
274  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
275 
276  if (pc1 && pc2)
277  {
278  while (Length--)
279  {
280  if( *pc1++ != *pc2++ )
281  return FALSE;
282  }
283  return TRUE;
284  }
285  return FALSE;
286 }
287 
288 /*
289  * IopDisplayLoadingMessage
290  *
291  * Display 'Loading XXX...' message.
292  */
293 VOID
294 FASTCALL
296 {
297  CHAR TextBuffer[256];
298  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
299 
300  if (ExpInTextModeSetup) return;
301  if (!KeLoaderBlock) return;
303  snprintf(TextBuffer, sizeof(TextBuffer),
304  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
307  ServiceName,
308  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
310 }
311 
312 /*
313  * IopNormalizeImagePath
314  *
315  * Normalize an image path to contain complete path.
316  *
317  * Parameters
318  * ImagePath
319  * The input path and on exit the result path. ImagePath.Buffer
320  * must be allocated by ExAllocatePool on input. Caller is responsible
321  * for freeing the buffer when it's no longer needed.
322  *
323  * ServiceName
324  * Name of the service that ImagePath belongs to.
325  *
326  * Return Value
327  * Status
328  *
329  * Remarks
330  * The input image path isn't freed on error.
331  */
332 NTSTATUS
333 FASTCALL
335  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
336  PUNICODE_STRING ImagePath,
338 {
339  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
340  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
341  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
342  UNICODE_STRING InputImagePath;
343 
344  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
345 
346  InputImagePath = *ImagePath;
347  if (InputImagePath.Length == 0)
348  {
349  ImagePath->Length = 0;
350  ImagePath->MaximumLength = DriversPathString.Length +
351  ServiceName->Length +
352  DotSysString.Length +
353  sizeof(UNICODE_NULL);
354  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
355  ImagePath->MaximumLength,
356  TAG_IO);
357  if (ImagePath->Buffer == NULL)
358  return STATUS_NO_MEMORY;
359 
360  RtlCopyUnicodeString(ImagePath, &DriversPathString);
362  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
363  }
364  else if (InputImagePath.Buffer[0] != L'\\')
365  {
366  ImagePath->Length = 0;
367  ImagePath->MaximumLength = SystemRootString.Length +
368  InputImagePath.Length +
369  sizeof(UNICODE_NULL);
370  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
371  ImagePath->MaximumLength,
372  TAG_IO);
373  if (ImagePath->Buffer == NULL)
374  return STATUS_NO_MEMORY;
375 
376  RtlCopyUnicodeString(ImagePath, &SystemRootString);
377  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
378 
379  /* Free caller's string */
380  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
381  }
382 
383  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
384 
385  return STATUS_SUCCESS;
386 }
387 
407 NTSTATUS
409  _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
410  _In_ HANDLE ServiceHandle,
411  _Out_ PDRIVER_OBJECT *OutDriverObject,
412  _Out_ NTSTATUS *DriverEntryStatus)
413 {
416 
417  PAGED_CODE();
418 
419  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
420  if (!NT_SUCCESS(Status))
421  {
422  MmUnloadSystemImage(ModuleObject);
423  return Status;
424  }
425 
426  DPRINT("Driver name: '%wZ'\n", &DriverName);
427 
428  // obtain the registry path for the DriverInit routine
429  PKEY_NAME_INFORMATION nameInfo;
430  ULONG infoLength;
431  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
433  {
434  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
435  if (nameInfo)
436  {
437  Status = ZwQueryKey(ServiceHandle,
439  nameInfo,
440  infoLength,
441  &infoLength);
442  if (NT_SUCCESS(Status))
443  {
444  RegistryPath.Length = nameInfo->NameLength;
445  RegistryPath.MaximumLength = nameInfo->NameLength;
446  RegistryPath.Buffer = nameInfo->Name;
447  }
448  else
449  {
450  ExFreePoolWithTag(nameInfo, TAG_IO);
451  }
452  }
453  else
454  {
456  }
457  }
458  else
459  {
461  }
462 
463  if (!NT_SUCCESS(Status))
464  {
466  RtlFreeUnicodeString(&DriverName);
467  MmUnloadSystemImage(ModuleObject);
468  return Status;
469  }
470 
471  // create the driver object
472  UINT32 ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
473  OBJECT_ATTRIBUTES objAttrs;
474  PDRIVER_OBJECT driverObject;
475  InitializeObjectAttributes(&objAttrs,
476  &DriverName,
478  NULL,
479  NULL);
480 
483  &objAttrs,
484  KernelMode,
485  NULL,
486  ObjectSize,
487  0,
488  0,
489  (PVOID*)&driverObject);
490  if (!NT_SUCCESS(Status))
491  {
492  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
494  RtlFreeUnicodeString(&DriverName);
495  MmUnloadSystemImage(ModuleObject);
496  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
497  return Status;
498  }
499 
500  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
501 
502  RtlZeroMemory(driverObject, ObjectSize);
503  driverObject->Type = IO_TYPE_DRIVER;
504  driverObject->Size = sizeof(DRIVER_OBJECT);
505  driverObject->Flags = DRVO_LEGACY_DRIVER; // TODO: check the WDM_DRIVER flag on the module
506  driverObject->DriverSection = ModuleObject;
507  driverObject->DriverStart = ModuleObject->DllBase;
508  driverObject->DriverSize = ModuleObject->SizeOfImage;
509  driverObject->DriverInit = ModuleObject->EntryPoint;
510  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
511  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
512  driverObject->DriverExtension->DriverObject = driverObject;
513 
514  /* Loop all Major Functions */
515  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
516  {
517  /* Invalidate each function */
518  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
519  }
520 
521  /* Add the Object and get its handle */
522  HANDLE hDriver;
523  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
524  if (!NT_SUCCESS(Status))
525  {
526  ExFreePoolWithTag(nameInfo, TAG_IO);
528  RtlFreeUnicodeString(&DriverName);
529  return Status;
530  }
531 
532  /* Now reference it */
534  0,
536  KernelMode,
537  (PVOID*)&driverObject,
538  NULL);
539 
540  /* Close the extra handle */
541  ZwClose(hDriver);
542 
543  if (!NT_SUCCESS(Status))
544  {
545  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
547  RtlFreeUnicodeString(&DriverName);
548  return Status;
549  }
550 
551  /* Set up the service key name buffer */
552  UNICODE_STRING serviceKeyName;
553  serviceKeyName.Length = 0;
554  // put a NULL character at the end for Windows compatibility
555  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
556  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
557  serviceKeyName.MaximumLength,
558  TAG_IO);
559  if (!serviceKeyName.Buffer)
560  {
561  ObMakeTemporaryObject(driverObject);
562  ObDereferenceObject(driverObject);
563  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
565  RtlFreeUnicodeString(&DriverName);
567  }
568 
569  /* Copy the name and set it in the driver extension */
570  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
572  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
573 
574  /* Make a copy of the driver name to store in the driver object */
575  UNICODE_STRING driverNamePaged;
576  driverNamePaged.Length = 0;
577  // put a NULL character at the end for Windows compatibility
578  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
579  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
580  driverNamePaged.MaximumLength,
581  TAG_IO);
582  if (!driverNamePaged.Buffer)
583  {
584  ObMakeTemporaryObject(driverObject);
585  ObDereferenceObject(driverObject);
586  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
587  RtlFreeUnicodeString(&DriverName);
589  }
590 
591  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
592  driverObject->DriverName = driverNamePaged;
593 
594  /* Finally, call its init function */
595  Status = driverObject->DriverInit(driverObject, &RegistryPath);
596  *DriverEntryStatus = Status;
597  if (!NT_SUCCESS(Status))
598  {
599  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
600  // return a special status value in case of failure
602  }
603 
604  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
605  * Other parts of the I/O manager depend on this behavior */
606  if (!driverObject->DeviceObject)
607  {
608  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
609  }
610 
611  // Windows does this fixup - keep it for compatibility
612  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
613  {
614  /*
615  * Make sure the driver didn't set any dispatch entry point to NULL!
616  * Doing so is illegal; drivers shouldn't touch entry points they
617  * do not implement.
618  */
619 
620  /* Check if it did so anyway */
621  if (!driverObject->MajorFunction[i])
622  {
623  /* Print a warning in the debug log */
624  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
625  &driverObject->DriverName, i);
626 
627  /* Fix it up */
628  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
629  }
630  }
631 
632  // TODO: for legacy drivers, unload the driver if it didn't create any DO
633 
634  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
635  RtlFreeUnicodeString(&DriverName);
636 
637  if (!NT_SUCCESS(Status))
638  {
639  // if the driver entry has been failed, clear the object
640  ObMakeTemporaryObject(driverObject);
641  ObDereferenceObject(driverObject);
642  return Status;
643  }
644 
645  *OutDriverObject = driverObject;
646 
647  MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)driverObject->DriverSection);
648 
649  /* Set the driver as initialized */
650  IopReadyDeviceObjects(driverObject);
651 
653 
654  return STATUS_SUCCESS;
655 }
656 
657 NTSTATUS
658 NTAPI
660  IN PUNICODE_STRING ImageFileDirectory,
661  IN PUNICODE_STRING NamePrefix OPTIONAL,
662  OUT PCHAR *MissingApi,
663  OUT PWCHAR *MissingDriver,
664  OUT PLOAD_IMPORTS *LoadImports);
665 
666 //
667 // Used for images already loaded (boot drivers)
668 //
669 CODE_SEG("INIT")
670 NTSTATUS
671 NTAPI
674  PLDR_DATA_TABLE_ENTRY *ModuleObject)
675 {
677  UNICODE_STRING BaseName, BaseDirectory;
678  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
679  PCHAR MissingApiName, Buffer;
680  PWCHAR MissingDriverName;
681  PVOID DriverBase = LdrEntry->DllBase;
682 
683  /* Allocate a buffer we'll use for names */
686  TAG_LDR_WSTR);
687  if (!Buffer)
688  {
689  /* Fail */
691  }
692 
693  /* Check for a separator */
694  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
695  {
696  PWCHAR p;
697  ULONG BaseLength;
698 
699  /* Loop the path until we get to the base name */
700  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
701  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
702 
703  /* Get the length */
704  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
705  BaseLength *= sizeof(WCHAR);
706 
707  /* Setup the string */
708  BaseName.Length = (USHORT)BaseLength;
709  BaseName.Buffer = p;
710  }
711  else
712  {
713  /* Otherwise, we already have a base name */
714  BaseName.Length = FileName->Length;
715  BaseName.Buffer = FileName->Buffer;
716  }
717 
718  /* Setup the maximum length */
719  BaseName.MaximumLength = BaseName.Length;
720 
721  /* Now compute the base directory */
722  BaseDirectory = *FileName;
723  BaseDirectory.Length -= BaseName.Length;
724  BaseDirectory.MaximumLength = BaseDirectory.Length;
725 
726  /* Resolve imports */
727  MissingApiName = Buffer;
728  Status = MiResolveImageReferences(DriverBase,
729  &BaseDirectory,
730  NULL,
731  &MissingApiName,
732  &MissingDriverName,
733  &LoadedImports);
734 
735  /* Free the temporary buffer */
737 
738  /* Check the result of the imports resolution */
739  if (!NT_SUCCESS(Status)) return Status;
740 
741  /* Return */
742  *ModuleObject = LdrEntry;
743  return STATUS_SUCCESS;
744 }
745 
748 
749 /*
750  * IopInitializeBuiltinDriver
751  *
752  * Initialize a driver that is already loaded in memory.
753  */
754 CODE_SEG("INIT")
755 static
756 BOOLEAN
758 {
761  PWCHAR Buffer, FileNameWithoutPath;
762  PWSTR FileExtension;
763  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
764  PLDR_DATA_TABLE_ENTRY LdrEntry;
765  PLIST_ENTRY NextEntry;
768 
769  /*
770  * Display 'Loading XXX...' message
771  */
774 
776  ModuleName->Length + sizeof(UNICODE_NULL),
777  TAG_IO);
778  if (Buffer == NULL)
779  {
780  return FALSE;
781  }
782 
784  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
785 
786  /*
787  * Generate filename without path (not needed by freeldr)
788  */
789  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
790  if (FileNameWithoutPath == NULL)
791  {
792  FileNameWithoutPath = Buffer;
793  }
794  else
795  {
796  FileNameWithoutPath++;
797  }
798 
799  /*
800  * Strip the file extension from ServiceName
801  */
802  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
804  if (!Success)
805  {
806  return FALSE;
807  }
808 
809  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
810  if (FileExtension != NULL)
811  {
812  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
813  FileExtension[0] = UNICODE_NULL;
814  }
815 
817 
818  // Make the registry path for the driver
819  RegistryPath.Length = 0;
820  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
822  if (RegistryPath.Buffer == NULL)
823  {
824  return FALSE;
825  }
829 
830  HANDLE serviceHandle;
831  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
833  if (!NT_SUCCESS(Status))
834  {
835  return FALSE;
836  }
837 
838  /* Lookup the new Ldr entry in PsLoadedModuleList */
839  NextEntry = PsLoadedModuleList.Flink;
840  while (NextEntry != &PsLoadedModuleList)
841  {
842  LdrEntry = CONTAINING_RECORD(NextEntry,
844  InLoadOrderLinks);
846  {
847  break;
848  }
849 
850  NextEntry = NextEntry->Flink;
851  }
852  ASSERT(NextEntry != &PsLoadedModuleList);
853 
854  /*
855  * Initialize the driver
856  */
857  NTSTATUS driverEntryStatus;
859  serviceHandle,
860  &DriverObject,
861  &driverEntryStatus);
862 
863  if (!NT_SUCCESS(Status))
864  {
865  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
866  return FALSE;
867  }
868 
869  // The driver has been loaded, now check if where are any PDOs
870  // for that driver, and queue AddDevice call for them.
871  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
872  // is populated upon a new device arrival based on a (critical) device database
873 
874  // Legacy drivers may add devices inside DriverEntry.
875  // We're lazy and always assume that they are doing so
876  BOOLEAN deviceAdded = (_Bool)(DriverObject->Flags & DRVO_LEGACY_DRIVER);
877 
878  HANDLE enumServiceHandle;
879  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
880 
881  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
882  ZwClose(serviceHandle);
883 
884  if (NT_SUCCESS(Status))
885  {
886  UINT32 instanceCount = 0;
888  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
889  if (!NT_SUCCESS(Status))
890  {
891  goto Cleanup;
892  }
893  if (kvInfo->Type != REG_DWORD)
894  {
895  ExFreePool(kvInfo);
896  goto Cleanup;
897  }
898 
899  RtlMoveMemory(&instanceCount,
900  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
901  sizeof(UINT32));
902  ExFreePool(kvInfo);
903 
904  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
905 
906  for (UINT32 i = 0; i < instanceCount; i++)
907  {
908  WCHAR num[11];
909  UNICODE_STRING instancePath;
910  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
911 
912  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
913  if (!NT_SUCCESS(Status))
914  {
915  continue;
916  }
917  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
918  {
919  ExFreePool(kvInfo);
920  continue;
921  }
922 
923  instancePath.Length = kvInfo->DataLength - sizeof(WCHAR),
924  instancePath.MaximumLength = kvInfo->DataLength,
926  instancePath.MaximumLength,
927  TAG_IO);
928  if (instancePath.Buffer)
929  {
930  RtlMoveMemory(instancePath.Buffer,
931  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
932  instancePath.Length);
933 
936  ObDereferenceObject(pdo);
937  deviceAdded = TRUE;
938  }
939 
940  ExFreePool(kvInfo);
941  }
942 
943  ZwClose(enumServiceHandle);
944  }
945 Cleanup:
946  /* Remove extra reference from IopInitializeDriverModule */
948 
949  return deviceAdded;
950 }
951 
952 /*
953  * IopInitializeBootDrivers
954  *
955  * Initialize boot drivers and free memory for boot files.
956  *
957  * Parameters
958  * None
959  *
960  * Return Value
961  * None
962  */
963 CODE_SEG("INIT")
964 VOID
965 FASTCALL
967 {
968  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
969  PLDR_DATA_TABLE_ENTRY LdrEntry;
971  UNICODE_STRING DriverName;
972  ULONG i, Index;
973  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
975  PBOOT_DRIVER_LIST_ENTRY BootEntry;
976  DPRINT("IopInitializeBootDrivers()\n");
977 
978  /* Create the RAW FS built-in driver */
979  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
980 
981  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
982  if (!NT_SUCCESS(Status))
983  {
984  /* Fail */
985  return;
986  }
987 
988  /* Get highest group order index */
990  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
991 
992  /* Allocate the group table */
994  IopGroupIndex * sizeof(LIST_ENTRY),
995  TAG_IO);
996  if (IopGroupTable == NULL) ASSERT(FALSE);
997 
998  /* Initialize the group table lists */
999  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1000 
1001  /* Loop the boot modules */
1002  ListHead = &KeLoaderBlock->LoadOrderListHead;
1003  NextEntry = ListHead->Flink;
1004  while (ListHead != NextEntry)
1005  {
1006  /* Get the entry */
1007  LdrEntry = CONTAINING_RECORD(NextEntry,
1009  InLoadOrderLinks);
1010 
1011  /* Check if the DLL needs to be initialized */
1012  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1013  {
1014  /* Call its entrypoint */
1015  MmCallDllInitialize(LdrEntry, NULL);
1016  }
1017 
1018  /* Go to the next driver */
1019  NextEntry = NextEntry->Flink;
1020  }
1021 
1022  /* Loop the boot drivers */
1023  ListHead = &KeLoaderBlock->BootDriverListHead;
1024  NextEntry = ListHead->Flink;
1025  while (ListHead != NextEntry)
1026  {
1027  /* Get the entry */
1028  BootEntry = CONTAINING_RECORD(NextEntry,
1030  Link);
1031 
1032  /* Get the driver loader entry */
1033  LdrEntry = BootEntry->LdrEntry;
1034 
1035  /* Allocate our internal accounting structure */
1037  sizeof(DRIVER_INFORMATION),
1038  TAG_IO);
1039  if (DriverInfo)
1040  {
1041  /* Zero it and initialize it */
1044  DriverInfo->DataTableEntry = BootEntry;
1045 
1046  /* Open the registry key */
1048  NULL,
1049  &BootEntry->RegistryPath,
1050  KEY_READ);
1051  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1052 #if 0
1053  if (NT_SUCCESS(Status))
1054 #else // Hack still needed...
1055  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1056  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1057 #endif
1058  {
1059  /* Save the handle */
1061 
1062  /* Get the group oder index */
1064 
1065  /* Get the tag position */
1067 
1068  /* Insert it into the list, at the right place */
1070  NextEntry2 = IopGroupTable[Index].Flink;
1071  while (NextEntry2 != &IopGroupTable[Index])
1072  {
1073  /* Get the driver info */
1074  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1076  Link);
1077 
1078  /* Check if we found the right tag position */
1079  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1080  {
1081  /* We're done */
1082  break;
1083  }
1084 
1085  /* Next entry */
1086  NextEntry2 = NextEntry2->Flink;
1087  }
1088 
1089  /* Insert us right before the next entry */
1090  NextEntry2 = NextEntry2->Blink;
1091  InsertHeadList(NextEntry2, &DriverInfo->Link);
1092  }
1093  }
1094 
1095  /* Go to the next driver */
1096  NextEntry = NextEntry->Flink;
1097  }
1098 
1099  /* Loop each group index */
1100  for (i = 0; i < IopGroupIndex; i++)
1101  {
1102  /* Loop each group table */
1103  NextEntry = IopGroupTable[i].Flink;
1104  while (NextEntry != &IopGroupTable[i])
1105  {
1106  /* Get the entry */
1107  DriverInfo = CONTAINING_RECORD(NextEntry,
1109  Link);
1110 
1111  /* Get the driver loader entry */
1112  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1113 
1114  /* Initialize it */
1115  if (IopInitializeBuiltinDriver(LdrEntry))
1116  {
1117  // it does not make sense to enumerate the tree if there are no new devices added
1120  NULL,
1121  NULL);
1122  }
1123 
1124  /* Next entry */
1125  NextEntry = NextEntry->Flink;
1126  }
1127  }
1128 
1129  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1130  * when some devices are not being initialized with their drivers. This flag is used to delay
1131  * all actions with devices (except PnP root device) until boot drivers are loaded.
1132  * See PiQueueDeviceAction function
1133  */
1135 
1136  DbgPrint("BOOT DRIVERS LOADED\n");
1137 
1140  NULL,
1141  NULL);
1142 }
1143 
1144 CODE_SEG("INIT")
1145 VOID
1146 FASTCALL
1148 {
1149  PUNICODE_STRING *DriverList, *SavedList;
1150 
1152 
1153  /* No system drivers on the boot cd */
1154  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1155 
1156  /* Get the driver list */
1157  SavedList = DriverList = CmGetSystemDriverList();
1158  ASSERT(DriverList);
1159 
1160  /* Loop it */
1161  while (*DriverList)
1162  {
1163  /* Load the driver */
1164  ZwLoadDriver(*DriverList);
1165 
1166  /* Free the entry */
1167  RtlFreeUnicodeString(*DriverList);
1168  ExFreePool(*DriverList);
1169 
1170  /* Next entry */
1172  DriverList++;
1173  }
1174 
1175  /* Free the list */
1176  ExFreePool(SavedList);
1177 
1180  NULL,
1181  NULL);
1182 }
1183 
1184 /*
1185  * IopUnloadDriver
1186  *
1187  * Unloads a device driver.
1188  *
1189  * Parameters
1190  * DriverServiceName
1191  * Name of the service to unload (registry key).
1192  *
1193  * UnloadPnpDrivers
1194  * Whether to unload Plug & Plug or only legacy drivers. If this
1195  * parameter is set to FALSE, the routine will unload only legacy
1196  * drivers.
1197  *
1198  * Return Value
1199  * Status
1200  *
1201  * To do
1202  * Guard the whole function by SEH.
1203  */
1204 
1206 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1207 {
1208  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1210  UNICODE_STRING ImagePath;
1215  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1216  NTSTATUS Status;
1217  USHORT LastBackslash;
1218  BOOLEAN SafeToUnload = TRUE;
1220  UNICODE_STRING CapturedServiceName;
1221 
1222  PAGED_CODE();
1223 
1225 
1226  /* Need the appropriate priviliege */
1228  {
1229  DPRINT1("No unload privilege!\n");
1231  }
1232 
1233  /* Capture the service name */
1234  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1235  PreviousMode,
1236  DriverServiceName);
1237  if (!NT_SUCCESS(Status))
1238  {
1239  return Status;
1240  }
1241 
1242  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1243 
1244  /* We need a service name */
1245  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1246  {
1247  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1248  return STATUS_INVALID_PARAMETER;
1249  }
1250 
1251  /*
1252  * Get the service name from the registry key name
1253  */
1255  &CapturedServiceName,
1256  &Backslash,
1257  &LastBackslash);
1258  if (NT_SUCCESS(Status))
1259  {
1260  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1261  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1262  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1263  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1264  }
1265  else
1266  {
1267  ServiceName = CapturedServiceName;
1268  }
1269 
1270  /*
1271  * Construct the driver object name
1272  */
1273  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1274  ServiceName.Length,
1275  &ObjectName.MaximumLength);
1276  if (!NT_SUCCESS(Status))
1277  {
1278  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1279  return Status;
1280  }
1281  ObjectName.Length = 0;
1283  ObjectName.MaximumLength,
1284  TAG_IO);
1285  if (!ObjectName.Buffer)
1286  {
1287  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1289  }
1292 
1293  /*
1294  * Find the driver object
1295  */
1297  0,
1298  0,
1299  0,
1301  KernelMode,
1302  0,
1303  (PVOID*)&DriverObject);
1304 
1305  if (!NT_SUCCESS(Status))
1306  {
1307  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1309  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1310  return Status;
1311  }
1312 
1313  /* Free the buffer for driver object name */
1315 
1316  /* Check that driver is not already unloading */
1317  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1318  {
1319  DPRINT1("Driver deletion pending\n");
1321  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1322  return STATUS_DELETE_PENDING;
1323  }
1324 
1325  /*
1326  * Get path of service...
1327  */
1329 
1330  RtlInitUnicodeString(&ImagePath, NULL);
1331 
1332  QueryTable[0].Name = L"ImagePath";
1334  QueryTable[0].EntryContext = &ImagePath;
1335 
1337  CapturedServiceName.Buffer,
1338  QueryTable,
1339  NULL,
1340  NULL);
1341 
1342  /* We no longer need service name */
1343  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1344 
1345  if (!NT_SUCCESS(Status))
1346  {
1347  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1349  return Status;
1350  }
1351 
1352  /*
1353  * Normalize the image path for all later processing.
1354  */
1355  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1356 
1357  if (!NT_SUCCESS(Status))
1358  {
1359  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1361  return Status;
1362  }
1363 
1364  /* Free the service path */
1365  ExFreePool(ImagePath.Buffer);
1366 
1367  /*
1368  * Unload the module and release the references to the device object
1369  */
1370 
1371  /* Call the load/unload routine, depending on current process */
1372  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1373  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1374  {
1375  /* Loop through each device object of the driver
1376  and set DOE_UNLOAD_PENDING flag */
1377  DeviceObject = DriverObject->DeviceObject;
1378  while (DeviceObject)
1379  {
1380  /* Set the unload pending flag for the device */
1381  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1382  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1383 
1384  /* Make sure there are no attached devices or no reference counts */
1385  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1386  {
1387  /* Not safe to unload */
1388  DPRINT1("Drivers device object is referenced or has attached devices\n");
1389 
1390  SafeToUnload = FALSE;
1391  }
1392 
1393  DeviceObject = DeviceObject->NextDevice;
1394  }
1395 
1396  /* If not safe to unload, then return success */
1397  if (!SafeToUnload)
1398  {
1400  return STATUS_SUCCESS;
1401  }
1402 
1403  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1404 
1405  /* Set the unload invoked flag and call the unload routine */
1409 
1410  /* Mark the driver object temporary, so it could be deleted later */
1412 
1413  /* Dereference it 2 times */
1416 
1417  return Status;
1418  }
1419  else
1420  {
1421  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1422 
1423  /* Dereference one time (refd inside this function) */
1425 
1426  /* Return unloading failure */
1428  }
1429 }
1430 
1431 VOID
1432 NTAPI
1434 {
1435  PDRIVER_REINIT_ITEM ReinitItem;
1437 
1438  /* Get the first entry and start looping */
1441  while (Entry)
1442  {
1443  /* Get the item */
1444  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1445 
1446  /* Increment reinitialization counter */
1447  ReinitItem->DriverObject->DriverExtension->Count++;
1448 
1449  /* Remove the device object flag */
1450  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1451 
1452  /* Call the routine */
1453  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1454  ReinitItem->Context,
1455  ReinitItem->DriverObject->
1456  DriverExtension->Count);
1457 
1458  /* Free the entry */
1459  ExFreePool(Entry);
1460 
1461  /* Move to the next one */
1464  }
1465 }
1466 
1467 VOID
1468 NTAPI
1470 {
1471  PDRIVER_REINIT_ITEM ReinitItem;
1473 
1474  /* Get the first entry and start looping */
1477  while (Entry)
1478  {
1479  /* Get the item */
1480  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1481 
1482  /* Increment reinitialization counter */
1483  ReinitItem->DriverObject->DriverExtension->Count++;
1484 
1485  /* Remove the device object flag */
1487 
1488  /* Call the routine */
1489  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1490  ReinitItem->Context,
1491  ReinitItem->DriverObject->
1492  DriverExtension->Count);
1493 
1494  /* Free the entry */
1495  ExFreePool(Entry);
1496 
1497  /* Move to the next one */
1500  }
1501 
1502  /* Wait for all device actions being finished*/
1504 }
1505 
1506 /* PUBLIC FUNCTIONS ***********************************************************/
1507 
1508 /*
1509  * @implemented
1510  */
1511 NTSTATUS
1512 NTAPI
1514  _In_opt_ PUNICODE_STRING DriverName,
1515  _In_ PDRIVER_INITIALIZE InitializationFunction)
1516 {
1517  WCHAR NameBuffer[100];
1518  USHORT NameLength;
1519  UNICODE_STRING LocalDriverName;
1520  NTSTATUS Status;
1522  ULONG ObjectSize;
1524  UNICODE_STRING ServiceKeyName;
1525  HANDLE hDriver;
1526  ULONG i, RetryCount = 0;
1527 
1528 try_again:
1529  /* First, create a unique name for the driver if we don't have one */
1530  if (!DriverName)
1531  {
1532  /* Create a random name and set up the string */
1533  NameLength = (USHORT)swprintf(NameBuffer,
1534  DRIVER_ROOT_NAME L"%08u",
1536  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1537  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1538  LocalDriverName.Buffer = NameBuffer;
1539  }
1540  else
1541  {
1542  /* So we can avoid another code path, use a local var */
1543  LocalDriverName = *DriverName;
1544  }
1545 
1546  /* Initialize the Attributes */
1547  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1549  &LocalDriverName,
1551  NULL,
1552  NULL);
1553 
1554  /* Create the Object */
1558  KernelMode,
1559  NULL,
1560  ObjectSize,
1561  0,
1562  0,
1563  (PVOID*)&DriverObject);
1564  if (!NT_SUCCESS(Status)) return Status;
1565 
1566  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1567 
1568  /* Set up the Object */
1569  RtlZeroMemory(DriverObject, ObjectSize);
1570  DriverObject->Type = IO_TYPE_DRIVER;
1571  DriverObject->Size = sizeof(DRIVER_OBJECT);
1573  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1574  DriverObject->DriverExtension->DriverObject = DriverObject;
1575  DriverObject->DriverInit = InitializationFunction;
1576  /* Loop all Major Functions */
1577  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1578  {
1579  /* Invalidate each function */
1580  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1581  }
1582 
1583  /* Set up the service key name buffer */
1584  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1585  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1586  if (!ServiceKeyName.Buffer)
1587  {
1588  /* Fail */
1592  }
1593 
1594  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1595  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1596  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1597  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1598 
1599  /* Make a copy of the driver name to store in the driver object */
1600  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1601  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1602  DriverObject->DriverName.MaximumLength,
1603  TAG_IO);
1604  if (!DriverObject->DriverName.Buffer)
1605  {
1606  /* Fail */
1610  }
1611 
1612  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1613 
1614  /* Add the Object and get its handle */
1616  NULL,
1618  0,
1619  NULL,
1620  &hDriver);
1621 
1622  /* Eliminate small possibility when this function is called more than
1623  once in a row, and KeTickCount doesn't get enough time to change */
1624  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1625  {
1626  RetryCount++;
1627  goto try_again;
1628  }
1629 
1630  if (!NT_SUCCESS(Status)) return Status;
1631 
1632  /* Now reference it */
1634  0,
1636  KernelMode,
1637  (PVOID*)&DriverObject,
1638  NULL);
1639 
1640  /* Close the extra handle */
1641  ZwClose(hDriver);
1642 
1643  if (!NT_SUCCESS(Status))
1644  {
1645  /* Fail */
1648  return Status;
1649  }
1650 
1651  /* Finally, call its init function */
1652  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1653  Status = (*InitializationFunction)(DriverObject, NULL);
1654  if (!NT_SUCCESS(Status))
1655  {
1656  /* If it didn't work, then kill the object */
1657  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1660  return Status;
1661  }
1662 
1663  // Windows does this fixup - keep it for compatibility
1664  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1665  {
1666  /*
1667  * Make sure the driver didn't set any dispatch entry point to NULL!
1668  * Doing so is illegal; drivers shouldn't touch entry points they
1669  * do not implement.
1670  */
1671 
1672  /* Check if it did so anyway */
1673  if (!DriverObject->MajorFunction[i])
1674  {
1675  /* Print a warning in the debug log */
1676  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1677  &DriverObject->DriverName, i);
1678 
1679  /* Fix it up */
1680  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1681  }
1682  }
1683 
1684  /* Return the Status */
1685  return Status;
1686 }
1687 
1688 /*
1689  * @implemented
1690  */
1691 VOID
1692 NTAPI
1694 {
1695  /* Simply dereference the Object */
1697 }
1698 
1699 /*
1700  * @implemented
1701  */
1702 VOID
1703 NTAPI
1705  IN PDRIVER_REINITIALIZE ReinitRoutine,
1706  IN PVOID Context)
1707 {
1708  PDRIVER_REINIT_ITEM ReinitItem;
1709 
1710  /* Allocate the entry */
1711  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1712  sizeof(DRIVER_REINIT_ITEM),
1713  TAG_REINIT);
1714  if (!ReinitItem) return;
1715 
1716  /* Fill it out */
1717  ReinitItem->DriverObject = DriverObject;
1718  ReinitItem->ReinitRoutine = ReinitRoutine;
1719  ReinitItem->Context = Context;
1720 
1721  /* Set the Driver Object flag and insert the entry into the list */
1724  &ReinitItem->ItemEntry,
1726 }
1727 
1728 /*
1729  * @implemented
1730  */
1731 VOID
1732 NTAPI
1734  IN PDRIVER_REINITIALIZE ReinitRoutine,
1735  IN PVOID Context)
1736 {
1737  PDRIVER_REINIT_ITEM ReinitItem;
1738 
1739  /* Allocate the entry */
1740  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1741  sizeof(DRIVER_REINIT_ITEM),
1742  TAG_REINIT);
1743  if (!ReinitItem) return;
1744 
1745  /* Fill it out */
1746  ReinitItem->DriverObject = DriverObject;
1747  ReinitItem->ReinitRoutine = ReinitRoutine;
1748  ReinitItem->Context = Context;
1749 
1750  /* Set the Driver Object flag and insert the entry into the list */
1753  &ReinitItem->ItemEntry,
1755 }
1756 
1757 /*
1758  * @implemented
1759  */
1760 NTSTATUS
1761 NTAPI
1764  IN ULONG DriverObjectExtensionSize,
1765  OUT PVOID *DriverObjectExtension)
1766 {
1767  KIRQL OldIrql;
1768  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1769  BOOLEAN Inserted = FALSE;
1770 
1771  /* Assume failure */
1772  *DriverObjectExtension = NULL;
1773 
1774  /* Allocate the extension */
1775  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1776  sizeof(IO_CLIENT_EXTENSION) +
1777  DriverObjectExtensionSize,
1779  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1780 
1781  /* Clear the extension for teh caller */
1782  RtlZeroMemory(NewDriverExtension,
1783  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1784 
1785  /* Acqure lock */
1787 
1788  /* Fill out the extension */
1790 
1791  /* Loop the current extensions */
1792  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1793  ClientDriverExtension;
1794  while (DriverExtensions)
1795  {
1796  /* Check if the identifier matches */
1797  if (DriverExtensions->ClientIdentificationAddress ==
1799  {
1800  /* We have a collision, break out */
1801  break;
1802  }
1803 
1804  /* Go to the next one */
1805  DriverExtensions = DriverExtensions->NextExtension;
1806  }
1807 
1808  /* Check if we didn't collide */
1809  if (!DriverExtensions)
1810  {
1811  /* Link this one in */
1812  NewDriverExtension->NextExtension =
1813  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1814  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1815  NewDriverExtension;
1816  Inserted = TRUE;
1817  }
1818 
1819  /* Release the lock */
1821 
1822  /* Check if insertion failed */
1823  if (!Inserted)
1824  {
1825  /* Free the entry and fail */
1826  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1828  }
1829 
1830  /* Otherwise, return the pointer */
1831  *DriverObjectExtension = NewDriverExtension + 1;
1832  return STATUS_SUCCESS;
1833 }
1834 
1835 /*
1836  * @implemented
1837  */
1838 PVOID
1839 NTAPI
1842 {
1843  KIRQL OldIrql;
1844  PIO_CLIENT_EXTENSION DriverExtensions;
1845 
1846  /* Acquire lock */
1848 
1849  /* Loop the list until we find the right one */
1850  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1851  while (DriverExtensions)
1852  {
1853  /* Check for a match */
1854  if (DriverExtensions->ClientIdentificationAddress ==
1856  {
1857  /* Break out */
1858  break;
1859  }
1860 
1861  /* Keep looping */
1862  DriverExtensions = DriverExtensions->NextExtension;
1863  }
1864 
1865  /* Release lock */
1867 
1868  /* Return nothing or the extension */
1869  if (!DriverExtensions) return NULL;
1870  return DriverExtensions + 1;
1871 }
1872 
1873 NTSTATUS
1875  _In_ HANDLE ServiceHandle,
1877 {
1878  UNICODE_STRING ImagePath;
1879  NTSTATUS Status;
1880  PLDR_DATA_TABLE_ENTRY ModuleObject;
1882 
1884  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1885  if (NT_SUCCESS(Status))
1886  {
1887  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1888  {
1889  ExFreePool(kvInfo);
1891  }
1892 
1893  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL),
1894  ImagePath.MaximumLength = kvInfo->DataLength,
1896  if (!ImagePath.Buffer)
1897  {
1898  ExFreePool(kvInfo);
1900  }
1901 
1902  RtlMoveMemory(ImagePath.Buffer,
1903  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1904  ImagePath.Length);
1905  ExFreePool(kvInfo);
1906  }
1907  else
1908  {
1909  return Status;
1910  }
1911 
1912  /*
1913  * Normalize the image path for all later processing.
1914  */
1915  Status = IopNormalizeImagePath(&ImagePath, NULL);
1916  if (!NT_SUCCESS(Status))
1917  {
1918  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1919  return Status;
1920  }
1921 
1922  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1923 
1926 
1927  /*
1928  * Load the driver module
1929  */
1930  DPRINT("Loading module from %wZ\n", &ImagePath);
1931  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1932  RtlFreeUnicodeString(&ImagePath);
1933 
1934  if (!NT_SUCCESS(Status))
1935  {
1936  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1939  return Status;
1940  }
1941 
1942  // Display the loading message
1943  ULONG infoLength;
1944  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1946  {
1948  if (servName)
1949  {
1950  Status = ZwQueryKey(ServiceHandle,
1952  servName,
1953  infoLength,
1954  &infoLength);
1955  if (NT_SUCCESS(Status))
1956  {
1958  .Length = servName->NameLength,
1959  .MaximumLength = servName->NameLength,
1960  .Buffer = servName->Name
1961  };
1962 
1964  }
1965  ExFreePoolWithTag(servName, TAG_IO);
1966  }
1967  }
1968 
1969  NTSTATUS driverEntryStatus;
1970  Status = IopInitializeDriverModule(ModuleObject,
1971  ServiceHandle,
1972  DriverObject,
1973  &driverEntryStatus);
1974  if (!NT_SUCCESS(Status))
1975  {
1976  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
1977  }
1978 
1981 
1982  return Status;
1983 }
1984 
1985 static
1986 VOID
1987 NTAPI
1990 {
1991  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1992 
1994 
1995  if (LoadParams->DriverObject)
1996  {
1997  // unload request
1998  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
1999  LoadParams->Status = STATUS_SUCCESS;
2000  }
2001  else
2002  {
2003  // load request
2004  HANDLE serviceHandle;
2005  NTSTATUS status;
2006  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2007  if (!NT_SUCCESS(status))
2008  {
2009  LoadParams->Status = status;
2010  }
2011  else
2012  {
2013  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2014  ZwClose(serviceHandle);
2015  }
2016  }
2017 
2018  if (LoadParams->SetEvent)
2019  {
2020  KeSetEvent(&LoadParams->Event, 0, FALSE);
2021  }
2022 }
2023 
2033 NTSTATUS
2037 {
2038  LOAD_UNLOAD_PARAMS LoadParams;
2039 
2040  /* Prepare parameters block */
2041  LoadParams.RegistryPath = RegistryPath;
2042  LoadParams.DriverObject = *DriverObject;
2043 
2045  {
2046  LoadParams.SetEvent = TRUE;
2048 
2049  /* Initialize and queue a work item */
2050  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2052 
2053  /* And wait till it completes */
2055  }
2056  else
2057  {
2058  /* If we're already in a system process, call it right here */
2059  LoadParams.SetEvent = FALSE;
2060  IopLoadUnloadDriverWorker(&LoadParams);
2061  }
2062 
2063  return LoadParams.Status;
2064 }
2065 
2066 /*
2067  * NtLoadDriver
2068  *
2069  * Loads a device driver.
2070  *
2071  * Parameters
2072  * DriverServiceName
2073  * Name of the service to load (registry key).
2074  *
2075  * Return Value
2076  * Status
2077  *
2078  * Status
2079  * implemented
2080  */
2082 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2083 {
2084  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2087  NTSTATUS Status;
2088 
2089  PAGED_CODE();
2090 
2092 
2093  /* Need the appropriate priviliege */
2095  {
2096  DPRINT1("No load privilege!\n");
2098  }
2099 
2100  /* Capture the service name */
2101  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2102  PreviousMode,
2103  DriverServiceName);
2104  if (!NT_SUCCESS(Status))
2105  {
2106  return Status;
2107  }
2108 
2109  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2110 
2111  /* We need a service name */
2112  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2113  {
2114  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2115  return STATUS_INVALID_PARAMETER;
2116  }
2117 
2118  /* Load driver and call its entry point */
2119  DriverObject = NULL;
2120  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2121 
2122  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2123  return Status;
2124 }
2125 
2126 /*
2127  * NtUnloadDriver
2128  *
2129  * Unloads a legacy device driver.
2130  *
2131  * Parameters
2132  * DriverServiceName
2133  * Name of the service to unload (registry key).
2134  *
2135  * Return Value
2136  * Status
2137  *
2138  * Status
2139  * implemented
2140  */
2141 
2144 {
2145  return IopUnloadDriver(DriverServiceName, FALSE);
2146 }
2147 
2148 /* EOF */
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END
Definition: rtl.h:25
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
static const unsigned char pc2[48]
Definition: des.c:68
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG LowPart
Definition: ketypes.h:917
BOOLEAN ExpInTextModeSetup
Definition: init.c:67
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2227
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
#define IN
Definition: typedefs.h:39
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1635
VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:966
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:711
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:823
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1147
PSTR ArcBootDeviceName
Definition: arc.h:503
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const unsigned char pc1[56]
Definition: des.c:54
#define TAG_IO
Definition: tag.h:69
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1776
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1762
struct _Entry Entry
Definition: kefuncs.h:627
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2616
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1988
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1433
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define DbgPrint
Definition: loader.c:25
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_RTLREGISTRY
Definition: driver.c:35
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:295
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
PVOID Context
Definition: io.h:459
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ACPI_SIZE Length
Definition: actypes.h:1044
char CHAR
Definition: xmlstorage.h:175
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define IRP_MJ_MAXIMUM_FUNCTION
NTSTATUS IopDoLoadUnloadDriver(_In_opt_ PUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Process load and unload driver operations. This is mostly for NtLoadDriver and NtUnloadDriver,...
Definition: driver.c:2034
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define STATUS_FAILED_DRIVER_ENTRY
Definition: ntstatus.h:911
WORK_QUEUE_ITEM WorkItem
Definition: driver.c:52
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define snprintf
Definition: wintirpc.h:48
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:520
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1874
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1274
uint16_t * PWCHAR
Definition: typedefs.h:56
#define swprintf
Definition: precomp.h:40
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_In_ PVOID Parameter
Definition: ldrtypes.h:241
VOID NTAPI IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
Definition: driver.c:1693
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:125
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:67
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI IopReinitializeBootDrivers(VOID)
Definition: driver.c:1469
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:956
int32_t INT
Definition: typedefs.h:58
static int Link(const char **args)
Definition: vfdcmd.c:2414
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define _In_opt_
Definition: no_sal2.h:212
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT NTAPI PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
Definition: pnpinit.c:155
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4468
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1733
uint32_t ULONG_PTR
Definition: typedefs.h:65
LIST_ENTRY ItemEntry
Definition: io.h:456
Definition: arc.h:198
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
static BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:757
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:27
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
_In_ PIRP Irp
Definition: csq.h:116
unsigned int UINT32
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:308
struct _LOAD_UNLOAD_PARAMS LOAD_UNLOAD_PARAMS
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define FILE_READ_DATA
Definition: nt_native.h:628
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
#define PsGetCurrentProcess
Definition: psfuncs.h:17
LIST_ENTRY Link
Definition: io.h:399
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:121
unsigned char BOOLEAN
NTSTATUS FASTCALL IopNormalizeImagePath(_Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName)
Definition: driver.c:334
VOID(NTAPI * PDRIVER_REINITIALIZE)(_In_ struct _DRIVER_OBJECT *DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Definition: iotypes.h:4454
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
HANDLE ServiceHandle
Definition: io.h:402
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
#define _Out_
Definition: no_sal2.h:160
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1513
PDRIVER_OBJECT DriverObject
Definition: io.h:457
Definition: bufpool.h:45
USHORT TagPosition
Definition: io.h:403
CODE_SEG("INIT")
Definition: Interface.c:1810
void * PVOID
Definition: retypes.h:9
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
__drv_aliasesMem _In_ PVOID ClientIdentificationAddress
Definition: iofuncs.h:1028
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define TAG_REINIT
Definition: tag.h:73
KEVENT PiEnumerationFinished
Definition: devaction.c:50
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2225
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
#define STATUS_ILL_FORMED_SERVICE_ENTRY
Definition: ntstatus.h:588
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
char serviceName[]
Definition: tftpd.cpp:34
#define _Out_opt_
Definition: no_sal2.h:214
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:239
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:45
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define TAG_DRIVER_EXTENSION
Definition: tag.h:42
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
PLIST_ENTRY DriverReinitTailEntry
Definition: driver.c:23
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:1000
#define ObDereferenceObject
Definition: obfuncs.h:203
GLuint GLuint num
Definition: glext.h:9618
PLIST_ENTRY IopGroupTable
Definition: driver.c:43
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:162
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
VOID NTAPI IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
Definition: device.c:34
VOID NTAPI IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1704
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define _Post_notnull_
Definition: sal.h:701
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:401
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
DRIVER_INITIALIZE * PDRIVER_INITIALIZE
Definition: iotypes.h:2235
NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2143
static const WCHAR L[]
Definition: oid.c:1250
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
NTSTATUS Status
Definition: driver.c:50
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1840
#define OBJ_PERMANENT
Definition: winternl.h:226
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1922
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
BOOLEAN SetEvent
Definition: driver.c:55
struct _DRIVER_OBJECT DRIVER_OBJECT
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
static const WCHAR Cleanup[]
Definition: register.c:80
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
PLIST_ENTRY DriverBootReinitTailEntry
Definition: driver.c:25
LIST_ENTRY LoadOrderListHead
Definition: arc.h:493
NTSTATUS PiPerformSyncDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
Perfom a device operation synchronously via PiQueueDeviceAction.
Definition: devaction.c:2675
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
#define _In_
Definition: no_sal2.h:158
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
struct _FileName FileName
Definition: fatprocs.h:893
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2931
UNICODE_STRING RegistryPath
Definition: arc.h:202
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
PUNICODE_STRING RegistryPath
Definition: driver.c:51
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:203
VOID NTAPI IopDeleteDriver(IN PVOID ObjectBody)
Definition: driver.c:79
#define _At_(t, a)
Definition: no_sal2.h:40
struct _DRIVER_EXTENSION * PDRIVER_EXTENSION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
UNICODE_STRING IopHardwareDatabaseKey
Definition: driver.c:29
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
struct _LOAD_UNLOAD_PARAMS * PLOAD_UNLOAD_PARAMS
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
_In_ const STRING * String2
Definition: rtlfuncs.h:2291
NTSTATUS IopInitializeDriverModule(_In_ PLDR_DATA_TABLE_ENTRY ModuleObject, _In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *OutDriverObject, _Out_ NTSTATUS *DriverEntryStatus)
Initialize a loaded driver.
Definition: driver.c:408
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define _When_(c, a)
Definition: no_sal2.h:38
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
ULONG Flags
Definition: ntddk_ex.h:207
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:458
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID ClientIdentificationAddress
Definition: iotypes.h:824
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1206
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define REG_DWORD
Definition: sdbapi.c:596
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:132
NTSTATUS NTAPI ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, OUT PVOID *ObjectPtr)
Definition: obref.c:409
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2082
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT IopGroupIndex
Definition: driver.c:42
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2898
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define PAGED_CODE()
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4470
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:198
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3312
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry, PUNICODE_STRING FileName, PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:672
Definition: ps.c:97
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:261