ReactOS  0.4.15-dev-3295-gaa8fc87
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  /*
451  * Retrieve the driver's PE image NT header and perform some sanity checks.
452  * NOTE: We suppose that since the driver has been successfully loaded,
453  * its NT and optional headers are all valid and have expected sizes.
454  */
455  PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
456  ASSERT(NtHeaders);
457  // NOTE: ModuleObject->SizeOfImage is actually (number of PTEs)*PAGE_SIZE.
458  ASSERT(ModuleObject->SizeOfImage == ROUND_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage));
459  ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
460 
461  /* Obtain the registry path for the DriverInit routine */
462  PKEY_NAME_INFORMATION nameInfo;
463  ULONG infoLength;
464  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
466  {
467  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
468  if (nameInfo)
469  {
470  Status = ZwQueryKey(ServiceHandle,
472  nameInfo,
473  infoLength,
474  &infoLength);
475  if (NT_SUCCESS(Status))
476  {
477  RegistryPath.Length = nameInfo->NameLength;
478  RegistryPath.MaximumLength = nameInfo->NameLength;
479  RegistryPath.Buffer = nameInfo->Name;
480  }
481  else
482  {
483  ExFreePoolWithTag(nameInfo, TAG_IO);
484  }
485  }
486  else
487  {
489  }
490  }
491  else
492  {
494  }
495 
496  if (!NT_SUCCESS(Status))
497  {
499  RtlFreeUnicodeString(&DriverName);
500  MmUnloadSystemImage(ModuleObject);
501  return Status;
502  }
503 
504  /* Create the driver object */
505  ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
506  OBJECT_ATTRIBUTES objAttrs;
507  PDRIVER_OBJECT driverObject;
508  InitializeObjectAttributes(&objAttrs,
509  &DriverName,
511  NULL,
512  NULL);
513 
516  &objAttrs,
517  KernelMode,
518  NULL,
519  ObjectSize,
520  0,
521  0,
522  (PVOID*)&driverObject);
523  if (!NT_SUCCESS(Status))
524  {
525  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
527  RtlFreeUnicodeString(&DriverName);
528  MmUnloadSystemImage(ModuleObject);
529  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
530  return Status;
531  }
532 
533  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
534 
535  RtlZeroMemory(driverObject, ObjectSize);
536  driverObject->Type = IO_TYPE_DRIVER;
537  driverObject->Size = sizeof(DRIVER_OBJECT);
538 
539  /* Set the legacy flag if this is not a WDM driver */
541  driverObject->Flags |= DRVO_LEGACY_DRIVER;
542 
543  driverObject->DriverSection = ModuleObject;
544  driverObject->DriverStart = ModuleObject->DllBase;
545  driverObject->DriverSize = ModuleObject->SizeOfImage;
546  driverObject->DriverInit = ModuleObject->EntryPoint;
547  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
548  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
549  driverObject->DriverExtension->DriverObject = driverObject;
550 
551  /* Loop all Major Functions */
552  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
553  {
554  /* Invalidate each function */
555  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
556  }
557 
558  /* Add the Object and get its handle */
559  HANDLE hDriver;
560  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
561  if (!NT_SUCCESS(Status))
562  {
563  ExFreePoolWithTag(nameInfo, TAG_IO);
565  RtlFreeUnicodeString(&DriverName);
566  return Status;
567  }
568 
569  /* Now reference it */
571  0,
573  KernelMode,
574  (PVOID*)&driverObject,
575  NULL);
576 
577  /* Close the extra handle */
578  ZwClose(hDriver);
579 
580  if (!NT_SUCCESS(Status))
581  {
582  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
584  RtlFreeUnicodeString(&DriverName);
585  return Status;
586  }
587 
588  /* Set up the service key name buffer */
589  UNICODE_STRING serviceKeyName;
590  serviceKeyName.Length = 0;
591  // NULL-terminate for Windows compatibility
592  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
593  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
594  serviceKeyName.MaximumLength,
595  TAG_IO);
596  if (!serviceKeyName.Buffer)
597  {
598  ObMakeTemporaryObject(driverObject);
599  ObDereferenceObject(driverObject);
600  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
602  RtlFreeUnicodeString(&DriverName);
604  }
605 
606  /* Copy the name and set it in the driver extension */
607  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
609  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
610 
611  /* Make a copy of the driver name to store in the driver object */
612  UNICODE_STRING driverNamePaged;
613  driverNamePaged.Length = 0;
614  // NULL-terminate for Windows compatibility
615  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
616  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
617  driverNamePaged.MaximumLength,
618  TAG_IO);
619  if (!driverNamePaged.Buffer)
620  {
621  ObMakeTemporaryObject(driverObject);
622  ObDereferenceObject(driverObject);
623  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
624  RtlFreeUnicodeString(&DriverName);
626  }
627 
628  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
629  driverObject->DriverName = driverNamePaged;
630 
631  /* Finally, call its init function */
632  Status = driverObject->DriverInit(driverObject, &RegistryPath);
633  *DriverEntryStatus = Status;
634  if (!NT_SUCCESS(Status))
635  {
636  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
637  // return a special status value in case of failure
639  }
640 
641  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
642  * Other parts of the I/O manager depend on this behavior */
643  if (!driverObject->DeviceObject)
644  {
645  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
646  }
647 
648  // Windows does this fixup - keep it for compatibility
649  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
650  {
651  /*
652  * Make sure the driver didn't set any dispatch entry point to NULL!
653  * Doing so is illegal; drivers shouldn't touch entry points they
654  * do not implement.
655  */
656 
657  /* Check if it did so anyway */
658  if (!driverObject->MajorFunction[i])
659  {
660  /* Print a warning in the debug log */
661  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
662  &driverObject->DriverName, i);
663 
664  /* Fix it up */
665  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
666  }
667  }
668 
669  // TODO: for legacy drivers, unload the driver if it didn't create any DO
670 
671  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
672  RtlFreeUnicodeString(&DriverName);
673 
674  if (!NT_SUCCESS(Status))
675  {
676  // if the driver entry has been failed, clear the object
677  ObMakeTemporaryObject(driverObject);
678  ObDereferenceObject(driverObject);
679  return Status;
680  }
681 
682  *OutDriverObject = driverObject;
683 
684  MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)driverObject->DriverSection);
685 
686  /* Set the driver as initialized */
687  IopReadyDeviceObjects(driverObject);
688 
690 
691  return STATUS_SUCCESS;
692 }
693 
694 NTSTATUS
695 NTAPI
697  IN PUNICODE_STRING ImageFileDirectory,
698  IN PUNICODE_STRING NamePrefix OPTIONAL,
699  OUT PCHAR *MissingApi,
700  OUT PWCHAR *MissingDriver,
701  OUT PLOAD_IMPORTS *LoadImports);
702 
703 //
704 // Used for images already loaded (boot drivers)
705 //
706 CODE_SEG("INIT")
707 NTSTATUS
708 NTAPI
711  PLDR_DATA_TABLE_ENTRY *ModuleObject)
712 {
714  UNICODE_STRING BaseName, BaseDirectory;
715  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
716  PCHAR MissingApiName, Buffer;
717  PWCHAR MissingDriverName;
718  PVOID DriverBase = LdrEntry->DllBase;
719 
720  /* Allocate a buffer we'll use for names */
723  TAG_LDR_WSTR);
724  if (!Buffer)
725  {
726  /* Fail */
728  }
729 
730  /* Check for a separator */
731  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
732  {
733  PWCHAR p;
734  ULONG BaseLength;
735 
736  /* Loop the path until we get to the base name */
737  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
738  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
739 
740  /* Get the length */
741  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
742  BaseLength *= sizeof(WCHAR);
743 
744  /* Setup the string */
745  BaseName.Length = (USHORT)BaseLength;
746  BaseName.Buffer = p;
747  }
748  else
749  {
750  /* Otherwise, we already have a base name */
751  BaseName.Length = FileName->Length;
752  BaseName.Buffer = FileName->Buffer;
753  }
754 
755  /* Setup the maximum length */
756  BaseName.MaximumLength = BaseName.Length;
757 
758  /* Now compute the base directory */
759  BaseDirectory = *FileName;
760  BaseDirectory.Length -= BaseName.Length;
761  BaseDirectory.MaximumLength = BaseDirectory.Length;
762 
763  /* Resolve imports */
764  MissingApiName = Buffer;
765  Status = MiResolveImageReferences(DriverBase,
766  &BaseDirectory,
767  NULL,
768  &MissingApiName,
769  &MissingDriverName,
770  &LoadedImports);
771 
772  /* Free the temporary buffer */
774 
775  /* Check the result of the imports resolution */
776  if (!NT_SUCCESS(Status)) return Status;
777 
778  /* Return */
779  *ModuleObject = LdrEntry;
780  return STATUS_SUCCESS;
781 }
782 
785 
786 /*
787  * IopInitializeBuiltinDriver
788  *
789  * Initialize a driver that is already loaded in memory.
790  */
791 CODE_SEG("INIT")
792 static
793 BOOLEAN
795 {
798  PWCHAR Buffer, FileNameWithoutPath;
799  PWSTR FileExtension;
800  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
801  PLDR_DATA_TABLE_ENTRY LdrEntry;
802  PLIST_ENTRY NextEntry;
805 
806  /*
807  * Display 'Loading XXX...' message
808  */
811 
813  ModuleName->Length + sizeof(UNICODE_NULL),
814  TAG_IO);
815  if (Buffer == NULL)
816  {
817  return FALSE;
818  }
819 
821  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
822 
823  /*
824  * Generate filename without path (not needed by freeldr)
825  */
826  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
827  if (FileNameWithoutPath == NULL)
828  {
829  FileNameWithoutPath = Buffer;
830  }
831  else
832  {
833  FileNameWithoutPath++;
834  }
835 
836  /*
837  * Strip the file extension from ServiceName
838  */
839  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
841  if (!Success)
842  {
843  return FALSE;
844  }
845 
846  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
847  if (FileExtension != NULL)
848  {
849  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
850  FileExtension[0] = UNICODE_NULL;
851  }
852 
854 
855  // Make the registry path for the driver
856  RegistryPath.Length = 0;
857  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
859  if (RegistryPath.Buffer == NULL)
860  {
861  return FALSE;
862  }
866 
867  HANDLE serviceHandle;
868  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
870  if (!NT_SUCCESS(Status))
871  {
872  return FALSE;
873  }
874 
875  /* Lookup the new Ldr entry in PsLoadedModuleList */
876  for (NextEntry = PsLoadedModuleList.Flink;
877  NextEntry != &PsLoadedModuleList;
878  NextEntry = NextEntry->Flink)
879  {
880  LdrEntry = CONTAINING_RECORD(NextEntry,
882  InLoadOrderLinks);
884  {
885  break;
886  }
887  }
888  ASSERT(NextEntry != &PsLoadedModuleList);
889 
890  /*
891  * Initialize the driver
892  */
893  NTSTATUS driverEntryStatus;
895  serviceHandle,
896  &DriverObject,
897  &driverEntryStatus);
898 
899  if (!NT_SUCCESS(Status))
900  {
901  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
902  return FALSE;
903  }
904 
905  // The driver has been loaded, now check if where are any PDOs
906  // for that driver, and queue AddDevice call for them.
907  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
908  // is populated upon a new device arrival based on a (critical) device database
909 
910  // Legacy drivers may add devices inside DriverEntry.
911  // We're lazy and always assume that they are doing so
912  BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
913 
914  HANDLE enumServiceHandle;
915  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
916 
917  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
918  ZwClose(serviceHandle);
919 
920  if (NT_SUCCESS(Status))
921  {
922  ULONG instanceCount = 0;
924  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
925  if (!NT_SUCCESS(Status))
926  {
927  goto Cleanup;
928  }
929  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
930  {
931  ExFreePool(kvInfo);
932  goto Cleanup;
933  }
934 
935  RtlMoveMemory(&instanceCount,
936  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
937  sizeof(ULONG));
938  ExFreePool(kvInfo);
939 
940  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
941 
942  for (ULONG i = 0; i < instanceCount; i++)
943  {
944  WCHAR num[11];
945  UNICODE_STRING instancePath;
946  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
947 
948  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
949  if (!NT_SUCCESS(Status))
950  {
951  continue;
952  }
953  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
954  {
955  ExFreePool(kvInfo);
956  continue;
957  }
958 
959  instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
960  instancePath.MaximumLength = kvInfo->DataLength;
962  instancePath.MaximumLength,
963  TAG_IO);
964  if (instancePath.Buffer)
965  {
966  RtlMoveMemory(instancePath.Buffer,
967  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
968  instancePath.Length);
969  instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
970 
973  ObDereferenceObject(pdo);
974  deviceAdded = TRUE;
975  }
976 
977  ExFreePool(kvInfo);
978  }
979 
980  ZwClose(enumServiceHandle);
981  }
982 Cleanup:
983  /* Remove extra reference from IopInitializeDriverModule */
985 
986  return deviceAdded;
987 }
988 
989 /*
990  * IopInitializeBootDrivers
991  *
992  * Initialize boot drivers and free memory for boot files.
993  *
994  * Parameters
995  * None
996  *
997  * Return Value
998  * None
999  */
1000 CODE_SEG("INIT")
1001 VOID
1002 FASTCALL
1004 {
1005  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1006  PLDR_DATA_TABLE_ENTRY LdrEntry;
1007  NTSTATUS Status;
1008  UNICODE_STRING DriverName;
1009  ULONG i, Index;
1010  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1011  HANDLE KeyHandle;
1012  PBOOT_DRIVER_LIST_ENTRY BootEntry;
1013  DPRINT("IopInitializeBootDrivers()\n");
1014 
1015  /* Create the RAW FS built-in driver */
1016  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1017 
1018  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1019  if (!NT_SUCCESS(Status))
1020  {
1021  /* Fail */
1022  return;
1023  }
1024 
1025  /* Get highest group order index */
1027  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
1028 
1029  /* Allocate the group table */
1031  IopGroupIndex * sizeof(LIST_ENTRY),
1032  TAG_IO);
1033  if (IopGroupTable == NULL) ASSERT(FALSE);
1034 
1035  /* Initialize the group table lists */
1036  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1037 
1038  /* Loop the boot modules */
1039  ListHead = &KeLoaderBlock->LoadOrderListHead;
1040  for (NextEntry = ListHead->Flink;
1041  NextEntry != ListHead;
1042  NextEntry = NextEntry->Flink)
1043  {
1044  /* Get the entry */
1045  LdrEntry = CONTAINING_RECORD(NextEntry,
1047  InLoadOrderLinks);
1048 
1049  /* Check if the DLL needs to be initialized */
1050  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1051  {
1052  /* Call its entrypoint */
1053  MmCallDllInitialize(LdrEntry, NULL);
1054  }
1055  }
1056 
1057  /* Loop the boot drivers */
1058  ListHead = &KeLoaderBlock->BootDriverListHead;
1059  for (NextEntry = ListHead->Flink;
1060  NextEntry != ListHead;
1061  NextEntry = NextEntry->Flink)
1062  {
1063  /* Get the entry */
1064  BootEntry = CONTAINING_RECORD(NextEntry,
1066  Link);
1067 
1068  // FIXME: TODO: This LdrEntry is to be used in a special handling
1069  // for SETUPLDR (a similar procedure is done on Windows), where
1070  // the loader would, under certain conditions, be loaded in the
1071  // SETUPLDR-specific code block below...
1072 #if 0
1073  /* Get the driver loader entry */
1074  LdrEntry = BootEntry->LdrEntry;
1075 #endif
1076 
1077  /* Allocate our internal accounting structure */
1079  sizeof(DRIVER_INFORMATION),
1080  TAG_IO);
1081  if (DriverInfo)
1082  {
1083  /* Zero it and initialize it */
1086  DriverInfo->DataTableEntry = BootEntry;
1087 
1088  /* Open the registry key */
1090  NULL,
1091  &BootEntry->RegistryPath,
1092  KEY_READ);
1093  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1094 #if 0
1095  if (NT_SUCCESS(Status))
1096 #else // Hack still needed...
1097  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1098  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1099 #endif
1100  {
1101  /* Save the handle */
1103 
1104  /* Get the group oder index */
1106 
1107  /* Get the tag position */
1109 
1110  /* Insert it into the list, at the right place */
1112  NextEntry2 = IopGroupTable[Index].Flink;
1113  while (NextEntry2 != &IopGroupTable[Index])
1114  {
1115  /* Get the driver info */
1116  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1118  Link);
1119 
1120  /* Check if we found the right tag position */
1121  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1122  {
1123  /* We're done */
1124  break;
1125  }
1126 
1127  /* Next entry */
1128  NextEntry2 = NextEntry2->Flink;
1129  }
1130 
1131  /* Insert us right before the next entry */
1132  NextEntry2 = NextEntry2->Blink;
1133  InsertHeadList(NextEntry2, &DriverInfo->Link);
1134  }
1135  }
1136  }
1137 
1138  /* Loop each group index */
1139  for (i = 0; i < IopGroupIndex; i++)
1140  {
1141  /* Loop each group table */
1142  for (NextEntry = IopGroupTable[i].Flink;
1143  NextEntry != &IopGroupTable[i];
1144  NextEntry = NextEntry->Flink)
1145  {
1146  /* Get the entry */
1147  DriverInfo = CONTAINING_RECORD(NextEntry,
1149  Link);
1150 
1151  /* Get the driver loader entry */
1152  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1153 
1154  /* Initialize it */
1155  if (IopInitializeBuiltinDriver(LdrEntry))
1156  {
1157  // it does not make sense to enumerate the tree if there are no new devices added
1160  NULL,
1161  NULL);
1162  }
1163  }
1164  }
1165 
1166  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1167  * when some devices are not being initialized with their drivers. This flag is used to delay
1168  * all actions with devices (except PnP root device) until boot drivers are loaded.
1169  * See PiQueueDeviceAction function
1170  */
1172 
1173  DbgPrint("BOOT DRIVERS LOADED\n");
1174 
1177  NULL,
1178  NULL);
1179 }
1180 
1181 CODE_SEG("INIT")
1182 VOID
1183 FASTCALL
1185 {
1186  PUNICODE_STRING *DriverList, *SavedList;
1187 
1189 
1190  /* No system drivers on the boot cd */
1191  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1192 
1193  /* Get the driver list */
1194  SavedList = DriverList = CmGetSystemDriverList();
1195  ASSERT(DriverList);
1196 
1197  /* Loop it */
1198  while (*DriverList)
1199  {
1200  /* Load the driver */
1201  ZwLoadDriver(*DriverList);
1202 
1203  /* Free the entry */
1204  RtlFreeUnicodeString(*DriverList);
1205  ExFreePool(*DriverList);
1206 
1207  /* Next entry */
1209  DriverList++;
1210  }
1211 
1212  /* Free the list */
1213  ExFreePool(SavedList);
1214 
1217  NULL,
1218  NULL);
1219 }
1220 
1221 /*
1222  * IopUnloadDriver
1223  *
1224  * Unloads a device driver.
1225  *
1226  * Parameters
1227  * DriverServiceName
1228  * Name of the service to unload (registry key).
1229  *
1230  * UnloadPnpDrivers
1231  * Whether to unload Plug & Plug or only legacy drivers. If this
1232  * parameter is set to FALSE, the routine will unload only legacy
1233  * drivers.
1234  *
1235  * Return Value
1236  * Status
1237  *
1238  * To do
1239  * Guard the whole function by SEH.
1240  */
1241 
1243 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1244 {
1245  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1247  UNICODE_STRING ImagePath;
1252  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1253  NTSTATUS Status;
1254  USHORT LastBackslash;
1255  BOOLEAN SafeToUnload = TRUE;
1257  UNICODE_STRING CapturedServiceName;
1258 
1259  PAGED_CODE();
1260 
1262 
1263  /* Need the appropriate priviliege */
1265  {
1266  DPRINT1("No unload privilege!\n");
1268  }
1269 
1270  /* Capture the service name */
1271  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1272  PreviousMode,
1273  DriverServiceName);
1274  if (!NT_SUCCESS(Status))
1275  {
1276  return Status;
1277  }
1278 
1279  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1280 
1281  /* We need a service name */
1282  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1283  {
1284  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1285  return STATUS_INVALID_PARAMETER;
1286  }
1287 
1288  /*
1289  * Get the service name from the registry key name
1290  */
1292  &CapturedServiceName,
1293  &Backslash,
1294  &LastBackslash);
1295  if (NT_SUCCESS(Status))
1296  {
1297  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1298  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1299  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1300  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1301  }
1302  else
1303  {
1304  ServiceName = CapturedServiceName;
1305  }
1306 
1307  /*
1308  * Construct the driver object name
1309  */
1310  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1311  ServiceName.Length,
1312  &ObjectName.MaximumLength);
1313  if (!NT_SUCCESS(Status))
1314  {
1315  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1316  return Status;
1317  }
1318  ObjectName.Length = 0;
1320  ObjectName.MaximumLength,
1321  TAG_IO);
1322  if (!ObjectName.Buffer)
1323  {
1324  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1326  }
1329 
1330  /*
1331  * Find the driver object
1332  */
1334  0,
1335  0,
1336  0,
1338  KernelMode,
1339  0,
1340  (PVOID*)&DriverObject);
1341 
1342  if (!NT_SUCCESS(Status))
1343  {
1344  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1346  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1347  return Status;
1348  }
1349 
1350  /* Free the buffer for driver object name */
1352 
1353  /* Check that driver is not already unloading */
1354  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1355  {
1356  DPRINT1("Driver deletion pending\n");
1358  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1359  return STATUS_DELETE_PENDING;
1360  }
1361 
1362  /*
1363  * Get path of service...
1364  */
1366 
1367  RtlInitUnicodeString(&ImagePath, NULL);
1368 
1369  QueryTable[0].Name = L"ImagePath";
1371  QueryTable[0].EntryContext = &ImagePath;
1372 
1374  CapturedServiceName.Buffer,
1375  QueryTable,
1376  NULL,
1377  NULL);
1378 
1379  /* We no longer need service name */
1380  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1381 
1382  if (!NT_SUCCESS(Status))
1383  {
1384  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1386  return Status;
1387  }
1388 
1389  /*
1390  * Normalize the image path for all later processing.
1391  */
1392  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1393 
1394  if (!NT_SUCCESS(Status))
1395  {
1396  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1398  return Status;
1399  }
1400 
1401  /* Free the service path */
1402  ExFreePool(ImagePath.Buffer);
1403 
1404  /*
1405  * Unload the module and release the references to the device object
1406  */
1407 
1408  /* Call the load/unload routine, depending on current process */
1409  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1410  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1411  {
1412  /* Loop through each device object of the driver
1413  and set DOE_UNLOAD_PENDING flag */
1414  DeviceObject = DriverObject->DeviceObject;
1415  while (DeviceObject)
1416  {
1417  /* Set the unload pending flag for the device */
1418  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1419  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1420 
1421  /* Make sure there are no attached devices or no reference counts */
1422  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1423  {
1424  /* Not safe to unload */
1425  DPRINT1("Drivers device object is referenced or has attached devices\n");
1426 
1427  SafeToUnload = FALSE;
1428  }
1429 
1430  DeviceObject = DeviceObject->NextDevice;
1431  }
1432 
1433  /* If not safe to unload, then return success */
1434  if (!SafeToUnload)
1435  {
1437  return STATUS_SUCCESS;
1438  }
1439 
1440  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1441 
1442  /* Set the unload invoked flag and call the unload routine */
1446 
1447  /* Mark the driver object temporary, so it could be deleted later */
1449 
1450  /* Dereference it 2 times */
1453 
1454  return Status;
1455  }
1456  else
1457  {
1458  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1459 
1460  /* Dereference one time (refd inside this function) */
1462 
1463  /* Return unloading failure */
1465  }
1466 }
1467 
1468 VOID
1469 NTAPI
1471 {
1472  PDRIVER_REINIT_ITEM ReinitItem;
1474 
1475  /* Get the first entry and start looping */
1478  while (Entry)
1479  {
1480  /* Get the item */
1481  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1482 
1483  /* Increment reinitialization counter */
1484  ReinitItem->DriverObject->DriverExtension->Count++;
1485 
1486  /* Remove the device object flag */
1487  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1488 
1489  /* Call the routine */
1490  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1491  ReinitItem->Context,
1492  ReinitItem->DriverObject->
1493  DriverExtension->Count);
1494 
1495  /* Free the entry */
1496  ExFreePool(Entry);
1497 
1498  /* Move to the next one */
1501  }
1502 }
1503 
1504 VOID
1505 NTAPI
1507 {
1508  PDRIVER_REINIT_ITEM ReinitItem;
1510 
1511  /* Get the first entry and start looping */
1514  while (Entry)
1515  {
1516  /* Get the item */
1517  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1518 
1519  /* Increment reinitialization counter */
1520  ReinitItem->DriverObject->DriverExtension->Count++;
1521 
1522  /* Remove the device object flag */
1524 
1525  /* Call the routine */
1526  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1527  ReinitItem->Context,
1528  ReinitItem->DriverObject->
1529  DriverExtension->Count);
1530 
1531  /* Free the entry */
1532  ExFreePool(Entry);
1533 
1534  /* Move to the next one */
1537  }
1538 
1539  /* Wait for all device actions being finished*/
1541 }
1542 
1543 /* PUBLIC FUNCTIONS ***********************************************************/
1544 
1545 /*
1546  * @implemented
1547  */
1548 NTSTATUS
1549 NTAPI
1551  _In_opt_ PUNICODE_STRING DriverName,
1552  _In_ PDRIVER_INITIALIZE InitializationFunction)
1553 {
1554  WCHAR NameBuffer[100];
1555  USHORT NameLength;
1556  UNICODE_STRING LocalDriverName;
1557  NTSTATUS Status;
1559  ULONG ObjectSize;
1561  UNICODE_STRING ServiceKeyName;
1562  HANDLE hDriver;
1563  ULONG i, RetryCount = 0;
1564 
1565 try_again:
1566  /* First, create a unique name for the driver if we don't have one */
1567  if (!DriverName)
1568  {
1569  /* Create a random name and set up the string */
1570  NameLength = (USHORT)swprintf(NameBuffer,
1571  DRIVER_ROOT_NAME L"%08u",
1573  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1574  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1575  LocalDriverName.Buffer = NameBuffer;
1576  }
1577  else
1578  {
1579  /* So we can avoid another code path, use a local var */
1580  LocalDriverName = *DriverName;
1581  }
1582 
1583  /* Initialize the Attributes */
1584  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1586  &LocalDriverName,
1588  NULL,
1589  NULL);
1590 
1591  /* Create the Object */
1595  KernelMode,
1596  NULL,
1597  ObjectSize,
1598  0,
1599  0,
1600  (PVOID*)&DriverObject);
1601  if (!NT_SUCCESS(Status)) return Status;
1602 
1603  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1604 
1605  /* Set up the Object */
1606  RtlZeroMemory(DriverObject, ObjectSize);
1607  DriverObject->Type = IO_TYPE_DRIVER;
1608  DriverObject->Size = sizeof(DRIVER_OBJECT);
1610  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1611  DriverObject->DriverExtension->DriverObject = DriverObject;
1612  DriverObject->DriverInit = InitializationFunction;
1613  /* Loop all Major Functions */
1614  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1615  {
1616  /* Invalidate each function */
1617  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1618  }
1619 
1620  /* Set up the service key name buffer */
1621  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1622  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1623  if (!ServiceKeyName.Buffer)
1624  {
1625  /* Fail */
1629  }
1630 
1631  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1632  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1633  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1634  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1635 
1636  /* Make a copy of the driver name to store in the driver object */
1637  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1638  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1639  DriverObject->DriverName.MaximumLength,
1640  TAG_IO);
1641  if (!DriverObject->DriverName.Buffer)
1642  {
1643  /* Fail */
1647  }
1648 
1649  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1650 
1651  /* Add the Object and get its handle */
1653  NULL,
1655  0,
1656  NULL,
1657  &hDriver);
1658 
1659  /* Eliminate small possibility when this function is called more than
1660  once in a row, and KeTickCount doesn't get enough time to change */
1661  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1662  {
1663  RetryCount++;
1664  goto try_again;
1665  }
1666 
1667  if (!NT_SUCCESS(Status)) return Status;
1668 
1669  /* Now reference it */
1671  0,
1673  KernelMode,
1674  (PVOID*)&DriverObject,
1675  NULL);
1676 
1677  /* Close the extra handle */
1678  ZwClose(hDriver);
1679 
1680  if (!NT_SUCCESS(Status))
1681  {
1682  /* Fail */
1685  return Status;
1686  }
1687 
1688  /* Finally, call its init function */
1689  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1690  Status = InitializationFunction(DriverObject, NULL);
1691  if (!NT_SUCCESS(Status))
1692  {
1693  /* If it didn't work, then kill the object */
1694  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1697  return Status;
1698  }
1699 
1700  // Windows does this fixup - keep it for compatibility
1701  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1702  {
1703  /*
1704  * Make sure the driver didn't set any dispatch entry point to NULL!
1705  * Doing so is illegal; drivers shouldn't touch entry points they
1706  * do not implement.
1707  */
1708 
1709  /* Check if it did so anyway */
1710  if (!DriverObject->MajorFunction[i])
1711  {
1712  /* Print a warning in the debug log */
1713  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1714  &DriverObject->DriverName, i);
1715 
1716  /* Fix it up */
1717  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1718  }
1719  }
1720 
1721  /* Return the Status */
1722  return Status;
1723 }
1724 
1725 /*
1726  * @implemented
1727  */
1728 VOID
1729 NTAPI
1731 {
1732  /* Simply dereference the Object */
1734 }
1735 
1736 /*
1737  * @implemented
1738  */
1739 VOID
1740 NTAPI
1742  IN PDRIVER_REINITIALIZE ReinitRoutine,
1743  IN PVOID Context)
1744 {
1745  PDRIVER_REINIT_ITEM ReinitItem;
1746 
1747  /* Allocate the entry */
1748  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1749  sizeof(DRIVER_REINIT_ITEM),
1750  TAG_REINIT);
1751  if (!ReinitItem) return;
1752 
1753  /* Fill it out */
1754  ReinitItem->DriverObject = DriverObject;
1755  ReinitItem->ReinitRoutine = ReinitRoutine;
1756  ReinitItem->Context = Context;
1757 
1758  /* Set the Driver Object flag and insert the entry into the list */
1761  &ReinitItem->ItemEntry,
1763 }
1764 
1765 /*
1766  * @implemented
1767  */
1768 VOID
1769 NTAPI
1771  IN PDRIVER_REINITIALIZE ReinitRoutine,
1772  IN PVOID Context)
1773 {
1774  PDRIVER_REINIT_ITEM ReinitItem;
1775 
1776  /* Allocate the entry */
1777  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1778  sizeof(DRIVER_REINIT_ITEM),
1779  TAG_REINIT);
1780  if (!ReinitItem) return;
1781 
1782  /* Fill it out */
1783  ReinitItem->DriverObject = DriverObject;
1784  ReinitItem->ReinitRoutine = ReinitRoutine;
1785  ReinitItem->Context = Context;
1786 
1787  /* Set the Driver Object flag and insert the entry into the list */
1790  &ReinitItem->ItemEntry,
1792 }
1793 
1794 /*
1795  * @implemented
1796  */
1797 NTSTATUS
1798 NTAPI
1801  IN ULONG DriverObjectExtensionSize,
1802  OUT PVOID *DriverObjectExtension)
1803 {
1804  KIRQL OldIrql;
1805  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1806  BOOLEAN Inserted = FALSE;
1807 
1808  /* Assume failure */
1809  *DriverObjectExtension = NULL;
1810 
1811  /* Allocate the extension */
1812  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1813  sizeof(IO_CLIENT_EXTENSION) +
1814  DriverObjectExtensionSize,
1816  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1817 
1818  /* Clear the extension for teh caller */
1819  RtlZeroMemory(NewDriverExtension,
1820  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1821 
1822  /* Acqure lock */
1824 
1825  /* Fill out the extension */
1827 
1828  /* Loop the current extensions */
1829  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1830  ClientDriverExtension;
1831  while (DriverExtensions)
1832  {
1833  /* Check if the identifier matches */
1834  if (DriverExtensions->ClientIdentificationAddress ==
1836  {
1837  /* We have a collision, break out */
1838  break;
1839  }
1840 
1841  /* Go to the next one */
1842  DriverExtensions = DriverExtensions->NextExtension;
1843  }
1844 
1845  /* Check if we didn't collide */
1846  if (!DriverExtensions)
1847  {
1848  /* Link this one in */
1849  NewDriverExtension->NextExtension =
1850  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1851  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1852  NewDriverExtension;
1853  Inserted = TRUE;
1854  }
1855 
1856  /* Release the lock */
1858 
1859  /* Check if insertion failed */
1860  if (!Inserted)
1861  {
1862  /* Free the entry and fail */
1863  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1865  }
1866 
1867  /* Otherwise, return the pointer */
1868  *DriverObjectExtension = NewDriverExtension + 1;
1869  return STATUS_SUCCESS;
1870 }
1871 
1872 /*
1873  * @implemented
1874  */
1875 PVOID
1876 NTAPI
1879 {
1880  KIRQL OldIrql;
1881  PIO_CLIENT_EXTENSION DriverExtensions;
1882 
1883  /* Acquire lock */
1885 
1886  /* Loop the list until we find the right one */
1887  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1888  while (DriverExtensions)
1889  {
1890  /* Check for a match */
1891  if (DriverExtensions->ClientIdentificationAddress ==
1893  {
1894  /* Break out */
1895  break;
1896  }
1897 
1898  /* Keep looping */
1899  DriverExtensions = DriverExtensions->NextExtension;
1900  }
1901 
1902  /* Release lock */
1904 
1905  /* Return nothing or the extension */
1906  if (!DriverExtensions) return NULL;
1907  return DriverExtensions + 1;
1908 }
1909 
1910 NTSTATUS
1912  _In_ HANDLE ServiceHandle,
1914 {
1915  UNICODE_STRING ImagePath;
1916  NTSTATUS Status;
1917  PLDR_DATA_TABLE_ENTRY ModuleObject;
1919 
1921  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1922  if (NT_SUCCESS(Status))
1923  {
1924  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1925  {
1926  ExFreePool(kvInfo);
1928  }
1929 
1930  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1931  ImagePath.MaximumLength = kvInfo->DataLength;
1933  if (!ImagePath.Buffer)
1934  {
1935  ExFreePool(kvInfo);
1937  }
1938 
1939  RtlMoveMemory(ImagePath.Buffer,
1940  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1941  ImagePath.Length);
1942  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1943  ExFreePool(kvInfo);
1944  }
1945  else
1946  {
1947  return Status;
1948  }
1949 
1950  /*
1951  * Normalize the image path for all later processing.
1952  */
1953  Status = IopNormalizeImagePath(&ImagePath, NULL);
1954  if (!NT_SUCCESS(Status))
1955  {
1956  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1957  return Status;
1958  }
1959 
1960  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1961 
1964 
1965  /*
1966  * Load the driver module
1967  */
1968  DPRINT("Loading module from %wZ\n", &ImagePath);
1969  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1970  RtlFreeUnicodeString(&ImagePath);
1971 
1972  if (!NT_SUCCESS(Status))
1973  {
1974  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1977  return Status;
1978  }
1979 
1980  // Display the loading message
1981  ULONG infoLength;
1982  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1984  {
1986  if (servName)
1987  {
1988  Status = ZwQueryKey(ServiceHandle,
1990  servName,
1991  infoLength,
1992  &infoLength);
1993  if (NT_SUCCESS(Status))
1994  {
1996  .Length = servName->NameLength,
1997  .MaximumLength = servName->NameLength,
1998  .Buffer = servName->Name
1999  };
2000 
2002  }
2003  ExFreePoolWithTag(servName, TAG_IO);
2004  }
2005  }
2006 
2007  NTSTATUS driverEntryStatus;
2008  Status = IopInitializeDriverModule(ModuleObject,
2009  ServiceHandle,
2010  DriverObject,
2011  &driverEntryStatus);
2012  if (!NT_SUCCESS(Status))
2013  {
2014  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2015  }
2016 
2019 
2020  return Status;
2021 }
2022 
2023 static
2024 VOID
2025 NTAPI
2028 {
2029  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2030 
2032 
2033  if (LoadParams->DriverObject)
2034  {
2035  // unload request
2036  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2037  LoadParams->Status = STATUS_SUCCESS;
2038  }
2039  else
2040  {
2041  // load request
2042  HANDLE serviceHandle;
2043  NTSTATUS status;
2044  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2045  if (!NT_SUCCESS(status))
2046  {
2047  LoadParams->Status = status;
2048  }
2049  else
2050  {
2051  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2052  ZwClose(serviceHandle);
2053  }
2054  }
2055 
2056  if (LoadParams->SetEvent)
2057  {
2058  KeSetEvent(&LoadParams->Event, 0, FALSE);
2059  }
2060 }
2061 
2071 NTSTATUS
2075 {
2076  LOAD_UNLOAD_PARAMS LoadParams;
2077 
2078  /* Prepare parameters block */
2079  LoadParams.RegistryPath = RegistryPath;
2080  LoadParams.DriverObject = *DriverObject;
2081 
2083  {
2084  LoadParams.SetEvent = TRUE;
2086 
2087  /* Initialize and queue a work item */
2088  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2090 
2091  /* And wait till it completes */
2093  }
2094  else
2095  {
2096  /* If we're already in a system process, call it right here */
2097  LoadParams.SetEvent = FALSE;
2098  IopLoadUnloadDriverWorker(&LoadParams);
2099  }
2100 
2101  return LoadParams.Status;
2102 }
2103 
2104 /*
2105  * NtLoadDriver
2106  *
2107  * Loads a device driver.
2108  *
2109  * Parameters
2110  * DriverServiceName
2111  * Name of the service to load (registry key).
2112  *
2113  * Return Value
2114  * Status
2115  *
2116  * Status
2117  * implemented
2118  */
2120 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2121 {
2122  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2125  NTSTATUS Status;
2126 
2127  PAGED_CODE();
2128 
2130 
2131  /* Need the appropriate priviliege */
2133  {
2134  DPRINT1("No load privilege!\n");
2136  }
2137 
2138  /* Capture the service name */
2139  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2140  PreviousMode,
2141  DriverServiceName);
2142  if (!NT_SUCCESS(Status))
2143  {
2144  return Status;
2145  }
2146 
2147  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2148 
2149  /* We need a service name */
2150  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2151  {
2152  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2153  return STATUS_INVALID_PARAMETER;
2154  }
2155 
2156  /* Load driver and call its entry point */
2157  DriverObject = NULL;
2158  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2159 
2160  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2161  return Status;
2162 }
2163 
2164 /*
2165  * NtUnloadDriver
2166  *
2167  * Unloads a legacy device driver.
2168  *
2169  * Parameters
2170  * DriverServiceName
2171  * Name of the service to unload (registry key).
2172  *
2173  * Return Value
2174  * Status
2175  *
2176  * Status
2177  * implemented
2178  */
2179 
2182 {
2183  return IopUnloadDriver(DriverServiceName, FALSE);
2184 }
2185 
2186 /* 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:1003
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:1184
PSTR ArcBootDeviceName
Definition: arc.h:503
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
_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
#define DbgPrint
Definition: hal.h:12
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:1799
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:2630
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2026
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1470
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
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
#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:2072
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
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:1911
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:1730
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:1506
#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:1770
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
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
static BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:794
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
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:122
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:29
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:1550
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
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
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:1741
#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:2181
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:1877
#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
PLIST_ENTRY DriverBootReinitTailEntry
Definition: driver.c:25
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
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:2689
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
#define ROUND_TO_PAGES(Size)
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
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
Definition: ntimage.h:462
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
#define RtlImageNtHeader
Definition: compat.h:665
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
_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
DWORD RVA
Definition: compat.h:1121
#define OUT
Definition: typedefs.h:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
ULONG Flags
Definition: ntddk_ex.h:207
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
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
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1243
#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:2120
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:709
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