ReactOS  0.4.13-dev-544-gede3fdd
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 {
1190  UNICODE_STRING ImagePath;
1195  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1196  NTSTATUS Status;
1197  PWSTR Start;
1198  BOOLEAN SafeToUnload = TRUE;
1200  UNICODE_STRING CapturedServiceName;
1201 
1202  PAGED_CODE();
1203 
1205 
1206  /* Need the appropriate priviliege */
1208  {
1209  DPRINT1("No unload privilege!\n");
1211  }
1212 
1213  /* Capture the service name */
1214  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
1215  if (!NT_SUCCESS(Status))
1216  {
1217  return Status;
1218  }
1219 
1220  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1221 
1222 
1223  /* We need a service name */
1224  if (CapturedServiceName.Length == 0)
1225  {
1226  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1227  return STATUS_INVALID_PARAMETER;
1228  }
1229 
1230  /*
1231  * Get the service name from the registry key name
1232  */
1233  Start = wcsrchr(CapturedServiceName.Buffer, L'\\');
1234  if (Start == NULL)
1235  Start = CapturedServiceName.Buffer;
1236  else
1237  Start++;
1238 
1240 
1241  /*
1242  * Construct the driver object name
1243  */
1244  ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
1245  ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
1247  ObjectName.MaximumLength,
1248  TAG_IO);
1249  if (!ObjectName.Buffer)
1250  {
1251  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1253  }
1255  memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
1256  ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = UNICODE_NULL;
1257 
1258  /*
1259  * Find the driver object
1260  */
1262  0,
1263  0,
1264  0,
1266  KernelMode,
1267  0,
1268  (PVOID*)&DriverObject);
1269 
1270  if (!NT_SUCCESS(Status))
1271  {
1272  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1274  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1275  return Status;
1276  }
1277 
1278  /* Free the buffer for driver object name */
1280 
1281  /* Check that driver is not already unloading */
1283  {
1284  DPRINT1("Driver deletion pending\n");
1286  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1287  return STATUS_DELETE_PENDING;
1288  }
1289 
1290  /*
1291  * Get path of service...
1292  */
1294 
1295  RtlInitUnicodeString(&ImagePath, NULL);
1296 
1297  QueryTable[0].Name = L"ImagePath";
1299  QueryTable[0].EntryContext = &ImagePath;
1300 
1302  CapturedServiceName.Buffer,
1303  QueryTable,
1304  NULL,
1305  NULL);
1306 
1307  /* We no longer need service name */
1308  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1309 
1310  if (!NT_SUCCESS(Status))
1311  {
1312  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1314  return Status;
1315  }
1316 
1317  /*
1318  * Normalize the image path for all later processing.
1319  */
1320  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1321 
1322  if (!NT_SUCCESS(Status))
1323  {
1324  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1326  return Status;
1327  }
1328 
1329  /* Free the service path */
1330  ExFreePool(ImagePath.Buffer);
1331 
1332  /*
1333  * Unload the module and release the references to the device object
1334  */
1335 
1336  /* Call the load/unload routine, depending on current process */
1338  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1339  {
1340  /* Loop through each device object of the driver
1341  and set DOE_UNLOAD_PENDING flag */
1343  while (DeviceObject)
1344  {
1345  /* Set the unload pending flag for the device */
1346  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1347  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1348 
1349  /* Make sure there are no attached devices or no reference counts */
1350  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1351  {
1352  /* Not safe to unload */
1353  DPRINT1("Drivers device object is referenced or has attached devices\n");
1354 
1355  SafeToUnload = FALSE;
1356  }
1357 
1358  DeviceObject = DeviceObject->NextDevice;
1359  }
1360 
1361  /* If not safe to unload, then return success */
1362  if (!SafeToUnload)
1363  {
1365  return STATUS_SUCCESS;
1366  }
1367 
1368  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1369 
1370  /* Set the unload invoked flag and call the unload routine */
1374 
1375  /* Mark the driver object temporary, so it could be deleted later */
1377 
1378  /* Dereference it 2 times */
1381 
1382  return Status;
1383  }
1384  else
1385  {
1386  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1387 
1388  /* Dereference one time (refd inside this function) */
1390 
1391  /* Return unloading failure */
1393  }
1394 }
1395 
1396 VOID
1397 NTAPI
1399 {
1400  PDRIVER_REINIT_ITEM ReinitItem;
1402 
1403  /* Get the first entry and start looping */
1406  while (Entry)
1407  {
1408  /* Get the item */
1409  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1410 
1411  /* Increment reinitialization counter */
1412  ReinitItem->DriverObject->DriverExtension->Count++;
1413 
1414  /* Remove the device object flag */
1415  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1416 
1417  /* Call the routine */
1418  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1419  ReinitItem->Context,
1420  ReinitItem->DriverObject->
1421  DriverExtension->Count);
1422 
1423  /* Free the entry */
1424  ExFreePool(Entry);
1425 
1426  /* Move to the next one */
1429  }
1430 }
1431 
1432 VOID
1433 NTAPI
1435 {
1436  PDRIVER_REINIT_ITEM ReinitItem;
1438 
1439  /* Get the first entry and start looping */
1442  while (Entry)
1443  {
1444  /* Get the item */
1445  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1446 
1447  /* Increment reinitialization counter */
1448  ReinitItem->DriverObject->DriverExtension->Count++;
1449 
1450  /* Remove the device object flag */
1452 
1453  /* Call the routine */
1454  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1455  ReinitItem->Context,
1456  ReinitItem->DriverObject->
1457  DriverExtension->Count);
1458 
1459  /* Free the entry */
1460  ExFreePool(Entry);
1461 
1462  /* Move to the next one */
1465  }
1466 }
1467 
1468 NTSTATUS
1469 NTAPI
1471  IN PDRIVER_INITIALIZE InitializationFunction,
1474  IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL,
1475  OUT PDRIVER_OBJECT *pDriverObject)
1476 {
1477  WCHAR NameBuffer[100];
1478  USHORT NameLength;
1479  UNICODE_STRING LocalDriverName;
1480  NTSTATUS Status;
1482  ULONG ObjectSize;
1484  UNICODE_STRING ServiceKeyName;
1485  HANDLE hDriver;
1486  ULONG i, RetryCount = 0;
1487 
1488 try_again:
1489  /* First, create a unique name for the driver if we don't have one */
1490  if (!DriverName)
1491  {
1492  /* Create a random name and set up the string */
1493  NameLength = (USHORT)swprintf(NameBuffer,
1494  DRIVER_ROOT_NAME L"%08u",
1496  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1497  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1498  LocalDriverName.Buffer = NameBuffer;
1499  }
1500  else
1501  {
1502  /* So we can avoid another code path, use a local var */
1503  LocalDriverName = *DriverName;
1504  }
1505 
1506  /* Initialize the Attributes */
1507  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1509  &LocalDriverName,
1511  NULL,
1512  NULL);
1513 
1514  /* Create the Object */
1518  KernelMode,
1519  NULL,
1520  ObjectSize,
1521  0,
1522  0,
1523  (PVOID*)&DriverObject);
1524  if (!NT_SUCCESS(Status)) return Status;
1525 
1526  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1527 
1528  /* Set up the Object */
1529  RtlZeroMemory(DriverObject, ObjectSize);
1531  DriverObject->Size = sizeof(DRIVER_OBJECT);
1532 
1533  /*
1534  * Check whether RegistryPath and ModuleObject are both NULL because
1535  * IoCreateDriver() was called to initialize a built-in driver.
1536  */
1537  if ((RegistryPath != NULL) || (ModuleObject != NULL))
1539  else
1541 
1544  DriverObject->DriverInit = InitializationFunction;
1545  DriverObject->DriverSection = ModuleObject;
1546  /* Loop all Major Functions */
1547  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1548  {
1549  /* Invalidate each function */
1551  }
1552 
1553  /* Set up the service key name buffer */
1554  ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
1555  ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
1556  ServiceKeyName.MaximumLength,
1557  TAG_IO);
1558  if (!ServiceKeyName.Buffer)
1559  {
1560  /* Fail */
1564  }
1565 
1566  /* Copy the name and set it in the driver extension */
1567  RtlCopyUnicodeString(&ServiceKeyName,
1568  ServiceName);
1569  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1570 
1571  /* Make a copy of the driver name to store in the driver object */
1572  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1575  TAG_IO);
1577  {
1578  /* Fail */
1582  }
1583 
1585  &LocalDriverName);
1586 
1587  /* Add the Object and get its handle */
1589  NULL,
1591  0,
1592  NULL,
1593  &hDriver);
1594 
1595  /* Eliminate small possibility when this function is called more than
1596  once in a row, and KeTickCount doesn't get enough time to change */
1597  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1598  {
1599  RetryCount++;
1600  goto try_again;
1601  }
1602 
1603  if (!NT_SUCCESS(Status)) return Status;
1604 
1605  /* Now reference it */
1607  0,
1609  KernelMode,
1610  (PVOID*)&DriverObject,
1611  NULL);
1612 
1613  /* Close the extra handle */
1614  ZwClose(hDriver);
1615 
1616  if (!NT_SUCCESS(Status))
1617  {
1618  /* Fail */
1621  return Status;
1622  }
1623 
1625  DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
1626  DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
1627 
1628  /* Finally, call its init function */
1629  DPRINT("RegistryKey: %wZ\n", RegistryPath);
1630  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1631  Status = (*InitializationFunction)(DriverObject, RegistryPath);
1632  if (!NT_SUCCESS(Status))
1633  {
1634  /* If it didn't work, then kill the object */
1635  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1639  return Status;
1640  }
1641  else
1642  {
1643  /* Returns to caller the object */
1644  *pDriverObject = DriverObject;
1645  }
1646 
1647  /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
1648  * Other parts of the I/O manager depend on this behavior */
1650 
1651  /* Loop all Major Functions */
1652  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1653  {
1654  /*
1655  * Make sure the driver didn't set any dispatch entry point to NULL!
1656  * Doing so is illegal; drivers shouldn't touch entry points they
1657  * do not implement.
1658  */
1659 
1660  /* Check if it did so anyway */
1661  if (!DriverObject->MajorFunction[i])
1662  {
1663  /* Print a warning in the debug log */
1664  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1666 
1667  /* Fix it up */
1669  }
1670  }
1671 
1672  /* Return the Status */
1673  return Status;
1674 }
1675 
1676 /* PUBLIC FUNCTIONS ***********************************************************/
1677 
1678 /*
1679  * @implemented
1680  */
1681 NTSTATUS
1682 NTAPI
1684  IN PDRIVER_INITIALIZE InitializationFunction)
1685 {
1687  return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
1688 }
1689 
1690 /*
1691  * @implemented
1692  */
1693 VOID
1694 NTAPI
1696 {
1697  /* Simply dereference the Object */
1699 }
1700 
1701 /*
1702  * @implemented
1703  */
1704 VOID
1705 NTAPI
1707  IN PDRIVER_REINITIALIZE ReinitRoutine,
1708  IN PVOID Context)
1709 {
1710  PDRIVER_REINIT_ITEM ReinitItem;
1711 
1712  /* Allocate the entry */
1713  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1714  sizeof(DRIVER_REINIT_ITEM),
1715  TAG_REINIT);
1716  if (!ReinitItem) return;
1717 
1718  /* Fill it out */
1719  ReinitItem->DriverObject = DriverObject;
1720  ReinitItem->ReinitRoutine = ReinitRoutine;
1721  ReinitItem->Context = Context;
1722 
1723  /* Set the Driver Object flag and insert the entry into the list */
1726  &ReinitItem->ItemEntry,
1728 }
1729 
1730 /*
1731  * @implemented
1732  */
1733 VOID
1734 NTAPI
1736  IN PDRIVER_REINITIALIZE ReinitRoutine,
1737  IN PVOID Context)
1738 {
1739  PDRIVER_REINIT_ITEM ReinitItem;
1740 
1741  /* Allocate the entry */
1742  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1743  sizeof(DRIVER_REINIT_ITEM),
1744  TAG_REINIT);
1745  if (!ReinitItem) return;
1746 
1747  /* Fill it out */
1748  ReinitItem->DriverObject = DriverObject;
1749  ReinitItem->ReinitRoutine = ReinitRoutine;
1750  ReinitItem->Context = Context;
1751 
1752  /* Set the Driver Object flag and insert the entry into the list */
1755  &ReinitItem->ItemEntry,
1757 }
1758 
1759 /*
1760  * @implemented
1761  */
1762 NTSTATUS
1763 NTAPI
1766  IN ULONG DriverObjectExtensionSize,
1767  OUT PVOID *DriverObjectExtension)
1768 {
1769  KIRQL OldIrql;
1770  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1771  BOOLEAN Inserted = FALSE;
1772 
1773  /* Assume failure */
1774  *DriverObjectExtension = NULL;
1775 
1776  /* Allocate the extension */
1777  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1778  sizeof(IO_CLIENT_EXTENSION) +
1779  DriverObjectExtensionSize,
1781  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1782 
1783  /* Clear the extension for teh caller */
1784  RtlZeroMemory(NewDriverExtension,
1785  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1786 
1787  /* Acqure lock */
1789 
1790  /* Fill out the extension */
1792 
1793  /* Loop the current extensions */
1794  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1795  ClientDriverExtension;
1796  while (DriverExtensions)
1797  {
1798  /* Check if the identifier matches */
1799  if (DriverExtensions->ClientIdentificationAddress ==
1801  {
1802  /* We have a collision, break out */
1803  break;
1804  }
1805 
1806  /* Go to the next one */
1807  DriverExtensions = DriverExtensions->NextExtension;
1808  }
1809 
1810  /* Check if we didn't collide */
1811  if (!DriverExtensions)
1812  {
1813  /* Link this one in */
1814  NewDriverExtension->NextExtension =
1815  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1816  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1817  NewDriverExtension;
1818  Inserted = TRUE;
1819  }
1820 
1821  /* Release the lock */
1823 
1824  /* Check if insertion failed */
1825  if (!Inserted)
1826  {
1827  /* Free the entry and fail */
1828  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1830  }
1831 
1832  /* Otherwise, return the pointer */
1833  *DriverObjectExtension = NewDriverExtension + 1;
1834  return STATUS_SUCCESS;
1835 }
1836 
1837 /*
1838  * @implemented
1839  */
1840 PVOID
1841 NTAPI
1844 {
1845  KIRQL OldIrql;
1846  PIO_CLIENT_EXTENSION DriverExtensions;
1847 
1848  /* Acquire lock */
1850 
1851  /* Loop the list until we find the right one */
1852  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1853  while (DriverExtensions)
1854  {
1855  /* Check for a match */
1856  if (DriverExtensions->ClientIdentificationAddress ==
1858  {
1859  /* Break out */
1860  break;
1861  }
1862 
1863  /* Keep looping */
1864  DriverExtensions = DriverExtensions->NextExtension;
1865  }
1866 
1867  /* Release lock */
1869 
1870  /* Return nothing or the extension */
1871  if (!DriverExtensions) return NULL;
1872  return DriverExtensions + 1;
1873 }
1874 
1875 VOID
1876 NTAPI
1879 {
1880  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1881 
1883  LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
1884  &LoadParams->DriverObject);
1885  KeSetEvent(&LoadParams->Event, 0, FALSE);
1886 }
1887 
1888 NTSTATUS
1889 NTAPI
1893 {
1895  UNICODE_STRING ImagePath;
1897  NTSTATUS Status;
1898  ULONG Type;
1900  PLDR_DATA_TABLE_ENTRY ModuleObject;
1902  WCHAR *cur;
1903 
1904  /* Load/Unload must be called from system process */
1906  {
1907  LOAD_UNLOAD_PARAMS LoadParams;
1908 
1909  /* Prepare parameters block */
1910  LoadParams.RegistryPath = RegistryPath;
1911  LoadParams.DriverObject = *DriverObject;
1913 
1914  /* Initialize and queue a work item */
1915  ExInitializeWorkItem(&LoadParams.WorkItem,
1917  &LoadParams);
1919 
1920  /* And wait till it completes */
1921  KeWaitForSingleObject(&LoadParams.Event,
1922  UserRequest,
1923  KernelMode,
1924  FALSE,
1925  NULL);
1926  return LoadParams.Status;
1927  }
1928 
1929  /* Check if it's an unload request */
1930  if (*DriverObject)
1931  {
1932  (*DriverObject)->DriverUnload(*DriverObject);
1933  return STATUS_SUCCESS;
1934  }
1935 
1936  RtlInitUnicodeString(&ImagePath, NULL);
1937 
1938  /*
1939  * Get the service name from the registry key name.
1940  */
1941  ASSERT(RegistryPath->Length >= sizeof(WCHAR));
1942 
1944  cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
1945  while (RegistryPath->Buffer != cur)
1946  {
1947  if (*cur == L'\\')
1948  {
1949  ServiceName.Buffer = cur + 1;
1950  ServiceName.Length = RegistryPath->Length -
1951  (USHORT)((ULONG_PTR)ServiceName.Buffer -
1953  break;
1954  }
1955  cur--;
1956  }
1957 
1958  /*
1959  * Get service type.
1960  */
1961  RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1962 
1963  RtlInitUnicodeString(&ImagePath, NULL);
1964 
1965  QueryTable[0].Name = L"Type";
1968 
1969  QueryTable[1].Name = L"ImagePath";
1971  QueryTable[1].EntryContext = &ImagePath;
1972 
1975  QueryTable, NULL, NULL);
1976  if (!NT_SUCCESS(Status))
1977  {
1978  DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
1979  if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
1980  return Status;
1981  }
1982 
1983  /*
1984  * Normalize the image path for all later processing.
1985  */
1986  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1987  if (!NT_SUCCESS(Status))
1988  {
1989  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1990  return Status;
1991  }
1992 
1993  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1994  DPRINT("Type: %lx\n", Type);
1995 
1998  /*
1999  * Get existing DriverObject pointer (in case the driver
2000  * has already been loaded and initialized).
2001  */
2003  &ServiceName,
2006 
2007  if (!NT_SUCCESS(Status))
2008  {
2009  /*
2010  * Load the driver module
2011  */
2012  DPRINT("Loading module from %wZ\n", &ImagePath);
2013  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2014  if (!NT_SUCCESS(Status))
2015  {
2016  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2019  return Status;
2020  }
2021 
2022  /*
2023  * Initialize the driver module if it's loaded for the first time
2024  */
2026  if (!NT_SUCCESS(Status))
2027  {
2028  DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
2031  MmUnloadSystemImage(ModuleObject);
2032  return Status;
2033  }
2034 
2035  IopDisplayLoadingMessage(&DeviceNode->ServiceName);
2036 
2038  ModuleObject,
2039  &DeviceNode->ServiceName,
2042  DriverObject);
2043  if (!NT_SUCCESS(Status))
2044  {
2045  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2048  MmUnloadSystemImage(ModuleObject);
2049  return Status;
2050  }
2051 
2054 
2055  /* Initialize and start device */
2058  }
2059  else
2060  {
2063 
2064  DPRINT("DriverObject already exist in ObjectManager\n");
2066 
2067  /* IopGetDriverObject references the DriverObject, so dereference it */
2069  }
2070 
2071  return Status;
2072 }
2073 
2074 /*
2075  * NtLoadDriver
2076  *
2077  * Loads a device driver.
2078  *
2079  * Parameters
2080  * DriverServiceName
2081  * Name of the service to load (registry key).
2082  *
2083  * Return Value
2084  * Status
2085  *
2086  * Status
2087  * implemented
2088  */
2090 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2091 {
2092  UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
2095  NTSTATUS Status;
2096 
2097  PAGED_CODE();
2098 
2100 
2101  /*
2102  * Check security privileges
2103  */
2105  {
2106  DPRINT("Privilege not held\n");
2108  }
2109 
2110  Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
2111  PreviousMode,
2112  DriverServiceName);
2113  if (!NT_SUCCESS(Status))
2114  {
2115  return Status;
2116  }
2117 
2118  DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
2119 
2120  /* Load driver and call its entry point */
2121  DriverObject = NULL;
2122  Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
2123 
2124  ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
2125  PreviousMode);
2126 
2127  return Status;
2128 }
2129 
2130 /*
2131  * NtUnloadDriver
2132  *
2133  * Unloads a legacy device driver.
2134  *
2135  * Parameters
2136  * DriverServiceName
2137  * Name of the service to unload (registry key).
2138  *
2139  * Return Value
2140  * Status
2141  *
2142  * Status
2143  * implemented
2144  */
2145 
2148 {
2149  return IopUnloadDriver(DriverServiceName, FALSE);
2150 }
2151 
2152 /* EOF */
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#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:2118
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define IN
Definition: typedefs.h:38
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2117
#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:1764
struct _Entry Entry
Definition: kefuncs.h:640
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1398
_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:744
ACPI_SIZE Length
Definition: actypes.h:1042
char CHAR
Definition: xmlstorage.h:175
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
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:1081
#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:2170
WORK_QUEUE_ITEM WorkItem
Definition: io.h:401
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
ULONG SizeOfImage
Definition: ldrtypes.h:142
#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:2982
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:1470
#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:1252
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS FASTCALL IopLoadServiceModule(IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:314
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_In_ PVOID Parameter
Definition: ldrtypes.h:240
KEVENT Event
Definition: io.h:402
VOID NTAPI IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
Definition: driver.c:1695
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: driver.c:10
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:55
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:1434
#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:4112
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1735
uint32_t ULONG_PTR
Definition: typedefs.h:63
LIST_ENTRY ItemEntry
Definition: io.h:468
Definition: arc.h:198
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1835
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:2110
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:2173
#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:3988
VOID(NTAPI * PDRIVER_REINITIALIZE)(_In_ struct _DRIVER_OBJECT *DriverObject, _In_opt_ PVOID Context, _In_ ULONG Count)
Definition: iotypes.h:4098
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:2175
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:2167
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:2116
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:911
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:228
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1627
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:1000
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
Definition: partlist.h:33
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:1706
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)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DRIVER_INITIALIZE * PDRIVER_INITIALIZE
Definition: iotypes.h:2126
NTSTATUS NTAPI NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
Definition: driver.c:2147
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:803
NTSTATUS Status
Definition: io.h:399
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2179
_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:1842
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1831
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct _DRIVER_OBJECT DRIVER_OBJECT
Definition: typedefs.h:117
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
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:2113
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:1683
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:3670
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:144
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:2245
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define OUT
Definition: typedefs.h:39
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
ULONG Flags
Definition: ntddk_ex.h:207
struct tagContext Context
Definition: acpixf.h:1012
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
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:2171
#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:2777
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
CSHORT Type
Definition: iotypes.h:2166
#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:2090
#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:2172
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2177
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
UNICODE_STRING DriverName
Definition: iotypes.h:2174
NTSTATUS NTAPI IopLoadUnloadDriver(_In_opt_ PCUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1890
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2168
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:2756
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:492
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4114
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:146
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361
VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1877
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:173