ReactOS  0.4.15-dev-985-gd905dd5
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 */
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 */
85  {
86  /* Unload it */
88  }
89 
90  /* Check if it has a name */
92  {
93  /* Free it */
95  }
96 
97  /* Check if it has a service key name */
99  {
100  /* Free it */
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 INIT_FUNCTION
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 INIT_FUNCTION
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 INIT_FUNCTION
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  /* Next entry */
1126  NextEntry = NextEntry->Flink;
1127  }
1128  }
1129 
1130  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1131  * when some devices are not being initialized with their drivers. This flag is used to delay
1132  * all actions with devices (except PnP root device) until boot drivers are loaded.
1133  * See PiQueueDeviceAction function
1134  */
1136 
1137  /* In old ROS, the loader list became empty after this point. Simulate. */
1139 }
1140 
1141 INIT_FUNCTION
1142 VOID
1143 FASTCALL
1145 {
1146  PUNICODE_STRING *DriverList, *SavedList;
1147 
1148  /* No system drivers on the boot cd */
1149  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1150 
1151  /* Get the driver list */
1152  SavedList = DriverList = CmGetSystemDriverList();
1153  ASSERT(DriverList);
1154 
1155  /* Loop it */
1156  while (*DriverList)
1157  {
1158  /* Load the driver */
1159  ZwLoadDriver(*DriverList);
1160 
1161  /* Free the entry */
1162  RtlFreeUnicodeString(*DriverList);
1163  ExFreePool(*DriverList);
1164 
1165  /* Next entry */
1167  DriverList++;
1168  }
1169 
1170  /* Free the list */
1171  ExFreePool(SavedList);
1172 }
1173 
1174 /*
1175  * IopUnloadDriver
1176  *
1177  * Unloads a device driver.
1178  *
1179  * Parameters
1180  * DriverServiceName
1181  * Name of the service to unload (registry key).
1182  *
1183  * UnloadPnpDrivers
1184  * Whether to unload Plug & Plug or only legacy drivers. If this
1185  * parameter is set to FALSE, the routine will unload only legacy
1186  * drivers.
1187  *
1188  * Return Value
1189  * Status
1190  *
1191  * To do
1192  * Guard the whole function by SEH.
1193  */
1194 
1196 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1197 {
1200  UNICODE_STRING ImagePath;
1205  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1206  NTSTATUS Status;
1207  USHORT LastBackslash;
1208  BOOLEAN SafeToUnload = TRUE;
1210  UNICODE_STRING CapturedServiceName;
1211 
1212  PAGED_CODE();
1213 
1215 
1216  /* Need the appropriate priviliege */
1218  {
1219  DPRINT1("No unload privilege!\n");
1221  }
1222 
1223  /* Capture the service name */
1224  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
1225  if (!NT_SUCCESS(Status))
1226  {
1227  return Status;
1228  }
1229 
1230  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1231 
1232 
1233  /* We need a service name */
1234  if (CapturedServiceName.Length == 0)
1235  {
1236  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1237  return STATUS_INVALID_PARAMETER;
1238  }
1239 
1240  /*
1241  * Get the service name from the registry key name
1242  */
1244  &CapturedServiceName,
1245  &Backslash,
1246  &LastBackslash);
1247  if (NT_SUCCESS(Status))
1248  {
1249  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1250  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1251  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1252  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1253  }
1254  else
1255  {
1256  ServiceName = CapturedServiceName;
1257  }
1258 
1259  /*
1260  * Construct the driver object name
1261  */
1262  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1263  ServiceName.Length,
1264  &ObjectName.MaximumLength);
1265  if (!NT_SUCCESS(Status))
1266  {
1267  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1268  return Status;
1269  }
1270  ObjectName.Length = 0;
1272  ObjectName.MaximumLength,
1273  TAG_IO);
1274  if (!ObjectName.Buffer)
1275  {
1276  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1278  }
1281 
1282  /*
1283  * Find the driver object
1284  */
1286  0,
1287  0,
1288  0,
1290  KernelMode,
1291  0,
1292  (PVOID*)&DriverObject);
1293 
1294  if (!NT_SUCCESS(Status))
1295  {
1296  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1298  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1299  return Status;
1300  }
1301 
1302  /* Free the buffer for driver object name */
1304 
1305  /* Check that driver is not already unloading */
1307  {
1308  DPRINT1("Driver deletion pending\n");
1310  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1311  return STATUS_DELETE_PENDING;
1312  }
1313 
1314  /*
1315  * Get path of service...
1316  */
1318 
1319  RtlInitUnicodeString(&ImagePath, NULL);
1320 
1321  QueryTable[0].Name = L"ImagePath";
1323  QueryTable[0].EntryContext = &ImagePath;
1324 
1326  CapturedServiceName.Buffer,
1327  QueryTable,
1328  NULL,
1329  NULL);
1330 
1331  /* We no longer need service name */
1332  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1333 
1334  if (!NT_SUCCESS(Status))
1335  {
1336  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1338  return Status;
1339  }
1340 
1341  /*
1342  * Normalize the image path for all later processing.
1343  */
1344  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1345 
1346  if (!NT_SUCCESS(Status))
1347  {
1348  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1350  return Status;
1351  }
1352 
1353  /* Free the service path */
1354  ExFreePool(ImagePath.Buffer);
1355 
1356  /*
1357  * Unload the module and release the references to the device object
1358  */
1359 
1360  /* Call the load/unload routine, depending on current process */
1362  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1363  {
1364  /* Loop through each device object of the driver
1365  and set DOE_UNLOAD_PENDING flag */
1367  while (DeviceObject)
1368  {
1369  /* Set the unload pending flag for the device */
1370  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1371  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1372 
1373  /* Make sure there are no attached devices or no reference counts */
1374  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1375  {
1376  /* Not safe to unload */
1377  DPRINT1("Drivers device object is referenced or has attached devices\n");
1378 
1379  SafeToUnload = FALSE;
1380  }
1381 
1382  DeviceObject = DeviceObject->NextDevice;
1383  }
1384 
1385  /* If not safe to unload, then return success */
1386  if (!SafeToUnload)
1387  {
1389  return STATUS_SUCCESS;
1390  }
1391 
1392  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1393 
1394  /* Set the unload invoked flag and call the unload routine */
1398 
1399  /* Mark the driver object temporary, so it could be deleted later */
1401 
1402  /* Dereference it 2 times */
1405 
1406  return Status;
1407  }
1408  else
1409  {
1410  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1411 
1412  /* Dereference one time (refd inside this function) */
1414 
1415  /* Return unloading failure */
1417  }
1418 }
1419 
1420 VOID
1421 NTAPI
1423 {
1424  PDRIVER_REINIT_ITEM ReinitItem;
1426 
1427  /* Get the first entry and start looping */
1430  while (Entry)
1431  {
1432  /* Get the item */
1433  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1434 
1435  /* Increment reinitialization counter */
1436  ReinitItem->DriverObject->DriverExtension->Count++;
1437 
1438  /* Remove the device object flag */
1439  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1440 
1441  /* Call the routine */
1442  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1443  ReinitItem->Context,
1444  ReinitItem->DriverObject->
1445  DriverExtension->Count);
1446 
1447  /* Free the entry */
1448  ExFreePool(Entry);
1449 
1450  /* Move to the next one */
1453  }
1454 }
1455 
1456 VOID
1457 NTAPI
1459 {
1460  PDRIVER_REINIT_ITEM ReinitItem;
1462 
1463  /* Get the first entry and start looping */
1466  while (Entry)
1467  {
1468  /* Get the item */
1469  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1470 
1471  /* Increment reinitialization counter */
1472  ReinitItem->DriverObject->DriverExtension->Count++;
1473 
1474  /* Remove the device object flag */
1476 
1477  /* Call the routine */
1478  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1479  ReinitItem->Context,
1480  ReinitItem->DriverObject->
1481  DriverExtension->Count);
1482 
1483  /* Free the entry */
1484  ExFreePool(Entry);
1485 
1486  /* Move to the next one */
1489  }
1490 
1491  /* Wait for all device actions being finished*/
1493 }
1494 
1495 NTSTATUS
1496 NTAPI
1498  IN PDRIVER_INITIALIZE InitializationFunction,
1501  IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL,
1502  OUT PDRIVER_OBJECT *pDriverObject)
1503 {
1504  WCHAR NameBuffer[100];
1505  USHORT NameLength;
1506  UNICODE_STRING LocalDriverName;
1507  NTSTATUS Status;
1509  ULONG ObjectSize;
1511  UNICODE_STRING ServiceKeyName;
1512  HANDLE hDriver;
1513  ULONG i, RetryCount = 0;
1514 
1515 try_again:
1516  /* First, create a unique name for the driver if we don't have one */
1517  if (!DriverName)
1518  {
1519  /* Create a random name and set up the string */
1520  NameLength = (USHORT)swprintf(NameBuffer,
1521  DRIVER_ROOT_NAME L"%08u",
1523  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1524  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1525  LocalDriverName.Buffer = NameBuffer;
1526  }
1527  else
1528  {
1529  /* So we can avoid another code path, use a local var */
1530  LocalDriverName = *DriverName;
1531  }
1532 
1533  /* Initialize the Attributes */
1534  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1536  &LocalDriverName,
1538  NULL,
1539  NULL);
1540 
1541  /* Create the Object */
1545  KernelMode,
1546  NULL,
1547  ObjectSize,
1548  0,
1549  0,
1550  (PVOID*)&DriverObject);
1551  if (!NT_SUCCESS(Status)) return Status;
1552 
1553  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1554 
1555  /* Set up the Object */
1556  RtlZeroMemory(DriverObject, ObjectSize);
1558  DriverObject->Size = sizeof(DRIVER_OBJECT);
1559 
1560  /*
1561  * Check whether RegistryPath and ModuleObject are both NULL because
1562  * IoCreateDriver() was called to initialize a built-in driver.
1563  */
1564  if ((RegistryPath != NULL) || (ModuleObject != NULL))
1566  else
1568 
1571  DriverObject->DriverInit = InitializationFunction;
1572  DriverObject->DriverSection = ModuleObject;
1573  /* Loop all Major Functions */
1574  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1575  {
1576  /* Invalidate each function */
1578  }
1579 
1580  /* Set up the service key name buffer */
1581  ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
1582  ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
1583  ServiceKeyName.MaximumLength,
1584  TAG_IO);
1585  if (!ServiceKeyName.Buffer)
1586  {
1587  /* Fail */
1591  }
1592 
1593  /* Copy the name and set it in the driver extension */
1594  RtlCopyUnicodeString(&ServiceKeyName,
1595  ServiceName);
1596  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1597 
1598  /* Make a copy of the driver name to store in the driver object */
1599  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1602  TAG_IO);
1604  {
1605  /* Fail */
1609  }
1610 
1612  &LocalDriverName);
1613 
1614  /* Add the Object and get its handle */
1616  NULL,
1618  0,
1619  NULL,
1620  &hDriver);
1621 
1622  /* Eliminate small possibility when this function is called more than
1623  once in a row, and KeTickCount doesn't get enough time to change */
1624  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1625  {
1626  RetryCount++;
1627  goto try_again;
1628  }
1629 
1630  if (!NT_SUCCESS(Status)) return Status;
1631 
1632  /* Now reference it */
1634  0,
1636  KernelMode,
1637  (PVOID*)&DriverObject,
1638  NULL);
1639 
1640  /* Close the extra handle */
1641  ZwClose(hDriver);
1642 
1643  if (!NT_SUCCESS(Status))
1644  {
1645  /* Fail */
1648  return Status;
1649  }
1650 
1652  DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
1653  DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
1654 
1655  /* Finally, call its init function */
1656  DPRINT("RegistryKey: %wZ\n", RegistryPath);
1657  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1658  Status = (*InitializationFunction)(DriverObject, RegistryPath);
1659  if (!NT_SUCCESS(Status))
1660  {
1661  /* If it didn't work, then kill the object */
1662  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1666  return Status;
1667  }
1668  else
1669  {
1670  /* Returns to caller the object */
1671  *pDriverObject = DriverObject;
1672  }
1673 
1674  /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
1675  * Other parts of the I/O manager depend on this behavior */
1677 
1678  /* Loop all Major Functions */
1679  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1680  {
1681  /*
1682  * Make sure the driver didn't set any dispatch entry point to NULL!
1683  * Doing so is illegal; drivers shouldn't touch entry points they
1684  * do not implement.
1685  */
1686 
1687  /* Check if it did so anyway */
1688  if (!DriverObject->MajorFunction[i])
1689  {
1690  /* Print a warning in the debug log */
1691  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1693 
1694  /* Fix it up */
1696  }
1697  }
1698 
1699  /* Return the Status */
1700  return Status;
1701 }
1702 
1703 /* PUBLIC FUNCTIONS ***********************************************************/
1704 
1705 /*
1706  * @implemented
1707  */
1708 NTSTATUS
1709 NTAPI
1711  IN PDRIVER_INITIALIZE InitializationFunction)
1712 {
1714  return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
1715 }
1716 
1717 /*
1718  * @implemented
1719  */
1720 VOID
1721 NTAPI
1723 {
1724  /* Simply dereference the Object */
1726 }
1727 
1728 /*
1729  * @implemented
1730  */
1731 VOID
1732 NTAPI
1734  IN PDRIVER_REINITIALIZE ReinitRoutine,
1735  IN PVOID Context)
1736 {
1737  PDRIVER_REINIT_ITEM ReinitItem;
1738 
1739  /* Allocate the entry */
1740  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1741  sizeof(DRIVER_REINIT_ITEM),
1742  TAG_REINIT);
1743  if (!ReinitItem) return;
1744 
1745  /* Fill it out */
1746  ReinitItem->DriverObject = DriverObject;
1747  ReinitItem->ReinitRoutine = ReinitRoutine;
1748  ReinitItem->Context = Context;
1749 
1750  /* Set the Driver Object flag and insert the entry into the list */
1753  &ReinitItem->ItemEntry,
1755 }
1756 
1757 /*
1758  * @implemented
1759  */
1760 VOID
1761 NTAPI
1763  IN PDRIVER_REINITIALIZE ReinitRoutine,
1764  IN PVOID Context)
1765 {
1766  PDRIVER_REINIT_ITEM ReinitItem;
1767 
1768  /* Allocate the entry */
1769  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1770  sizeof(DRIVER_REINIT_ITEM),
1771  TAG_REINIT);
1772  if (!ReinitItem) return;
1773 
1774  /* Fill it out */
1775  ReinitItem->DriverObject = DriverObject;
1776  ReinitItem->ReinitRoutine = ReinitRoutine;
1777  ReinitItem->Context = Context;
1778 
1779  /* Set the Driver Object flag and insert the entry into the list */
1782  &ReinitItem->ItemEntry,
1784 }
1785 
1786 /*
1787  * @implemented
1788  */
1789 NTSTATUS
1790 NTAPI
1793  IN ULONG DriverObjectExtensionSize,
1794  OUT PVOID *DriverObjectExtension)
1795 {
1796  KIRQL OldIrql;
1797  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1798  BOOLEAN Inserted = FALSE;
1799 
1800  /* Assume failure */
1801  *DriverObjectExtension = NULL;
1802 
1803  /* Allocate the extension */
1804  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1805  sizeof(IO_CLIENT_EXTENSION) +
1806  DriverObjectExtensionSize,
1808  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1809 
1810  /* Clear the extension for teh caller */
1811  RtlZeroMemory(NewDriverExtension,
1812  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1813 
1814  /* Acqure lock */
1816 
1817  /* Fill out the extension */
1819 
1820  /* Loop the current extensions */
1821  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1822  ClientDriverExtension;
1823  while (DriverExtensions)
1824  {
1825  /* Check if the identifier matches */
1826  if (DriverExtensions->ClientIdentificationAddress ==
1828  {
1829  /* We have a collision, break out */
1830  break;
1831  }
1832 
1833  /* Go to the next one */
1834  DriverExtensions = DriverExtensions->NextExtension;
1835  }
1836 
1837  /* Check if we didn't collide */
1838  if (!DriverExtensions)
1839  {
1840  /* Link this one in */
1841  NewDriverExtension->NextExtension =
1842  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1843  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1844  NewDriverExtension;
1845  Inserted = TRUE;
1846  }
1847 
1848  /* Release the lock */
1850 
1851  /* Check if insertion failed */
1852  if (!Inserted)
1853  {
1854  /* Free the entry and fail */
1855  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1857  }
1858 
1859  /* Otherwise, return the pointer */
1860  *DriverObjectExtension = NewDriverExtension + 1;
1861  return STATUS_SUCCESS;
1862 }
1863 
1864 /*
1865  * @implemented
1866  */
1867 PVOID
1868 NTAPI
1871 {
1872  KIRQL OldIrql;
1873  PIO_CLIENT_EXTENSION DriverExtensions;
1874 
1875  /* Acquire lock */
1877 
1878  /* Loop the list until we find the right one */
1879  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1880  while (DriverExtensions)
1881  {
1882  /* Check for a match */
1883  if (DriverExtensions->ClientIdentificationAddress ==
1885  {
1886  /* Break out */
1887  break;
1888  }
1889 
1890  /* Keep looping */
1891  DriverExtensions = DriverExtensions->NextExtension;
1892  }
1893 
1894  /* Release lock */
1896 
1897  /* Return nothing or the extension */
1898  if (!DriverExtensions) return NULL;
1899  return DriverExtensions + 1;
1900 }
1901 
1902 VOID
1903 NTAPI
1906 {
1907  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1908 
1910  LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
1911  &LoadParams->DriverObject);
1912  KeSetEvent(&LoadParams->Event, 0, FALSE);
1913 }
1914 
1915 NTSTATUS
1916 NTAPI
1920 {
1922  UNICODE_STRING ImagePath;
1924  NTSTATUS Status;
1925  ULONG Type;
1927  PLDR_DATA_TABLE_ENTRY ModuleObject;
1929  WCHAR *cur;
1930 
1931  /* Load/Unload must be called from system process */
1933  {
1934  LOAD_UNLOAD_PARAMS LoadParams;
1935 
1936  /* Prepare parameters block */
1937  LoadParams.RegistryPath = RegistryPath;
1938  LoadParams.DriverObject = *DriverObject;
1940 
1941  /* Initialize and queue a work item */
1942  ExInitializeWorkItem(&LoadParams.WorkItem,
1944  &LoadParams);
1946 
1947  /* And wait till it completes */
1948  KeWaitForSingleObject(&LoadParams.Event,
1949  UserRequest,
1950  KernelMode,
1951  FALSE,
1952  NULL);
1953  return LoadParams.Status;
1954  }
1955 
1956  /* Check if it's an unload request */
1957  if (*DriverObject)
1958  {
1959  (*DriverObject)->DriverUnload(*DriverObject);
1960  return STATUS_SUCCESS;
1961  }
1962 
1963  RtlInitUnicodeString(&ImagePath, NULL);
1964 
1965  /*
1966  * Get the service name from the registry key name.
1967  */
1968  ASSERT(RegistryPath->Length >= sizeof(WCHAR));
1969 
1971  cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
1972  while (RegistryPath->Buffer != cur)
1973  {
1974  if (*cur == L'\\')
1975  {
1976  ServiceName.Buffer = cur + 1;
1977  ServiceName.Length = RegistryPath->Length -
1978  (USHORT)((ULONG_PTR)ServiceName.Buffer -
1979  (ULONG_PTR)RegistryPath->Buffer);
1980  break;
1981  }
1982  cur--;
1983  }
1984 
1985  /*
1986  * Get service type.
1987  */
1988  RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1989 
1990  RtlInitUnicodeString(&ImagePath, NULL);
1991 
1992  QueryTable[0].Name = L"Type";
1995 
1996  QueryTable[1].Name = L"ImagePath";
1998  QueryTable[1].EntryContext = &ImagePath;
1999 
2001  RegistryPath->Buffer,
2002  QueryTable, NULL, NULL);
2003  if (!NT_SUCCESS(Status))
2004  {
2005  DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
2006  if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
2007  return Status;
2008  }
2009 
2010  /*
2011  * Normalize the image path for all later processing.
2012  */
2013  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
2014  if (!NT_SUCCESS(Status))
2015  {
2016  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
2017  return Status;
2018  }
2019 
2020  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
2021  DPRINT("Type: %lx\n", Type);
2022 
2025  /*
2026  * Get existing DriverObject pointer (in case the driver
2027  * has already been loaded and initialized).
2028  */
2030  &ServiceName,
2033 
2034  if (!NT_SUCCESS(Status))
2035  {
2036  /*
2037  * Load the driver module
2038  */
2039  DPRINT("Loading module from %wZ\n", &ImagePath);
2040  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2041  if (!NT_SUCCESS(Status))
2042  {
2043  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2046  return Status;
2047  }
2048 
2049  /*
2050  * Initialize the driver module if it's loaded for the first time
2051  */
2053  if (!NT_SUCCESS(Status))
2054  {
2055  DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
2058  MmUnloadSystemImage(ModuleObject);
2059  return Status;
2060  }
2061 
2062  IopDisplayLoadingMessage(&DeviceNode->ServiceName);
2063 
2065  ModuleObject,
2066  &DeviceNode->ServiceName,
2069  DriverObject);
2070  if (!NT_SUCCESS(Status))
2071  {
2072  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2075  MmUnloadSystemImage(ModuleObject);
2076  return Status;
2077  }
2078 
2081 
2082  /* Initialize and start device */
2085  }
2086  else
2087  {
2090 
2091  DPRINT("DriverObject already exist in ObjectManager\n");
2093 
2094  /* IopGetDriverObject references the DriverObject, so dereference it */
2096  }
2097 
2098  return Status;
2099 }
2100 
2101 /*
2102  * NtLoadDriver
2103  *
2104  * Loads a device driver.
2105  *
2106  * Parameters
2107  * DriverServiceName
2108  * Name of the service to load (registry key).
2109  *
2110  * Return Value
2111  * Status
2112  *
2113  * Status
2114  * implemented
2115  */
2117 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2118 {
2119  UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
2122  NTSTATUS Status;
2123 
2124  PAGED_CODE();
2125 
2127 
2128  /*
2129  * Check security privileges
2130  */
2132  {
2133  DPRINT("Privilege not held\n");
2135  }
2136 
2137  Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
2138  PreviousMode,
2139  DriverServiceName);
2140  if (!NT_SUCCESS(Status))
2141  {
2142  return Status;
2143  }
2144 
2145  DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
2146 
2147  /* Load driver and call its entry point */
2148  DriverObject = NULL;
2149  Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
2150 
2151  ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
2152  PreviousMode);
2153 
2154  return Status;
2155 }
2156 
2157 /*
2158  * NtUnloadDriver
2159  *
2160  * Unloads a legacy device driver.
2161  *
2162  * Parameters
2163  * DriverServiceName
2164  * Name of the service to unload (registry key).
2165  *
2166  * Return Value
2167  * Status
2168  *
2169  * Status
2170  * implemented
2171  */
2172 
2175 {
2176  return IopUnloadDriver(DriverServiceName, FALSE);
2177 }
2178 
2179 /* 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:67
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2126
_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
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2125
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_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: devnode.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
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:1791
struct _Entry Entry
Definition: kefuncs.h:627
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1422
_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 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
INIT_FUNCTION VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
ACPI_SIZE Length
Definition: actypes.h:1044
char CHAR
Definition: xmlstorage.h:175
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4154
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:2178
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:810
unsigned short Length
Definition: sprintf.c:451
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:1497
#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: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:1722
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
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:1458
#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:213
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:4120
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1762
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
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
_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: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
struct _DRIVER_OBJECT * DriverObject
Definition: iotypes.h:2118
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:2181
#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:4106
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:476
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:2183
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
CSHORT Size
Definition: iotypes.h:2175
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
KEVENT PiEnumerationFinished
Definition: devaction.c:49
VOID ServiceStart(DWORD argc, LPTSTR *argv)
Definition: nfs41_daemon.c:381
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2124
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: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:1628
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
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
#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:42
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:244
_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
Definition: Node.h:9
VOID NTAPI IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1733
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)
Status
Definition: gdiplustypes.h:24
DRIVER_INITIALIZE * PDRIVER_INITIALIZE
Definition: iotypes.h:2134
NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2174
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:2187
_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:1869
#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
PDRIVER_OBJECT DriverObject
Definition: io.h:403
#define _In_
Definition: no_sal2.h:204
UNICODE_STRING ServiceKeyName
Definition: iotypes.h:2121
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
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:1710
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:728
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:1591
INIT_FUNCTION VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1144
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
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
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:2291
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define OUT
Definition: typedefs.h:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2188
ULONG Flags
Definition: ntddk_ex.h:207
struct tagContext Context
Definition: acpixf.h:1034
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:570
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
NTSTATUS FASTCALL IopAttachFilterDrivers(PDEVICE_NODE DeviceNode, HANDLE EnumSubKey, HANDLE ClassKey, BOOLEAN Lower)
Definition: driver.c:651
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:470
INIT_FUNCTION VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:941
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ULONG DriverSize
Definition: iotypes.h:2179
#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:1196
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
CSHORT Type
Definition: iotypes.h:2174
#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:2117
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
PVOID DriverSection
Definition: iotypes.h:2180
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2185
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
UNICODE_STRING DriverName
Definition: iotypes.h:2182
NTSTATUS NTAPI IopLoadUnloadDriver(_In_opt_ PCUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1917
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2176
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:506
#define PAGED_CODE()
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4122
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
VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1904
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:175