ReactOS  0.4.15-dev-5608-gafb953a
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 
970  if (pdo != NULL)
971  {
973  ObDereferenceObject(pdo);
974  deviceAdded = TRUE;
975  }
976  else
977  {
978  DPRINT1("No device node found matching instance path '%wZ'\n", &instancePath);
979  }
980  }
981 
982  ExFreePool(kvInfo);
983  }
984 
985  ZwClose(enumServiceHandle);
986  }
987 Cleanup:
988  /* Remove extra reference from IopInitializeDriverModule */
990 
991  return deviceAdded;
992 }
993 
994 /*
995  * IopInitializeBootDrivers
996  *
997  * Initialize boot drivers and free memory for boot files.
998  *
999  * Parameters
1000  * None
1001  *
1002  * Return Value
1003  * None
1004  */
1005 CODE_SEG("INIT")
1006 VOID
1007 FASTCALL
1009 {
1010  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1011  PLDR_DATA_TABLE_ENTRY LdrEntry;
1012  NTSTATUS Status;
1013  UNICODE_STRING DriverName;
1014  ULONG i, Index;
1015  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1016  HANDLE KeyHandle;
1017  PBOOT_DRIVER_LIST_ENTRY BootEntry;
1018  DPRINT("IopInitializeBootDrivers()\n");
1019 
1020  /* Create the RAW FS built-in driver */
1021  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1022 
1023  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1024  if (!NT_SUCCESS(Status))
1025  {
1026  /* Fail */
1027  return;
1028  }
1029 
1030  /* Get highest group order index */
1032  if (IopGroupIndex == 0xFFFF)
1033  {
1035  }
1036 
1037  /* Allocate the group table */
1039  IopGroupIndex * sizeof(LIST_ENTRY),
1040  TAG_IO);
1041  if (IopGroupTable == NULL)
1042  {
1044  }
1045 
1046  /* Initialize the group table lists */
1047  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1048 
1049  /* Loop the boot modules */
1050  ListHead = &KeLoaderBlock->LoadOrderListHead;
1051  for (NextEntry = ListHead->Flink;
1052  NextEntry != ListHead;
1053  NextEntry = NextEntry->Flink)
1054  {
1055  /* Get the entry */
1056  LdrEntry = CONTAINING_RECORD(NextEntry,
1058  InLoadOrderLinks);
1059 
1060  /* Check if the DLL needs to be initialized */
1061  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1062  {
1063  /* Call its entrypoint */
1064  MmCallDllInitialize(LdrEntry, NULL);
1065  }
1066  }
1067 
1068  /* Loop the boot drivers */
1069  ListHead = &KeLoaderBlock->BootDriverListHead;
1070  for (NextEntry = ListHead->Flink;
1071  NextEntry != ListHead;
1072  NextEntry = NextEntry->Flink)
1073  {
1074  /* Get the entry */
1075  BootEntry = CONTAINING_RECORD(NextEntry,
1077  Link);
1078 
1079  // FIXME: TODO: This LdrEntry is to be used in a special handling
1080  // for SETUPLDR (a similar procedure is done on Windows), where
1081  // the loader would, under certain conditions, be loaded in the
1082  // SETUPLDR-specific code block below...
1083 #if 0
1084  /* Get the driver loader entry */
1085  LdrEntry = BootEntry->LdrEntry;
1086 #endif
1087 
1088  /* Allocate our internal accounting structure */
1090  sizeof(DRIVER_INFORMATION),
1091  TAG_IO);
1092  if (DriverInfo)
1093  {
1094  /* Zero it and initialize it */
1097  DriverInfo->DataTableEntry = BootEntry;
1098 
1099  /* Open the registry key */
1101  NULL,
1102  &BootEntry->RegistryPath,
1103  KEY_READ);
1104  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1105 #if 0
1106  if (NT_SUCCESS(Status))
1107 #else // Hack still needed...
1108  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1109  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1110 #endif
1111  {
1112  /* Save the handle */
1114 
1115  /* Get the group oder index */
1117 
1118  /* Get the tag position */
1120 
1121  /* Insert it into the list, at the right place */
1123  NextEntry2 = IopGroupTable[Index].Flink;
1124  while (NextEntry2 != &IopGroupTable[Index])
1125  {
1126  /* Get the driver info */
1127  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1129  Link);
1130 
1131  /* Check if we found the right tag position */
1132  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1133  {
1134  /* We're done */
1135  break;
1136  }
1137 
1138  /* Next entry */
1139  NextEntry2 = NextEntry2->Flink;
1140  }
1141 
1142  /* Insert us right before the next entry */
1143  NextEntry2 = NextEntry2->Blink;
1144  InsertHeadList(NextEntry2, &DriverInfo->Link);
1145  }
1146  }
1147  }
1148 
1149  /* Loop each group index */
1150  for (i = 0; i < IopGroupIndex; i++)
1151  {
1152  /* Loop each group table */
1153  for (NextEntry = IopGroupTable[i].Flink;
1154  NextEntry != &IopGroupTable[i];
1155  NextEntry = NextEntry->Flink)
1156  {
1157  /* Get the entry */
1158  DriverInfo = CONTAINING_RECORD(NextEntry,
1160  Link);
1161 
1162  /* Get the driver loader entry */
1163  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1164 
1165  /* Initialize it */
1166  if (IopInitializeBuiltinDriver(LdrEntry))
1167  {
1168  // it does not make sense to enumerate the tree if there are no new devices added
1171  NULL,
1172  NULL);
1173  }
1174  }
1175  }
1176 
1177  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1178  * when some devices are not being initialized with their drivers. This flag is used to delay
1179  * all actions with devices (except PnP root device) until boot drivers are loaded.
1180  * See PiQueueDeviceAction function
1181  */
1183 
1184  DbgPrint("BOOT DRIVERS LOADED\n");
1185 
1188  NULL,
1189  NULL);
1190 }
1191 
1192 CODE_SEG("INIT")
1193 VOID
1194 FASTCALL
1196 {
1197  PUNICODE_STRING *DriverList, *SavedList;
1198 
1200 
1201  /* No system drivers on the boot cd */
1202  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1203 
1204  /* Get the driver list */
1205  SavedList = DriverList = CmGetSystemDriverList();
1206  ASSERT(DriverList);
1207 
1208  /* Loop it */
1209  while (*DriverList)
1210  {
1211  /* Load the driver */
1212  ZwLoadDriver(*DriverList);
1213 
1214  /* Free the entry */
1215  RtlFreeUnicodeString(*DriverList);
1216  ExFreePool(*DriverList);
1217 
1218  /* Next entry */
1220  DriverList++;
1221  }
1222 
1223  /* Free the list */
1224  ExFreePool(SavedList);
1225 
1228  NULL,
1229  NULL);
1230 }
1231 
1232 /*
1233  * IopUnloadDriver
1234  *
1235  * Unloads a device driver.
1236  *
1237  * Parameters
1238  * DriverServiceName
1239  * Name of the service to unload (registry key).
1240  *
1241  * UnloadPnpDrivers
1242  * Whether to unload Plug & Plug or only legacy drivers. If this
1243  * parameter is set to FALSE, the routine will unload only legacy
1244  * drivers.
1245  *
1246  * Return Value
1247  * Status
1248  *
1249  * To do
1250  * Guard the whole function by SEH.
1251  */
1252 
1254 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1255 {
1256  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1258  UNICODE_STRING ImagePath;
1263  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1264  NTSTATUS Status;
1265  USHORT LastBackslash;
1266  BOOLEAN SafeToUnload = TRUE;
1268  UNICODE_STRING CapturedServiceName;
1269 
1270  PAGED_CODE();
1271 
1273 
1274  /* Need the appropriate priviliege */
1276  {
1277  DPRINT1("No unload privilege!\n");
1279  }
1280 
1281  /* Capture the service name */
1282  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1283  PreviousMode,
1284  DriverServiceName);
1285  if (!NT_SUCCESS(Status))
1286  {
1287  return Status;
1288  }
1289 
1290  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1291 
1292  /* We need a service name */
1293  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1294  {
1295  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1296  return STATUS_INVALID_PARAMETER;
1297  }
1298 
1299  /*
1300  * Get the service name from the registry key name
1301  */
1303  &CapturedServiceName,
1304  &Backslash,
1305  &LastBackslash);
1306  if (NT_SUCCESS(Status))
1307  {
1308  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1309  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1310  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1311  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1312  }
1313  else
1314  {
1315  ServiceName = CapturedServiceName;
1316  }
1317 
1318  /*
1319  * Construct the driver object name
1320  */
1321  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1322  ServiceName.Length,
1323  &ObjectName.MaximumLength);
1324  if (!NT_SUCCESS(Status))
1325  {
1326  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1327  return Status;
1328  }
1329  ObjectName.Length = 0;
1331  ObjectName.MaximumLength,
1332  TAG_IO);
1333  if (!ObjectName.Buffer)
1334  {
1335  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1337  }
1340 
1341  /*
1342  * Find the driver object
1343  */
1345  0,
1346  0,
1347  0,
1349  KernelMode,
1350  0,
1351  (PVOID*)&DriverObject);
1352 
1353  if (!NT_SUCCESS(Status))
1354  {
1355  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1357  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1358  return Status;
1359  }
1360 
1361  /* Free the buffer for driver object name */
1363 
1364  /* Check that driver is not already unloading */
1365  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1366  {
1367  DPRINT1("Driver deletion pending\n");
1369  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1370  return STATUS_DELETE_PENDING;
1371  }
1372 
1373  /*
1374  * Get path of service...
1375  */
1377 
1378  RtlInitUnicodeString(&ImagePath, NULL);
1379 
1380  QueryTable[0].Name = L"ImagePath";
1382  QueryTable[0].EntryContext = &ImagePath;
1383 
1385  CapturedServiceName.Buffer,
1386  QueryTable,
1387  NULL,
1388  NULL);
1389 
1390  /* We no longer need service name */
1391  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1392 
1393  if (!NT_SUCCESS(Status))
1394  {
1395  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1397  return Status;
1398  }
1399 
1400  /*
1401  * Normalize the image path for all later processing.
1402  */
1403  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1404 
1405  if (!NT_SUCCESS(Status))
1406  {
1407  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1409  return Status;
1410  }
1411 
1412  /* Free the service path */
1413  ExFreePool(ImagePath.Buffer);
1414 
1415  /*
1416  * Unload the module and release the references to the device object
1417  */
1418 
1419  /* Call the load/unload routine, depending on current process */
1420  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1421  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1422  {
1423  /* Loop through each device object of the driver
1424  and set DOE_UNLOAD_PENDING flag */
1425  DeviceObject = DriverObject->DeviceObject;
1426  while (DeviceObject)
1427  {
1428  /* Set the unload pending flag for the device */
1429  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1430  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1431 
1432  /* Make sure there are no attached devices or no reference counts */
1433  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1434  {
1435  /* Not safe to unload */
1436  DPRINT1("Drivers device object is referenced or has attached devices\n");
1437 
1438  SafeToUnload = FALSE;
1439  }
1440 
1441  DeviceObject = DeviceObject->NextDevice;
1442  }
1443 
1444  /* If not safe to unload, then return success */
1445  if (!SafeToUnload)
1446  {
1448  return STATUS_SUCCESS;
1449  }
1450 
1451  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1452 
1453  /* Set the unload invoked flag and call the unload routine */
1457 
1458  /* Mark the driver object temporary, so it could be deleted later */
1460 
1461  /* Dereference it 2 times */
1464 
1465  return Status;
1466  }
1467  else
1468  {
1469  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1470 
1471  /* Dereference one time (refd inside this function) */
1473 
1474  /* Return unloading failure */
1476  }
1477 }
1478 
1479 VOID
1480 NTAPI
1482 {
1483  PDRIVER_REINIT_ITEM ReinitItem;
1485 
1486  /* Get the first entry and start looping */
1489  while (Entry)
1490  {
1491  /* Get the item */
1492  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1493 
1494  /* Increment reinitialization counter */
1495  ReinitItem->DriverObject->DriverExtension->Count++;
1496 
1497  /* Remove the device object flag */
1498  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1499 
1500  /* Call the routine */
1501  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1502  ReinitItem->Context,
1503  ReinitItem->DriverObject->
1504  DriverExtension->Count);
1505 
1506  /* Free the entry */
1507  ExFreePool(Entry);
1508 
1509  /* Move to the next one */
1512  }
1513 }
1514 
1515 VOID
1516 NTAPI
1518 {
1519  PDRIVER_REINIT_ITEM ReinitItem;
1521 
1522  /* Get the first entry and start looping */
1525  while (Entry)
1526  {
1527  /* Get the item */
1528  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1529 
1530  /* Increment reinitialization counter */
1531  ReinitItem->DriverObject->DriverExtension->Count++;
1532 
1533  /* Remove the device object flag */
1535 
1536  /* Call the routine */
1537  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1538  ReinitItem->Context,
1539  ReinitItem->DriverObject->
1540  DriverExtension->Count);
1541 
1542  /* Free the entry */
1543  ExFreePool(Entry);
1544 
1545  /* Move to the next one */
1548  }
1549 
1550  /* Wait for all device actions being finished*/
1552 }
1553 
1554 /* PUBLIC FUNCTIONS ***********************************************************/
1555 
1556 /*
1557  * @implemented
1558  */
1559 NTSTATUS
1560 NTAPI
1562  _In_opt_ PUNICODE_STRING DriverName,
1563  _In_ PDRIVER_INITIALIZE InitializationFunction)
1564 {
1565  WCHAR NameBuffer[100];
1566  USHORT NameLength;
1567  UNICODE_STRING LocalDriverName;
1568  NTSTATUS Status;
1570  ULONG ObjectSize;
1572  UNICODE_STRING ServiceKeyName;
1573  HANDLE hDriver;
1574  ULONG i, RetryCount = 0;
1575 
1576 try_again:
1577  /* First, create a unique name for the driver if we don't have one */
1578  if (!DriverName)
1579  {
1580  /* Create a random name and set up the string */
1581  NameLength = (USHORT)swprintf(NameBuffer,
1582  DRIVER_ROOT_NAME L"%08u",
1584  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1585  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1586  LocalDriverName.Buffer = NameBuffer;
1587  }
1588  else
1589  {
1590  /* So we can avoid another code path, use a local var */
1591  LocalDriverName = *DriverName;
1592  }
1593 
1594  /* Initialize the Attributes */
1595  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1597  &LocalDriverName,
1599  NULL,
1600  NULL);
1601 
1602  /* Create the Object */
1606  KernelMode,
1607  NULL,
1608  ObjectSize,
1609  0,
1610  0,
1611  (PVOID*)&DriverObject);
1612  if (!NT_SUCCESS(Status)) return Status;
1613 
1614  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1615 
1616  /* Set up the Object */
1617  RtlZeroMemory(DriverObject, ObjectSize);
1618  DriverObject->Type = IO_TYPE_DRIVER;
1619  DriverObject->Size = sizeof(DRIVER_OBJECT);
1621  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1622  DriverObject->DriverExtension->DriverObject = DriverObject;
1623  DriverObject->DriverInit = InitializationFunction;
1624  /* Loop all Major Functions */
1625  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1626  {
1627  /* Invalidate each function */
1628  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1629  }
1630 
1631  /* Set up the service key name buffer */
1632  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1633  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1634  if (!ServiceKeyName.Buffer)
1635  {
1636  /* Fail */
1640  }
1641 
1642  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1643  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1644  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1645  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1646 
1647  /* Make a copy of the driver name to store in the driver object */
1648  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1649  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1650  DriverObject->DriverName.MaximumLength,
1651  TAG_IO);
1652  if (!DriverObject->DriverName.Buffer)
1653  {
1654  /* Fail */
1658  }
1659 
1660  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1661 
1662  /* Add the Object and get its handle */
1664  NULL,
1666  0,
1667  NULL,
1668  &hDriver);
1669 
1670  /* Eliminate small possibility when this function is called more than
1671  once in a row, and KeTickCount doesn't get enough time to change */
1672  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1673  {
1674  RetryCount++;
1675  goto try_again;
1676  }
1677 
1678  if (!NT_SUCCESS(Status)) return Status;
1679 
1680  /* Now reference it */
1682  0,
1684  KernelMode,
1685  (PVOID*)&DriverObject,
1686  NULL);
1687 
1688  /* Close the extra handle */
1689  ZwClose(hDriver);
1690 
1691  if (!NT_SUCCESS(Status))
1692  {
1693  /* Fail */
1696  return Status;
1697  }
1698 
1699  /* Finally, call its init function */
1700  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1701  Status = InitializationFunction(DriverObject, NULL);
1702  if (!NT_SUCCESS(Status))
1703  {
1704  /* If it didn't work, then kill the object */
1705  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &LocalDriverName, Status);
1708  return Status;
1709  }
1710 
1711  /* Windows does this fixup, keep it for compatibility */
1712  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1713  {
1714  /*
1715  * Make sure the driver didn't set any dispatch entry point to NULL!
1716  * Doing so is illegal; drivers shouldn't touch entry points they
1717  * do not implement.
1718  */
1719 
1720  /* Check if it did so anyway */
1721  if (!DriverObject->MajorFunction[i])
1722  {
1723  /* Print a warning in the debug log */
1724  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1725  &DriverObject->DriverName, i);
1726 
1727  /* Fix it up */
1728  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1729  }
1730  }
1731 
1732  /* Return the Status */
1733  return Status;
1734 }
1735 
1736 /*
1737  * @implemented
1738  */
1739 VOID
1740 NTAPI
1743 {
1744  /* Simply dereference the Object */
1746 }
1747 
1748 /*
1749  * @implemented
1750  */
1751 VOID
1752 NTAPI
1754  IN PDRIVER_REINITIALIZE ReinitRoutine,
1755  IN PVOID Context)
1756 {
1757  PDRIVER_REINIT_ITEM ReinitItem;
1758 
1759  /* Allocate the entry */
1760  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1761  sizeof(DRIVER_REINIT_ITEM),
1762  TAG_REINIT);
1763  if (!ReinitItem) return;
1764 
1765  /* Fill it out */
1766  ReinitItem->DriverObject = DriverObject;
1767  ReinitItem->ReinitRoutine = ReinitRoutine;
1768  ReinitItem->Context = Context;
1769 
1770  /* Set the Driver Object flag and insert the entry into the list */
1773  &ReinitItem->ItemEntry,
1775 }
1776 
1777 /*
1778  * @implemented
1779  */
1780 VOID
1781 NTAPI
1783  IN PDRIVER_REINITIALIZE ReinitRoutine,
1784  IN PVOID Context)
1785 {
1786  PDRIVER_REINIT_ITEM ReinitItem;
1787 
1788  /* Allocate the entry */
1789  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1790  sizeof(DRIVER_REINIT_ITEM),
1791  TAG_REINIT);
1792  if (!ReinitItem) return;
1793 
1794  /* Fill it out */
1795  ReinitItem->DriverObject = DriverObject;
1796  ReinitItem->ReinitRoutine = ReinitRoutine;
1797  ReinitItem->Context = Context;
1798 
1799  /* Set the Driver Object flag and insert the entry into the list */
1802  &ReinitItem->ItemEntry,
1804 }
1805 
1806 /*
1807  * @implemented
1808  */
1809 NTSTATUS
1810 NTAPI
1813  IN ULONG DriverObjectExtensionSize,
1814  OUT PVOID *DriverObjectExtension)
1815 {
1816  KIRQL OldIrql;
1817  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1818  BOOLEAN Inserted = FALSE;
1819 
1820  /* Assume failure */
1821  *DriverObjectExtension = NULL;
1822 
1823  /* Allocate the extension */
1824  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1825  sizeof(IO_CLIENT_EXTENSION) +
1826  DriverObjectExtensionSize,
1828  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1829 
1830  /* Clear the extension for teh caller */
1831  RtlZeroMemory(NewDriverExtension,
1832  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1833 
1834  /* Acqure lock */
1836 
1837  /* Fill out the extension */
1839 
1840  /* Loop the current extensions */
1841  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1842  ClientDriverExtension;
1843  while (DriverExtensions)
1844  {
1845  /* Check if the identifier matches */
1846  if (DriverExtensions->ClientIdentificationAddress ==
1848  {
1849  /* We have a collision, break out */
1850  break;
1851  }
1852 
1853  /* Go to the next one */
1854  DriverExtensions = DriverExtensions->NextExtension;
1855  }
1856 
1857  /* Check if we didn't collide */
1858  if (!DriverExtensions)
1859  {
1860  /* Link this one in */
1861  NewDriverExtension->NextExtension =
1862  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1863  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1864  NewDriverExtension;
1865  Inserted = TRUE;
1866  }
1867 
1868  /* Release the lock */
1870 
1871  /* Check if insertion failed */
1872  if (!Inserted)
1873  {
1874  /* Free the entry and fail */
1875  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1877  }
1878 
1879  /* Otherwise, return the pointer */
1880  *DriverObjectExtension = NewDriverExtension + 1;
1881  return STATUS_SUCCESS;
1882 }
1883 
1884 /*
1885  * @implemented
1886  */
1887 PVOID
1888 NTAPI
1891 {
1892  KIRQL OldIrql;
1893  PIO_CLIENT_EXTENSION DriverExtensions;
1894 
1895  /* Acquire lock */
1897 
1898  /* Loop the list until we find the right one */
1899  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1900  while (DriverExtensions)
1901  {
1902  /* Check for a match */
1903  if (DriverExtensions->ClientIdentificationAddress ==
1905  {
1906  /* Break out */
1907  break;
1908  }
1909 
1910  /* Keep looping */
1911  DriverExtensions = DriverExtensions->NextExtension;
1912  }
1913 
1914  /* Release lock */
1916 
1917  /* Return nothing or the extension */
1918  if (!DriverExtensions) return NULL;
1919  return DriverExtensions + 1;
1920 }
1921 
1922 NTSTATUS
1924  _In_ HANDLE ServiceHandle,
1926 {
1927  UNICODE_STRING ImagePath;
1928  NTSTATUS Status;
1929  PLDR_DATA_TABLE_ENTRY ModuleObject;
1931 
1933  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1934  if (NT_SUCCESS(Status))
1935  {
1936  if ((kvInfo->Type != REG_EXPAND_SZ && kvInfo->Type != REG_SZ) || kvInfo->DataLength == 0)
1937  {
1938  ExFreePool(kvInfo);
1940  }
1941 
1942  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1943  ImagePath.MaximumLength = kvInfo->DataLength;
1945  if (!ImagePath.Buffer)
1946  {
1947  ExFreePool(kvInfo);
1949  }
1950 
1951  RtlMoveMemory(ImagePath.Buffer,
1952  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1953  ImagePath.Length);
1954  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1955  ExFreePool(kvInfo);
1956  }
1957  else
1958  {
1959  return Status;
1960  }
1961 
1962  /*
1963  * Normalize the image path for all later processing.
1964  */
1965  Status = IopNormalizeImagePath(&ImagePath, NULL);
1966  if (!NT_SUCCESS(Status))
1967  {
1968  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1969  return Status;
1970  }
1971 
1972  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1973 
1976 
1977  /*
1978  * Load the driver module
1979  */
1980  DPRINT("Loading module from %wZ\n", &ImagePath);
1981  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1982  RtlFreeUnicodeString(&ImagePath);
1983 
1984  if (!NT_SUCCESS(Status))
1985  {
1986  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1989  return Status;
1990  }
1991 
1992  // Display the loading message
1993  ULONG infoLength;
1994  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1996  {
1998  if (servName)
1999  {
2000  Status = ZwQueryKey(ServiceHandle,
2002  servName,
2003  infoLength,
2004  &infoLength);
2005  if (NT_SUCCESS(Status))
2006  {
2008  .Length = servName->NameLength,
2009  .MaximumLength = servName->NameLength,
2010  .Buffer = servName->Name
2011  };
2012 
2014  }
2015  ExFreePoolWithTag(servName, TAG_IO);
2016  }
2017  }
2018 
2019  NTSTATUS driverEntryStatus;
2020  Status = IopInitializeDriverModule(ModuleObject,
2021  ServiceHandle,
2022  DriverObject,
2023  &driverEntryStatus);
2024  if (!NT_SUCCESS(Status))
2025  {
2026  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2027  }
2028 
2031 
2032  return Status;
2033 }
2034 
2035 static
2036 VOID
2037 NTAPI
2040 {
2041  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2042 
2044 
2045  if (LoadParams->DriverObject)
2046  {
2047  // unload request
2048  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2049  LoadParams->Status = STATUS_SUCCESS;
2050  }
2051  else
2052  {
2053  // load request
2054  HANDLE serviceHandle;
2055  NTSTATUS status;
2056  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2057  if (!NT_SUCCESS(status))
2058  {
2059  LoadParams->Status = status;
2060  }
2061  else
2062  {
2063  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2064  ZwClose(serviceHandle);
2065  }
2066  }
2067 
2068  if (LoadParams->SetEvent)
2069  {
2070  KeSetEvent(&LoadParams->Event, 0, FALSE);
2071  }
2072 }
2073 
2083 NTSTATUS
2087 {
2088  LOAD_UNLOAD_PARAMS LoadParams;
2089 
2090  /* Prepare parameters block */
2091  LoadParams.RegistryPath = RegistryPath;
2092  LoadParams.DriverObject = *DriverObject;
2093 
2095  {
2096  LoadParams.SetEvent = TRUE;
2098 
2099  /* Initialize and queue a work item */
2100  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2102 
2103  /* And wait till it completes */
2105  }
2106  else
2107  {
2108  /* If we're already in a system process, call it right here */
2109  LoadParams.SetEvent = FALSE;
2110  IopLoadUnloadDriverWorker(&LoadParams);
2111  }
2112 
2113  return LoadParams.Status;
2114 }
2115 
2116 /*
2117  * NtLoadDriver
2118  *
2119  * Loads a device driver.
2120  *
2121  * Parameters
2122  * DriverServiceName
2123  * Name of the service to load (registry key).
2124  *
2125  * Return Value
2126  * Status
2127  *
2128  * Status
2129  * implemented
2130  */
2132 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2133 {
2134  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2137  NTSTATUS Status;
2138 
2139  PAGED_CODE();
2140 
2142 
2143  /* Need the appropriate priviliege */
2145  {
2146  DPRINT1("No load privilege!\n");
2148  }
2149 
2150  /* Capture the service name */
2151  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2152  PreviousMode,
2153  DriverServiceName);
2154  if (!NT_SUCCESS(Status))
2155  {
2156  return Status;
2157  }
2158 
2159  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2160 
2161  /* We need a service name */
2162  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2163  {
2164  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2165  return STATUS_INVALID_PARAMETER;
2166  }
2167 
2168  /* Load driver and call its entry point */
2169  DriverObject = NULL;
2170  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2171 
2172  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2173  return Status;
2174 }
2175 
2176 /*
2177  * NtUnloadDriver
2178  *
2179  * Unloads a legacy device driver.
2180  *
2181  * Parameters
2182  * DriverServiceName
2183  * Name of the service to unload (registry key).
2184  *
2185  * Return Value
2186  * Status
2187  *
2188  * Status
2189  * implemented
2190  */
2191 
2194 {
2195  return IopUnloadDriver(DriverServiceName, FALSE);
2196 }
2197 
2198 /* 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:4196
#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:1622
VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:1008
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:1195
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:80
#define TAG_RTLREGISTRY
Definition: tag.h:97
#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:1811
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:2655
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2038
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1481
_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:1053
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:2084
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:3062
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1923
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:1278
#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
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:1517
#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:1782
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:102
#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:295
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:118
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:1561
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:84
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:898
#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:61
__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:21
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:987
#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:1753
#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:2193
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:1889
#define OBJ_PERMANENT
Definition: winternl.h:226
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1876
_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:2714
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:2935
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
VOID NTAPI IoDeleteDriver(_In_ PDRIVER_OBJECT DriverObject)
Definition: driver.c:1741
#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 UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:806
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:2345
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:1038
DWORD RVA
Definition: compat.h:1262
#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:1254
#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:2132
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:2885
#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: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