ReactOS  0.4.14-dev-854-gb9426a3
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;
38 
41 
42 /* PRIVATE FUNCTIONS **********************************************************/
43 
45 NTAPI
48  PIRP Irp)
49 {
50  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
51  Irp->IoStatus.Information = 0;
54 }
55 
56 VOID
57 NTAPI
59 {
60  PDRIVER_OBJECT DriverObject = ObjectBody;
61  PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
62  PAGED_CODE();
63 
64  DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
65 
66  /* There must be no device objects remaining at this point */
68 
69  /* Get the extension and loop them */
70  DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
71  while (DriverExtension)
72  {
73  /* Get the next one */
74  NextDriverExtension = DriverExtension->NextExtension;
76 
77  /* Move on */
78  DriverExtension = NextDriverExtension;
79  }
80 
81  /* Check if the driver image is still loaded */
83  {
84  /* Unload it */
86  }
87 
88  /* Check if it has a name */
90  {
91  /* Free it */
93  }
94 
95  /* Check if it has a service key name */
97  {
98  /* Free it */
100  }
101 }
102 
103 NTSTATUS
104 FASTCALL
109 {
112  UNICODE_STRING DriverName;
114 
115  DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
117 
119  *DriverObject = NULL;
120 
121  /* Create ModuleName string */
122  if (ServiceName == NULL || ServiceName->Buffer == NULL)
123  /* We don't know which DriverObject we have to open */
125 
126  if (FileSystem != FALSE)
128  else
130 
131  DriverName.Length = 0;
132  DriverName.MaximumLength = Prefix.Length + ServiceName->Length + sizeof(UNICODE_NULL);
133  ASSERT(DriverName.MaximumLength > ServiceName->Length);
134  DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, DriverName.MaximumLength, TAG_IO);
135  if (DriverName.Buffer == NULL)
136  {
138  }
139  RtlAppendUnicodeStringToString(&DriverName, &Prefix);
141 
142  DPRINT("Driver name: '%wZ'\n", &DriverName);
143 
144  /* Open driver object */
145  Status = ObReferenceObjectByName(&DriverName,
147  NULL, /* PassedAccessState */
148  0, /* DesiredAccess */
150  KernelMode,
151  NULL, /* ParseContext */
152  (PVOID*)&Object);
153  ExFreePoolWithTag(DriverName.Buffer, TAG_IO);
154  if (!NT_SUCCESS(Status))
155  {
156  DPRINT("Failed to reference driver object, status=0x%08x\n", Status);
157  return Status;
158  }
159 
160  *DriverObject = Object;
161 
162  DPRINT("Driver Object: %p\n", Object);
163 
164  return STATUS_SUCCESS;
165 }
166 
167 /*
168  * RETURNS
169  * TRUE if String2 contains String1 as a suffix.
170  */
171 BOOLEAN
172 NTAPI
174  IN PCUNICODE_STRING String1,
176 {
177  PWCHAR pc1;
178  PWCHAR pc2;
179  ULONG Length;
180 
181  if (String2->Length < String1->Length)
182  return FALSE;
183 
184  Length = String1->Length / 2;
185  pc1 = String1->Buffer;
186  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
187 
188  if (pc1 && pc2)
189  {
190  while (Length--)
191  {
192  if( *pc1++ != *pc2++ )
193  return FALSE;
194  }
195  return TRUE;
196  }
197  return FALSE;
198 }
199 
200 /*
201  * IopDisplayLoadingMessage
202  *
203  * Display 'Loading XXX...' message.
204  */
205 VOID
206 FASTCALL
208 {
209  CHAR TextBuffer[256];
210  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
211 
212  if (ExpInTextModeSetup) return;
213  if (!KeLoaderBlock) return;
215  snprintf(TextBuffer, sizeof(TextBuffer),
216  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
219  ServiceName,
220  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
222 }
223 
224 /*
225  * IopNormalizeImagePath
226  *
227  * Normalize an image path to contain complete path.
228  *
229  * Parameters
230  * ImagePath
231  * The input path and on exit the result path. ImagePath.Buffer
232  * must be allocated by ExAllocatePool on input. Caller is responsible
233  * for freeing the buffer when it's no longer needed.
234  *
235  * ServiceName
236  * Name of the service that ImagePath belongs to.
237  *
238  * Return Value
239  * Status
240  *
241  * Remarks
242  * The input image path isn't freed on error.
243  */
244 NTSTATUS
245 FASTCALL
247  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
248  PUNICODE_STRING ImagePath,
250 {
251  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
252  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
253  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
254  UNICODE_STRING InputImagePath;
255 
256  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
257 
258  InputImagePath = *ImagePath;
259  if (InputImagePath.Length == 0)
260  {
261  ImagePath->Length = 0;
262  ImagePath->MaximumLength = DriversPathString.Length +
263  ServiceName->Length +
264  DotSysString.Length +
265  sizeof(UNICODE_NULL);
266  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
267  ImagePath->MaximumLength,
268  TAG_IO);
269  if (ImagePath->Buffer == NULL)
270  return STATUS_NO_MEMORY;
271 
272  RtlCopyUnicodeString(ImagePath, &DriversPathString);
274  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
275  }
276  else if (InputImagePath.Buffer[0] != L'\\')
277  {
278  ImagePath->Length = 0;
279  ImagePath->MaximumLength = SystemRootString.Length +
280  InputImagePath.Length +
281  sizeof(UNICODE_NULL);
282  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
283  ImagePath->MaximumLength,
284  TAG_IO);
285  if (ImagePath->Buffer == NULL)
286  return STATUS_NO_MEMORY;
287 
288  RtlCopyUnicodeString(ImagePath, &SystemRootString);
289  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
290 
291  /* Free caller's string */
292  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
293  }
294 
295  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
296 
297  return STATUS_SUCCESS;
298 }
299 
300 /*
301  * IopLoadServiceModule
302  *
303  * Load a module specified by registry settings for service.
304  *
305  * Parameters
306  * ServiceName
307  * Name of the service to load.
308  *
309  * Return Value
310  * Status
311  */
312 NTSTATUS
313 FASTCALL
316  OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
317 {
320  UNICODE_STRING ServiceImagePath, CCSName;
322  HANDLE CCSKey, ServiceKey;
324 
326  ASSERT(ServiceName->Length);
327  DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
328 
329  if (ExpInTextModeSetup)
330  {
331  /* We have no registry, but luckily we know where all the drivers are */
332  DPRINT1("IopLoadServiceModule(%wZ, 0x%p) called in ExpInTextModeSetup mode...\n", ServiceName, ModuleObject);
333 
334  /* ServiceStart < 4 is all that matters */
335  ServiceStart = 0;
336 
337  /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
338  RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
339  }
340  else
341  {
342  /* Open CurrentControlSet */
343  RtlInitUnicodeString(&CCSName,
344  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
345  Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
346  if (!NT_SUCCESS(Status))
347  {
348  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
349  &CCSName, Status);
350  return Status;
351  }
352 
353  /* Open service key */
354  Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
355  if (!NT_SUCCESS(Status))
356  {
357  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
359  ZwClose(CCSKey);
360  return Status;
361  }
362 
363  /*
364  * Get information about the service.
365  */
367 
368  RtlInitUnicodeString(&ServiceImagePath, NULL);
369 
370  QueryTable[0].Name = L"Start";
373 
374  QueryTable[1].Name = L"ImagePath";
376  QueryTable[1].EntryContext = &ServiceImagePath;
377 
379  (PWSTR)ServiceKey,
380  QueryTable,
381  NULL,
382  NULL);
383 
384  ZwClose(ServiceKey);
385  ZwClose(CCSKey);
386 
387  if (!NT_SUCCESS(Status))
388  {
389  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
390  return Status;
391  }
392  }
393 
394  /*
395  * Normalize the image path for all later processing.
396  */
397  Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
398 
399  if (!NT_SUCCESS(Status))
400  {
401  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
402  return Status;
403  }
404 
405  /*
406  * Case for disabled drivers
407  */
408  if (ServiceStart >= 4)
409  {
410  /* We can't load this */
412  }
413  else
414  {
415  DPRINT("Loading module from %wZ\n", &ServiceImagePath);
416  Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
417  if (NT_SUCCESS(Status))
418  {
420  }
421  }
422 
423  ExFreePool(ServiceImagePath.Buffer);
424 
425  /*
426  * Now check if the module was loaded successfully.
427  */
428  if (!NT_SUCCESS(Status))
429  {
430  DPRINT("Module loading failed (Status %x)\n", Status);
431  }
432 
433  DPRINT("Module loading (Status %x)\n", Status);
434 
435  return Status;
436 }
437 
438 VOID
439 NTAPI
441 
442 /*
443  * IopInitializeDriverModule
444  *
445  * Initialize a loaded driver.
446  *
447  * Parameters
448  * DeviceNode
449  * Pointer to device node.
450  *
451  * ModuleObject
452  * Module object representing the driver. It can be retrieve by
453  * IopLoadServiceModule.
454  *
455  * ServiceName
456  * Name of the service (as in registry).
457  *
458  * FileSystemDriver
459  * Set to TRUE for file system drivers.
460  *
461  * DriverObject
462  * On successful return this contains the driver object representing
463  * the loaded driver.
464  */
465 NTSTATUS
466 FASTCALL
469  IN PLDR_DATA_TABLE_ENTRY ModuleObject,
471  IN BOOLEAN FileSystemDriver,
473 {
474  static const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
475  UNICODE_STRING DriverName;
476  UNICODE_STRING RegistryKey;
480 
481  DriverEntry = ModuleObject->EntryPoint;
482 
483  if (ServiceName != NULL && ServiceName->Length != 0)
484  {
485  RegistryKey.Length = 0;
486  RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length;
487  RegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool,
488  RegistryKey.MaximumLength,
489  TAG_IO);
490  if (RegistryKey.Buffer == NULL)
491  {
493  }
494  RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName);
496  }
497  else
498  {
499  RtlInitEmptyUnicodeString(&RegistryKey, NULL, 0);
500  }
501 
502  /* Create ModuleName string */
503  if (ServiceName && ServiceName->Length > 0)
504  {
505  DriverName.Length = 0;
506  DriverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME) + ServiceName->Length;
508  DriverName.MaximumLength,
509  TAG_IO);
510  if (DriverName.Buffer == NULL)
511  {
512  RtlFreeUnicodeString(&RegistryKey);
514  }
515 
516  if (FileSystemDriver != FALSE)
518  else
521 
522  DPRINT("Driver name: '%wZ'\n", &DriverName);
523  }
524  else
525  {
526  RtlInitEmptyUnicodeString(&DriverName, NULL, 0);
527  }
528 
529  Status = IopCreateDriver(DriverName.Length > 0 ? &DriverName : NULL,
530  DriverEntry,
531  &RegistryKey,
532  ServiceName,
533  ModuleObject,
534  &Driver);
535  RtlFreeUnicodeString(&RegistryKey);
536  RtlFreeUnicodeString(&DriverName);
537 
538  if (!NT_SUCCESS(Status))
539  {
540  DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status);
541  return Status;
542  }
543 
544  *DriverObject = Driver;
545 
547 
548  /* Set the driver as initialized */
550 
552 
553  return STATUS_SUCCESS;
554 }
555 
556 /*
557  * IopAttachFilterDriversCallback
558  *
559  * Internal routine used by IopAttachFilterDrivers.
560  */
561 NTSTATUS
562 NTAPI
568  PVOID Context,
570 {
573  PWCHAR Filters;
574  PLDR_DATA_TABLE_ENTRY ModuleObject;
577 
578  /* No filter value present */
579  if (ValueType == REG_NONE)
580  return STATUS_SUCCESS;
581 
582  for (Filters = ValueData;
583  ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
584  *Filters != 0;
585  Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
586  {
587  DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
588 
589  ServiceName.Buffer = Filters;
590  ServiceName.MaximumLength =
591  ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
592 
596  &ServiceName,
597  FALSE);
598  if (!NT_SUCCESS(Status))
599  {
600  /* Load and initialize the filter driver */
601  Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
602  if (!NT_SUCCESS(Status))
603  {
606  return Status;
607  }
608 
610  ModuleObject,
611  &ServiceName,
612  FALSE,
613  &DriverObject);
614  if (!NT_SUCCESS(Status))
615  {
618  return Status;
619  }
620  }
621 
624 
626 
627  /* Remove extra reference */
629 
630  if (!NT_SUCCESS(Status))
631  return Status;
632  }
633 
634  return STATUS_SUCCESS;
635 }
636 
637 /*
638  * IopAttachFilterDrivers
639  *
640  * Load filter drivers for specified device node.
641  *
642  * Parameters
643  * Lower
644  * Set to TRUE for loading lower level filters or FALSE for upper
645  * level filters.
646  */
647 NTSTATUS
648 FASTCALL
651  HANDLE EnumSubKey,
652  HANDLE ClassKey,
653  BOOLEAN Lower)
654 {
655  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
657 
658  /*
659  * First load the device filters
660  */
662  if (Lower)
663  QueryTable[0].Name = L"LowerFilters";
664  else
665  QueryTable[0].Name = L"UpperFilters";
666  QueryTable[0].Flags = 0;
668 
670  (PWSTR)EnumSubKey,
671  QueryTable,
672  DeviceNode,
673  NULL);
674  if (!NT_SUCCESS(Status))
675  {
676  DPRINT1("Failed to load device %s filters: %08X\n",
677  Lower ? "lower" : "upper", Status);
678  return Status;
679  }
680 
682  if (Lower)
683  QueryTable[0].Name = L"LowerFilters";
684  else
685  QueryTable[0].Name = L"UpperFilters";
687  QueryTable[0].Flags = 0;
689 
690  if (ClassKey == NULL)
691  {
692  return STATUS_SUCCESS;
693  }
694 
696  (PWSTR)ClassKey,
697  QueryTable,
698  DeviceNode,
699  NULL);
700 
701  if (!NT_SUCCESS(Status))
702  {
703  DPRINT1("Failed to load class %s filters: %08X\n",
704  Lower ? "lower" : "upper", Status);
705  return Status;
706  }
707 
708  return STATUS_SUCCESS;
709 }
710 
711 NTSTATUS
712 NTAPI
714  IN PUNICODE_STRING ImageFileDirectory,
715  IN PUNICODE_STRING NamePrefix OPTIONAL,
716  OUT PCHAR *MissingApi,
717  OUT PWCHAR *MissingDriver,
718  OUT PLOAD_IMPORTS *LoadImports);
719 
720 //
721 // Used for images already loaded (boot drivers)
722 //
723 INIT_FUNCTION
724 NTSTATUS
725 NTAPI
728  PLDR_DATA_TABLE_ENTRY *ModuleObject)
729 {
731  UNICODE_STRING BaseName, BaseDirectory;
732  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
733  PCHAR MissingApiName, Buffer;
734  PWCHAR MissingDriverName;
735  PVOID DriverBase = LdrEntry->DllBase;
736 
737  /* Allocate a buffer we'll use for names */
740  TAG_LDR_WSTR);
741  if (!Buffer)
742  {
743  /* Fail */
745  }
746 
747  /* Check for a separator */
748  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
749  {
750  PWCHAR p;
751  ULONG BaseLength;
752 
753  /* Loop the path until we get to the base name */
754  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
755  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
756 
757  /* Get the length */
758  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
759  BaseLength *= sizeof(WCHAR);
760 
761  /* Setup the string */
762  BaseName.Length = (USHORT)BaseLength;
763  BaseName.Buffer = p;
764  }
765  else
766  {
767  /* Otherwise, we already have a base name */
768  BaseName.Length = FileName->Length;
769  BaseName.Buffer = FileName->Buffer;
770  }
771 
772  /* Setup the maximum length */
773  BaseName.MaximumLength = BaseName.Length;
774 
775  /* Now compute the base directory */
776  BaseDirectory = *FileName;
777  BaseDirectory.Length -= BaseName.Length;
778  BaseDirectory.MaximumLength = BaseDirectory.Length;
779 
780  /* Resolve imports */
781  MissingApiName = Buffer;
782  Status = MiResolveImageReferences(DriverBase,
783  &BaseDirectory,
784  NULL,
785  &MissingApiName,
786  &MissingDriverName,
787  &LoadedImports);
788 
789  /* Free the temporary buffer */
791 
792  /* Check the result of the imports resolution */
793  if (!NT_SUCCESS(Status)) return Status;
794 
795  /* Return */
796  *ModuleObject = LdrEntry;
797  return STATUS_SUCCESS;
798 }
799 
800 /*
801  * IopInitializeBuiltinDriver
802  *
803  * Initialize a driver that is already loaded in memory.
804  */
805 INIT_FUNCTION
806 NTSTATUS
807 NTAPI
809 {
813  PWCHAR Buffer, FileNameWithoutPath;
814  PWSTR FileExtension;
815  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
816  PLDR_DATA_TABLE_ENTRY LdrEntry;
817  PLIST_ENTRY NextEntry;
820 
821  /*
822  * Display 'Loading XXX...' message
823  */
826 
828  ModuleName->Length + sizeof(UNICODE_NULL),
829  TAG_IO);
830  if (Buffer == NULL)
831  {
833  }
834 
836  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
837 
838  /*
839  * Generate filename without path (not needed by freeldr)
840  */
841  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
842  if (FileNameWithoutPath == NULL)
843  {
844  FileNameWithoutPath = Buffer;
845  }
846  else
847  {
848  FileNameWithoutPath++;
849  }
850 
851  /*
852  * Strip the file extension from ServiceName
853  */
854  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
856  if (!Success)
857  {
859  }
860 
861  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
862  if (FileExtension != NULL)
863  {
864  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
865  FileExtension[0] = UNICODE_NULL;
866  }
867 
868  /*
869  * Determine the right device object
870  */
871  /* Use IopRootDeviceNode for now */
873  NULL,
874  &ServiceName,
875  &DeviceNode);
877  if (!NT_SUCCESS(Status))
878  {
879  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
880  return Status;
881  }
882 
883  /* Lookup the new Ldr entry in PsLoadedModuleList */
884  NextEntry = PsLoadedModuleList.Flink;
885  while (NextEntry != &PsLoadedModuleList)
886  {
887  LdrEntry = CONTAINING_RECORD(NextEntry,
889  InLoadOrderLinks);
891  {
892  break;
893  }
894 
895  NextEntry = NextEntry->Flink;
896  }
897  ASSERT(NextEntry != &PsLoadedModuleList);
898 
899  /*
900  * Initialize the driver
901  */
903  LdrEntry,
904  &DeviceNode->ServiceName,
905  FALSE,
906  &DriverObject);
907 
908  if (!NT_SUCCESS(Status))
909  {
910  return Status;
911  }
912 
914  if (NT_SUCCESS(Status))
915  {
917  }
918 
919  /* Remove extra reference from IopInitializeDriverModule */
921 
922  return Status;
923 }
924 
925 /*
926  * IopInitializeBootDrivers
927  *
928  * Initialize boot drivers and free memory for boot files.
929  *
930  * Parameters
931  * None
932  *
933  * Return Value
934  * None
935  */
936 INIT_FUNCTION
937 VOID
938 FASTCALL
940 {
941  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
942  PLDR_DATA_TABLE_ENTRY LdrEntry;
945  LDR_DATA_TABLE_ENTRY ModuleObject;
947  UNICODE_STRING DriverName;
948  ULONG i, Index;
949  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
951  PBOOT_DRIVER_LIST_ENTRY BootEntry;
952  DPRINT("IopInitializeBootDrivers()\n");
953 
954  /* Use IopRootDeviceNode for now */
956  if (!NT_SUCCESS(Status)) return;
957 
958  /* Setup the module object for the RAW FS Driver */
959  ModuleObject.DllBase = NULL;
960  ModuleObject.SizeOfImage = 0;
961  ModuleObject.EntryPoint = RawFsDriverEntry;
962  RtlInitUnicodeString(&DriverName, L"RAW");
963 
964  /* Initialize it */
966  &ModuleObject,
967  &DriverName,
968  TRUE,
969  &DriverObject);
970  if (!NT_SUCCESS(Status))
971  {
972  /* Fail */
973  return;
974  }
975 
976  /* Now initialize the associated device */
978  if (!NT_SUCCESS(Status))
979  {
980  /* Fail */
982  return;
983  }
984 
985  /* Start it up */
987  if (!NT_SUCCESS(Status))
988  {
989  /* Fail */
991  return;
992  }
993 
994  /* Get highest group order index */
996  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
997 
998  /* Allocate the group table */
1000  IopGroupIndex * sizeof(LIST_ENTRY),
1001  TAG_IO);
1002  if (IopGroupTable == NULL) ASSERT(FALSE);
1003 
1004  /* Initialize the group table lists */
1005  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1006 
1007  /* Loop the boot modules */
1008  ListHead = &KeLoaderBlock->LoadOrderListHead;
1009  NextEntry = ListHead->Flink;
1010  while (ListHead != NextEntry)
1011  {
1012  /* Get the entry */
1013  LdrEntry = CONTAINING_RECORD(NextEntry,
1015  InLoadOrderLinks);
1016 
1017  /* Check if the DLL needs to be initialized */
1018  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1019  {
1020  /* Call its entrypoint */
1021  MmCallDllInitialize(LdrEntry, NULL);
1022  }
1023 
1024  /* Go to the next driver */
1025  NextEntry = NextEntry->Flink;
1026  }
1027 
1028  /* Loop the boot drivers */
1029  ListHead = &KeLoaderBlock->BootDriverListHead;
1030  NextEntry = ListHead->Flink;
1031  while (ListHead != NextEntry)
1032  {
1033  /* Get the entry */
1034  BootEntry = CONTAINING_RECORD(NextEntry,
1036  Link);
1037 
1038  /* Get the driver loader entry */
1039  LdrEntry = BootEntry->LdrEntry;
1040 
1041  /* Allocate our internal accounting structure */
1043  sizeof(DRIVER_INFORMATION),
1044  TAG_IO);
1045  if (DriverInfo)
1046  {
1047  /* Zero it and initialize it */
1050  DriverInfo->DataTableEntry = BootEntry;
1051 
1052  /* Open the registry key */
1054  NULL,
1055  &BootEntry->RegistryPath,
1056  KEY_READ);
1057  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1058 #if 0
1059  if (NT_SUCCESS(Status))
1060 #else // Hack still needed...
1061  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1062  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1063 #endif
1064  {
1065  /* Save the handle */
1067 
1068  /* Get the group oder index */
1070 
1071  /* Get the tag position */
1073 
1074  /* Insert it into the list, at the right place */
1076  NextEntry2 = IopGroupTable[Index].Flink;
1077  while (NextEntry2 != &IopGroupTable[Index])
1078  {
1079  /* Get the driver info */
1080  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1082  Link);
1083 
1084  /* Check if we found the right tag position */
1085  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1086  {
1087  /* We're done */
1088  break;
1089  }
1090 
1091  /* Next entry */
1092  NextEntry2 = NextEntry2->Flink;
1093  }
1094 
1095  /* Insert us right before the next entry */
1096  NextEntry2 = NextEntry2->Blink;
1097  InsertHeadList(NextEntry2, &DriverInfo->Link);
1098  }
1099  }
1100 
1101  /* Go to the next driver */
1102  NextEntry = NextEntry->Flink;
1103  }
1104 
1105  /* Loop each group index */
1106  for (i = 0; i < IopGroupIndex; i++)
1107  {
1108  /* Loop each group table */
1109  NextEntry = IopGroupTable[i].Flink;
1110  while (NextEntry != &IopGroupTable[i])
1111  {
1112  /* Get the entry */
1113  DriverInfo = CONTAINING_RECORD(NextEntry,
1115  Link);
1116 
1117  /* Get the driver loader entry */
1118  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1119 
1120  /* Initialize it */
1121  IopInitializeBuiltinDriver(LdrEntry);
1122 
1123  /* Next entry */
1124  NextEntry = NextEntry->Flink;
1125  }
1126  }
1127 
1128  /* In old ROS, the loader list became empty after this point. Simulate. */
1130 }
1131 
1132 INIT_FUNCTION
1133 VOID
1134 FASTCALL
1136 {
1137  PUNICODE_STRING *DriverList, *SavedList;
1138 
1139  /* No system drivers on the boot cd */
1140  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1141 
1142  /* Get the driver list */
1143  SavedList = DriverList = CmGetSystemDriverList();
1144  ASSERT(DriverList);
1145 
1146  /* Loop it */
1147  while (*DriverList)
1148  {
1149  /* Load the driver */
1150  ZwLoadDriver(*DriverList);
1151 
1152  /* Free the entry */
1153  RtlFreeUnicodeString(*DriverList);
1154  ExFreePool(*DriverList);
1155 
1156  /* Next entry */
1158  DriverList++;
1159  }
1160 
1161  /* Free the list */
1162  ExFreePool(SavedList);
1163 }
1164 
1165 /*
1166  * IopUnloadDriver
1167  *
1168  * Unloads a device driver.
1169  *
1170  * Parameters
1171  * DriverServiceName
1172  * Name of the service to unload (registry key).
1173  *
1174  * UnloadPnpDrivers
1175  * Whether to unload Plug & Plug or only legacy drivers. If this
1176  * parameter is set to FALSE, the routine will unload only legacy
1177  * drivers.
1178  *
1179  * Return Value
1180  * Status
1181  *
1182  * To do
1183  * Guard the whole function by SEH.
1184  */
1185 
1187 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1188 {
1191  UNICODE_STRING ImagePath;
1196  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1197  NTSTATUS Status;
1198  USHORT LastBackslash;
1199  BOOLEAN SafeToUnload = TRUE;
1201  UNICODE_STRING CapturedServiceName;
1202 
1203  PAGED_CODE();
1204 
1206 
1207  /* Need the appropriate priviliege */
1209  {
1210  DPRINT1("No unload privilege!\n");
1212  }
1213 
1214  /* Capture the service name */
1215  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
1216  if (!NT_SUCCESS(Status))
1217  {
1218  return Status;
1219  }
1220 
1221  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1222 
1223 
1224  /* We need a service name */
1225  if (CapturedServiceName.Length == 0)
1226  {
1227  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1228  return STATUS_INVALID_PARAMETER;
1229  }
1230 
1231  /*
1232  * Get the service name from the registry key name
1233  */
1235  &CapturedServiceName,
1236  &Backslash,
1237  &LastBackslash);
1238  if (NT_SUCCESS(Status))
1239  {
1240  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1241  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1242  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1243  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1244  }
1245  else
1246  {
1247  ServiceName = CapturedServiceName;
1248  }
1249 
1250  /*
1251  * Construct the driver object name
1252  */
1253  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1254  ServiceName.Length,
1255  &ObjectName.MaximumLength);
1256  if (!NT_SUCCESS(Status))
1257  {
1258  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1259  return Status;
1260  }
1261  ObjectName.Length = 0;
1263  ObjectName.MaximumLength,
1264  TAG_IO);
1265  if (!ObjectName.Buffer)
1266  {
1267  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1269  }
1272 
1273  /*
1274  * Find the driver object
1275  */
1277  0,
1278  0,
1279  0,
1281  KernelMode,
1282  0,
1283  (PVOID*)&DriverObject);
1284 
1285  if (!NT_SUCCESS(Status))
1286  {
1287  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1289  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1290  return Status;
1291  }
1292 
1293  /* Free the buffer for driver object name */
1295 
1296  /* Check that driver is not already unloading */
1298  {
1299  DPRINT1("Driver deletion pending\n");
1301  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1302  return STATUS_DELETE_PENDING;
1303  }
1304 
1305  /*
1306  * Get path of service...
1307  */
1309 
1310  RtlInitUnicodeString(&ImagePath, NULL);
1311 
1312  QueryTable[0].Name = L"ImagePath";
1314  QueryTable[0].EntryContext = &ImagePath;
1315 
1317  CapturedServiceName.Buffer,
1318  QueryTable,
1319  NULL,
1320  NULL);
1321 
1322  /* We no longer need service name */
1323  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1324 
1325  if (!NT_SUCCESS(Status))
1326  {
1327  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1329  return Status;
1330  }
1331 
1332  /*
1333  * Normalize the image path for all later processing.
1334  */
1335  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1336 
1337  if (!NT_SUCCESS(Status))
1338  {
1339  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1341  return Status;
1342  }
1343 
1344  /* Free the service path */
1345  ExFreePool(ImagePath.Buffer);
1346 
1347  /*
1348  * Unload the module and release the references to the device object
1349  */
1350 
1351  /* Call the load/unload routine, depending on current process */
1353  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1354  {
1355  /* Loop through each device object of the driver
1356  and set DOE_UNLOAD_PENDING flag */
1358  while (DeviceObject)
1359  {
1360  /* Set the unload pending flag for the device */
1361  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1362  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1363 
1364  /* Make sure there are no attached devices or no reference counts */
1365  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1366  {
1367  /* Not safe to unload */
1368  DPRINT1("Drivers device object is referenced or has attached devices\n");
1369 
1370  SafeToUnload = FALSE;
1371  }
1372 
1373  DeviceObject = DeviceObject->NextDevice;
1374  }
1375 
1376  /* If not safe to unload, then return success */
1377  if (!SafeToUnload)
1378  {
1380  return STATUS_SUCCESS;
1381  }
1382 
1383  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1384 
1385  /* Set the unload invoked flag and call the unload routine */
1389 
1390  /* Mark the driver object temporary, so it could be deleted later */
1392 
1393  /* Dereference it 2 times */
1396 
1397  return Status;
1398  }
1399  else
1400  {
1401  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1402 
1403  /* Dereference one time (refd inside this function) */
1405 
1406  /* Return unloading failure */
1408  }
1409 }
1410 
1411 VOID
1412 NTAPI
1414 {
1415  PDRIVER_REINIT_ITEM ReinitItem;
1417 
1418  /* Get the first entry and start looping */
1421  while (Entry)
1422  {
1423  /* Get the item */
1424  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1425 
1426  /* Increment reinitialization counter */
1427  ReinitItem->DriverObject->DriverExtension->Count++;
1428 
1429  /* Remove the device object flag */
1430  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1431 
1432  /* Call the routine */
1433  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1434  ReinitItem->Context,
1435  ReinitItem->DriverObject->
1436  DriverExtension->Count);
1437 
1438  /* Free the entry */
1439  ExFreePool(Entry);
1440 
1441  /* Move to the next one */
1444  }
1445 }
1446 
1447 VOID
1448 NTAPI
1450 {
1451  PDRIVER_REINIT_ITEM ReinitItem;
1453 
1454  /* Get the first entry and start looping */
1457  while (Entry)
1458  {
1459  /* Get the item */
1460  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1461 
1462  /* Increment reinitialization counter */
1463  ReinitItem->DriverObject->DriverExtension->Count++;
1464 
1465  /* Remove the device object flag */
1467 
1468  /* Call the routine */
1469  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1470  ReinitItem->Context,
1471  ReinitItem->DriverObject->
1472  DriverExtension->Count);
1473 
1474  /* Free the entry */
1475  ExFreePool(Entry);
1476 
1477  /* Move to the next one */
1480  }
1481 }
1482 
1483 NTSTATUS
1484 NTAPI
1486  IN PDRIVER_INITIALIZE InitializationFunction,
1489  IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL,
1490  OUT PDRIVER_OBJECT *pDriverObject)
1491 {
1492  WCHAR NameBuffer[100];
1493  USHORT NameLength;
1494  UNICODE_STRING LocalDriverName;
1495  NTSTATUS Status;
1497  ULONG ObjectSize;
1499  UNICODE_STRING ServiceKeyName;
1500  HANDLE hDriver;
1501  ULONG i, RetryCount = 0;
1502 
1503 try_again:
1504  /* First, create a unique name for the driver if we don't have one */
1505  if (!DriverName)
1506  {
1507  /* Create a random name and set up the string */
1508  NameLength = (USHORT)swprintf(NameBuffer,
1509  DRIVER_ROOT_NAME L"%08u",
1511  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1512  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1513  LocalDriverName.Buffer = NameBuffer;
1514  }
1515  else
1516  {
1517  /* So we can avoid another code path, use a local var */
1518  LocalDriverName = *DriverName;
1519  }
1520 
1521  /* Initialize the Attributes */
1522  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1524  &LocalDriverName,
1526  NULL,
1527  NULL);
1528 
1529  /* Create the Object */
1533  KernelMode,
1534  NULL,
1535  ObjectSize,
1536  0,
1537  0,
1538  (PVOID*)&DriverObject);
1539  if (!NT_SUCCESS(Status)) return Status;
1540 
1541  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1542 
1543  /* Set up the Object */
1544  RtlZeroMemory(DriverObject, ObjectSize);
1546  DriverObject->Size = sizeof(DRIVER_OBJECT);
1547 
1548  /*
1549  * Check whether RegistryPath and ModuleObject are both NULL because
1550  * IoCreateDriver() was called to initialize a built-in driver.
1551  */
1552  if ((RegistryPath != NULL) || (ModuleObject != NULL))
1554  else
1556 
1559  DriverObject->DriverInit = InitializationFunction;
1560  DriverObject->DriverSection = ModuleObject;
1561  /* Loop all Major Functions */
1562  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1563  {
1564  /* Invalidate each function */
1566  }
1567 
1568  /* Set up the service key name buffer */
1569  ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
1570  ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
1571  ServiceKeyName.MaximumLength,
1572  TAG_IO);
1573  if (!ServiceKeyName.Buffer)
1574  {
1575  /* Fail */
1579  }
1580 
1581  /* Copy the name and set it in the driver extension */
1582  RtlCopyUnicodeString(&ServiceKeyName,
1583  ServiceName);
1584  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1585 
1586  /* Make a copy of the driver name to store in the driver object */
1587  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1590  TAG_IO);
1592  {
1593  /* Fail */
1597  }
1598 
1600  &LocalDriverName);
1601 
1602  /* Add the Object and get its handle */
1604  NULL,
1606  0,
1607  NULL,
1608  &hDriver);
1609 
1610  /* Eliminate small possibility when this function is called more than
1611  once in a row, and KeTickCount doesn't get enough time to change */
1612  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1613  {
1614  RetryCount++;
1615  goto try_again;
1616  }
1617 
1618  if (!NT_SUCCESS(Status)) return Status;
1619 
1620  /* Now reference it */
1622  0,
1624  KernelMode,
1625  (PVOID*)&DriverObject,
1626  NULL);
1627 
1628  /* Close the extra handle */
1629  ZwClose(hDriver);
1630 
1631  if (!NT_SUCCESS(Status))
1632  {
1633  /* Fail */
1636  return Status;
1637  }
1638 
1640  DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
1641  DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
1642 
1643  /* Finally, call its init function */
1644  DPRINT("RegistryKey: %wZ\n", RegistryPath);
1645  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1646  Status = (*InitializationFunction)(DriverObject, RegistryPath);
1647  if (!NT_SUCCESS(Status))
1648  {
1649  /* If it didn't work, then kill the object */
1650  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1654  return Status;
1655  }
1656  else
1657  {
1658  /* Returns to caller the object */
1659  *pDriverObject = DriverObject;
1660  }
1661 
1662  /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
1663  * Other parts of the I/O manager depend on this behavior */
1665 
1666  /* Loop all Major Functions */
1667  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1668  {
1669  /*
1670  * Make sure the driver didn't set any dispatch entry point to NULL!
1671  * Doing so is illegal; drivers shouldn't touch entry points they
1672  * do not implement.
1673  */
1674 
1675  /* Check if it did so anyway */
1676  if (!DriverObject->MajorFunction[i])
1677  {
1678  /* Print a warning in the debug log */
1679  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1681 
1682  /* Fix it up */
1684  }
1685  }
1686 
1687  /* Return the Status */
1688  return Status;
1689 }
1690 
1691 /* PUBLIC FUNCTIONS ***********************************************************/
1692 
1693 /*
1694  * @implemented
1695  */
1696 NTSTATUS
1697 NTAPI
1699  IN PDRIVER_INITIALIZE InitializationFunction)
1700 {
1702  return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
1703 }
1704 
1705 /*
1706  * @implemented
1707  */
1708 VOID
1709 NTAPI
1711 {
1712  /* Simply dereference the Object */
1714 }
1715 
1716 /*
1717  * @implemented
1718  */
1719 VOID
1720 NTAPI
1722  IN PDRIVER_REINITIALIZE ReinitRoutine,
1723  IN PVOID Context)
1724 {
1725  PDRIVER_REINIT_ITEM ReinitItem;
1726 
1727  /* Allocate the entry */
1728  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1729  sizeof(DRIVER_REINIT_ITEM),
1730  TAG_REINIT);
1731  if (!ReinitItem) return;
1732 
1733  /* Fill it out */
1734  ReinitItem->DriverObject = DriverObject;
1735  ReinitItem->ReinitRoutine = ReinitRoutine;
1736  ReinitItem->Context = Context;
1737 
1738  /* Set the Driver Object flag and insert the entry into the list */
1741  &ReinitItem->ItemEntry,
1743 }
1744 
1745 /*
1746  * @implemented
1747  */
1748 VOID
1749 NTAPI
1751  IN PDRIVER_REINITIALIZE ReinitRoutine,
1752  IN PVOID Context)
1753 {
1754  PDRIVER_REINIT_ITEM ReinitItem;
1755 
1756  /* Allocate the entry */
1757  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1758  sizeof(DRIVER_REINIT_ITEM),
1759  TAG_REINIT);
1760  if (!ReinitItem) return;
1761 
1762  /* Fill it out */
1763  ReinitItem->DriverObject = DriverObject;
1764  ReinitItem->ReinitRoutine = ReinitRoutine;
1765  ReinitItem->Context = Context;
1766 
1767  /* Set the Driver Object flag and insert the entry into the list */
1770  &ReinitItem->ItemEntry,
1772 }
1773 
1774 /*
1775  * @implemented
1776  */
1777 NTSTATUS
1778 NTAPI
1781  IN ULONG DriverObjectExtensionSize,
1782  OUT PVOID *DriverObjectExtension)
1783 {
1784  KIRQL OldIrql;
1785  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1786  BOOLEAN Inserted = FALSE;
1787 
1788  /* Assume failure */
1789  *DriverObjectExtension = NULL;
1790 
1791  /* Allocate the extension */
1792  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1793  sizeof(IO_CLIENT_EXTENSION) +
1794  DriverObjectExtensionSize,
1796  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1797 
1798  /* Clear the extension for teh caller */
1799  RtlZeroMemory(NewDriverExtension,
1800  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1801 
1802  /* Acqure lock */
1804 
1805  /* Fill out the extension */
1807 
1808  /* Loop the current extensions */
1809  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1810  ClientDriverExtension;
1811  while (DriverExtensions)
1812  {
1813  /* Check if the identifier matches */
1814  if (DriverExtensions->ClientIdentificationAddress ==
1816  {
1817  /* We have a collision, break out */
1818  break;
1819  }
1820 
1821  /* Go to the next one */
1822  DriverExtensions = DriverExtensions->NextExtension;
1823  }
1824 
1825  /* Check if we didn't collide */
1826  if (!DriverExtensions)
1827  {
1828  /* Link this one in */
1829  NewDriverExtension->NextExtension =
1830  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1831  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1832  NewDriverExtension;
1833  Inserted = TRUE;
1834  }
1835 
1836  /* Release the lock */
1838 
1839  /* Check if insertion failed */
1840  if (!Inserted)
1841  {
1842  /* Free the entry and fail */
1843  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1845  }
1846 
1847  /* Otherwise, return the pointer */
1848  *DriverObjectExtension = NewDriverExtension + 1;
1849  return STATUS_SUCCESS;
1850 }
1851 
1852 /*
1853  * @implemented
1854  */
1855 PVOID
1856 NTAPI
1859 {
1860  KIRQL OldIrql;
1861  PIO_CLIENT_EXTENSION DriverExtensions;
1862 
1863  /* Acquire lock */
1865 
1866  /* Loop the list until we find the right one */
1867  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1868  while (DriverExtensions)
1869  {
1870  /* Check for a match */
1871  if (DriverExtensions->ClientIdentificationAddress ==
1873  {
1874  /* Break out */
1875  break;
1876  }
1877 
1878  /* Keep looping */
1879  DriverExtensions = DriverExtensions->NextExtension;
1880  }
1881 
1882  /* Release lock */
1884 
1885  /* Return nothing or the extension */
1886  if (!DriverExtensions) return NULL;
1887  return DriverExtensions + 1;
1888 }
1889 
1890 VOID
1891 NTAPI
1894 {
1895  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1896 
1898  LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
1899  &LoadParams->DriverObject);
1900  KeSetEvent(&LoadParams->Event, 0, FALSE);
1901 }
1902 
1903 NTSTATUS
1904 NTAPI
1908 {
1910  UNICODE_STRING ImagePath;
1912  NTSTATUS Status;
1913  ULONG Type;
1915  PLDR_DATA_TABLE_ENTRY ModuleObject;
1917  WCHAR *cur;
1918 
1919  /* Load/Unload must be called from system process */
1921  {
1922  LOAD_UNLOAD_PARAMS LoadParams;
1923 
1924  /* Prepare parameters block */
1925  LoadParams.RegistryPath = RegistryPath;
1926  LoadParams.DriverObject = *DriverObject;
1928 
1929  /* Initialize and queue a work item */
1930  ExInitializeWorkItem(&LoadParams.WorkItem,
1932  &LoadParams);
1934 
1935  /* And wait till it completes */
1936  KeWaitForSingleObject(&LoadParams.Event,
1937  UserRequest,
1938  KernelMode,
1939  FALSE,
1940  NULL);
1941  return LoadParams.Status;
1942  }
1943 
1944  /* Check if it's an unload request */
1945  if (*DriverObject)
1946  {
1947  (*DriverObject)->DriverUnload(*DriverObject);
1948  return STATUS_SUCCESS;
1949  }
1950 
1951  RtlInitUnicodeString(&ImagePath, NULL);
1952 
1953  /*
1954  * Get the service name from the registry key name.
1955  */
1956  ASSERT(RegistryPath->Length >= sizeof(WCHAR));
1957 
1959  cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
1960  while (RegistryPath->Buffer != cur)
1961  {
1962  if (*cur == L'\\')
1963  {
1964  ServiceName.Buffer = cur + 1;
1965  ServiceName.Length = RegistryPath->Length -
1966  (USHORT)((ULONG_PTR)ServiceName.Buffer -
1968  break;
1969  }
1970  cur--;
1971  }
1972 
1973  /*
1974  * Get service type.
1975  */
1976  RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1977 
1978  RtlInitUnicodeString(&ImagePath, NULL);
1979 
1980  QueryTable[0].Name = L"Type";
1983 
1984  QueryTable[1].Name = L"ImagePath";
1986  QueryTable[1].EntryContext = &ImagePath;
1987 
1990  QueryTable, NULL, NULL);
1991  if (!NT_SUCCESS(Status))
1992  {
1993  DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
1994  if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
1995  return Status;
1996  }
1997 
1998  /*
1999  * Normalize the image path for all later processing.
2000  */
2001  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
2002  if (!NT_SUCCESS(Status))
2003  {
2004  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
2005  return Status;
2006  }
2007 
2008  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
2009  DPRINT("Type: %lx\n", Type);
2010 
2013  /*
2014  * Get existing DriverObject pointer (in case the driver
2015  * has already been loaded and initialized).
2016  */
2018  &ServiceName,
2021 
2022  if (!NT_SUCCESS(Status))
2023  {
2024  /*
2025  * Load the driver module
2026  */
2027  DPRINT("Loading module from %wZ\n", &ImagePath);
2028  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2029  if (!NT_SUCCESS(Status))
2030  {
2031  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2034  return Status;
2035  }
2036 
2037  /*
2038  * Initialize the driver module if it's loaded for the first time
2039  */
2041  if (!NT_SUCCESS(Status))
2042  {
2043  DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
2046  MmUnloadSystemImage(ModuleObject);
2047  return Status;
2048  }
2049 
2050  IopDisplayLoadingMessage(&DeviceNode->ServiceName);
2051 
2053  ModuleObject,
2054  &DeviceNode->ServiceName,
2057  DriverObject);
2058  if (!NT_SUCCESS(Status))
2059  {
2060  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2063  MmUnloadSystemImage(ModuleObject);
2064  return Status;
2065  }
2066 
2069 
2070  /* Initialize and start device */
2073  }
2074  else
2075  {
2078 
2079  DPRINT("DriverObject already exist in ObjectManager\n");
2081 
2082  /* IopGetDriverObject references the DriverObject, so dereference it */
2084  }
2085 
2086  return Status;
2087 }
2088 
2089 /*
2090  * NtLoadDriver
2091  *
2092  * Loads a device driver.
2093  *
2094  * Parameters
2095  * DriverServiceName
2096  * Name of the service to load (registry key).
2097  *
2098  * Return Value
2099  * Status
2100  *
2101  * Status
2102  * implemented
2103  */
2105 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2106 {
2107  UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
2110  NTSTATUS Status;
2111 
2112  PAGED_CODE();
2113 
2115 
2116  /*
2117  * Check security privileges
2118  */
2120  {
2121  DPRINT("Privilege not held\n");
2123  }
2124 
2125  Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
2126  PreviousMode,
2127  DriverServiceName);
2128  if (!NT_SUCCESS(Status))
2129  {
2130  return Status;
2131  }
2132 
2133  DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
2134 
2135  /* Load driver and call its entry point */
2136  DriverObject = NULL;
2137  Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
2138 
2139  ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
2140  PreviousMode);
2141 
2142  return Status;
2143 }
2144 
2145 /*
2146  * NtUnloadDriver
2147  *
2148  * Unloads a legacy device driver.
2149  *
2150  * Parameters
2151  * DriverServiceName
2152  * Name of the service to unload (registry key).
2153  *
2154  * Return Value
2155  * Status
2156  *
2157  * Status
2158  * implemented
2159  */
2160 
2163 {
2164  return IopUnloadDriver(DriverServiceName, FALSE);
2165 }
2166 
2167 /* 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:910
BOOLEAN ExpInTextModeSetup
Definition: init.c:66
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2119
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
#define IN
Definition: typedefs.h:38
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2118
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PDEVICE_NODE IopRootDeviceNode
Definition: pnpmgr.c:18
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
INIT_FUNCTION NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:814
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
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
static const unsigned char pc1[56]
Definition: des.c:54
#define TAG_IO
Definition: tag.h:69
PWCHAR FileSystem
Definition: format.c:72
Type
Definition: Type.h:6
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1779
struct _Entry Entry
Definition: kefuncs.h:627
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1413
_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_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:207
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
PVOID Context
Definition: io.h:471
INIT_FUNCTION VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:883
ACPI_SIZE Length
Definition: actypes.h:1042
char CHAR
Definition: xmlstorage.h:175
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4047
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
NTSTATUS IopCreateDeviceNode(IN PDEVICE_NODE ParentNode, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING ServiceName, OUT PDEVICE_NODE *DeviceNode)
PVOID DriverStart
Definition: iotypes.h:2171
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
INIT_FUNCTION NTSTATUS NTAPI IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:808
unsigned short Length
Definition: sprintf.c:451
#define OBJ_PERMANENT
Definition: winternl.h:226
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
#define _Post_notnull_
Definition: no_sal2.h:460
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:1485
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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:1270
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS FASTCALL IopLoadServiceModule(IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:314
#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:1710
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:46
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
VOID NTAPI IopReinitializeBootDrivers(VOID)
Definition: driver.c:1449
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:954
static int Link(const char **args)
Definition: vfdcmd.c:2414
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define PAGED_CODE()
Definition: video.h:57
#define _In_opt_
Definition: no_sal2.h:213
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
USHORT NTAPI PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
Definition: pnpinit.c:103
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4113
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1750
uint32_t ULONG_PTR
Definition: typedefs.h:63
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:1857
INIT_FUNCTION PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1776
NTSTATUS IopStartDevice(IN PDEVICE_NODE DeviceNode)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
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 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:731
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define TAG_LDR_WSTR
Definition: tag.h:110
#define UNICODE_NULL
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
struct _DRIVER_OBJECT * DriverObject
Definition: iotypes.h:2111
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:2174
#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:246
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4035
VOID(NTAPI * PDRIVER_REINITIALIZE)(_In_ struct _DRIVER_OBJECT *DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Definition: iotypes.h:4099
smooth NULL
Definition: ftsmooth.c:416
const LUID SeLoadDriverPrivilege
Definition: priv.c:31
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
HANDLE ServiceHandle
Definition: io.h:414
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define _At_(target, annos)
Definition: no_sal2.h:11
PUNICODE_STRING HardwareDatabase
Definition: iotypes.h:2176
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
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:105
void * PVOID
Definition: retypes.h:9
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:952
CSHORT Size
Definition: iotypes.h:2168
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
_In_ PCUNICODE_STRING _In_ PVOID Driver
Definition: cmfuncs.h:32
__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
VOID ServiceStart(DWORD argc, LPTSTR *argv)
Definition: nfs41_daemon.c:380
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2117
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
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
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:1628
NTSTATUS NTAPI IopAttachFilterDriversCallback(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: driver.c:563
_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 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
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
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
PLIST_ENTRY IopGroupTable
Definition: driver.c:40
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:244
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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
static IUnknown Object
Definition: main.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: Node.h:9
VOID NTAPI IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1721
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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:2127
NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2162
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
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1857
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1853
struct _DRIVER_OBJECT DRIVER_OBJECT
Definition: typedefs.h:117
#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
PDRIVER_OBJECT DriverObject
Definition: io.h:403
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
UNICODE_STRING ServiceKeyName
Definition: iotypes.h:2114
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct _FileName FileName
Definition: fatprocs.h:884
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:1698
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
INIT_FUNCTION NTSTATUS NTAPI LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry, PUNICODE_STRING FileName, PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:726
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#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:3688
INIT_FUNCTION VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1135
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:467
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:58
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:246
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
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define _When_(expr, annos)
Definition: no_sal2.h:639
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
_In_ const STRING * String2
Definition: rtlfuncs.h:2292
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define OUT
Definition: typedefs.h:39
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
ULONG Flags
Definition: ntddk_ex.h:207
struct tagContext Context
Definition: acpixf.h:1030
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
NTSTATUS FASTCALL IopAttachFilterDrivers(PDEVICE_NODE DeviceNode, HANDLE EnumSubKey, HANDLE ClassKey, BOOLEAN Lower)
Definition: driver.c:649
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:470
INIT_FUNCTION VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:939
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ULONG DriverSize
Definition: iotypes.h:2172
#define REG_NONE
Definition: nt_native.h:1492
PVOID ClientIdentificationAddress
Definition: iotypes.h:815
GLfloat GLfloat p
Definition: glext.h:8902
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1187
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
CSHORT Type
Definition: iotypes.h:2167
#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:2105
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT IopGroupIndex
Definition: driver.c:39
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
PVOID DriverSection
Definition: iotypes.h:2173
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2178
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
UNICODE_STRING DriverName
Definition: iotypes.h:2175
NTSTATUS NTAPI IopLoadUnloadDriver(_In_opt_ PCUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1905
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2169
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:2804
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:492
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4115
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:146
#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
VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1892
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:173