ReactOS  0.4.15-dev-4570-g4f8bbd1
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 
36 extern BOOLEAN PnpSystemInit;
39 
42 
43 /* TYPES *********************************************************************/
44 
45 // Parameters packet for Load/Unload work item's context
46 typedef struct _LOAD_UNLOAD_PARAMS
47 {
55 
60 
61 /* PRIVATE FUNCTIONS **********************************************************/
62 
64 NTAPI
67  PIRP Irp)
68 {
69  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
70  Irp->IoStatus.Information = 0;
73 }
74 
75 VOID
76 NTAPI
78 {
79  PDRIVER_OBJECT DriverObject = ObjectBody;
80  PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
81  PAGED_CODE();
82 
83  DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
84 
85  /* There must be no device objects remaining at this point */
86  ASSERT(!DriverObject->DeviceObject);
87 
88  /* Get the extension and loop them */
89  DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
90  while (DriverExtension)
91  {
92  /* Get the next one */
93  NextDriverExtension = DriverExtension->NextExtension;
95 
96  /* Move on */
97  DriverExtension = NextDriverExtension;
98  }
99 
100  /* Check if the driver image is still loaded */
101  if (DriverObject->DriverSection)
102  {
103  /* Unload it */
104  MmUnloadSystemImage(DriverObject->DriverSection);
105  }
106 
107  /* Check if it has a name */
108  if (DriverObject->DriverName.Buffer)
109  {
110  /* Free it */
111  ExFreePool(DriverObject->DriverName.Buffer);
112  }
113 
114  /* Check if it has a service key name */
115  if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
116  {
117  /* Free it */
118  ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
119  }
120 }
121 
122 NTSTATUS
124  _In_ HANDLE ServiceHandle,
125  _Out_ PUNICODE_STRING DriverName,
127 {
128  UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
131 
132  PAGED_CODE();
133 
134  /* 1. Check the "ObjectName" field in the driver's registry key (it has priority) */
135  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
136  if (NT_SUCCESS(status))
137  {
138  /* We've got the ObjectName, use it as the driver name */
139  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
140  {
141  ExFreePool(kvInfo);
143  }
144 
145  driverName.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
146  driverName.MaximumLength = kvInfo->DataLength;
147  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
148  if (!driverName.Buffer)
149  {
150  ExFreePool(kvInfo);
152  }
153 
154  RtlMoveMemory(driverName.Buffer,
155  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
156  driverName.Length);
157  driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
158  ExFreePool(kvInfo);
159  }
160 
161  /* Check whether we need to get ServiceName as well, either to construct
162  * the driver name (because we could not use "ObjectName"), or because
163  * it is requested by the caller. */
164  PKEY_BASIC_INFORMATION basicInfo = NULL;
165  if (!NT_SUCCESS(status) || ServiceName != NULL)
166  {
167  /* Retrieve the necessary buffer size */
168  ULONG infoLength;
169  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
171  {
173  goto Cleanup;
174  }
175 
176  /* Allocate the buffer and retrieve the data */
177  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
178  if (!basicInfo)
179  {
181  goto Cleanup;
182  }
183 
184  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
185  if (!NT_SUCCESS(status))
186  {
187  goto Cleanup;
188  }
189 
190  serviceName.Length = basicInfo->NameLength;
191  serviceName.MaximumLength = basicInfo->NameLength;
192  serviceName.Buffer = basicInfo->Name;
193  }
194 
195  /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
196  * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
197  if (driverName.Buffer == NULL)
198  {
199  ASSERT(basicInfo); // Container for serviceName
200 
201  /* Retrieve the driver type */
202  ULONG driverType;
203  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
204  if (!NT_SUCCESS(status))
205  {
206  goto Cleanup;
207  }
208  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
209  {
210  ExFreePool(kvInfo);
212  goto Cleanup;
213  }
214 
215  RtlMoveMemory(&driverType,
216  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
217  sizeof(ULONG));
218  ExFreePool(kvInfo);
219 
220  /* Compute the necessary driver name string size */
221  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
222  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
223  else
224  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
225 
226  driverName.MaximumLength += serviceName.Length;
227  driverName.Length = 0;
228 
229  /* Allocate and build it */
230  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
231  if (!driverName.Buffer)
232  {
234  goto Cleanup;
235  }
236 
237  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
239  else
241 
243  }
244 
245  if (ServiceName != NULL)
246  {
247  ASSERT(basicInfo); // Container for serviceName
248 
249  /* Allocate a copy for the caller */
251  if (!buf)
252  {
254  goto Cleanup;
255  }
256  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
257  ServiceName->MaximumLength = serviceName.Length;
258  ServiceName->Length = serviceName.Length;
259  ServiceName->Buffer = buf;
260  }
261 
262  *DriverName = driverName;
264 
265 Cleanup:
266  if (basicInfo)
267  ExFreePoolWithTag(basicInfo, TAG_IO);
268 
269  if (!NT_SUCCESS(status) && driverName.Buffer)
270  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
271 
272  return status;
273 }
274 
275 /*
276  * RETURNS
277  * TRUE if String2 contains String1 as a suffix.
278  */
279 BOOLEAN
280 NTAPI
282  IN PCUNICODE_STRING String1,
284 {
285  PWCHAR pc1;
286  PWCHAR pc2;
287  ULONG Length;
288 
289  if (String2->Length < String1->Length)
290  return FALSE;
291 
292  Length = String1->Length / 2;
293  pc1 = String1->Buffer;
294  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
295 
296  if (pc1 && pc2)
297  {
298  while (Length--)
299  {
300  if( *pc1++ != *pc2++ )
301  return FALSE;
302  }
303  return TRUE;
304  }
305  return FALSE;
306 }
307 
308 /*
309  * IopDisplayLoadingMessage
310  *
311  * Display 'Loading XXX...' message.
312  */
313 VOID
314 FASTCALL
316 {
317  CHAR TextBuffer[256];
318  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
319 
320  if (ExpInTextModeSetup) return;
321  if (!KeLoaderBlock) return;
323  snprintf(TextBuffer, sizeof(TextBuffer),
324  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
327  ServiceName,
328  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
330 }
331 
332 /*
333  * IopNormalizeImagePath
334  *
335  * Normalize an image path to contain complete path.
336  *
337  * Parameters
338  * ImagePath
339  * The input path and on exit the result path. ImagePath.Buffer
340  * must be allocated by ExAllocatePool on input. Caller is responsible
341  * for freeing the buffer when it's no longer needed.
342  *
343  * ServiceName
344  * Name of the service that ImagePath belongs to.
345  *
346  * Return Value
347  * Status
348  *
349  * Remarks
350  * The input image path isn't freed on error.
351  */
352 NTSTATUS
353 FASTCALL
355  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
356  PUNICODE_STRING ImagePath,
358 {
359  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
360  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
361  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
362  UNICODE_STRING InputImagePath;
363 
364  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
365 
366  InputImagePath = *ImagePath;
367  if (InputImagePath.Length == 0)
368  {
369  ImagePath->Length = 0;
370  ImagePath->MaximumLength = DriversPathString.Length +
371  ServiceName->Length +
372  DotSysString.Length +
373  sizeof(UNICODE_NULL);
374  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
375  ImagePath->MaximumLength,
376  TAG_IO);
377  if (ImagePath->Buffer == NULL)
378  return STATUS_NO_MEMORY;
379 
380  RtlCopyUnicodeString(ImagePath, &DriversPathString);
382  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
383  }
384  else if (InputImagePath.Buffer[0] != L'\\')
385  {
386  ImagePath->Length = 0;
387  ImagePath->MaximumLength = SystemRootString.Length +
388  InputImagePath.Length +
389  sizeof(UNICODE_NULL);
390  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
391  ImagePath->MaximumLength,
392  TAG_IO);
393  if (ImagePath->Buffer == NULL)
394  return STATUS_NO_MEMORY;
395 
396  RtlCopyUnicodeString(ImagePath, &SystemRootString);
397  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
398 
399  /* Free caller's string */
400  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
401  }
402 
403  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
404 
405  return STATUS_SUCCESS;
406 }
407 
427 NTSTATUS
429  _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
430  _In_ HANDLE ServiceHandle,
431  _Out_ PDRIVER_OBJECT *OutDriverObject,
432  _Out_ NTSTATUS *DriverEntryStatus)
433 {
436 
437  PAGED_CODE();
438 
439  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
440  if (!NT_SUCCESS(Status))
441  {
442  MmUnloadSystemImage(ModuleObject);
443  return Status;
444  }
445 
446  DPRINT("Driver name: '%wZ'\n", &DriverName);
447 
448  /*
449  * Retrieve the driver's PE image NT header and perform some sanity checks.
450  * NOTE: We suppose that since the driver has been successfully loaded,
451  * its NT and optional headers are all valid and have expected sizes.
452  */
453  PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
454  ASSERT(NtHeaders);
455  // NOTE: ModuleObject->SizeOfImage is actually (number of PTEs)*PAGE_SIZE.
456  ASSERT(ModuleObject->SizeOfImage == ROUND_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage));
457  ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
458 
459  /* Obtain the registry path for the DriverInit routine */
460  PKEY_NAME_INFORMATION nameInfo;
461  ULONG infoLength;
462  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
464  {
465  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
466  if (nameInfo)
467  {
468  Status = ZwQueryKey(ServiceHandle,
470  nameInfo,
471  infoLength,
472  &infoLength);
473  if (NT_SUCCESS(Status))
474  {
475  RegistryPath.Length = nameInfo->NameLength;
476  RegistryPath.MaximumLength = nameInfo->NameLength;
477  RegistryPath.Buffer = nameInfo->Name;
478  }
479  else
480  {
481  ExFreePoolWithTag(nameInfo, TAG_IO);
482  }
483  }
484  else
485  {
487  }
488  }
489  else
490  {
492  }
493 
494  if (!NT_SUCCESS(Status))
495  {
497  RtlFreeUnicodeString(&DriverName);
498  MmUnloadSystemImage(ModuleObject);
499  return Status;
500  }
501 
502  /* Create the driver object */
503  ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
504  OBJECT_ATTRIBUTES objAttrs;
505  PDRIVER_OBJECT driverObject;
506  InitializeObjectAttributes(&objAttrs,
507  &DriverName,
509  NULL,
510  NULL);
511 
514  &objAttrs,
515  KernelMode,
516  NULL,
517  ObjectSize,
518  0,
519  0,
520  (PVOID*)&driverObject);
521  if (!NT_SUCCESS(Status))
522  {
523  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
525  RtlFreeUnicodeString(&DriverName);
526  MmUnloadSystemImage(ModuleObject);
527  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
528  return Status;
529  }
530 
531  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
532 
533  RtlZeroMemory(driverObject, ObjectSize);
534  driverObject->Type = IO_TYPE_DRIVER;
535  driverObject->Size = sizeof(DRIVER_OBJECT);
536 
537  /* Set the legacy flag if this is not a WDM driver */
539  driverObject->Flags |= DRVO_LEGACY_DRIVER;
540 
541  driverObject->DriverSection = ModuleObject;
542  driverObject->DriverStart = ModuleObject->DllBase;
543  driverObject->DriverSize = ModuleObject->SizeOfImage;
544  driverObject->DriverInit = ModuleObject->EntryPoint;
545  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
546  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
547  driverObject->DriverExtension->DriverObject = driverObject;
548 
549  /* Loop all Major Functions */
550  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
551  {
552  /* Invalidate each function */
553  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
554  }
555 
556  /* Add the Object and get its handle */
557  HANDLE hDriver;
558  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
559  if (!NT_SUCCESS(Status))
560  {
561  ExFreePoolWithTag(nameInfo, TAG_IO);
563  RtlFreeUnicodeString(&DriverName);
564  return Status;
565  }
566 
567  /* Now reference it */
569  0,
571  KernelMode,
572  (PVOID*)&driverObject,
573  NULL);
574 
575  /* Close the extra handle */
576  ZwClose(hDriver);
577 
578  if (!NT_SUCCESS(Status))
579  {
580  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
582  RtlFreeUnicodeString(&DriverName);
583  return Status;
584  }
585 
586  /* Set up the service key name buffer */
587  UNICODE_STRING serviceKeyName;
588  serviceKeyName.Length = 0;
589  // NULL-terminate for Windows compatibility
590  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
591  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
592  serviceKeyName.MaximumLength,
593  TAG_IO);
594  if (!serviceKeyName.Buffer)
595  {
596  ObMakeTemporaryObject(driverObject);
597  ObDereferenceObject(driverObject);
598  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
600  RtlFreeUnicodeString(&DriverName);
602  }
603 
604  /* Copy the name and set it in the driver extension */
605  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
607  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
608 
609  /* Make a copy of the driver name to store in the driver object */
610  UNICODE_STRING driverNamePaged;
611  driverNamePaged.Length = 0;
612  // NULL-terminate for Windows compatibility
613  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
614  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
615  driverNamePaged.MaximumLength,
616  TAG_IO);
617  if (!driverNamePaged.Buffer)
618  {
619  ObMakeTemporaryObject(driverObject);
620  ObDereferenceObject(driverObject);
621  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
622  RtlFreeUnicodeString(&DriverName);
624  }
625 
626  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
627  driverObject->DriverName = driverNamePaged;
628 
629  /* Finally, call its init function */
630  Status = driverObject->DriverInit(driverObject, &RegistryPath);
631  *DriverEntryStatus = Status;
632  if (!NT_SUCCESS(Status))
633  {
634  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
635  // return a special status value in case of failure
637  }
638 
639  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
640  * Other parts of the I/O manager depend on this behavior */
641  if (!driverObject->DeviceObject)
642  {
643  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
644  }
645 
646  // Windows does this fixup - keep it for compatibility
647  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
648  {
649  /*
650  * Make sure the driver didn't set any dispatch entry point to NULL!
651  * Doing so is illegal; drivers shouldn't touch entry points they
652  * do not implement.
653  */
654 
655  /* Check if it did so anyway */
656  if (!driverObject->MajorFunction[i])
657  {
658  /* Print a warning in the debug log */
659  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
660  &driverObject->DriverName, i);
661 
662  /* Fix it up */
663  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
664  }
665  }
666 
667  // TODO: for legacy drivers, unload the driver if it didn't create any DO
668 
669  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
670  RtlFreeUnicodeString(&DriverName);
671 
672  if (!NT_SUCCESS(Status))
673  {
674  // if the driver entry has been failed, clear the object
675  ObMakeTemporaryObject(driverObject);
676  ObDereferenceObject(driverObject);
677  return Status;
678  }
679 
680  *OutDriverObject = driverObject;
681 
682  MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)driverObject->DriverSection);
683 
684  /* Set the driver as initialized */
685  IopReadyDeviceObjects(driverObject);
686 
688 
689  return STATUS_SUCCESS;
690 }
691 
692 NTSTATUS
693 NTAPI
695  IN PUNICODE_STRING ImageFileDirectory,
696  IN PUNICODE_STRING NamePrefix OPTIONAL,
697  OUT PCHAR *MissingApi,
698  OUT PWCHAR *MissingDriver,
699  OUT PLOAD_IMPORTS *LoadImports);
700 
701 //
702 // Used for images already loaded (boot drivers)
703 //
704 CODE_SEG("INIT")
705 NTSTATUS
706 NTAPI
709  PLDR_DATA_TABLE_ENTRY *ModuleObject)
710 {
712  UNICODE_STRING BaseName, BaseDirectory;
713  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
714  PCHAR MissingApiName, Buffer;
715  PWCHAR MissingDriverName;
716  PVOID DriverBase = LdrEntry->DllBase;
717 
718  /* Allocate a buffer we'll use for names */
721  TAG_LDR_WSTR);
722  if (!Buffer)
723  {
724  /* Fail */
726  }
727 
728  /* Check for a separator */
729  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
730  {
731  PWCHAR p;
732  ULONG BaseLength;
733 
734  /* Loop the path until we get to the base name */
735  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
736  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
737 
738  /* Get the length */
739  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
740  BaseLength *= sizeof(WCHAR);
741 
742  /* Setup the string */
743  BaseName.Length = (USHORT)BaseLength;
744  BaseName.Buffer = p;
745  }
746  else
747  {
748  /* Otherwise, we already have a base name */
749  BaseName.Length = FileName->Length;
750  BaseName.Buffer = FileName->Buffer;
751  }
752 
753  /* Setup the maximum length */
754  BaseName.MaximumLength = BaseName.Length;
755 
756  /* Now compute the base directory */
757  BaseDirectory = *FileName;
758  BaseDirectory.Length -= BaseName.Length;
759  BaseDirectory.MaximumLength = BaseDirectory.Length;
760 
761  /* Resolve imports */
762  MissingApiName = Buffer;
763  Status = MiResolveImageReferences(DriverBase,
764  &BaseDirectory,
765  NULL,
766  &MissingApiName,
767  &MissingDriverName,
768  &LoadedImports);
769 
770  /* Free the temporary buffer */
772 
773  /* Check the result of the imports resolution */
774  if (!NT_SUCCESS(Status)) return Status;
775 
776  /* Return */
777  *ModuleObject = LdrEntry;
778  return STATUS_SUCCESS;
779 }
780 
783 
784 /*
785  * IopInitializeBuiltinDriver
786  *
787  * Initialize a driver that is already loaded in memory.
788  */
789 CODE_SEG("INIT")
790 static
791 BOOLEAN
793 {
796  PWCHAR Buffer, FileNameWithoutPath;
797  PWSTR FileExtension;
798  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
799  PLDR_DATA_TABLE_ENTRY LdrEntry;
800  PLIST_ENTRY NextEntry;
803 
804  /*
805  * Display 'Loading XXX...' message
806  */
809 
811  ModuleName->Length + sizeof(UNICODE_NULL),
812  TAG_IO);
813  if (Buffer == NULL)
814  {
815  return FALSE;
816  }
817 
819  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
820 
821  /*
822  * Generate filename without path (not needed by freeldr)
823  */
824  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
825  if (FileNameWithoutPath == NULL)
826  {
827  FileNameWithoutPath = Buffer;
828  }
829  else
830  {
831  FileNameWithoutPath++;
832  }
833 
834  /*
835  * Strip the file extension from ServiceName
836  */
837  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
839  if (!Success)
840  {
841  return FALSE;
842  }
843 
844  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
845  if (FileExtension != NULL)
846  {
847  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
848  FileExtension[0] = UNICODE_NULL;
849  }
850 
852 
853  // Make the registry path for the driver
854  RegistryPath.Length = 0;
855  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
857  if (RegistryPath.Buffer == NULL)
858  {
859  return FALSE;
860  }
864 
865  HANDLE serviceHandle;
866  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
868  if (!NT_SUCCESS(Status))
869  {
870  return FALSE;
871  }
872 
873  /* Lookup the new Ldr entry in PsLoadedModuleList */
874  for (NextEntry = PsLoadedModuleList.Flink;
875  NextEntry != &PsLoadedModuleList;
876  NextEntry = NextEntry->Flink)
877  {
878  LdrEntry = CONTAINING_RECORD(NextEntry,
880  InLoadOrderLinks);
882  {
883  break;
884  }
885  }
886  ASSERT(NextEntry != &PsLoadedModuleList);
887 
888  /*
889  * Initialize the driver
890  */
891  NTSTATUS driverEntryStatus;
893  serviceHandle,
894  &DriverObject,
895  &driverEntryStatus);
896 
897  if (!NT_SUCCESS(Status))
898  {
899  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
900  return FALSE;
901  }
902 
903  // The driver has been loaded, now check if where are any PDOs
904  // for that driver, and queue AddDevice call for them.
905  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
906  // is populated upon a new device arrival based on a (critical) device database
907 
908  // Legacy drivers may add devices inside DriverEntry.
909  // We're lazy and always assume that they are doing so
910  BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
911 
912  HANDLE enumServiceHandle;
913  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
914 
915  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
916  ZwClose(serviceHandle);
917 
918  if (NT_SUCCESS(Status))
919  {
920  ULONG instanceCount = 0;
922  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
923  if (!NT_SUCCESS(Status))
924  {
925  goto Cleanup;
926  }
927  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
928  {
929  ExFreePool(kvInfo);
930  goto Cleanup;
931  }
932 
933  RtlMoveMemory(&instanceCount,
934  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
935  sizeof(ULONG));
936  ExFreePool(kvInfo);
937 
938  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
939 
940  for (ULONG i = 0; i < instanceCount; i++)
941  {
942  WCHAR num[11];
943  UNICODE_STRING instancePath;
944  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
945 
946  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
947  if (!NT_SUCCESS(Status))
948  {
949  continue;
950  }
951  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
952  {
953  ExFreePool(kvInfo);
954  continue;
955  }
956 
957  instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
958  instancePath.MaximumLength = kvInfo->DataLength;
960  instancePath.MaximumLength,
961  TAG_IO);
962  if (instancePath.Buffer)
963  {
964  RtlMoveMemory(instancePath.Buffer,
965  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
966  instancePath.Length);
967  instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
968 
971  ObDereferenceObject(pdo);
972  deviceAdded = TRUE;
973  }
974 
975  ExFreePool(kvInfo);
976  }
977 
978  ZwClose(enumServiceHandle);
979  }
980 Cleanup:
981  /* Remove extra reference from IopInitializeDriverModule */
983 
984  return deviceAdded;
985 }
986 
987 /*
988  * IopInitializeBootDrivers
989  *
990  * Initialize boot drivers and free memory for boot files.
991  *
992  * Parameters
993  * None
994  *
995  * Return Value
996  * None
997  */
998 CODE_SEG("INIT")
999 VOID
1000 FASTCALL
1002 {
1003  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1004  PLDR_DATA_TABLE_ENTRY LdrEntry;
1005  NTSTATUS Status;
1006  UNICODE_STRING DriverName;
1007  ULONG i, Index;
1008  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1009  HANDLE KeyHandle;
1010  PBOOT_DRIVER_LIST_ENTRY BootEntry;
1011  DPRINT("IopInitializeBootDrivers()\n");
1012 
1013  /* Create the RAW FS built-in driver */
1014  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1015 
1016  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1017  if (!NT_SUCCESS(Status))
1018  {
1019  /* Fail */
1020  return;
1021  }
1022 
1023  /* Get highest group order index */
1025  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
1026 
1027  /* Allocate the group table */
1029  IopGroupIndex * sizeof(LIST_ENTRY),
1030  TAG_IO);
1031  if (IopGroupTable == NULL) ASSERT(FALSE);
1032 
1033  /* Initialize the group table lists */
1034  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1035 
1036  /* Loop the boot modules */
1037  ListHead = &KeLoaderBlock->LoadOrderListHead;
1038  for (NextEntry = ListHead->Flink;
1039  NextEntry != ListHead;
1040  NextEntry = NextEntry->Flink)
1041  {
1042  /* Get the entry */
1043  LdrEntry = CONTAINING_RECORD(NextEntry,
1045  InLoadOrderLinks);
1046 
1047  /* Check if the DLL needs to be initialized */
1048  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1049  {
1050  /* Call its entrypoint */
1051  MmCallDllInitialize(LdrEntry, NULL);
1052  }
1053  }
1054 
1055  /* Loop the boot drivers */
1056  ListHead = &KeLoaderBlock->BootDriverListHead;
1057  for (NextEntry = ListHead->Flink;
1058  NextEntry != ListHead;
1059  NextEntry = NextEntry->Flink)
1060  {
1061  /* Get the entry */
1062  BootEntry = CONTAINING_RECORD(NextEntry,
1064  Link);
1065 
1066  // FIXME: TODO: This LdrEntry is to be used in a special handling
1067  // for SETUPLDR (a similar procedure is done on Windows), where
1068  // the loader would, under certain conditions, be loaded in the
1069  // SETUPLDR-specific code block below...
1070 #if 0
1071  /* Get the driver loader entry */
1072  LdrEntry = BootEntry->LdrEntry;
1073 #endif
1074 
1075  /* Allocate our internal accounting structure */
1077  sizeof(DRIVER_INFORMATION),
1078  TAG_IO);
1079  if (DriverInfo)
1080  {
1081  /* Zero it and initialize it */
1084  DriverInfo->DataTableEntry = BootEntry;
1085 
1086  /* Open the registry key */
1088  NULL,
1089  &BootEntry->RegistryPath,
1090  KEY_READ);
1091  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1092 #if 0
1093  if (NT_SUCCESS(Status))
1094 #else // Hack still needed...
1095  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1096  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1097 #endif
1098  {
1099  /* Save the handle */
1101 
1102  /* Get the group oder index */
1104 
1105  /* Get the tag position */
1107 
1108  /* Insert it into the list, at the right place */
1110  NextEntry2 = IopGroupTable[Index].Flink;
1111  while (NextEntry2 != &IopGroupTable[Index])
1112  {
1113  /* Get the driver info */
1114  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1116  Link);
1117 
1118  /* Check if we found the right tag position */
1119  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1120  {
1121  /* We're done */
1122  break;
1123  }
1124 
1125  /* Next entry */
1126  NextEntry2 = NextEntry2->Flink;
1127  }
1128 
1129  /* Insert us right before the next entry */
1130  NextEntry2 = NextEntry2->Blink;
1131  InsertHeadList(NextEntry2, &DriverInfo->Link);
1132  }
1133  }
1134  }
1135 
1136  /* Loop each group index */
1137  for (i = 0; i < IopGroupIndex; i++)
1138  {
1139  /* Loop each group table */
1140  for (NextEntry = IopGroupTable[i].Flink;
1141  NextEntry != &IopGroupTable[i];
1142  NextEntry = NextEntry->Flink)
1143  {
1144  /* Get the entry */
1145  DriverInfo = CONTAINING_RECORD(NextEntry,
1147  Link);
1148 
1149  /* Get the driver loader entry */
1150  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1151 
1152  /* Initialize it */
1153  if (IopInitializeBuiltinDriver(LdrEntry))
1154  {
1155  // it does not make sense to enumerate the tree if there are no new devices added
1158  NULL,
1159  NULL);
1160  }
1161  }
1162  }
1163 
1164  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1165  * when some devices are not being initialized with their drivers. This flag is used to delay
1166  * all actions with devices (except PnP root device) until boot drivers are loaded.
1167  * See PiQueueDeviceAction function
1168  */
1170 
1171  DbgPrint("BOOT DRIVERS LOADED\n");
1172 
1175  NULL,
1176  NULL);
1177 }
1178 
1179 CODE_SEG("INIT")
1180 VOID
1181 FASTCALL
1183 {
1184  PUNICODE_STRING *DriverList, *SavedList;
1185 
1187 
1188  /* No system drivers on the boot cd */
1189  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1190 
1191  /* Get the driver list */
1192  SavedList = DriverList = CmGetSystemDriverList();
1193  ASSERT(DriverList);
1194 
1195  /* Loop it */
1196  while (*DriverList)
1197  {
1198  /* Load the driver */
1199  ZwLoadDriver(*DriverList);
1200 
1201  /* Free the entry */
1202  RtlFreeUnicodeString(*DriverList);
1203  ExFreePool(*DriverList);
1204 
1205  /* Next entry */
1207  DriverList++;
1208  }
1209 
1210  /* Free the list */
1211  ExFreePool(SavedList);
1212 
1215  NULL,
1216  NULL);
1217 }
1218 
1219 /*
1220  * IopUnloadDriver
1221  *
1222  * Unloads a device driver.
1223  *
1224  * Parameters
1225  * DriverServiceName
1226  * Name of the service to unload (registry key).
1227  *
1228  * UnloadPnpDrivers
1229  * Whether to unload Plug & Plug or only legacy drivers. If this
1230  * parameter is set to FALSE, the routine will unload only legacy
1231  * drivers.
1232  *
1233  * Return Value
1234  * Status
1235  *
1236  * To do
1237  * Guard the whole function by SEH.
1238  */
1239 
1241 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1242 {
1243  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1245  UNICODE_STRING ImagePath;
1250  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1251  NTSTATUS Status;
1252  USHORT LastBackslash;
1253  BOOLEAN SafeToUnload = TRUE;
1255  UNICODE_STRING CapturedServiceName;
1256 
1257  PAGED_CODE();
1258 
1260 
1261  /* Need the appropriate priviliege */
1263  {
1264  DPRINT1("No unload privilege!\n");
1266  }
1267 
1268  /* Capture the service name */
1269  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1270  PreviousMode,
1271  DriverServiceName);
1272  if (!NT_SUCCESS(Status))
1273  {
1274  return Status;
1275  }
1276 
1277  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1278 
1279  /* We need a service name */
1280  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1281  {
1282  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1283  return STATUS_INVALID_PARAMETER;
1284  }
1285 
1286  /*
1287  * Get the service name from the registry key name
1288  */
1290  &CapturedServiceName,
1291  &Backslash,
1292  &LastBackslash);
1293  if (NT_SUCCESS(Status))
1294  {
1295  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1296  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1297  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1298  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1299  }
1300  else
1301  {
1302  ServiceName = CapturedServiceName;
1303  }
1304 
1305  /*
1306  * Construct the driver object name
1307  */
1308  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1309  ServiceName.Length,
1310  &ObjectName.MaximumLength);
1311  if (!NT_SUCCESS(Status))
1312  {
1313  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1314  return Status;
1315  }
1316  ObjectName.Length = 0;
1318  ObjectName.MaximumLength,
1319  TAG_IO);
1320  if (!ObjectName.Buffer)
1321  {
1322  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1324  }
1327 
1328  /*
1329  * Find the driver object
1330  */
1332  0,
1333  0,
1334  0,
1336  KernelMode,
1337  0,
1338  (PVOID*)&DriverObject);
1339 
1340  if (!NT_SUCCESS(Status))
1341  {
1342  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1344  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1345  return Status;
1346  }
1347 
1348  /* Free the buffer for driver object name */
1350 
1351  /* Check that driver is not already unloading */
1352  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1353  {
1354  DPRINT1("Driver deletion pending\n");
1356  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1357  return STATUS_DELETE_PENDING;
1358  }
1359 
1360  /*
1361  * Get path of service...
1362  */
1364 
1365  RtlInitUnicodeString(&ImagePath, NULL);
1366 
1367  QueryTable[0].Name = L"ImagePath";
1369  QueryTable[0].EntryContext = &ImagePath;
1370 
1372  CapturedServiceName.Buffer,
1373  QueryTable,
1374  NULL,
1375  NULL);
1376 
1377  /* We no longer need service name */
1378  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1379 
1380  if (!NT_SUCCESS(Status))
1381  {
1382  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1384  return Status;
1385  }
1386 
1387  /*
1388  * Normalize the image path for all later processing.
1389  */
1390  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1391 
1392  if (!NT_SUCCESS(Status))
1393  {
1394  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1396  return Status;
1397  }
1398 
1399  /* Free the service path */
1400  ExFreePool(ImagePath.Buffer);
1401 
1402  /*
1403  * Unload the module and release the references to the device object
1404  */
1405 
1406  /* Call the load/unload routine, depending on current process */
1407  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1408  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1409  {
1410  /* Loop through each device object of the driver
1411  and set DOE_UNLOAD_PENDING flag */
1412  DeviceObject = DriverObject->DeviceObject;
1413  while (DeviceObject)
1414  {
1415  /* Set the unload pending flag for the device */
1416  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1417  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1418 
1419  /* Make sure there are no attached devices or no reference counts */
1420  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1421  {
1422  /* Not safe to unload */
1423  DPRINT1("Drivers device object is referenced or has attached devices\n");
1424 
1425  SafeToUnload = FALSE;
1426  }
1427 
1428  DeviceObject = DeviceObject->NextDevice;
1429  }
1430 
1431  /* If not safe to unload, then return success */
1432  if (!SafeToUnload)
1433  {
1435  return STATUS_SUCCESS;
1436  }
1437 
1438  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1439 
1440  /* Set the unload invoked flag and call the unload routine */
1444 
1445  /* Mark the driver object temporary, so it could be deleted later */
1447 
1448  /* Dereference it 2 times */
1451 
1452  return Status;
1453  }
1454  else
1455  {
1456  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1457 
1458  /* Dereference one time (refd inside this function) */
1460 
1461  /* Return unloading failure */
1463  }
1464 }
1465 
1466 VOID
1467 NTAPI
1469 {
1470  PDRIVER_REINIT_ITEM ReinitItem;
1472 
1473  /* Get the first entry and start looping */
1476  while (Entry)
1477  {
1478  /* Get the item */
1479  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1480 
1481  /* Increment reinitialization counter */
1482  ReinitItem->DriverObject->DriverExtension->Count++;
1483 
1484  /* Remove the device object flag */
1485  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1486 
1487  /* Call the routine */
1488  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1489  ReinitItem->Context,
1490  ReinitItem->DriverObject->
1491  DriverExtension->Count);
1492 
1493  /* Free the entry */
1494  ExFreePool(Entry);
1495 
1496  /* Move to the next one */
1499  }
1500 }
1501 
1502 VOID
1503 NTAPI
1505 {
1506  PDRIVER_REINIT_ITEM ReinitItem;
1508 
1509  /* Get the first entry and start looping */
1512  while (Entry)
1513  {
1514  /* Get the item */
1515  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1516 
1517  /* Increment reinitialization counter */
1518  ReinitItem->DriverObject->DriverExtension->Count++;
1519 
1520  /* Remove the device object flag */
1522 
1523  /* Call the routine */
1524  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1525  ReinitItem->Context,
1526  ReinitItem->DriverObject->
1527  DriverExtension->Count);
1528 
1529  /* Free the entry */
1530  ExFreePool(Entry);
1531 
1532  /* Move to the next one */
1535  }
1536 
1537  /* Wait for all device actions being finished*/
1539 }
1540 
1541 /* PUBLIC FUNCTIONS ***********************************************************/
1542 
1543 /*
1544  * @implemented
1545  */
1546 NTSTATUS
1547 NTAPI
1549  _In_opt_ PUNICODE_STRING DriverName,
1550  _In_ PDRIVER_INITIALIZE InitializationFunction)
1551 {
1552  WCHAR NameBuffer[100];
1553  USHORT NameLength;
1554  UNICODE_STRING LocalDriverName;
1555  NTSTATUS Status;
1557  ULONG ObjectSize;
1559  UNICODE_STRING ServiceKeyName;
1560  HANDLE hDriver;
1561  ULONG i, RetryCount = 0;
1562 
1563 try_again:
1564  /* First, create a unique name for the driver if we don't have one */
1565  if (!DriverName)
1566  {
1567  /* Create a random name and set up the string */
1568  NameLength = (USHORT)swprintf(NameBuffer,
1569  DRIVER_ROOT_NAME L"%08u",
1571  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1572  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1573  LocalDriverName.Buffer = NameBuffer;
1574  }
1575  else
1576  {
1577  /* So we can avoid another code path, use a local var */
1578  LocalDriverName = *DriverName;
1579  }
1580 
1581  /* Initialize the Attributes */
1582  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1584  &LocalDriverName,
1586  NULL,
1587  NULL);
1588 
1589  /* Create the Object */
1593  KernelMode,
1594  NULL,
1595  ObjectSize,
1596  0,
1597  0,
1598  (PVOID*)&DriverObject);
1599  if (!NT_SUCCESS(Status)) return Status;
1600 
1601  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1602 
1603  /* Set up the Object */
1604  RtlZeroMemory(DriverObject, ObjectSize);
1605  DriverObject->Type = IO_TYPE_DRIVER;
1606  DriverObject->Size = sizeof(DRIVER_OBJECT);
1608  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1609  DriverObject->DriverExtension->DriverObject = DriverObject;
1610  DriverObject->DriverInit = InitializationFunction;
1611  /* Loop all Major Functions */
1612  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1613  {
1614  /* Invalidate each function */
1615  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1616  }
1617 
1618  /* Set up the service key name buffer */
1619  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1620  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1621  if (!ServiceKeyName.Buffer)
1622  {
1623  /* Fail */
1627  }
1628 
1629  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1630  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1631  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1632  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1633 
1634  /* Make a copy of the driver name to store in the driver object */
1635  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1636  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1637  DriverObject->DriverName.MaximumLength,
1638  TAG_IO);
1639  if (!DriverObject->DriverName.Buffer)
1640  {
1641  /* Fail */
1645  }
1646 
1647  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1648 
1649  /* Add the Object and get its handle */
1651  NULL,
1653  0,
1654  NULL,
1655  &hDriver);
1656 
1657  /* Eliminate small possibility when this function is called more than
1658  once in a row, and KeTickCount doesn't get enough time to change */
1659  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1660  {
1661  RetryCount++;
1662  goto try_again;
1663  }
1664 
1665  if (!NT_SUCCESS(Status)) return Status;
1666 
1667  /* Now reference it */
1669  0,
1671  KernelMode,
1672  (PVOID*)&DriverObject,
1673  NULL);
1674 
1675  /* Close the extra handle */
1676  ZwClose(hDriver);
1677 
1678  if (!NT_SUCCESS(Status))
1679  {
1680  /* Fail */
1683  return Status;
1684  }
1685 
1686  /* Finally, call its init function */
1687  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1688  Status = InitializationFunction(DriverObject, NULL);
1689  if (!NT_SUCCESS(Status))
1690  {
1691  /* If it didn't work, then kill the object */
1692  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1695  return Status;
1696  }
1697 
1698  // Windows does this fixup - keep it for compatibility
1699  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1700  {
1701  /*
1702  * Make sure the driver didn't set any dispatch entry point to NULL!
1703  * Doing so is illegal; drivers shouldn't touch entry points they
1704  * do not implement.
1705  */
1706 
1707  /* Check if it did so anyway */
1708  if (!DriverObject->MajorFunction[i])
1709  {
1710  /* Print a warning in the debug log */
1711  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1712  &DriverObject->DriverName, i);
1713 
1714  /* Fix it up */
1715  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1716  }
1717  }
1718 
1719  /* Return the Status */
1720  return Status;
1721 }
1722 
1723 /*
1724  * @implemented
1725  */
1726 VOID
1727 NTAPI
1729 {
1730  /* Simply dereference the Object */
1732 }
1733 
1734 /*
1735  * @implemented
1736  */
1737 VOID
1738 NTAPI
1740  IN PDRIVER_REINITIALIZE ReinitRoutine,
1741  IN PVOID Context)
1742 {
1743  PDRIVER_REINIT_ITEM ReinitItem;
1744 
1745  /* Allocate the entry */
1746  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1747  sizeof(DRIVER_REINIT_ITEM),
1748  TAG_REINIT);
1749  if (!ReinitItem) return;
1750 
1751  /* Fill it out */
1752  ReinitItem->DriverObject = DriverObject;
1753  ReinitItem->ReinitRoutine = ReinitRoutine;
1754  ReinitItem->Context = Context;
1755 
1756  /* Set the Driver Object flag and insert the entry into the list */
1759  &ReinitItem->ItemEntry,
1761 }
1762 
1763 /*
1764  * @implemented
1765  */
1766 VOID
1767 NTAPI
1769  IN PDRIVER_REINITIALIZE ReinitRoutine,
1770  IN PVOID Context)
1771 {
1772  PDRIVER_REINIT_ITEM ReinitItem;
1773 
1774  /* Allocate the entry */
1775  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1776  sizeof(DRIVER_REINIT_ITEM),
1777  TAG_REINIT);
1778  if (!ReinitItem) return;
1779 
1780  /* Fill it out */
1781  ReinitItem->DriverObject = DriverObject;
1782  ReinitItem->ReinitRoutine = ReinitRoutine;
1783  ReinitItem->Context = Context;
1784 
1785  /* Set the Driver Object flag and insert the entry into the list */
1788  &ReinitItem->ItemEntry,
1790 }
1791 
1792 /*
1793  * @implemented
1794  */
1795 NTSTATUS
1796 NTAPI
1799  IN ULONG DriverObjectExtensionSize,
1800  OUT PVOID *DriverObjectExtension)
1801 {
1802  KIRQL OldIrql;
1803  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1804  BOOLEAN Inserted = FALSE;
1805 
1806  /* Assume failure */
1807  *DriverObjectExtension = NULL;
1808 
1809  /* Allocate the extension */
1810  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1811  sizeof(IO_CLIENT_EXTENSION) +
1812  DriverObjectExtensionSize,
1814  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1815 
1816  /* Clear the extension for teh caller */
1817  RtlZeroMemory(NewDriverExtension,
1818  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1819 
1820  /* Acqure lock */
1822 
1823  /* Fill out the extension */
1825 
1826  /* Loop the current extensions */
1827  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1828  ClientDriverExtension;
1829  while (DriverExtensions)
1830  {
1831  /* Check if the identifier matches */
1832  if (DriverExtensions->ClientIdentificationAddress ==
1834  {
1835  /* We have a collision, break out */
1836  break;
1837  }
1838 
1839  /* Go to the next one */
1840  DriverExtensions = DriverExtensions->NextExtension;
1841  }
1842 
1843  /* Check if we didn't collide */
1844  if (!DriverExtensions)
1845  {
1846  /* Link this one in */
1847  NewDriverExtension->NextExtension =
1848  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1849  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1850  NewDriverExtension;
1851  Inserted = TRUE;
1852  }
1853 
1854  /* Release the lock */
1856 
1857  /* Check if insertion failed */
1858  if (!Inserted)
1859  {
1860  /* Free the entry and fail */
1861  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1863  }
1864 
1865  /* Otherwise, return the pointer */
1866  *DriverObjectExtension = NewDriverExtension + 1;
1867  return STATUS_SUCCESS;
1868 }
1869 
1870 /*
1871  * @implemented
1872  */
1873 PVOID
1874 NTAPI
1877 {
1878  KIRQL OldIrql;
1879  PIO_CLIENT_EXTENSION DriverExtensions;
1880 
1881  /* Acquire lock */
1883 
1884  /* Loop the list until we find the right one */
1885  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1886  while (DriverExtensions)
1887  {
1888  /* Check for a match */
1889  if (DriverExtensions->ClientIdentificationAddress ==
1891  {
1892  /* Break out */
1893  break;
1894  }
1895 
1896  /* Keep looping */
1897  DriverExtensions = DriverExtensions->NextExtension;
1898  }
1899 
1900  /* Release lock */
1902 
1903  /* Return nothing or the extension */
1904  if (!DriverExtensions) return NULL;
1905  return DriverExtensions + 1;
1906 }
1907 
1908 NTSTATUS
1910  _In_ HANDLE ServiceHandle,
1912 {
1913  UNICODE_STRING ImagePath;
1914  NTSTATUS Status;
1915  PLDR_DATA_TABLE_ENTRY ModuleObject;
1917 
1919  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1920  if (NT_SUCCESS(Status))
1921  {
1922  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1923  {
1924  ExFreePool(kvInfo);
1926  }
1927 
1928  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1929  ImagePath.MaximumLength = kvInfo->DataLength;
1931  if (!ImagePath.Buffer)
1932  {
1933  ExFreePool(kvInfo);
1935  }
1936 
1937  RtlMoveMemory(ImagePath.Buffer,
1938  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1939  ImagePath.Length);
1940  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1941  ExFreePool(kvInfo);
1942  }
1943  else
1944  {
1945  return Status;
1946  }
1947 
1948  /*
1949  * Normalize the image path for all later processing.
1950  */
1951  Status = IopNormalizeImagePath(&ImagePath, NULL);
1952  if (!NT_SUCCESS(Status))
1953  {
1954  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1955  return Status;
1956  }
1957 
1958  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1959 
1962 
1963  /*
1964  * Load the driver module
1965  */
1966  DPRINT("Loading module from %wZ\n", &ImagePath);
1967  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1968  RtlFreeUnicodeString(&ImagePath);
1969 
1970  if (!NT_SUCCESS(Status))
1971  {
1972  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1975  return Status;
1976  }
1977 
1978  // Display the loading message
1979  ULONG infoLength;
1980  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1982  {
1984  if (servName)
1985  {
1986  Status = ZwQueryKey(ServiceHandle,
1988  servName,
1989  infoLength,
1990  &infoLength);
1991  if (NT_SUCCESS(Status))
1992  {
1994  .Length = servName->NameLength,
1995  .MaximumLength = servName->NameLength,
1996  .Buffer = servName->Name
1997  };
1998 
2000  }
2001  ExFreePoolWithTag(servName, TAG_IO);
2002  }
2003  }
2004 
2005  NTSTATUS driverEntryStatus;
2006  Status = IopInitializeDriverModule(ModuleObject,
2007  ServiceHandle,
2008  DriverObject,
2009  &driverEntryStatus);
2010  if (!NT_SUCCESS(Status))
2011  {
2012  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2013  }
2014 
2017 
2018  return Status;
2019 }
2020 
2021 static
2022 VOID
2023 NTAPI
2026 {
2027  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2028 
2030 
2031  if (LoadParams->DriverObject)
2032  {
2033  // unload request
2034  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2035  LoadParams->Status = STATUS_SUCCESS;
2036  }
2037  else
2038  {
2039  // load request
2040  HANDLE serviceHandle;
2041  NTSTATUS status;
2042  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2043  if (!NT_SUCCESS(status))
2044  {
2045  LoadParams->Status = status;
2046  }
2047  else
2048  {
2049  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2050  ZwClose(serviceHandle);
2051  }
2052  }
2053 
2054  if (LoadParams->SetEvent)
2055  {
2056  KeSetEvent(&LoadParams->Event, 0, FALSE);
2057  }
2058 }
2059 
2069 NTSTATUS
2073 {
2074  LOAD_UNLOAD_PARAMS LoadParams;
2075 
2076  /* Prepare parameters block */
2077  LoadParams.RegistryPath = RegistryPath;
2078  LoadParams.DriverObject = *DriverObject;
2079 
2081  {
2082  LoadParams.SetEvent = TRUE;
2084 
2085  /* Initialize and queue a work item */
2086  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2088 
2089  /* And wait till it completes */
2091  }
2092  else
2093  {
2094  /* If we're already in a system process, call it right here */
2095  LoadParams.SetEvent = FALSE;
2096  IopLoadUnloadDriverWorker(&LoadParams);
2097  }
2098 
2099  return LoadParams.Status;
2100 }
2101 
2102 /*
2103  * NtLoadDriver
2104  *
2105  * Loads a device driver.
2106  *
2107  * Parameters
2108  * DriverServiceName
2109  * Name of the service to load (registry key).
2110  *
2111  * Return Value
2112  * Status
2113  *
2114  * Status
2115  * implemented
2116  */
2118 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2119 {
2120  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2123  NTSTATUS Status;
2124 
2125  PAGED_CODE();
2126 
2128 
2129  /* Need the appropriate priviliege */
2131  {
2132  DPRINT1("No load privilege!\n");
2134  }
2135 
2136  /* Capture the service name */
2137  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2138  PreviousMode,
2139  DriverServiceName);
2140  if (!NT_SUCCESS(Status))
2141  {
2142  return Status;
2143  }
2144 
2145  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2146 
2147  /* We need a service name */
2148  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2149  {
2150  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2151  return STATUS_INVALID_PARAMETER;
2152  }
2153 
2154  /* Load driver and call its entry point */
2155  DriverObject = NULL;
2156  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2157 
2158  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2159  return Status;
2160 }
2161 
2162 /*
2163  * NtUnloadDriver
2164  *
2165  * Unloads a legacy device driver.
2166  *
2167  * Parameters
2168  * DriverServiceName
2169  * Name of the service to unload (registry key).
2170  *
2171  * Return Value
2172  * Status
2173  *
2174  * Status
2175  * implemented
2176  */
2177 
2180 {
2181  return IopUnloadDriver(DriverServiceName, FALSE);
2182 }
2183 
2184 /* 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:69
#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:1001
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
VOID NTAPI InbvIndicateProgress(VOID)
Gives some progress feedback, without specifying any explicit number of progress steps or percentage....
Definition: inbv.c:625
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:828
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1182
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:75
#define TAG_RTLREGISTRY
Definition: tag.h:92
#define _In_opt_
Definition: ms_sal.h:309
#define _Inout_
Definition: ms_sal.h:378
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1727
#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:1797
struct _Entry Entry
Definition: kefuncs.h:629
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:2647
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2024
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1468
_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
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:315
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:451
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:1108
#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:2070
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:50
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:3063
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1909
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 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:1728
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:123
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:65
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:1504
#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:1768
uint32_t ULONG_PTR
Definition: typedefs.h:65
LIST_ENTRY ItemEntry
Definition: io.h:448
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:792
#define L(x)
Definition: ntvdm.h:50
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:97
#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:354
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:1548
PDRIVER_OBJECT DriverObject
Definition: io.h:449
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:79
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:951
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:56
__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:41
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:1739
#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:2179
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
NTSTATUS Status
Definition: driver.c:48
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1875
#define OBJ_PERMANENT
Definition: winternl.h:226
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1866
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
BOOLEAN SetEvent
Definition: driver.c:53
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
int _cdecl swprintf(const WCHAR *,...)
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:2706
PDRIVER_OBJECT DriverObject
Definition: driver.c:52
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:2934
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:49
#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:77
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:428
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:450
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
PVOID ClientIdentificationAddress
Definition: iotypes.h:829
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:1241
#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:2118
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:40
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:1360
#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:707
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:281