ReactOS  0.4.15-dev-2991-g632fa1c
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 priority) */
137  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
138  if (NT_SUCCESS(status))
139  {
140  /* We've got the ObjectName, use it as the driver name */
141  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
142  {
143  ExFreePool(kvInfo);
145  }
146 
147  driverName.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
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  driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
160  ExFreePool(kvInfo);
161  }
162 
163  /* Check whether we need to get ServiceName as well, either to construct
164  * the driver name (because we could not use "ObjectName"), or because
165  * it is requested by the caller. */
166  PKEY_BASIC_INFORMATION basicInfo = NULL;
167  if (!NT_SUCCESS(status) || ServiceName != NULL)
168  {
169  /* Retrieve the necessary buffer size */
170  ULONG infoLength;
171  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
173  {
175  goto Cleanup;
176  }
177 
178  /* Allocate the buffer and retrieve the data */
179  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
180  if (!basicInfo)
181  {
183  goto Cleanup;
184  }
185 
186  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
187  if (!NT_SUCCESS(status))
188  {
189  goto Cleanup;
190  }
191 
192  serviceName.Length = basicInfo->NameLength;
193  serviceName.MaximumLength = basicInfo->NameLength;
194  serviceName.Buffer = basicInfo->Name;
195  }
196 
197  /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
198  * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
199  if (driverName.Buffer == NULL)
200  {
201  ASSERT(basicInfo); // Container for serviceName
202 
203  /* Retrieve the driver type */
204  ULONG driverType;
205  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
206  if (!NT_SUCCESS(status))
207  {
208  goto Cleanup;
209  }
210  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
211  {
212  ExFreePool(kvInfo);
214  goto Cleanup;
215  }
216 
217  RtlMoveMemory(&driverType,
218  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
219  sizeof(ULONG));
220  ExFreePool(kvInfo);
221 
222  /* Compute the necessary driver name string size */
223  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
224  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
225  else
226  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
227 
228  driverName.MaximumLength += serviceName.Length;
229  driverName.Length = 0;
230 
231  /* Allocate and build it */
232  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
233  if (!driverName.Buffer)
234  {
236  goto Cleanup;
237  }
238 
239  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
241  else
243 
245  }
246 
247  if (ServiceName != NULL)
248  {
249  ASSERT(basicInfo); // Container for serviceName
250 
251  /* Allocate a copy for the caller */
253  if (!buf)
254  {
256  goto Cleanup;
257  }
258  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
259  ServiceName->MaximumLength = serviceName.Length;
260  ServiceName->Length = serviceName.Length;
261  ServiceName->Buffer = buf;
262  }
263 
264  *DriverName = driverName;
266 
267 Cleanup:
268  if (basicInfo)
269  ExFreePoolWithTag(basicInfo, TAG_IO);
270 
271  if (!NT_SUCCESS(status) && driverName.Buffer)
272  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
273 
274  return status;
275 }
276 
277 /*
278  * RETURNS
279  * TRUE if String2 contains String1 as a suffix.
280  */
281 BOOLEAN
282 NTAPI
284  IN PCUNICODE_STRING String1,
286 {
287  PWCHAR pc1;
288  PWCHAR pc2;
289  ULONG Length;
290 
291  if (String2->Length < String1->Length)
292  return FALSE;
293 
294  Length = String1->Length / 2;
295  pc1 = String1->Buffer;
296  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
297 
298  if (pc1 && pc2)
299  {
300  while (Length--)
301  {
302  if( *pc1++ != *pc2++ )
303  return FALSE;
304  }
305  return TRUE;
306  }
307  return FALSE;
308 }
309 
310 /*
311  * IopDisplayLoadingMessage
312  *
313  * Display 'Loading XXX...' message.
314  */
315 VOID
316 FASTCALL
318 {
319  CHAR TextBuffer[256];
320  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
321 
322  if (ExpInTextModeSetup) return;
323  if (!KeLoaderBlock) return;
325  snprintf(TextBuffer, sizeof(TextBuffer),
326  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
329  ServiceName,
330  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
332 }
333 
334 /*
335  * IopNormalizeImagePath
336  *
337  * Normalize an image path to contain complete path.
338  *
339  * Parameters
340  * ImagePath
341  * The input path and on exit the result path. ImagePath.Buffer
342  * must be allocated by ExAllocatePool on input. Caller is responsible
343  * for freeing the buffer when it's no longer needed.
344  *
345  * ServiceName
346  * Name of the service that ImagePath belongs to.
347  *
348  * Return Value
349  * Status
350  *
351  * Remarks
352  * The input image path isn't freed on error.
353  */
354 NTSTATUS
355 FASTCALL
357  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
358  PUNICODE_STRING ImagePath,
360 {
361  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
362  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
363  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
364  UNICODE_STRING InputImagePath;
365 
366  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
367 
368  InputImagePath = *ImagePath;
369  if (InputImagePath.Length == 0)
370  {
371  ImagePath->Length = 0;
372  ImagePath->MaximumLength = DriversPathString.Length +
373  ServiceName->Length +
374  DotSysString.Length +
375  sizeof(UNICODE_NULL);
376  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
377  ImagePath->MaximumLength,
378  TAG_IO);
379  if (ImagePath->Buffer == NULL)
380  return STATUS_NO_MEMORY;
381 
382  RtlCopyUnicodeString(ImagePath, &DriversPathString);
384  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
385  }
386  else if (InputImagePath.Buffer[0] != L'\\')
387  {
388  ImagePath->Length = 0;
389  ImagePath->MaximumLength = SystemRootString.Length +
390  InputImagePath.Length +
391  sizeof(UNICODE_NULL);
392  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
393  ImagePath->MaximumLength,
394  TAG_IO);
395  if (ImagePath->Buffer == NULL)
396  return STATUS_NO_MEMORY;
397 
398  RtlCopyUnicodeString(ImagePath, &SystemRootString);
399  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
400 
401  /* Free caller's string */
402  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
403  }
404 
405  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
406 
407  return STATUS_SUCCESS;
408 }
409 
429 NTSTATUS
431  _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
432  _In_ HANDLE ServiceHandle,
433  _Out_ PDRIVER_OBJECT *OutDriverObject,
434  _Out_ NTSTATUS *DriverEntryStatus)
435 {
438 
439  PAGED_CODE();
440 
441  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
442  if (!NT_SUCCESS(Status))
443  {
444  MmUnloadSystemImage(ModuleObject);
445  return Status;
446  }
447 
448  DPRINT("Driver name: '%wZ'\n", &DriverName);
449 
450  /* Obtain the registry path for the DriverInit routine */
451  PKEY_NAME_INFORMATION nameInfo;
452  ULONG infoLength;
453  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
455  {
456  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
457  if (nameInfo)
458  {
459  Status = ZwQueryKey(ServiceHandle,
461  nameInfo,
462  infoLength,
463  &infoLength);
464  if (NT_SUCCESS(Status))
465  {
466  RegistryPath.Length = nameInfo->NameLength;
467  RegistryPath.MaximumLength = nameInfo->NameLength;
468  RegistryPath.Buffer = nameInfo->Name;
469  }
470  else
471  {
472  ExFreePoolWithTag(nameInfo, TAG_IO);
473  }
474  }
475  else
476  {
478  }
479  }
480  else
481  {
483  }
484 
485  if (!NT_SUCCESS(Status))
486  {
488  RtlFreeUnicodeString(&DriverName);
489  MmUnloadSystemImage(ModuleObject);
490  return Status;
491  }
492 
493  /* Create the driver object */
494  ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
495  OBJECT_ATTRIBUTES objAttrs;
496  PDRIVER_OBJECT driverObject;
497  InitializeObjectAttributes(&objAttrs,
498  &DriverName,
500  NULL,
501  NULL);
502 
505  &objAttrs,
506  KernelMode,
507  NULL,
508  ObjectSize,
509  0,
510  0,
511  (PVOID*)&driverObject);
512  if (!NT_SUCCESS(Status))
513  {
514  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
516  RtlFreeUnicodeString(&DriverName);
517  MmUnloadSystemImage(ModuleObject);
518  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
519  return Status;
520  }
521 
522  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
523 
524  RtlZeroMemory(driverObject, ObjectSize);
525  driverObject->Type = IO_TYPE_DRIVER;
526  driverObject->Size = sizeof(DRIVER_OBJECT);
527  driverObject->Flags = DRVO_LEGACY_DRIVER; // TODO: check the WDM_DRIVER flag on the module
528  driverObject->DriverSection = ModuleObject;
529  driverObject->DriverStart = ModuleObject->DllBase;
530  driverObject->DriverSize = ModuleObject->SizeOfImage;
531  driverObject->DriverInit = ModuleObject->EntryPoint;
532  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
533  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
534  driverObject->DriverExtension->DriverObject = driverObject;
535 
536  /* Loop all Major Functions */
537  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
538  {
539  /* Invalidate each function */
540  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
541  }
542 
543  /* Add the Object and get its handle */
544  HANDLE hDriver;
545  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
546  if (!NT_SUCCESS(Status))
547  {
548  ExFreePoolWithTag(nameInfo, TAG_IO);
550  RtlFreeUnicodeString(&DriverName);
551  return Status;
552  }
553 
554  /* Now reference it */
556  0,
558  KernelMode,
559  (PVOID*)&driverObject,
560  NULL);
561 
562  /* Close the extra handle */
563  ZwClose(hDriver);
564 
565  if (!NT_SUCCESS(Status))
566  {
567  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
569  RtlFreeUnicodeString(&DriverName);
570  return Status;
571  }
572 
573  /* Set up the service key name buffer */
574  UNICODE_STRING serviceKeyName;
575  serviceKeyName.Length = 0;
576  // NULL-terminate for Windows compatibility
577  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
578  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
579  serviceKeyName.MaximumLength,
580  TAG_IO);
581  if (!serviceKeyName.Buffer)
582  {
583  ObMakeTemporaryObject(driverObject);
584  ObDereferenceObject(driverObject);
585  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
587  RtlFreeUnicodeString(&DriverName);
589  }
590 
591  /* Copy the name and set it in the driver extension */
592  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
594  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
595 
596  /* Make a copy of the driver name to store in the driver object */
597  UNICODE_STRING driverNamePaged;
598  driverNamePaged.Length = 0;
599  // NULL-terminate for Windows compatibility
600  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
601  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
602  driverNamePaged.MaximumLength,
603  TAG_IO);
604  if (!driverNamePaged.Buffer)
605  {
606  ObMakeTemporaryObject(driverObject);
607  ObDereferenceObject(driverObject);
608  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
609  RtlFreeUnicodeString(&DriverName);
611  }
612 
613  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
614  driverObject->DriverName = driverNamePaged;
615 
616  /* Finally, call its init function */
617  Status = driverObject->DriverInit(driverObject, &RegistryPath);
618  *DriverEntryStatus = Status;
619  if (!NT_SUCCESS(Status))
620  {
621  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
622  // return a special status value in case of failure
624  }
625 
626  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
627  * Other parts of the I/O manager depend on this behavior */
628  if (!driverObject->DeviceObject)
629  {
630  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
631  }
632 
633  // Windows does this fixup - keep it for compatibility
634  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
635  {
636  /*
637  * Make sure the driver didn't set any dispatch entry point to NULL!
638  * Doing so is illegal; drivers shouldn't touch entry points they
639  * do not implement.
640  */
641 
642  /* Check if it did so anyway */
643  if (!driverObject->MajorFunction[i])
644  {
645  /* Print a warning in the debug log */
646  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
647  &driverObject->DriverName, i);
648 
649  /* Fix it up */
650  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
651  }
652  }
653 
654  // TODO: for legacy drivers, unload the driver if it didn't create any DO
655 
656  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
657  RtlFreeUnicodeString(&DriverName);
658 
659  if (!NT_SUCCESS(Status))
660  {
661  // if the driver entry has been failed, clear the object
662  ObMakeTemporaryObject(driverObject);
663  ObDereferenceObject(driverObject);
664  return Status;
665  }
666 
667  *OutDriverObject = driverObject;
668 
669  MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)driverObject->DriverSection);
670 
671  /* Set the driver as initialized */
672  IopReadyDeviceObjects(driverObject);
673 
675 
676  return STATUS_SUCCESS;
677 }
678 
679 NTSTATUS
680 NTAPI
682  IN PUNICODE_STRING ImageFileDirectory,
683  IN PUNICODE_STRING NamePrefix OPTIONAL,
684  OUT PCHAR *MissingApi,
685  OUT PWCHAR *MissingDriver,
686  OUT PLOAD_IMPORTS *LoadImports);
687 
688 //
689 // Used for images already loaded (boot drivers)
690 //
691 CODE_SEG("INIT")
692 NTSTATUS
693 NTAPI
696  PLDR_DATA_TABLE_ENTRY *ModuleObject)
697 {
699  UNICODE_STRING BaseName, BaseDirectory;
700  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
701  PCHAR MissingApiName, Buffer;
702  PWCHAR MissingDriverName;
703  PVOID DriverBase = LdrEntry->DllBase;
704 
705  /* Allocate a buffer we'll use for names */
708  TAG_LDR_WSTR);
709  if (!Buffer)
710  {
711  /* Fail */
713  }
714 
715  /* Check for a separator */
716  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
717  {
718  PWCHAR p;
719  ULONG BaseLength;
720 
721  /* Loop the path until we get to the base name */
722  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
723  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
724 
725  /* Get the length */
726  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
727  BaseLength *= sizeof(WCHAR);
728 
729  /* Setup the string */
730  BaseName.Length = (USHORT)BaseLength;
731  BaseName.Buffer = p;
732  }
733  else
734  {
735  /* Otherwise, we already have a base name */
736  BaseName.Length = FileName->Length;
737  BaseName.Buffer = FileName->Buffer;
738  }
739 
740  /* Setup the maximum length */
741  BaseName.MaximumLength = BaseName.Length;
742 
743  /* Now compute the base directory */
744  BaseDirectory = *FileName;
745  BaseDirectory.Length -= BaseName.Length;
746  BaseDirectory.MaximumLength = BaseDirectory.Length;
747 
748  /* Resolve imports */
749  MissingApiName = Buffer;
750  Status = MiResolveImageReferences(DriverBase,
751  &BaseDirectory,
752  NULL,
753  &MissingApiName,
754  &MissingDriverName,
755  &LoadedImports);
756 
757  /* Free the temporary buffer */
759 
760  /* Check the result of the imports resolution */
761  if (!NT_SUCCESS(Status)) return Status;
762 
763  /* Return */
764  *ModuleObject = LdrEntry;
765  return STATUS_SUCCESS;
766 }
767 
770 
771 /*
772  * IopInitializeBuiltinDriver
773  *
774  * Initialize a driver that is already loaded in memory.
775  */
776 CODE_SEG("INIT")
777 static
778 BOOLEAN
780 {
783  PWCHAR Buffer, FileNameWithoutPath;
784  PWSTR FileExtension;
785  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
786  PLDR_DATA_TABLE_ENTRY LdrEntry;
787  PLIST_ENTRY NextEntry;
790 
791  /*
792  * Display 'Loading XXX...' message
793  */
796 
798  ModuleName->Length + sizeof(UNICODE_NULL),
799  TAG_IO);
800  if (Buffer == NULL)
801  {
802  return FALSE;
803  }
804 
806  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
807 
808  /*
809  * Generate filename without path (not needed by freeldr)
810  */
811  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
812  if (FileNameWithoutPath == NULL)
813  {
814  FileNameWithoutPath = Buffer;
815  }
816  else
817  {
818  FileNameWithoutPath++;
819  }
820 
821  /*
822  * Strip the file extension from ServiceName
823  */
824  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
826  if (!Success)
827  {
828  return FALSE;
829  }
830 
831  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
832  if (FileExtension != NULL)
833  {
834  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
835  FileExtension[0] = UNICODE_NULL;
836  }
837 
839 
840  // Make the registry path for the driver
841  RegistryPath.Length = 0;
842  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
844  if (RegistryPath.Buffer == NULL)
845  {
846  return FALSE;
847  }
851 
852  HANDLE serviceHandle;
853  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
855  if (!NT_SUCCESS(Status))
856  {
857  return FALSE;
858  }
859 
860  /* Lookup the new Ldr entry in PsLoadedModuleList */
861  for (NextEntry = PsLoadedModuleList.Flink;
862  NextEntry != &PsLoadedModuleList;
863  NextEntry = NextEntry->Flink)
864  {
865  LdrEntry = CONTAINING_RECORD(NextEntry,
867  InLoadOrderLinks);
869  {
870  break;
871  }
872  }
873  ASSERT(NextEntry != &PsLoadedModuleList);
874 
875  /*
876  * Initialize the driver
877  */
878  NTSTATUS driverEntryStatus;
880  serviceHandle,
881  &DriverObject,
882  &driverEntryStatus);
883 
884  if (!NT_SUCCESS(Status))
885  {
886  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
887  return FALSE;
888  }
889 
890  // The driver has been loaded, now check if where are any PDOs
891  // for that driver, and queue AddDevice call for them.
892  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
893  // is populated upon a new device arrival based on a (critical) device database
894 
895  // Legacy drivers may add devices inside DriverEntry.
896  // We're lazy and always assume that they are doing so
897  BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
898 
899  HANDLE enumServiceHandle;
900  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
901 
902  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
903  ZwClose(serviceHandle);
904 
905  if (NT_SUCCESS(Status))
906  {
907  ULONG instanceCount = 0;
909  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
910  if (!NT_SUCCESS(Status))
911  {
912  goto Cleanup;
913  }
914  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
915  {
916  ExFreePool(kvInfo);
917  goto Cleanup;
918  }
919 
920  RtlMoveMemory(&instanceCount,
921  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
922  sizeof(ULONG));
923  ExFreePool(kvInfo);
924 
925  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
926 
927  for (ULONG i = 0; i < instanceCount; i++)
928  {
929  WCHAR num[11];
930  UNICODE_STRING instancePath;
931  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
932 
933  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
934  if (!NT_SUCCESS(Status))
935  {
936  continue;
937  }
938  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
939  {
940  ExFreePool(kvInfo);
941  continue;
942  }
943 
944  instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
945  instancePath.MaximumLength = kvInfo->DataLength;
947  instancePath.MaximumLength,
948  TAG_IO);
949  if (instancePath.Buffer)
950  {
951  RtlMoveMemory(instancePath.Buffer,
952  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
953  instancePath.Length);
954  instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
955 
958  ObDereferenceObject(pdo);
959  deviceAdded = TRUE;
960  }
961 
962  ExFreePool(kvInfo);
963  }
964 
965  ZwClose(enumServiceHandle);
966  }
967 Cleanup:
968  /* Remove extra reference from IopInitializeDriverModule */
970 
971  return deviceAdded;
972 }
973 
974 /*
975  * IopInitializeBootDrivers
976  *
977  * Initialize boot drivers and free memory for boot files.
978  *
979  * Parameters
980  * None
981  *
982  * Return Value
983  * None
984  */
985 CODE_SEG("INIT")
986 VOID
987 FASTCALL
989 {
990  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
991  PLDR_DATA_TABLE_ENTRY LdrEntry;
993  UNICODE_STRING DriverName;
994  ULONG i, Index;
995  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
997  PBOOT_DRIVER_LIST_ENTRY BootEntry;
998  DPRINT("IopInitializeBootDrivers()\n");
999 
1000  /* Create the RAW FS built-in driver */
1001  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1002 
1003  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1004  if (!NT_SUCCESS(Status))
1005  {
1006  /* Fail */
1007  return;
1008  }
1009 
1010  /* Get highest group order index */
1012  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
1013 
1014  /* Allocate the group table */
1016  IopGroupIndex * sizeof(LIST_ENTRY),
1017  TAG_IO);
1018  if (IopGroupTable == NULL) ASSERT(FALSE);
1019 
1020  /* Initialize the group table lists */
1021  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1022 
1023  /* Loop the boot modules */
1024  ListHead = &KeLoaderBlock->LoadOrderListHead;
1025  for (NextEntry = ListHead->Flink;
1026  NextEntry != ListHead;
1027  NextEntry = NextEntry->Flink)
1028  {
1029  /* Get the entry */
1030  LdrEntry = CONTAINING_RECORD(NextEntry,
1032  InLoadOrderLinks);
1033 
1034  /* Check if the DLL needs to be initialized */
1035  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1036  {
1037  /* Call its entrypoint */
1038  MmCallDllInitialize(LdrEntry, NULL);
1039  }
1040  }
1041 
1042  /* Loop the boot drivers */
1043  ListHead = &KeLoaderBlock->BootDriverListHead;
1044  for (NextEntry = ListHead->Flink;
1045  NextEntry != ListHead;
1046  NextEntry = NextEntry->Flink)
1047  {
1048  /* Get the entry */
1049  BootEntry = CONTAINING_RECORD(NextEntry,
1051  Link);
1052 
1053  // FIXME: TODO: This LdrEntry is to be used in a special handling
1054  // for SETUPLDR (a similar procedure is done on Windows), where
1055  // the loader would, under certain conditions, be loaded in the
1056  // SETUPLDR-specific code block below...
1057 #if 0
1058  /* Get the driver loader entry */
1059  LdrEntry = BootEntry->LdrEntry;
1060 #endif
1061 
1062  /* Allocate our internal accounting structure */
1064  sizeof(DRIVER_INFORMATION),
1065  TAG_IO);
1066  if (DriverInfo)
1067  {
1068  /* Zero it and initialize it */
1071  DriverInfo->DataTableEntry = BootEntry;
1072 
1073  /* Open the registry key */
1075  NULL,
1076  &BootEntry->RegistryPath,
1077  KEY_READ);
1078  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1079 #if 0
1080  if (NT_SUCCESS(Status))
1081 #else // Hack still needed...
1082  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1083  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1084 #endif
1085  {
1086  /* Save the handle */
1088 
1089  /* Get the group oder index */
1091 
1092  /* Get the tag position */
1094 
1095  /* Insert it into the list, at the right place */
1097  NextEntry2 = IopGroupTable[Index].Flink;
1098  while (NextEntry2 != &IopGroupTable[Index])
1099  {
1100  /* Get the driver info */
1101  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1103  Link);
1104 
1105  /* Check if we found the right tag position */
1106  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1107  {
1108  /* We're done */
1109  break;
1110  }
1111 
1112  /* Next entry */
1113  NextEntry2 = NextEntry2->Flink;
1114  }
1115 
1116  /* Insert us right before the next entry */
1117  NextEntry2 = NextEntry2->Blink;
1118  InsertHeadList(NextEntry2, &DriverInfo->Link);
1119  }
1120  }
1121  }
1122 
1123  /* Loop each group index */
1124  for (i = 0; i < IopGroupIndex; i++)
1125  {
1126  /* Loop each group table */
1127  for (NextEntry = IopGroupTable[i].Flink;
1128  NextEntry != &IopGroupTable[i];
1129  NextEntry = NextEntry->Flink)
1130  {
1131  /* Get the entry */
1132  DriverInfo = CONTAINING_RECORD(NextEntry,
1134  Link);
1135 
1136  /* Get the driver loader entry */
1137  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1138 
1139  /* Initialize it */
1140  if (IopInitializeBuiltinDriver(LdrEntry))
1141  {
1142  // it does not make sense to enumerate the tree if there are no new devices added
1145  NULL,
1146  NULL);
1147  }
1148  }
1149  }
1150 
1151  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1152  * when some devices are not being initialized with their drivers. This flag is used to delay
1153  * all actions with devices (except PnP root device) until boot drivers are loaded.
1154  * See PiQueueDeviceAction function
1155  */
1157 
1158  DbgPrint("BOOT DRIVERS LOADED\n");
1159 
1162  NULL,
1163  NULL);
1164 }
1165 
1166 CODE_SEG("INIT")
1167 VOID
1168 FASTCALL
1170 {
1171  PUNICODE_STRING *DriverList, *SavedList;
1172 
1174 
1175  /* No system drivers on the boot cd */
1176  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1177 
1178  /* Get the driver list */
1179  SavedList = DriverList = CmGetSystemDriverList();
1180  ASSERT(DriverList);
1181 
1182  /* Loop it */
1183  while (*DriverList)
1184  {
1185  /* Load the driver */
1186  ZwLoadDriver(*DriverList);
1187 
1188  /* Free the entry */
1189  RtlFreeUnicodeString(*DriverList);
1190  ExFreePool(*DriverList);
1191 
1192  /* Next entry */
1194  DriverList++;
1195  }
1196 
1197  /* Free the list */
1198  ExFreePool(SavedList);
1199 
1202  NULL,
1203  NULL);
1204 }
1205 
1206 /*
1207  * IopUnloadDriver
1208  *
1209  * Unloads a device driver.
1210  *
1211  * Parameters
1212  * DriverServiceName
1213  * Name of the service to unload (registry key).
1214  *
1215  * UnloadPnpDrivers
1216  * Whether to unload Plug & Plug or only legacy drivers. If this
1217  * parameter is set to FALSE, the routine will unload only legacy
1218  * drivers.
1219  *
1220  * Return Value
1221  * Status
1222  *
1223  * To do
1224  * Guard the whole function by SEH.
1225  */
1226 
1228 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1229 {
1230  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1232  UNICODE_STRING ImagePath;
1237  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1238  NTSTATUS Status;
1239  USHORT LastBackslash;
1240  BOOLEAN SafeToUnload = TRUE;
1242  UNICODE_STRING CapturedServiceName;
1243 
1244  PAGED_CODE();
1245 
1247 
1248  /* Need the appropriate priviliege */
1250  {
1251  DPRINT1("No unload privilege!\n");
1253  }
1254 
1255  /* Capture the service name */
1256  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1257  PreviousMode,
1258  DriverServiceName);
1259  if (!NT_SUCCESS(Status))
1260  {
1261  return Status;
1262  }
1263 
1264  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1265 
1266  /* We need a service name */
1267  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1268  {
1269  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1270  return STATUS_INVALID_PARAMETER;
1271  }
1272 
1273  /*
1274  * Get the service name from the registry key name
1275  */
1277  &CapturedServiceName,
1278  &Backslash,
1279  &LastBackslash);
1280  if (NT_SUCCESS(Status))
1281  {
1282  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1283  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1284  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1285  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1286  }
1287  else
1288  {
1289  ServiceName = CapturedServiceName;
1290  }
1291 
1292  /*
1293  * Construct the driver object name
1294  */
1295  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1296  ServiceName.Length,
1297  &ObjectName.MaximumLength);
1298  if (!NT_SUCCESS(Status))
1299  {
1300  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1301  return Status;
1302  }
1303  ObjectName.Length = 0;
1305  ObjectName.MaximumLength,
1306  TAG_IO);
1307  if (!ObjectName.Buffer)
1308  {
1309  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1311  }
1314 
1315  /*
1316  * Find the driver object
1317  */
1319  0,
1320  0,
1321  0,
1323  KernelMode,
1324  0,
1325  (PVOID*)&DriverObject);
1326 
1327  if (!NT_SUCCESS(Status))
1328  {
1329  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1331  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1332  return Status;
1333  }
1334 
1335  /* Free the buffer for driver object name */
1337 
1338  /* Check that driver is not already unloading */
1339  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1340  {
1341  DPRINT1("Driver deletion pending\n");
1343  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1344  return STATUS_DELETE_PENDING;
1345  }
1346 
1347  /*
1348  * Get path of service...
1349  */
1351 
1352  RtlInitUnicodeString(&ImagePath, NULL);
1353 
1354  QueryTable[0].Name = L"ImagePath";
1356  QueryTable[0].EntryContext = &ImagePath;
1357 
1359  CapturedServiceName.Buffer,
1360  QueryTable,
1361  NULL,
1362  NULL);
1363 
1364  /* We no longer need service name */
1365  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1366 
1367  if (!NT_SUCCESS(Status))
1368  {
1369  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1371  return Status;
1372  }
1373 
1374  /*
1375  * Normalize the image path for all later processing.
1376  */
1377  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1378 
1379  if (!NT_SUCCESS(Status))
1380  {
1381  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1383  return Status;
1384  }
1385 
1386  /* Free the service path */
1387  ExFreePool(ImagePath.Buffer);
1388 
1389  /*
1390  * Unload the module and release the references to the device object
1391  */
1392 
1393  /* Call the load/unload routine, depending on current process */
1394  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1395  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1396  {
1397  /* Loop through each device object of the driver
1398  and set DOE_UNLOAD_PENDING flag */
1399  DeviceObject = DriverObject->DeviceObject;
1400  while (DeviceObject)
1401  {
1402  /* Set the unload pending flag for the device */
1403  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1404  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1405 
1406  /* Make sure there are no attached devices or no reference counts */
1407  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1408  {
1409  /* Not safe to unload */
1410  DPRINT1("Drivers device object is referenced or has attached devices\n");
1411 
1412  SafeToUnload = FALSE;
1413  }
1414 
1415  DeviceObject = DeviceObject->NextDevice;
1416  }
1417 
1418  /* If not safe to unload, then return success */
1419  if (!SafeToUnload)
1420  {
1422  return STATUS_SUCCESS;
1423  }
1424 
1425  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1426 
1427  /* Set the unload invoked flag and call the unload routine */
1431 
1432  /* Mark the driver object temporary, so it could be deleted later */
1434 
1435  /* Dereference it 2 times */
1438 
1439  return Status;
1440  }
1441  else
1442  {
1443  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1444 
1445  /* Dereference one time (refd inside this function) */
1447 
1448  /* Return unloading failure */
1450  }
1451 }
1452 
1453 VOID
1454 NTAPI
1456 {
1457  PDRIVER_REINIT_ITEM ReinitItem;
1459 
1460  /* Get the first entry and start looping */
1463  while (Entry)
1464  {
1465  /* Get the item */
1466  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1467 
1468  /* Increment reinitialization counter */
1469  ReinitItem->DriverObject->DriverExtension->Count++;
1470 
1471  /* Remove the device object flag */
1472  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1473 
1474  /* Call the routine */
1475  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1476  ReinitItem->Context,
1477  ReinitItem->DriverObject->
1478  DriverExtension->Count);
1479 
1480  /* Free the entry */
1481  ExFreePool(Entry);
1482 
1483  /* Move to the next one */
1486  }
1487 }
1488 
1489 VOID
1490 NTAPI
1492 {
1493  PDRIVER_REINIT_ITEM ReinitItem;
1495 
1496  /* Get the first entry and start looping */
1499  while (Entry)
1500  {
1501  /* Get the item */
1502  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1503 
1504  /* Increment reinitialization counter */
1505  ReinitItem->DriverObject->DriverExtension->Count++;
1506 
1507  /* Remove the device object flag */
1509 
1510  /* Call the routine */
1511  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1512  ReinitItem->Context,
1513  ReinitItem->DriverObject->
1514  DriverExtension->Count);
1515 
1516  /* Free the entry */
1517  ExFreePool(Entry);
1518 
1519  /* Move to the next one */
1522  }
1523 
1524  /* Wait for all device actions being finished*/
1526 }
1527 
1528 /* PUBLIC FUNCTIONS ***********************************************************/
1529 
1530 /*
1531  * @implemented
1532  */
1533 NTSTATUS
1534 NTAPI
1536  _In_opt_ PUNICODE_STRING DriverName,
1537  _In_ PDRIVER_INITIALIZE InitializationFunction)
1538 {
1539  WCHAR NameBuffer[100];
1540  USHORT NameLength;
1541  UNICODE_STRING LocalDriverName;
1542  NTSTATUS Status;
1544  ULONG ObjectSize;
1546  UNICODE_STRING ServiceKeyName;
1547  HANDLE hDriver;
1548  ULONG i, RetryCount = 0;
1549 
1550 try_again:
1551  /* First, create a unique name for the driver if we don't have one */
1552  if (!DriverName)
1553  {
1554  /* Create a random name and set up the string */
1555  NameLength = (USHORT)swprintf(NameBuffer,
1556  DRIVER_ROOT_NAME L"%08u",
1558  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1559  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1560  LocalDriverName.Buffer = NameBuffer;
1561  }
1562  else
1563  {
1564  /* So we can avoid another code path, use a local var */
1565  LocalDriverName = *DriverName;
1566  }
1567 
1568  /* Initialize the Attributes */
1569  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1571  &LocalDriverName,
1573  NULL,
1574  NULL);
1575 
1576  /* Create the Object */
1580  KernelMode,
1581  NULL,
1582  ObjectSize,
1583  0,
1584  0,
1585  (PVOID*)&DriverObject);
1586  if (!NT_SUCCESS(Status)) return Status;
1587 
1588  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1589 
1590  /* Set up the Object */
1591  RtlZeroMemory(DriverObject, ObjectSize);
1592  DriverObject->Type = IO_TYPE_DRIVER;
1593  DriverObject->Size = sizeof(DRIVER_OBJECT);
1595  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1596  DriverObject->DriverExtension->DriverObject = DriverObject;
1597  DriverObject->DriverInit = InitializationFunction;
1598  /* Loop all Major Functions */
1599  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1600  {
1601  /* Invalidate each function */
1602  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1603  }
1604 
1605  /* Set up the service key name buffer */
1606  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1607  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1608  if (!ServiceKeyName.Buffer)
1609  {
1610  /* Fail */
1614  }
1615 
1616  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1617  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1618  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1619  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1620 
1621  /* Make a copy of the driver name to store in the driver object */
1622  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1623  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1624  DriverObject->DriverName.MaximumLength,
1625  TAG_IO);
1626  if (!DriverObject->DriverName.Buffer)
1627  {
1628  /* Fail */
1632  }
1633 
1634  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1635 
1636  /* Add the Object and get its handle */
1638  NULL,
1640  0,
1641  NULL,
1642  &hDriver);
1643 
1644  /* Eliminate small possibility when this function is called more than
1645  once in a row, and KeTickCount doesn't get enough time to change */
1646  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1647  {
1648  RetryCount++;
1649  goto try_again;
1650  }
1651 
1652  if (!NT_SUCCESS(Status)) return Status;
1653 
1654  /* Now reference it */
1656  0,
1658  KernelMode,
1659  (PVOID*)&DriverObject,
1660  NULL);
1661 
1662  /* Close the extra handle */
1663  ZwClose(hDriver);
1664 
1665  if (!NT_SUCCESS(Status))
1666  {
1667  /* Fail */
1670  return Status;
1671  }
1672 
1673  /* Finally, call its init function */
1674  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1675  Status = InitializationFunction(DriverObject, NULL);
1676  if (!NT_SUCCESS(Status))
1677  {
1678  /* If it didn't work, then kill the object */
1679  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1682  return Status;
1683  }
1684 
1685  // Windows does this fixup - keep it for compatibility
1686  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1687  {
1688  /*
1689  * Make sure the driver didn't set any dispatch entry point to NULL!
1690  * Doing so is illegal; drivers shouldn't touch entry points they
1691  * do not implement.
1692  */
1693 
1694  /* Check if it did so anyway */
1695  if (!DriverObject->MajorFunction[i])
1696  {
1697  /* Print a warning in the debug log */
1698  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1699  &DriverObject->DriverName, i);
1700 
1701  /* Fix it up */
1702  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1703  }
1704  }
1705 
1706  /* Return the Status */
1707  return Status;
1708 }
1709 
1710 /*
1711  * @implemented
1712  */
1713 VOID
1714 NTAPI
1716 {
1717  /* Simply dereference the Object */
1719 }
1720 
1721 /*
1722  * @implemented
1723  */
1724 VOID
1725 NTAPI
1727  IN PDRIVER_REINITIALIZE ReinitRoutine,
1728  IN PVOID Context)
1729 {
1730  PDRIVER_REINIT_ITEM ReinitItem;
1731 
1732  /* Allocate the entry */
1733  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1734  sizeof(DRIVER_REINIT_ITEM),
1735  TAG_REINIT);
1736  if (!ReinitItem) return;
1737 
1738  /* Fill it out */
1739  ReinitItem->DriverObject = DriverObject;
1740  ReinitItem->ReinitRoutine = ReinitRoutine;
1741  ReinitItem->Context = Context;
1742 
1743  /* Set the Driver Object flag and insert the entry into the list */
1746  &ReinitItem->ItemEntry,
1748 }
1749 
1750 /*
1751  * @implemented
1752  */
1753 VOID
1754 NTAPI
1756  IN PDRIVER_REINITIALIZE ReinitRoutine,
1757  IN PVOID Context)
1758 {
1759  PDRIVER_REINIT_ITEM ReinitItem;
1760 
1761  /* Allocate the entry */
1762  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1763  sizeof(DRIVER_REINIT_ITEM),
1764  TAG_REINIT);
1765  if (!ReinitItem) return;
1766 
1767  /* Fill it out */
1768  ReinitItem->DriverObject = DriverObject;
1769  ReinitItem->ReinitRoutine = ReinitRoutine;
1770  ReinitItem->Context = Context;
1771 
1772  /* Set the Driver Object flag and insert the entry into the list */
1775  &ReinitItem->ItemEntry,
1777 }
1778 
1779 /*
1780  * @implemented
1781  */
1782 NTSTATUS
1783 NTAPI
1786  IN ULONG DriverObjectExtensionSize,
1787  OUT PVOID *DriverObjectExtension)
1788 {
1789  KIRQL OldIrql;
1790  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1791  BOOLEAN Inserted = FALSE;
1792 
1793  /* Assume failure */
1794  *DriverObjectExtension = NULL;
1795 
1796  /* Allocate the extension */
1797  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1798  sizeof(IO_CLIENT_EXTENSION) +
1799  DriverObjectExtensionSize,
1801  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1802 
1803  /* Clear the extension for teh caller */
1804  RtlZeroMemory(NewDriverExtension,
1805  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1806 
1807  /* Acqure lock */
1809 
1810  /* Fill out the extension */
1812 
1813  /* Loop the current extensions */
1814  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1815  ClientDriverExtension;
1816  while (DriverExtensions)
1817  {
1818  /* Check if the identifier matches */
1819  if (DriverExtensions->ClientIdentificationAddress ==
1821  {
1822  /* We have a collision, break out */
1823  break;
1824  }
1825 
1826  /* Go to the next one */
1827  DriverExtensions = DriverExtensions->NextExtension;
1828  }
1829 
1830  /* Check if we didn't collide */
1831  if (!DriverExtensions)
1832  {
1833  /* Link this one in */
1834  NewDriverExtension->NextExtension =
1835  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1836  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1837  NewDriverExtension;
1838  Inserted = TRUE;
1839  }
1840 
1841  /* Release the lock */
1843 
1844  /* Check if insertion failed */
1845  if (!Inserted)
1846  {
1847  /* Free the entry and fail */
1848  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1850  }
1851 
1852  /* Otherwise, return the pointer */
1853  *DriverObjectExtension = NewDriverExtension + 1;
1854  return STATUS_SUCCESS;
1855 }
1856 
1857 /*
1858  * @implemented
1859  */
1860 PVOID
1861 NTAPI
1864 {
1865  KIRQL OldIrql;
1866  PIO_CLIENT_EXTENSION DriverExtensions;
1867 
1868  /* Acquire lock */
1870 
1871  /* Loop the list until we find the right one */
1872  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1873  while (DriverExtensions)
1874  {
1875  /* Check for a match */
1876  if (DriverExtensions->ClientIdentificationAddress ==
1878  {
1879  /* Break out */
1880  break;
1881  }
1882 
1883  /* Keep looping */
1884  DriverExtensions = DriverExtensions->NextExtension;
1885  }
1886 
1887  /* Release lock */
1889 
1890  /* Return nothing or the extension */
1891  if (!DriverExtensions) return NULL;
1892  return DriverExtensions + 1;
1893 }
1894 
1895 NTSTATUS
1897  _In_ HANDLE ServiceHandle,
1899 {
1900  UNICODE_STRING ImagePath;
1901  NTSTATUS Status;
1902  PLDR_DATA_TABLE_ENTRY ModuleObject;
1904 
1906  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1907  if (NT_SUCCESS(Status))
1908  {
1909  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1910  {
1911  ExFreePool(kvInfo);
1913  }
1914 
1915  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1916  ImagePath.MaximumLength = kvInfo->DataLength;
1918  if (!ImagePath.Buffer)
1919  {
1920  ExFreePool(kvInfo);
1922  }
1923 
1924  RtlMoveMemory(ImagePath.Buffer,
1925  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1926  ImagePath.Length);
1927  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1928  ExFreePool(kvInfo);
1929  }
1930  else
1931  {
1932  return Status;
1933  }
1934 
1935  /*
1936  * Normalize the image path for all later processing.
1937  */
1938  Status = IopNormalizeImagePath(&ImagePath, NULL);
1939  if (!NT_SUCCESS(Status))
1940  {
1941  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1942  return Status;
1943  }
1944 
1945  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1946 
1949 
1950  /*
1951  * Load the driver module
1952  */
1953  DPRINT("Loading module from %wZ\n", &ImagePath);
1954  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1955  RtlFreeUnicodeString(&ImagePath);
1956 
1957  if (!NT_SUCCESS(Status))
1958  {
1959  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1962  return Status;
1963  }
1964 
1965  // Display the loading message
1966  ULONG infoLength;
1967  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1969  {
1971  if (servName)
1972  {
1973  Status = ZwQueryKey(ServiceHandle,
1975  servName,
1976  infoLength,
1977  &infoLength);
1978  if (NT_SUCCESS(Status))
1979  {
1981  .Length = servName->NameLength,
1982  .MaximumLength = servName->NameLength,
1983  .Buffer = servName->Name
1984  };
1985 
1987  }
1988  ExFreePoolWithTag(servName, TAG_IO);
1989  }
1990  }
1991 
1992  NTSTATUS driverEntryStatus;
1993  Status = IopInitializeDriverModule(ModuleObject,
1994  ServiceHandle,
1995  DriverObject,
1996  &driverEntryStatus);
1997  if (!NT_SUCCESS(Status))
1998  {
1999  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2000  }
2001 
2004 
2005  return Status;
2006 }
2007 
2008 static
2009 VOID
2010 NTAPI
2013 {
2014  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2015 
2017 
2018  if (LoadParams->DriverObject)
2019  {
2020  // unload request
2021  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2022  LoadParams->Status = STATUS_SUCCESS;
2023  }
2024  else
2025  {
2026  // load request
2027  HANDLE serviceHandle;
2028  NTSTATUS status;
2029  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2030  if (!NT_SUCCESS(status))
2031  {
2032  LoadParams->Status = status;
2033  }
2034  else
2035  {
2036  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2037  ZwClose(serviceHandle);
2038  }
2039  }
2040 
2041  if (LoadParams->SetEvent)
2042  {
2043  KeSetEvent(&LoadParams->Event, 0, FALSE);
2044  }
2045 }
2046 
2056 NTSTATUS
2060 {
2061  LOAD_UNLOAD_PARAMS LoadParams;
2062 
2063  /* Prepare parameters block */
2064  LoadParams.RegistryPath = RegistryPath;
2065  LoadParams.DriverObject = *DriverObject;
2066 
2068  {
2069  LoadParams.SetEvent = TRUE;
2071 
2072  /* Initialize and queue a work item */
2073  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2075 
2076  /* And wait till it completes */
2078  }
2079  else
2080  {
2081  /* If we're already in a system process, call it right here */
2082  LoadParams.SetEvent = FALSE;
2083  IopLoadUnloadDriverWorker(&LoadParams);
2084  }
2085 
2086  return LoadParams.Status;
2087 }
2088 
2089 /*
2090  * NtLoadDriver
2091  *
2092  * Loads a device driver.
2093  *
2094  * Parameters
2095  * DriverServiceName
2096  * Name of the service to load (registry key).
2097  *
2098  * Return Value
2099  * Status
2100  *
2101  * Status
2102  * implemented
2103  */
2105 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2106 {
2107  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2110  NTSTATUS Status;
2111 
2112  PAGED_CODE();
2113 
2115 
2116  /* Need the appropriate priviliege */
2118  {
2119  DPRINT1("No load privilege!\n");
2121  }
2122 
2123  /* Capture the service name */
2124  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2125  PreviousMode,
2126  DriverServiceName);
2127  if (!NT_SUCCESS(Status))
2128  {
2129  return Status;
2130  }
2131 
2132  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2133 
2134  /* We need a service name */
2135  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2136  {
2137  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2138  return STATUS_INVALID_PARAMETER;
2139  }
2140 
2141  /* Load driver and call its entry point */
2142  DriverObject = NULL;
2143  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2144 
2145  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2146  return Status;
2147 }
2148 
2149 /*
2150  * NtUnloadDriver
2151  *
2152  * Unloads a legacy device driver.
2153  *
2154  * Parameters
2155  * DriverServiceName
2156  * Name of the service to unload (registry key).
2157  *
2158  * Return Value
2159  * Status
2160  *
2161  * Status
2162  * implemented
2163  */
2164 
2167 {
2168  return IopUnloadDriver(DriverServiceName, FALSE);
2169 }
2170 
2171 /* 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:4155
#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:988
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:723
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:1169
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
#define _In_opt_
Definition: ms_sal.h:309
#define _Inout_
Definition: ms_sal.h:378
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:1784
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:2620
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2011
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1455
_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 _Out_
Definition: ms_sal.h:345
#define _At_(target, annos)
Definition: ms_sal.h:244
#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:317
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:463
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:2057
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:3070
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1896
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
#define _When_(expr, annos)
Definition: ms_sal.h:254
uint16_t * PWCHAR
Definition: typedefs.h:56
#define swprintf
Definition: precomp.h:40
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
_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:1715
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:1491
#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 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:4469
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1755
uint32_t ULONG_PTR
Definition: typedefs.h:65
LIST_ENTRY ItemEntry
Definition: io.h:460
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:779
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
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:403
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:356
VOID(NTAPI * PDRIVER_REINITIALIZE)(_In_ struct _DRIVER_OBJECT *DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Definition: iotypes.h:4455
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
HANDLE ServiceHandle
Definition: io.h:406
#define _In_
Definition: ms_sal.h:308
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1535
PDRIVER_OBJECT DriverObject
Definition: io.h:461
Definition: bufpool.h:45
USHORT TagPosition
Definition: io.h:407
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
KIRQL OldIrql
Definition: mm.h:1502
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
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:256
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:44
#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
#define _Post_notnull_
Definition: ms_sal.h:701
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)
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:1726
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:405
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:2166
static const WCHAR L[]
Definition: oid.c:1250
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
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:1862
#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:2679
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1606
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:1455
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
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 _Out_opt_
Definition: ms_sal.h:346
#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:2304
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:430
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
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:462
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
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:1228
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:129
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:136
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:2105
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
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:4471
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:3310
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:694
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:283