ReactOS  0.4.15-dev-1367-g07cc0b5
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 
33 
34 #define TAG_RTLREGISTRY 'vrqR'
35 
37 extern BOOLEAN PnpSystemInit;
40 
43 
44 /* PRIVATE FUNCTIONS **********************************************************/
45 
47 NTAPI
50  PIRP Irp)
51 {
52  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
53  Irp->IoStatus.Information = 0;
56 }
57 
58 VOID
59 NTAPI
61 {
62  PDRIVER_OBJECT DriverObject = ObjectBody;
63  PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
64  PAGED_CODE();
65 
66  DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
67 
68  /* There must be no device objects remaining at this point */
69  ASSERT(!DriverObject->DeviceObject);
70 
71  /* Get the extension and loop them */
72  DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
73  while (DriverExtension)
74  {
75  /* Get the next one */
76  NextDriverExtension = DriverExtension->NextExtension;
78 
79  /* Move on */
80  DriverExtension = NextDriverExtension;
81  }
82 
83  /* Check if the driver image is still loaded */
84  if (DriverObject->DriverSection)
85  {
86  /* Unload it */
87  MmUnloadSystemImage(DriverObject->DriverSection);
88  }
89 
90  /* Check if it has a name */
91  if (DriverObject->DriverName.Buffer)
92  {
93  /* Free it */
94  ExFreePool(DriverObject->DriverName.Buffer);
95  }
96 
97  /* Check if it has a service key name */
98  if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
99  {
100  /* Free it */
101  ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
102  }
103 }
104 
105 NTSTATUS
106 FASTCALL
111 {
114  UNICODE_STRING DriverName;
116 
117  DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
119 
121  *DriverObject = NULL;
122 
123  /* Create ModuleName string */
124  if (ServiceName == NULL || ServiceName->Buffer == NULL)
125  /* We don't know which DriverObject we have to open */
127 
128  if (FileSystem != FALSE)
130  else
132 
133  DriverName.Length = 0;
134  DriverName.MaximumLength = Prefix.Length + ServiceName->Length + sizeof(UNICODE_NULL);
135  ASSERT(DriverName.MaximumLength > ServiceName->Length);
136  DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, DriverName.MaximumLength, TAG_IO);
137  if (DriverName.Buffer == NULL)
138  {
140  }
141  RtlAppendUnicodeStringToString(&DriverName, &Prefix);
143 
144  DPRINT("Driver name: '%wZ'\n", &DriverName);
145 
146  /* Open driver object */
147  Status = ObReferenceObjectByName(&DriverName,
149  NULL, /* PassedAccessState */
150  0, /* DesiredAccess */
152  KernelMode,
153  NULL, /* ParseContext */
154  (PVOID*)&Object);
155  ExFreePoolWithTag(DriverName.Buffer, TAG_IO);
156  if (!NT_SUCCESS(Status))
157  {
158  DPRINT("Failed to reference driver object, status=0x%08x\n", Status);
159  return Status;
160  }
161 
162  *DriverObject = Object;
163 
164  DPRINT("Driver Object: %p\n", Object);
165 
166  return STATUS_SUCCESS;
167 }
168 
169 /*
170  * RETURNS
171  * TRUE if String2 contains String1 as a suffix.
172  */
173 BOOLEAN
174 NTAPI
176  IN PCUNICODE_STRING String1,
178 {
179  PWCHAR pc1;
180  PWCHAR pc2;
181  ULONG Length;
182 
183  if (String2->Length < String1->Length)
184  return FALSE;
185 
186  Length = String1->Length / 2;
187  pc1 = String1->Buffer;
188  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
189 
190  if (pc1 && pc2)
191  {
192  while (Length--)
193  {
194  if( *pc1++ != *pc2++ )
195  return FALSE;
196  }
197  return TRUE;
198  }
199  return FALSE;
200 }
201 
202 /*
203  * IopDisplayLoadingMessage
204  *
205  * Display 'Loading XXX...' message.
206  */
207 VOID
208 FASTCALL
210 {
211  CHAR TextBuffer[256];
212  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
213 
214  if (ExpInTextModeSetup) return;
215  if (!KeLoaderBlock) return;
217  snprintf(TextBuffer, sizeof(TextBuffer),
218  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
221  ServiceName,
222  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
224 }
225 
226 /*
227  * IopNormalizeImagePath
228  *
229  * Normalize an image path to contain complete path.
230  *
231  * Parameters
232  * ImagePath
233  * The input path and on exit the result path. ImagePath.Buffer
234  * must be allocated by ExAllocatePool on input. Caller is responsible
235  * for freeing the buffer when it's no longer needed.
236  *
237  * ServiceName
238  * Name of the service that ImagePath belongs to.
239  *
240  * Return Value
241  * Status
242  *
243  * Remarks
244  * The input image path isn't freed on error.
245  */
246 NTSTATUS
247 FASTCALL
249  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
250  PUNICODE_STRING ImagePath,
252 {
253  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
254  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
255  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
256  UNICODE_STRING InputImagePath;
257 
258  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
259 
260  InputImagePath = *ImagePath;
261  if (InputImagePath.Length == 0)
262  {
263  ImagePath->Length = 0;
264  ImagePath->MaximumLength = DriversPathString.Length +
265  ServiceName->Length +
266  DotSysString.Length +
267  sizeof(UNICODE_NULL);
268  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
269  ImagePath->MaximumLength,
270  TAG_IO);
271  if (ImagePath->Buffer == NULL)
272  return STATUS_NO_MEMORY;
273 
274  RtlCopyUnicodeString(ImagePath, &DriversPathString);
276  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
277  }
278  else if (InputImagePath.Buffer[0] != L'\\')
279  {
280  ImagePath->Length = 0;
281  ImagePath->MaximumLength = SystemRootString.Length +
282  InputImagePath.Length +
283  sizeof(UNICODE_NULL);
284  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
285  ImagePath->MaximumLength,
286  TAG_IO);
287  if (ImagePath->Buffer == NULL)
288  return STATUS_NO_MEMORY;
289 
290  RtlCopyUnicodeString(ImagePath, &SystemRootString);
291  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
292 
293  /* Free caller's string */
294  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
295  }
296 
297  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
298 
299  return STATUS_SUCCESS;
300 }
301 
302 /*
303  * IopLoadServiceModule
304  *
305  * Load a module specified by registry settings for service.
306  *
307  * Parameters
308  * ServiceName
309  * Name of the service to load.
310  *
311  * Return Value
312  * Status
313  */
314 NTSTATUS
315 FASTCALL
318  OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
319 {
322  UNICODE_STRING ServiceImagePath, CCSName;
324  HANDLE CCSKey, ServiceKey;
326 
328  ASSERT(ServiceName->Length);
329  DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
330 
331  if (ExpInTextModeSetup)
332  {
333  /* We have no registry, but luckily we know where all the drivers are */
334  DPRINT1("IopLoadServiceModule(%wZ, 0x%p) called in ExpInTextModeSetup mode...\n", ServiceName, ModuleObject);
335 
336  /* ServiceStart < 4 is all that matters */
337  ServiceStart = 0;
338 
339  /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
340  RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
341  }
342  else
343  {
344  /* Open CurrentControlSet */
345  RtlInitUnicodeString(&CCSName,
346  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
347  Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
348  if (!NT_SUCCESS(Status))
349  {
350  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
351  &CCSName, Status);
352  return Status;
353  }
354 
355  /* Open service key */
356  Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
357  if (!NT_SUCCESS(Status))
358  {
359  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
361  ZwClose(CCSKey);
362  return Status;
363  }
364 
365  /*
366  * Get information about the service.
367  */
369 
370  RtlInitUnicodeString(&ServiceImagePath, NULL);
371 
372  QueryTable[0].Name = L"Start";
375 
376  QueryTable[1].Name = L"ImagePath";
378  QueryTable[1].EntryContext = &ServiceImagePath;
379 
381  (PWSTR)ServiceKey,
382  QueryTable,
383  NULL,
384  NULL);
385 
386  ZwClose(ServiceKey);
387  ZwClose(CCSKey);
388 
389  if (!NT_SUCCESS(Status))
390  {
391  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
392  return Status;
393  }
394  }
395 
396  /*
397  * Normalize the image path for all later processing.
398  */
399  Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
400 
401  if (!NT_SUCCESS(Status))
402  {
403  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
404  return Status;
405  }
406 
407  /*
408  * Case for disabled drivers
409  */
410  if (ServiceStart >= 4)
411  {
412  /* We can't load this */
414  }
415  else
416  {
417  DPRINT("Loading module from %wZ\n", &ServiceImagePath);
418  Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
419  if (NT_SUCCESS(Status))
420  {
422  }
423  }
424 
425  ExFreePool(ServiceImagePath.Buffer);
426 
427  /*
428  * Now check if the module was loaded successfully.
429  */
430  if (!NT_SUCCESS(Status))
431  {
432  DPRINT("Module loading failed (Status %x)\n", Status);
433  }
434 
435  DPRINT("Module loading (Status %x)\n", Status);
436 
437  return Status;
438 }
439 
440 VOID
441 NTAPI
443 
444 /*
445  * IopInitializeDriverModule
446  *
447  * Initialize a loaded driver.
448  *
449  * Parameters
450  * DeviceNode
451  * Pointer to device node.
452  *
453  * ModuleObject
454  * Module object representing the driver. It can be retrieve by
455  * IopLoadServiceModule.
456  *
457  * ServiceName
458  * Name of the service (as in registry).
459  *
460  * FileSystemDriver
461  * Set to TRUE for file system drivers.
462  *
463  * DriverObject
464  * On successful return this contains the driver object representing
465  * the loaded driver.
466  */
467 NTSTATUS
468 FASTCALL
471  IN PLDR_DATA_TABLE_ENTRY ModuleObject,
473  IN BOOLEAN FileSystemDriver,
475 {
476  static const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
477  UNICODE_STRING DriverName;
478  UNICODE_STRING RegistryKey;
482 
483  DriverEntry = ModuleObject->EntryPoint;
484 
485  if (ServiceName != NULL && ServiceName->Length != 0)
486  {
487  RegistryKey.Length = 0;
488  RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length;
489  RegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool,
490  RegistryKey.MaximumLength,
491  TAG_IO);
492  if (RegistryKey.Buffer == NULL)
493  {
495  }
496  RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName);
498  }
499  else
500  {
501  RtlInitEmptyUnicodeString(&RegistryKey, NULL, 0);
502  }
503 
504  /* Create ModuleName string */
505  if (ServiceName && ServiceName->Length > 0)
506  {
507  DriverName.Length = 0;
508  DriverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME) + ServiceName->Length;
510  DriverName.MaximumLength,
511  TAG_IO);
512  if (DriverName.Buffer == NULL)
513  {
514  RtlFreeUnicodeString(&RegistryKey);
516  }
517 
518  if (FileSystemDriver != FALSE)
520  else
523 
524  DPRINT("Driver name: '%wZ'\n", &DriverName);
525  }
526  else
527  {
528  RtlInitEmptyUnicodeString(&DriverName, NULL, 0);
529  }
530 
531  Status = IopCreateDriver(DriverName.Length > 0 ? &DriverName : NULL,
532  DriverEntry,
533  &RegistryKey,
534  ServiceName,
535  ModuleObject,
536  &Driver);
537  RtlFreeUnicodeString(&RegistryKey);
538  RtlFreeUnicodeString(&DriverName);
539 
540  if (!NT_SUCCESS(Status))
541  {
542  DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status);
543  return Status;
544  }
545 
546  *DriverObject = Driver;
547 
549 
550  /* Set the driver as initialized */
552 
554 
555  return STATUS_SUCCESS;
556 }
557 
558 /*
559  * IopAttachFilterDriversCallback
560  *
561  * Internal routine used by IopAttachFilterDrivers.
562  */
563 NTSTATUS
564 NTAPI
570  PVOID Context,
572 {
575  PWCHAR Filters;
576  PLDR_DATA_TABLE_ENTRY ModuleObject;
579 
580  /* No filter value present */
581  if (ValueType == REG_NONE)
582  return STATUS_SUCCESS;
583 
584  for (Filters = ValueData;
585  ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
586  *Filters != 0;
587  Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
588  {
589  DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
590 
591  ServiceName.Buffer = Filters;
592  ServiceName.MaximumLength =
593  ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
594 
598  &ServiceName,
599  FALSE);
600  if (!NT_SUCCESS(Status))
601  {
602  /* Load and initialize the filter driver */
603  Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
604  if (!NT_SUCCESS(Status))
605  {
608  return Status;
609  }
610 
612  ModuleObject,
613  &ServiceName,
614  FALSE,
615  &DriverObject);
616  if (!NT_SUCCESS(Status))
617  {
620  return Status;
621  }
622  }
623 
626 
628 
629  /* Remove extra reference */
631 
632  if (!NT_SUCCESS(Status))
633  return Status;
634  }
635 
636  return STATUS_SUCCESS;
637 }
638 
639 /*
640  * IopAttachFilterDrivers
641  *
642  * Load filter drivers for specified device node.
643  *
644  * Parameters
645  * Lower
646  * Set to TRUE for loading lower level filters or FALSE for upper
647  * level filters.
648  */
649 NTSTATUS
650 FASTCALL
653  HANDLE EnumSubKey,
654  HANDLE ClassKey,
655  BOOLEAN Lower)
656 {
657  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
659 
660  /*
661  * First load the device filters
662  */
664  if (Lower)
665  QueryTable[0].Name = L"LowerFilters";
666  else
667  QueryTable[0].Name = L"UpperFilters";
668  QueryTable[0].Flags = 0;
670 
672  (PWSTR)EnumSubKey,
673  QueryTable,
674  DeviceNode,
675  NULL);
676  if (!NT_SUCCESS(Status))
677  {
678  DPRINT1("Failed to load device %s filters: %08X\n",
679  Lower ? "lower" : "upper", Status);
680  return Status;
681  }
682 
684  if (Lower)
685  QueryTable[0].Name = L"LowerFilters";
686  else
687  QueryTable[0].Name = L"UpperFilters";
689  QueryTable[0].Flags = 0;
691 
692  if (ClassKey == NULL)
693  {
694  return STATUS_SUCCESS;
695  }
696 
698  (PWSTR)ClassKey,
699  QueryTable,
700  DeviceNode,
701  NULL);
702 
703  if (!NT_SUCCESS(Status))
704  {
705  DPRINT1("Failed to load class %s filters: %08X\n",
706  Lower ? "lower" : "upper", Status);
707  return Status;
708  }
709 
710  return STATUS_SUCCESS;
711 }
712 
713 NTSTATUS
714 NTAPI
716  IN PUNICODE_STRING ImageFileDirectory,
717  IN PUNICODE_STRING NamePrefix OPTIONAL,
718  OUT PCHAR *MissingApi,
719  OUT PWCHAR *MissingDriver,
720  OUT PLOAD_IMPORTS *LoadImports);
721 
722 //
723 // Used for images already loaded (boot drivers)
724 //
725 CODE_SEG("INIT")
726 NTSTATUS
727 NTAPI
730  PLDR_DATA_TABLE_ENTRY *ModuleObject)
731 {
733  UNICODE_STRING BaseName, BaseDirectory;
734  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
735  PCHAR MissingApiName, Buffer;
736  PWCHAR MissingDriverName;
737  PVOID DriverBase = LdrEntry->DllBase;
738 
739  /* Allocate a buffer we'll use for names */
742  TAG_LDR_WSTR);
743  if (!Buffer)
744  {
745  /* Fail */
747  }
748 
749  /* Check for a separator */
750  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
751  {
752  PWCHAR p;
753  ULONG BaseLength;
754 
755  /* Loop the path until we get to the base name */
756  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
757  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
758 
759  /* Get the length */
760  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
761  BaseLength *= sizeof(WCHAR);
762 
763  /* Setup the string */
764  BaseName.Length = (USHORT)BaseLength;
765  BaseName.Buffer = p;
766  }
767  else
768  {
769  /* Otherwise, we already have a base name */
770  BaseName.Length = FileName->Length;
771  BaseName.Buffer = FileName->Buffer;
772  }
773 
774  /* Setup the maximum length */
775  BaseName.MaximumLength = BaseName.Length;
776 
777  /* Now compute the base directory */
778  BaseDirectory = *FileName;
779  BaseDirectory.Length -= BaseName.Length;
780  BaseDirectory.MaximumLength = BaseDirectory.Length;
781 
782  /* Resolve imports */
783  MissingApiName = Buffer;
784  Status = MiResolveImageReferences(DriverBase,
785  &BaseDirectory,
786  NULL,
787  &MissingApiName,
788  &MissingDriverName,
789  &LoadedImports);
790 
791  /* Free the temporary buffer */
793 
794  /* Check the result of the imports resolution */
795  if (!NT_SUCCESS(Status)) return Status;
796 
797  /* Return */
798  *ModuleObject = LdrEntry;
799  return STATUS_SUCCESS;
800 }
801 
802 /*
803  * IopInitializeBuiltinDriver
804  *
805  * Initialize a driver that is already loaded in memory.
806  */
807 CODE_SEG("INIT")
808 NTSTATUS
809 NTAPI
811 {
815  PWCHAR Buffer, FileNameWithoutPath;
816  PWSTR FileExtension;
817  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
818  PLDR_DATA_TABLE_ENTRY LdrEntry;
819  PLIST_ENTRY NextEntry;
822 
823  /*
824  * Display 'Loading XXX...' message
825  */
828 
830  ModuleName->Length + sizeof(UNICODE_NULL),
831  TAG_IO);
832  if (Buffer == NULL)
833  {
835  }
836 
838  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
839 
840  /*
841  * Generate filename without path (not needed by freeldr)
842  */
843  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
844  if (FileNameWithoutPath == NULL)
845  {
846  FileNameWithoutPath = Buffer;
847  }
848  else
849  {
850  FileNameWithoutPath++;
851  }
852 
853  /*
854  * Strip the file extension from ServiceName
855  */
856  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
858  if (!Success)
859  {
861  }
862 
863  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
864  if (FileExtension != NULL)
865  {
866  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
867  FileExtension[0] = UNICODE_NULL;
868  }
869 
870  /*
871  * Determine the right device object
872  */
873  /* Use IopRootDeviceNode for now */
875  NULL,
876  &ServiceName,
877  &DeviceNode);
879  if (!NT_SUCCESS(Status))
880  {
881  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
882  return Status;
883  }
884 
885  /* Lookup the new Ldr entry in PsLoadedModuleList */
886  NextEntry = PsLoadedModuleList.Flink;
887  while (NextEntry != &PsLoadedModuleList)
888  {
889  LdrEntry = CONTAINING_RECORD(NextEntry,
891  InLoadOrderLinks);
893  {
894  break;
895  }
896 
897  NextEntry = NextEntry->Flink;
898  }
899  ASSERT(NextEntry != &PsLoadedModuleList);
900 
901  /*
902  * Initialize the driver
903  */
905  LdrEntry,
906  &DeviceNode->ServiceName,
907  FALSE,
908  &DriverObject);
909 
910  if (!NT_SUCCESS(Status))
911  {
912  return Status;
913  }
914 
916  if (NT_SUCCESS(Status))
917  {
919  }
920 
921  /* Remove extra reference from IopInitializeDriverModule */
923 
924  return Status;
925 }
926 
927 /*
928  * IopInitializeBootDrivers
929  *
930  * Initialize boot drivers and free memory for boot files.
931  *
932  * Parameters
933  * None
934  *
935  * Return Value
936  * None
937  */
938 CODE_SEG("INIT")
939 VOID
940 FASTCALL
942 {
943  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
944  PLDR_DATA_TABLE_ENTRY LdrEntry;
947  LDR_DATA_TABLE_ENTRY ModuleObject;
949  UNICODE_STRING DriverName;
950  ULONG i, Index;
951  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
953  PBOOT_DRIVER_LIST_ENTRY BootEntry;
954  DPRINT("IopInitializeBootDrivers()\n");
955 
956  /* Use IopRootDeviceNode for now */
958  if (!NT_SUCCESS(Status)) return;
959 
960  /* Setup the module object for the RAW FS Driver */
961  ModuleObject.DllBase = NULL;
962  ModuleObject.SizeOfImage = 0;
963  ModuleObject.EntryPoint = RawFsDriverEntry;
964  RtlInitUnicodeString(&DriverName, L"RAW");
965 
966  /* Initialize it */
968  &ModuleObject,
969  &DriverName,
970  TRUE,
971  &DriverObject);
972  if (!NT_SUCCESS(Status))
973  {
974  /* Fail */
975  return;
976  }
977 
978  /* Now initialize the associated device */
980  if (!NT_SUCCESS(Status))
981  {
982  /* Fail */
984  return;
985  }
986 
987  /* Start it up */
989  if (!NT_SUCCESS(Status))
990  {
991  /* Fail */
993  return;
994  }
995 
996  /* Get highest group order index */
998  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
999 
1000  /* Allocate the group table */
1002  IopGroupIndex * sizeof(LIST_ENTRY),
1003  TAG_IO);
1004  if (IopGroupTable == NULL) ASSERT(FALSE);
1005 
1006  /* Initialize the group table lists */
1007  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1008 
1009  /* Loop the boot modules */
1010  ListHead = &KeLoaderBlock->LoadOrderListHead;
1011  NextEntry = ListHead->Flink;
1012  while (ListHead != NextEntry)
1013  {
1014  /* Get the entry */
1015  LdrEntry = CONTAINING_RECORD(NextEntry,
1017  InLoadOrderLinks);
1018 
1019  /* Check if the DLL needs to be initialized */
1020  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1021  {
1022  /* Call its entrypoint */
1023  MmCallDllInitialize(LdrEntry, NULL);
1024  }
1025 
1026  /* Go to the next driver */
1027  NextEntry = NextEntry->Flink;
1028  }
1029 
1030  /* Loop the boot drivers */
1031  ListHead = &KeLoaderBlock->BootDriverListHead;
1032  NextEntry = ListHead->Flink;
1033  while (ListHead != NextEntry)
1034  {
1035  /* Get the entry */
1036  BootEntry = CONTAINING_RECORD(NextEntry,
1038  Link);
1039 
1040  /* Get the driver loader entry */
1041  LdrEntry = BootEntry->LdrEntry;
1042 
1043  /* Allocate our internal accounting structure */
1045  sizeof(DRIVER_INFORMATION),
1046  TAG_IO);
1047  if (DriverInfo)
1048  {
1049  /* Zero it and initialize it */
1052  DriverInfo->DataTableEntry = BootEntry;
1053 
1054  /* Open the registry key */
1056  NULL,
1057  &BootEntry->RegistryPath,
1058  KEY_READ);
1059  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1060 #if 0
1061  if (NT_SUCCESS(Status))
1062 #else // Hack still needed...
1063  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1064  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1065 #endif
1066  {
1067  /* Save the handle */
1069 
1070  /* Get the group oder index */
1072 
1073  /* Get the tag position */
1075 
1076  /* Insert it into the list, at the right place */
1078  NextEntry2 = IopGroupTable[Index].Flink;
1079  while (NextEntry2 != &IopGroupTable[Index])
1080  {
1081  /* Get the driver info */
1082  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1084  Link);
1085 
1086  /* Check if we found the right tag position */
1087  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1088  {
1089  /* We're done */
1090  break;
1091  }
1092 
1093  /* Next entry */
1094  NextEntry2 = NextEntry2->Flink;
1095  }
1096 
1097  /* Insert us right before the next entry */
1098  NextEntry2 = NextEntry2->Blink;
1099  InsertHeadList(NextEntry2, &DriverInfo->Link);
1100  }
1101  }
1102 
1103  /* Go to the next driver */
1104  NextEntry = NextEntry->Flink;
1105  }
1106 
1107  /* Loop each group index */
1108  for (i = 0; i < IopGroupIndex; i++)
1109  {
1110  /* Loop each group table */
1111  NextEntry = IopGroupTable[i].Flink;
1112  while (NextEntry != &IopGroupTable[i])
1113  {
1114  /* Get the entry */
1115  DriverInfo = CONTAINING_RECORD(NextEntry,
1117  Link);
1118 
1119  /* Get the driver loader entry */
1120  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1121 
1122  /* Initialize it */
1123  IopInitializeBuiltinDriver(LdrEntry);
1124 
1125  /* Start the devices found by a driver (if any) */
1128  NULL,
1129  NULL);
1130 
1131  /* Next entry */
1132  NextEntry = NextEntry->Flink;
1133  }
1134  }
1135 
1136  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1137  * when some devices are not being initialized with their drivers. This flag is used to delay
1138  * all actions with devices (except PnP root device) until boot drivers are loaded.
1139  * See PiQueueDeviceAction function
1140  */
1142 }
1143 
1144 CODE_SEG("INIT")
1145 VOID
1146 FASTCALL
1148 {
1149  PUNICODE_STRING *DriverList, *SavedList;
1150 
1151  /* No system drivers on the boot cd */
1152  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1153 
1154  /* Get the driver list */
1155  SavedList = DriverList = CmGetSystemDriverList();
1156  ASSERT(DriverList);
1157 
1158  /* Loop it */
1159  while (*DriverList)
1160  {
1161  /* Load the driver */
1162  ZwLoadDriver(*DriverList);
1163 
1164  /* Free the entry */
1165  RtlFreeUnicodeString(*DriverList);
1166  ExFreePool(*DriverList);
1167 
1168  /* Next entry */
1170  DriverList++;
1171  }
1172 
1173  /* Free the list */
1174  ExFreePool(SavedList);
1175 }
1176 
1177 /*
1178  * IopUnloadDriver
1179  *
1180  * Unloads a device driver.
1181  *
1182  * Parameters
1183  * DriverServiceName
1184  * Name of the service to unload (registry key).
1185  *
1186  * UnloadPnpDrivers
1187  * Whether to unload Plug & Plug or only legacy drivers. If this
1188  * parameter is set to FALSE, the routine will unload only legacy
1189  * drivers.
1190  *
1191  * Return Value
1192  * Status
1193  *
1194  * To do
1195  * Guard the whole function by SEH.
1196  */
1197 
1199 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1200 {
1203  UNICODE_STRING ImagePath;
1208  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1209  NTSTATUS Status;
1210  USHORT LastBackslash;
1211  BOOLEAN SafeToUnload = TRUE;
1213  UNICODE_STRING CapturedServiceName;
1214 
1215  PAGED_CODE();
1216 
1218 
1219  /* Need the appropriate priviliege */
1221  {
1222  DPRINT1("No unload privilege!\n");
1224  }
1225 
1226  /* Capture the service name */
1227  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
1228  if (!NT_SUCCESS(Status))
1229  {
1230  return Status;
1231  }
1232 
1233  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1234 
1235 
1236  /* We need a service name */
1237  if (CapturedServiceName.Length == 0)
1238  {
1239  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1240  return STATUS_INVALID_PARAMETER;
1241  }
1242 
1243  /*
1244  * Get the service name from the registry key name
1245  */
1247  &CapturedServiceName,
1248  &Backslash,
1249  &LastBackslash);
1250  if (NT_SUCCESS(Status))
1251  {
1252  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1253  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1254  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1255  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1256  }
1257  else
1258  {
1259  ServiceName = CapturedServiceName;
1260  }
1261 
1262  /*
1263  * Construct the driver object name
1264  */
1265  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1266  ServiceName.Length,
1267  &ObjectName.MaximumLength);
1268  if (!NT_SUCCESS(Status))
1269  {
1270  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1271  return Status;
1272  }
1273  ObjectName.Length = 0;
1275  ObjectName.MaximumLength,
1276  TAG_IO);
1277  if (!ObjectName.Buffer)
1278  {
1279  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1281  }
1284 
1285  /*
1286  * Find the driver object
1287  */
1289  0,
1290  0,
1291  0,
1293  KernelMode,
1294  0,
1295  (PVOID*)&DriverObject);
1296 
1297  if (!NT_SUCCESS(Status))
1298  {
1299  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1301  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1302  return Status;
1303  }
1304 
1305  /* Free the buffer for driver object name */
1307 
1308  /* Check that driver is not already unloading */
1309  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1310  {
1311  DPRINT1("Driver deletion pending\n");
1313  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1314  return STATUS_DELETE_PENDING;
1315  }
1316 
1317  /*
1318  * Get path of service...
1319  */
1321 
1322  RtlInitUnicodeString(&ImagePath, NULL);
1323 
1324  QueryTable[0].Name = L"ImagePath";
1326  QueryTable[0].EntryContext = &ImagePath;
1327 
1329  CapturedServiceName.Buffer,
1330  QueryTable,
1331  NULL,
1332  NULL);
1333 
1334  /* We no longer need service name */
1335  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1336 
1337  if (!NT_SUCCESS(Status))
1338  {
1339  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1341  return Status;
1342  }
1343 
1344  /*
1345  * Normalize the image path for all later processing.
1346  */
1347  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1348 
1349  if (!NT_SUCCESS(Status))
1350  {
1351  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1353  return Status;
1354  }
1355 
1356  /* Free the service path */
1357  ExFreePool(ImagePath.Buffer);
1358 
1359  /*
1360  * Unload the module and release the references to the device object
1361  */
1362 
1363  /* Call the load/unload routine, depending on current process */
1364  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1365  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1366  {
1367  /* Loop through each device object of the driver
1368  and set DOE_UNLOAD_PENDING flag */
1369  DeviceObject = DriverObject->DeviceObject;
1370  while (DeviceObject)
1371  {
1372  /* Set the unload pending flag for the device */
1373  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1374  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1375 
1376  /* Make sure there are no attached devices or no reference counts */
1377  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1378  {
1379  /* Not safe to unload */
1380  DPRINT1("Drivers device object is referenced or has attached devices\n");
1381 
1382  SafeToUnload = FALSE;
1383  }
1384 
1385  DeviceObject = DeviceObject->NextDevice;
1386  }
1387 
1388  /* If not safe to unload, then return success */
1389  if (!SafeToUnload)
1390  {
1392  return STATUS_SUCCESS;
1393  }
1394 
1395  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1396 
1397  /* Set the unload invoked flag and call the unload routine */
1401 
1402  /* Mark the driver object temporary, so it could be deleted later */
1404 
1405  /* Dereference it 2 times */
1408 
1409  return Status;
1410  }
1411  else
1412  {
1413  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1414 
1415  /* Dereference one time (refd inside this function) */
1417 
1418  /* Return unloading failure */
1420  }
1421 }
1422 
1423 VOID
1424 NTAPI
1426 {
1427  PDRIVER_REINIT_ITEM ReinitItem;
1429 
1430  /* Get the first entry and start looping */
1433  while (Entry)
1434  {
1435  /* Get the item */
1436  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1437 
1438  /* Increment reinitialization counter */
1439  ReinitItem->DriverObject->DriverExtension->Count++;
1440 
1441  /* Remove the device object flag */
1442  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1443 
1444  /* Call the routine */
1445  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1446  ReinitItem->Context,
1447  ReinitItem->DriverObject->
1448  DriverExtension->Count);
1449 
1450  /* Free the entry */
1451  ExFreePool(Entry);
1452 
1453  /* Move to the next one */
1456  }
1457 }
1458 
1459 VOID
1460 NTAPI
1462 {
1463  PDRIVER_REINIT_ITEM ReinitItem;
1465 
1466  /* Get the first entry and start looping */
1469  while (Entry)
1470  {
1471  /* Get the item */
1472  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1473 
1474  /* Increment reinitialization counter */
1475  ReinitItem->DriverObject->DriverExtension->Count++;
1476 
1477  /* Remove the device object flag */
1479 
1480  /* Call the routine */
1481  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1482  ReinitItem->Context,
1483  ReinitItem->DriverObject->
1484  DriverExtension->Count);
1485 
1486  /* Free the entry */
1487  ExFreePool(Entry);
1488 
1489  /* Move to the next one */
1492  }
1493 
1494  /* Wait for all device actions being finished*/
1496 }
1497 
1498 NTSTATUS
1499 NTAPI
1501  IN PDRIVER_INITIALIZE InitializationFunction,
1504  IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL,
1505  OUT PDRIVER_OBJECT *pDriverObject)
1506 {
1507  WCHAR NameBuffer[100];
1508  USHORT NameLength;
1509  UNICODE_STRING LocalDriverName;
1510  NTSTATUS Status;
1512  ULONG ObjectSize;
1514  UNICODE_STRING ServiceKeyName;
1515  HANDLE hDriver;
1516  ULONG i, RetryCount = 0;
1517 
1518 try_again:
1519  /* First, create a unique name for the driver if we don't have one */
1520  if (!DriverName)
1521  {
1522  /* Create a random name and set up the string */
1523  NameLength = (USHORT)swprintf(NameBuffer,
1524  DRIVER_ROOT_NAME L"%08u",
1526  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1527  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1528  LocalDriverName.Buffer = NameBuffer;
1529  }
1530  else
1531  {
1532  /* So we can avoid another code path, use a local var */
1533  LocalDriverName = *DriverName;
1534  }
1535 
1536  /* Initialize the Attributes */
1537  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1539  &LocalDriverName,
1541  NULL,
1542  NULL);
1543 
1544  /* Create the Object */
1548  KernelMode,
1549  NULL,
1550  ObjectSize,
1551  0,
1552  0,
1553  (PVOID*)&DriverObject);
1554  if (!NT_SUCCESS(Status)) return Status;
1555 
1556  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1557 
1558  /* Set up the Object */
1559  RtlZeroMemory(DriverObject, ObjectSize);
1560  DriverObject->Type = IO_TYPE_DRIVER;
1561  DriverObject->Size = sizeof(DRIVER_OBJECT);
1562 
1563  /*
1564  * Check whether RegistryPath and ModuleObject are both NULL because
1565  * IoCreateDriver() was called to initialize a built-in driver.
1566  */
1567  if ((RegistryPath != NULL) || (ModuleObject != NULL))
1569  else
1571 
1572  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1573  DriverObject->DriverExtension->DriverObject = DriverObject;
1574  DriverObject->DriverInit = InitializationFunction;
1575  DriverObject->DriverSection = ModuleObject;
1576  /* Loop all Major Functions */
1577  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1578  {
1579  /* Invalidate each function */
1580  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1581  }
1582 
1583  /* Set up the service key name buffer */
1584  ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
1585  ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
1586  ServiceKeyName.MaximumLength,
1587  TAG_IO);
1588  if (!ServiceKeyName.Buffer)
1589  {
1590  /* Fail */
1594  }
1595 
1596  /* Copy the name and set it in the driver extension */
1597  RtlCopyUnicodeString(&ServiceKeyName,
1598  ServiceName);
1599  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1600 
1601  /* Make a copy of the driver name to store in the driver object */
1602  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1603  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1604  DriverObject->DriverName.MaximumLength,
1605  TAG_IO);
1606  if (!DriverObject->DriverName.Buffer)
1607  {
1608  /* Fail */
1612  }
1613 
1614  RtlCopyUnicodeString(&DriverObject->DriverName,
1615  &LocalDriverName);
1616 
1617  /* Add the Object and get its handle */
1619  NULL,
1621  0,
1622  NULL,
1623  &hDriver);
1624 
1625  /* Eliminate small possibility when this function is called more than
1626  once in a row, and KeTickCount doesn't get enough time to change */
1627  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1628  {
1629  RetryCount++;
1630  goto try_again;
1631  }
1632 
1633  if (!NT_SUCCESS(Status)) return Status;
1634 
1635  /* Now reference it */
1637  0,
1639  KernelMode,
1640  (PVOID*)&DriverObject,
1641  NULL);
1642 
1643  /* Close the extra handle */
1644  ZwClose(hDriver);
1645 
1646  if (!NT_SUCCESS(Status))
1647  {
1648  /* Fail */
1651  return Status;
1652  }
1653 
1654  DriverObject->HardwareDatabase = &IopHardwareDatabaseKey;
1655  DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
1656  DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
1657 
1658  /* Finally, call its init function */
1659  DPRINT("RegistryKey: %wZ\n", RegistryPath);
1660  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1661  Status = (*InitializationFunction)(DriverObject, RegistryPath);
1662  if (!NT_SUCCESS(Status))
1663  {
1664  /* If it didn't work, then kill the object */
1665  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1666  DriverObject->DriverSection = NULL;
1669  return Status;
1670  }
1671  else
1672  {
1673  /* Returns to caller the object */
1674  *pDriverObject = DriverObject;
1675  }
1676 
1677  /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
1678  * Other parts of the I/O manager depend on this behavior */
1679  if (!DriverObject->DeviceObject) DriverObject->Flags &= ~DRVO_LEGACY_DRIVER;
1680 
1681  /* Loop all Major Functions */
1682  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1683  {
1684  /*
1685  * Make sure the driver didn't set any dispatch entry point to NULL!
1686  * Doing so is illegal; drivers shouldn't touch entry points they
1687  * do not implement.
1688  */
1689 
1690  /* Check if it did so anyway */
1691  if (!DriverObject->MajorFunction[i])
1692  {
1693  /* Print a warning in the debug log */
1694  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1695  &DriverObject->DriverName, i);
1696 
1697  /* Fix it up */
1698  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1699  }
1700  }
1701 
1702  /* Return the Status */
1703  return Status;
1704 }
1705 
1706 /* PUBLIC FUNCTIONS ***********************************************************/
1707 
1708 /*
1709  * @implemented
1710  */
1711 NTSTATUS
1712 NTAPI
1714  IN PDRIVER_INITIALIZE InitializationFunction)
1715 {
1717  return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
1718 }
1719 
1720 /*
1721  * @implemented
1722  */
1723 VOID
1724 NTAPI
1726 {
1727  /* Simply dereference the Object */
1729 }
1730 
1731 /*
1732  * @implemented
1733  */
1734 VOID
1735 NTAPI
1737  IN PDRIVER_REINITIALIZE ReinitRoutine,
1738  IN PVOID Context)
1739 {
1740  PDRIVER_REINIT_ITEM ReinitItem;
1741 
1742  /* Allocate the entry */
1743  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1744  sizeof(DRIVER_REINIT_ITEM),
1745  TAG_REINIT);
1746  if (!ReinitItem) return;
1747 
1748  /* Fill it out */
1749  ReinitItem->DriverObject = DriverObject;
1750  ReinitItem->ReinitRoutine = ReinitRoutine;
1751  ReinitItem->Context = Context;
1752 
1753  /* Set the Driver Object flag and insert the entry into the list */
1756  &ReinitItem->ItemEntry,
1758 }
1759 
1760 /*
1761  * @implemented
1762  */
1763 VOID
1764 NTAPI
1766  IN PDRIVER_REINITIALIZE ReinitRoutine,
1767  IN PVOID Context)
1768 {
1769  PDRIVER_REINIT_ITEM ReinitItem;
1770 
1771  /* Allocate the entry */
1772  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1773  sizeof(DRIVER_REINIT_ITEM),
1774  TAG_REINIT);
1775  if (!ReinitItem) return;
1776 
1777  /* Fill it out */
1778  ReinitItem->DriverObject = DriverObject;
1779  ReinitItem->ReinitRoutine = ReinitRoutine;
1780  ReinitItem->Context = Context;
1781 
1782  /* Set the Driver Object flag and insert the entry into the list */
1785  &ReinitItem->ItemEntry,
1787 }
1788 
1789 /*
1790  * @implemented
1791  */
1792 NTSTATUS
1793 NTAPI
1796  IN ULONG DriverObjectExtensionSize,
1797  OUT PVOID *DriverObjectExtension)
1798 {
1799  KIRQL OldIrql;
1800  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1801  BOOLEAN Inserted = FALSE;
1802 
1803  /* Assume failure */
1804  *DriverObjectExtension = NULL;
1805 
1806  /* Allocate the extension */
1807  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1808  sizeof(IO_CLIENT_EXTENSION) +
1809  DriverObjectExtensionSize,
1811  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1812 
1813  /* Clear the extension for teh caller */
1814  RtlZeroMemory(NewDriverExtension,
1815  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1816 
1817  /* Acqure lock */
1819 
1820  /* Fill out the extension */
1822 
1823  /* Loop the current extensions */
1824  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1825  ClientDriverExtension;
1826  while (DriverExtensions)
1827  {
1828  /* Check if the identifier matches */
1829  if (DriverExtensions->ClientIdentificationAddress ==
1831  {
1832  /* We have a collision, break out */
1833  break;
1834  }
1835 
1836  /* Go to the next one */
1837  DriverExtensions = DriverExtensions->NextExtension;
1838  }
1839 
1840  /* Check if we didn't collide */
1841  if (!DriverExtensions)
1842  {
1843  /* Link this one in */
1844  NewDriverExtension->NextExtension =
1845  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1846  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1847  NewDriverExtension;
1848  Inserted = TRUE;
1849  }
1850 
1851  /* Release the lock */
1853 
1854  /* Check if insertion failed */
1855  if (!Inserted)
1856  {
1857  /* Free the entry and fail */
1858  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1860  }
1861 
1862  /* Otherwise, return the pointer */
1863  *DriverObjectExtension = NewDriverExtension + 1;
1864  return STATUS_SUCCESS;
1865 }
1866 
1867 /*
1868  * @implemented
1869  */
1870 PVOID
1871 NTAPI
1874 {
1875  KIRQL OldIrql;
1876  PIO_CLIENT_EXTENSION DriverExtensions;
1877 
1878  /* Acquire lock */
1880 
1881  /* Loop the list until we find the right one */
1882  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1883  while (DriverExtensions)
1884  {
1885  /* Check for a match */
1886  if (DriverExtensions->ClientIdentificationAddress ==
1888  {
1889  /* Break out */
1890  break;
1891  }
1892 
1893  /* Keep looping */
1894  DriverExtensions = DriverExtensions->NextExtension;
1895  }
1896 
1897  /* Release lock */
1899 
1900  /* Return nothing or the extension */
1901  if (!DriverExtensions) return NULL;
1902  return DriverExtensions + 1;
1903 }
1904 
1905 VOID
1906 NTAPI
1909 {
1910  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1911 
1913  LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
1914  &LoadParams->DriverObject);
1915  KeSetEvent(&LoadParams->Event, 0, FALSE);
1916 }
1917 
1918 NTSTATUS
1919 NTAPI
1923 {
1925  UNICODE_STRING ImagePath;
1927  NTSTATUS Status;
1928  ULONG Type;
1930  PLDR_DATA_TABLE_ENTRY ModuleObject;
1932  WCHAR *cur;
1933 
1934  /* Load/Unload must be called from system process */
1936  {
1937  LOAD_UNLOAD_PARAMS LoadParams;
1938 
1939  /* Prepare parameters block */
1940  LoadParams.RegistryPath = RegistryPath;
1941  LoadParams.DriverObject = *DriverObject;
1943 
1944  /* Initialize and queue a work item */
1945  ExInitializeWorkItem(&LoadParams.WorkItem,
1947  &LoadParams);
1949 
1950  /* And wait till it completes */
1951  KeWaitForSingleObject(&LoadParams.Event,
1952  UserRequest,
1953  KernelMode,
1954  FALSE,
1955  NULL);
1956  return LoadParams.Status;
1957  }
1958 
1959  /* Check if it's an unload request */
1960  if (*DriverObject)
1961  {
1962  (*DriverObject)->DriverUnload(*DriverObject);
1963  return STATUS_SUCCESS;
1964  }
1965 
1966  RtlInitUnicodeString(&ImagePath, NULL);
1967 
1968  /*
1969  * Get the service name from the registry key name.
1970  */
1971  ASSERT(RegistryPath->Length >= sizeof(WCHAR));
1972 
1974  cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
1975  while (RegistryPath->Buffer != cur)
1976  {
1977  if (*cur == L'\\')
1978  {
1979  ServiceName.Buffer = cur + 1;
1980  ServiceName.Length = RegistryPath->Length -
1981  (USHORT)((ULONG_PTR)ServiceName.Buffer -
1982  (ULONG_PTR)RegistryPath->Buffer);
1983  break;
1984  }
1985  cur--;
1986  }
1987 
1988  /*
1989  * Get service type.
1990  */
1991  RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1992 
1993  RtlInitUnicodeString(&ImagePath, NULL);
1994 
1995  QueryTable[0].Name = L"Type";
1998 
1999  QueryTable[1].Name = L"ImagePath";
2001  QueryTable[1].EntryContext = &ImagePath;
2002 
2004  RegistryPath->Buffer,
2005  QueryTable, NULL, NULL);
2006  if (!NT_SUCCESS(Status))
2007  {
2008  DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
2009  if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
2010  return Status;
2011  }
2012 
2013  /*
2014  * Normalize the image path for all later processing.
2015  */
2016  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
2017  if (!NT_SUCCESS(Status))
2018  {
2019  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
2020  return Status;
2021  }
2022 
2023  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
2024  DPRINT("Type: %lx\n", Type);
2025 
2028  /*
2029  * Get existing DriverObject pointer (in case the driver
2030  * has already been loaded and initialized).
2031  */
2033  &ServiceName,
2036 
2037  if (!NT_SUCCESS(Status))
2038  {
2039  /*
2040  * Load the driver module
2041  */
2042  DPRINT("Loading module from %wZ\n", &ImagePath);
2043  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2044  if (!NT_SUCCESS(Status))
2045  {
2046  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2049  return Status;
2050  }
2051 
2052  /*
2053  * Initialize the driver module if it's loaded for the first time
2054  */
2056  if (!NT_SUCCESS(Status))
2057  {
2058  DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
2061  MmUnloadSystemImage(ModuleObject);
2062  return Status;
2063  }
2064 
2065  IopDisplayLoadingMessage(&DeviceNode->ServiceName);
2066 
2068  ModuleObject,
2069  &DeviceNode->ServiceName,
2072  DriverObject);
2073  if (!NT_SUCCESS(Status))
2074  {
2075  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2078  MmUnloadSystemImage(ModuleObject);
2079  return Status;
2080  }
2081 
2084 
2085  /* Initialize and start device */
2088  }
2089  else
2090  {
2093 
2094  DPRINT("DriverObject already exist in ObjectManager\n");
2096 
2097  /* IopGetDriverObject references the DriverObject, so dereference it */
2099  }
2100 
2101  return Status;
2102 }
2103 
2104 /*
2105  * NtLoadDriver
2106  *
2107  * Loads a device driver.
2108  *
2109  * Parameters
2110  * DriverServiceName
2111  * Name of the service to load (registry key).
2112  *
2113  * Return Value
2114  * Status
2115  *
2116  * Status
2117  * implemented
2118  */
2120 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2121 {
2122  UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
2125  NTSTATUS Status;
2126 
2127  PAGED_CODE();
2128 
2130 
2131  /*
2132  * Check security privileges
2133  */
2135  {
2136  DPRINT("Privilege not held\n");
2138  }
2139 
2140  Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
2141  PreviousMode,
2142  DriverServiceName);
2143  if (!NT_SUCCESS(Status))
2144  {
2145  return Status;
2146  }
2147 
2148  DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
2149 
2150  /* Load driver and call its entry point */
2151  DriverObject = NULL;
2152  Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
2153 
2154  ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
2155  PreviousMode);
2156 
2157  return Status;
2158 }
2159 
2160 /*
2161  * NtUnloadDriver
2162  *
2163  * Unloads a legacy device driver.
2164  *
2165  * Parameters
2166  * DriverServiceName
2167  * Name of the service to unload (registry key).
2168  *
2169  * Return Value
2170  * Status
2171  *
2172  * Status
2173  * implemented
2174  */
2175 
2178 {
2179  return IopUnloadDriver(DriverServiceName, FALSE);
2180 }
2181 
2182 /* 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:916
BOOLEAN ExpInTextModeSetup
Definition: init.c:67
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2207
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
#define IN
Definition: typedefs.h:39
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2206
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:941
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:711
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:814
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1147
PSTR ArcBootDeviceName
Definition: arc.h:503
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const unsigned char pc1[56]
Definition: des.c:54
#define TAG_IO
Definition: tag.h:69
PWCHAR FileSystem
Definition: format.c:72
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1776
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1794
struct _Entry Entry
Definition: kefuncs.h:627
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2474
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1425
_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 TAG_RTLREGISTRY
Definition: driver.c:34
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:209
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:471
ACPI_SIZE Length
Definition: actypes.h:1044
char CHAR
Definition: xmlstorage.h:175
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
NTSTATUS IopCreateDeviceNode(IN PDEVICE_NODE ParentNode, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING ServiceName, OUT PDEVICE_NODE *DeviceNode)
WORK_QUEUE_ITEM WorkItem
Definition: io.h:401
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
ULONG SizeOfImage
Definition: ldrtypes.h:143
#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
unsigned short Length
Definition: sprintf.c:451
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:520
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
NTSTATUS NTAPI IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL, IN PDRIVER_INITIALIZE InitializationFunction, IN PUNICODE_STRING RegistryPath OPTIONAL, IN PCUNICODE_STRING ServiceName, IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL, OUT PDRIVER_OBJECT *pDriverObject)
Definition: driver.c:1500
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:32
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1274
uint16_t * PWCHAR
Definition: typedefs.h:56
NTSTATUS FASTCALL IopLoadServiceModule(IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:316
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_In_ PVOID Parameter
Definition: ldrtypes.h:241
KEVENT Event
Definition: io.h:402
VOID NTAPI IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
Definition: driver.c:1725
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: driver.c:10
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:48
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
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:1461
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:956
static int Link(const char **args)
Definition: vfdcmd.c:2414
#define OBJ_OPENIF
Definition: winternl.h:229
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
USHORT NTAPI PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
Definition: pnpinit.c:154
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4448
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1765
uint32_t ULONG_PTR
Definition: typedefs.h:65
LIST_ENTRY ItemEntry
Definition: io.h:468
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
PVOID DllBase
Definition: btrfs_drv.h:1926
NTSTATUS IopStartDevice(IN PDEVICE_NODE DeviceNode)
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
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:496
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
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
#define STATUS_DRIVER_UNABLE_TO_LOAD
Definition: ntstatus.h:745
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:309
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define FILE_READ_DATA
Definition: nt_native.h:628
PVOID EntryPoint
Definition: ntddk_ex.h:203
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2262
#define PsGetCurrentProcess
Definition: psfuncs.h:17
LIST_ENTRY Link
Definition: io.h:411
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
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:248
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4142
VOID(NTAPI * PDRIVER_REINITIALIZE)(_In_ struct _DRIVER_OBJECT *DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Definition: iotypes.h:4434
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
HANDLE ServiceHandle
Definition: io.h:414
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
PDRIVER_OBJECT DriverObject
Definition: io.h:469
Definition: bufpool.h:45
USHORT TagPosition
Definition: io.h:415
NTSTATUS FASTCALL IopInitializeDevice(IN PDEVICE_NODE DeviceNode, IN PDRIVER_OBJECT DriverObject)
NTSTATUS FASTCALL IopGetDriverObject(PDRIVER_OBJECT *DriverObject, PUNICODE_STRING ServiceName, BOOLEAN FileSystem)
Definition: driver.c:107
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:1026
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define TAG_REINIT
Definition: tag.h:73
KEVENT PiEnumerationFinished
Definition: devaction.c:49
VOID ServiceStart(DWORD argc, LPTSTR *argv)
Definition: nfs41_daemon.c:381
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2205
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:912
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1636
NTSTATUS NTAPI IopAttachFilterDriversCallback(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: driver.c:565
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:239
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:45
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define TAG_DRIVER_EXTENSION
Definition: tag.h:42
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
PLIST_ENTRY DriverReinitTailEntry
Definition: driver.c:23
#define swprintf(buf, format,...)
Definition: sprintf.c:56
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:1001
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
Type
Definition: Type.h:6
PLIST_ENTRY IopGroupTable
Definition: driver.c:42
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:162
CODE_SEG("INIT")
Definition: fsrtlpc.c:19
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
VOID NTAPI IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
Definition: device.c:34
Definition: Node.h:9
VOID NTAPI IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1736
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define _Post_notnull_
Definition: sal.h:701
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:413
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
DRIVER_INITIALIZE * PDRIVER_INITIALIZE
Definition: iotypes.h:2215
NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2177
static const WCHAR L[]
Definition: oid.c:1250
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
NTSTATUS Status
Definition: io.h:399
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1872
#define OBJ_PERMANENT
Definition: winternl.h:226
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1922
struct _DRIVER_OBJECT DRIVER_OBJECT
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
static const WCHAR Backslash[]
Definition: cfgmgr.c:38
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
PLIST_ENTRY DriverBootReinitTailEntry
Definition: driver.c:25
LIST_ENTRY LoadOrderListHead
Definition: arc.h:493
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
PDRIVER_OBJECT DriverObject
Definition: io.h:403
FxCollectionEntry * cur
#define _In_
Definition: no_sal2.h:158
struct _FileName FileName
Definition: fatprocs.h:893
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
PCUNICODE_STRING RegistryPath
Definition: io.h:400
NTSTATUS NTAPI IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL, IN PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1713
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:2932
UNICODE_STRING RegistryPath
Definition: arc.h:202
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
NTSTATUS NTAPI IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:810
#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:1599
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
NTSTATUS FASTCALL IopInitializeDriverModule(IN PDEVICE_NODE DeviceNode, IN PLDR_DATA_TABLE_ENTRY ModuleObject, IN PUNICODE_STRING ServiceName, IN BOOLEAN FileSystemDriver, OUT PDRIVER_OBJECT *DriverObject)
Definition: driver.c:469
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:60
#define _At_(t, a)
Definition: no_sal2.h:40
struct _DRIVER_EXTENSION * PDRIVER_EXTENSION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
UNICODE_STRING IopHardwareDatabaseKey
Definition: driver.c:29
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
_In_ const STRING * String2
Definition: rtlfuncs.h:2291
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define _When_(c, a)
Definition: no_sal2.h:38
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
ULONG Flags
Definition: ntddk_ex.h:207
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSTATUS FASTCALL IopAttachFilterDrivers(PDEVICE_NODE DeviceNode, HANDLE EnumSubKey, HANDLE ClassKey, BOOLEAN Lower)
Definition: driver.c:651
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:470
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_NONE
Definition: nt_native.h:1492
PVOID ClientIdentificationAddress
Definition: iotypes.h:815
GLfloat GLfloat p
Definition: glext.h:8902
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1199
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:132
NTSTATUS NTAPI ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, OUT PVOID *ObjectPtr)
Definition: obref.c:411
NTSTATUS NTAPI NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2120
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT IopGroupIndex
Definition: driver.c:41
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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:2266
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
NTSTATUS NTAPI IopLoadUnloadDriver(_In_opt_ PCUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1920
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:2819
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:506
#define PAGED_CODE()
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4450
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:197
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3312
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361
NTSTATUS NTAPI LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry, PUNICODE_STRING FileName, PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:728
VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1907
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:175