ReactOS  0.4.12-dev-708-g95ed44e
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 {
111  WCHAR NameBuffer[MAX_PATH];
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  DriverName.Buffer = NameBuffer;
127  DriverName.Length = 0;
128  DriverName.MaximumLength = sizeof(NameBuffer);
129 
130  if (FileSystem != FALSE)
132  else
135 
136  DPRINT("Driver name: '%wZ'\n", &DriverName);
137 
138  /* Open driver object */
139  Status = ObReferenceObjectByName(&DriverName,
141  NULL, /* PassedAccessState */
142  0, /* DesiredAccess */
144  KernelMode,
145  NULL, /* ParseContext */
146  (PVOID*)&Object);
147  if (!NT_SUCCESS(Status))
148  {
149  DPRINT("Failed to reference driver object, status=0x%08x\n", Status);
150  return Status;
151  }
152 
153  *DriverObject = Object;
154 
155  DPRINT("Driver Object: %p\n", Object);
156 
157  return STATUS_SUCCESS;
158 }
159 
160 /*
161  * RETURNS
162  * TRUE if String2 contains String1 as a suffix.
163  */
164 BOOLEAN
165 NTAPI
167  IN PCUNICODE_STRING String1,
169 {
170  PWCHAR pc1;
171  PWCHAR pc2;
172  ULONG Length;
173 
174  if (String2->Length < String1->Length)
175  return FALSE;
176 
177  Length = String1->Length / 2;
178  pc1 = String1->Buffer;
179  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
180 
181  if (pc1 && pc2)
182  {
183  while (Length--)
184  {
185  if( *pc1++ != *pc2++ )
186  return FALSE;
187  }
188  return TRUE;
189  }
190  return FALSE;
191 }
192 
193 /*
194  * IopDisplayLoadingMessage
195  *
196  * Display 'Loading XXX...' message.
197  */
198 VOID
199 FASTCALL
201 {
202  CHAR TextBuffer[256];
203  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
204 
205  if (ExpInTextModeSetup) return;
206  if (!KeLoaderBlock) return;
208  snprintf(TextBuffer, sizeof(TextBuffer),
209  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
212  ServiceName,
213  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
215 }
216 
217 /*
218  * IopNormalizeImagePath
219  *
220  * Normalize an image path to contain complete path.
221  *
222  * Parameters
223  * ImagePath
224  * The input path and on exit the result path. ImagePath.Buffer
225  * must be allocated by ExAllocatePool on input. Caller is responsible
226  * for freeing the buffer when it's no longer needed.
227  *
228  * ServiceName
229  * Name of the service that ImagePath belongs to.
230  *
231  * Return Value
232  * Status
233  *
234  * Remarks
235  * The input image path isn't freed on error.
236  */
237 NTSTATUS
238 FASTCALL
240  _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
241  PUNICODE_STRING ImagePath,
243 {
244  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
245  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
246  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
247  UNICODE_STRING InputImagePath;
248 
249  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
250 
251  InputImagePath = *ImagePath;
252  if (InputImagePath.Length == 0)
253  {
254  ImagePath->Length = 0;
255  ImagePath->MaximumLength = DriversPathString.Length +
256  ServiceName->Length +
257  DotSysString.Length +
258  sizeof(UNICODE_NULL);
259  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
260  ImagePath->MaximumLength,
261  TAG_IO);
262  if (ImagePath->Buffer == NULL)
263  return STATUS_NO_MEMORY;
264 
265  RtlCopyUnicodeString(ImagePath, &DriversPathString);
267  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
268  }
269  else if (InputImagePath.Buffer[0] != L'\\')
270  {
271  ImagePath->Length = 0;
272  ImagePath->MaximumLength = SystemRootString.Length +
273  InputImagePath.Length +
274  sizeof(UNICODE_NULL);
275  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
276  ImagePath->MaximumLength,
277  TAG_IO);
278  if (ImagePath->Buffer == NULL)
279  return STATUS_NO_MEMORY;
280 
281  RtlCopyUnicodeString(ImagePath, &SystemRootString);
282  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
283 
284  /* Free caller's string */
285  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
286  }
287 
288  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
289 
290  return STATUS_SUCCESS;
291 }
292 
293 /*
294  * IopLoadServiceModule
295  *
296  * Load a module specified by registry settings for service.
297  *
298  * Parameters
299  * ServiceName
300  * Name of the service to load.
301  *
302  * Return Value
303  * Status
304  */
305 NTSTATUS
306 FASTCALL
309  OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
310 {
313  UNICODE_STRING ServiceImagePath, CCSName;
315  HANDLE CCSKey, ServiceKey;
317 
319  ASSERT(ServiceName->Length);
320  DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
321 
322  if (ExpInTextModeSetup)
323  {
324  /* We have no registry, but luckily we know where all the drivers are */
325  DPRINT1("IopLoadServiceModule(%wZ, 0x%p) called in ExpInTextModeSetup mode...\n", ServiceName, ModuleObject);
326 
327  /* ServiceStart < 4 is all that matters */
328  ServiceStart = 0;
329 
330  /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
331  RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
332  }
333  else
334  {
335  /* Open CurrentControlSet */
336  RtlInitUnicodeString(&CCSName,
337  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
338  Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
339  if (!NT_SUCCESS(Status))
340  {
341  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
342  &CCSName, Status);
343  return Status;
344  }
345 
346  /* Open service key */
347  Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
348  if (!NT_SUCCESS(Status))
349  {
350  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
352  ZwClose(CCSKey);
353  return Status;
354  }
355 
356  /*
357  * Get information about the service.
358  */
360 
361  RtlInitUnicodeString(&ServiceImagePath, NULL);
362 
363  QueryTable[0].Name = L"Start";
366 
367  QueryTable[1].Name = L"ImagePath";
369  QueryTable[1].EntryContext = &ServiceImagePath;
370 
372  (PWSTR)ServiceKey,
373  QueryTable,
374  NULL,
375  NULL);
376 
377  ZwClose(ServiceKey);
378  ZwClose(CCSKey);
379 
380  if (!NT_SUCCESS(Status))
381  {
382  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
383  return Status;
384  }
385  }
386 
387  /*
388  * Normalize the image path for all later processing.
389  */
390  Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
391 
392  if (!NT_SUCCESS(Status))
393  {
394  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
395  return Status;
396  }
397 
398  /*
399  * Case for disabled drivers
400  */
401  if (ServiceStart >= 4)
402  {
403  /* We can't load this */
405  }
406  else
407  {
408  DPRINT("Loading module from %wZ\n", &ServiceImagePath);
409  Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
410  if (NT_SUCCESS(Status))
411  {
413  }
414  }
415 
416  ExFreePool(ServiceImagePath.Buffer);
417 
418  /*
419  * Now check if the module was loaded successfully.
420  */
421  if (!NT_SUCCESS(Status))
422  {
423  DPRINT("Module loading failed (Status %x)\n", Status);
424  }
425 
426  DPRINT("Module loading (Status %x)\n", Status);
427 
428  return Status;
429 }
430 
431 VOID
432 NTAPI
434 
435 /*
436  * IopInitializeDriverModule
437  *
438  * Initialize a loaded driver.
439  *
440  * Parameters
441  * DeviceNode
442  * Pointer to device node.
443  *
444  * ModuleObject
445  * Module object representing the driver. It can be retrieve by
446  * IopLoadServiceModule.
447  *
448  * ServiceName
449  * Name of the service (as in registry).
450  *
451  * FileSystemDriver
452  * Set to TRUE for file system drivers.
453  *
454  * DriverObject
455  * On successful return this contains the driver object representing
456  * the loaded driver.
457  */
458 NTSTATUS
459 FASTCALL
462  IN PLDR_DATA_TABLE_ENTRY ModuleObject,
464  IN BOOLEAN FileSystemDriver,
466 {
467  static const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
468  UNICODE_STRING DriverName;
469  UNICODE_STRING RegistryKey;
473 
474  DriverEntry = ModuleObject->EntryPoint;
475 
476  if (ServiceName != NULL && ServiceName->Length != 0)
477  {
478  RegistryKey.Length = 0;
479  RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length;
480  RegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool,
481  RegistryKey.MaximumLength,
482  TAG_IO);
483  if (RegistryKey.Buffer == NULL)
484  {
486  }
487  RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName);
489  }
490  else
491  {
492  RtlInitEmptyUnicodeString(&RegistryKey, NULL, 0);
493  }
494 
495  /* Create ModuleName string */
496  if (ServiceName && ServiceName->Length > 0)
497  {
498  DriverName.Length = 0;
499  DriverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME) + ServiceName->Length;
501  DriverName.MaximumLength,
502  TAG_IO);
503  if (DriverName.Buffer == NULL)
504  {
505  RtlFreeUnicodeString(&RegistryKey);
507  }
508 
509  if (FileSystemDriver != FALSE)
511  else
514 
515  DPRINT("Driver name: '%wZ'\n", &DriverName);
516  }
517  else
518  {
519  RtlInitEmptyUnicodeString(&DriverName, NULL, 0);
520  }
521 
522  Status = IopCreateDriver(DriverName.Length > 0 ? &DriverName : NULL,
523  DriverEntry,
524  &RegistryKey,
525  ServiceName,
526  ModuleObject,
527  &Driver);
528  RtlFreeUnicodeString(&RegistryKey);
529  RtlFreeUnicodeString(&DriverName);
530 
531  if (!NT_SUCCESS(Status))
532  {
533  DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status);
534  return Status;
535  }
536 
537  *DriverObject = Driver;
538 
540 
541  /* Set the driver as initialized */
543 
545 
546  return STATUS_SUCCESS;
547 }
548 
549 /*
550  * IopAttachFilterDriversCallback
551  *
552  * Internal routine used by IopAttachFilterDrivers.
553  */
554 NTSTATUS
555 NTAPI
561  PVOID Context,
563 {
566  PWCHAR Filters;
567  PLDR_DATA_TABLE_ENTRY ModuleObject;
570 
571  /* No filter value present */
572  if (ValueType == REG_NONE)
573  return STATUS_SUCCESS;
574 
575  for (Filters = ValueData;
576  ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
577  *Filters != 0;
578  Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
579  {
580  DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
581 
582  ServiceName.Buffer = Filters;
583  ServiceName.MaximumLength =
584  ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
585 
589  &ServiceName,
590  FALSE);
591  if (!NT_SUCCESS(Status))
592  {
593  /* Load and initialize the filter driver */
594  Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
595  if (!NT_SUCCESS(Status))
596  {
599  return Status;
600  }
601 
603  ModuleObject,
604  &ServiceName,
605  FALSE,
606  &DriverObject);
607  if (!NT_SUCCESS(Status))
608  {
611  return Status;
612  }
613  }
614 
617 
619 
620  /* Remove extra reference */
622 
623  if (!NT_SUCCESS(Status))
624  return Status;
625  }
626 
627  return STATUS_SUCCESS;
628 }
629 
630 /*
631  * IopAttachFilterDrivers
632  *
633  * Load filter drivers for specified device node.
634  *
635  * Parameters
636  * Lower
637  * Set to TRUE for loading lower level filters or FALSE for upper
638  * level filters.
639  */
640 NTSTATUS
641 FASTCALL
644  HANDLE EnumSubKey,
645  HANDLE ClassKey,
646  BOOLEAN Lower)
647 {
648  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
650 
651  /*
652  * First load the device filters
653  */
655  if (Lower)
656  QueryTable[0].Name = L"LowerFilters";
657  else
658  QueryTable[0].Name = L"UpperFilters";
659  QueryTable[0].Flags = 0;
661 
663  (PWSTR)EnumSubKey,
664  QueryTable,
665  DeviceNode,
666  NULL);
667  if (!NT_SUCCESS(Status))
668  {
669  DPRINT1("Failed to load device %s filters: %08X\n",
670  Lower ? "lower" : "upper", Status);
671  return Status;
672  }
673 
675  if (Lower)
676  QueryTable[0].Name = L"LowerFilters";
677  else
678  QueryTable[0].Name = L"UpperFilters";
680  QueryTable[0].Flags = 0;
682 
683  if (ClassKey == NULL)
684  {
685  return STATUS_SUCCESS;
686  }
687 
689  (PWSTR)ClassKey,
690  QueryTable,
691  DeviceNode,
692  NULL);
693 
694  if (!NT_SUCCESS(Status))
695  {
696  DPRINT1("Failed to load class %s filters: %08X\n",
697  Lower ? "lower" : "upper", Status);
698  return Status;
699  }
700 
701  return STATUS_SUCCESS;
702 }
703 
704 NTSTATUS
705 NTAPI
707  IN PUNICODE_STRING ImageFileDirectory,
708  IN PUNICODE_STRING NamePrefix OPTIONAL,
709  OUT PCHAR *MissingApi,
710  OUT PWCHAR *MissingDriver,
711  OUT PLOAD_IMPORTS *LoadImports);
712 
713 //
714 // Used for images already loaded (boot drivers)
715 //
716 INIT_FUNCTION
717 NTSTATUS
718 NTAPI
721  PLDR_DATA_TABLE_ENTRY *ModuleObject)
722 {
724  UNICODE_STRING BaseName, BaseDirectory;
725  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
726  PCHAR MissingApiName, Buffer;
727  PWCHAR MissingDriverName;
728  PVOID DriverBase = LdrEntry->DllBase;
729 
730  /* Allocate a buffer we'll use for names */
732  if (!Buffer)
733  {
734  /* Fail */
736  }
737 
738  /* Check for a separator */
739  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
740  {
741  PWCHAR p;
742  ULONG BaseLength;
743 
744  /* Loop the path until we get to the base name */
745  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
746  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
747 
748  /* Get the length */
749  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
750  BaseLength *= sizeof(WCHAR);
751 
752  /* Setup the string */
753  BaseName.Length = (USHORT)BaseLength;
754  BaseName.Buffer = p;
755  }
756  else
757  {
758  /* Otherwise, we already have a base name */
759  BaseName.Length = FileName->Length;
760  BaseName.Buffer = FileName->Buffer;
761  }
762 
763  /* Setup the maximum length */
764  BaseName.MaximumLength = BaseName.Length;
765 
766  /* Now compute the base directory */
767  BaseDirectory = *FileName;
768  BaseDirectory.Length -= BaseName.Length;
769  BaseDirectory.MaximumLength = BaseDirectory.Length;
770 
771  /* Resolve imports */
772  MissingApiName = Buffer;
773  Status = MiResolveImageReferences(DriverBase,
774  &BaseDirectory,
775  NULL,
776  &MissingApiName,
777  &MissingDriverName,
778  &LoadedImports);
779 
780  /* Free the temporary buffer */
782 
783  /* Check the result of the imports resolution */
784  if (!NT_SUCCESS(Status)) return Status;
785 
786  /* Return */
787  *ModuleObject = LdrEntry;
788  return STATUS_SUCCESS;
789 }
790 
791 /*
792  * IopInitializeBuiltinDriver
793  *
794  * Initialize a driver that is already loaded in memory.
795  */
796 INIT_FUNCTION
797 NTSTATUS
798 NTAPI
800 {
804  PWCHAR Buffer, FileNameWithoutPath;
805  PWSTR FileExtension;
806  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
807  PLDR_DATA_TABLE_ENTRY LdrEntry;
808  PLIST_ENTRY NextEntry;
811 
812  /*
813  * Display 'Loading XXX...' message
814  */
817 
819  ModuleName->Length + sizeof(UNICODE_NULL),
820  TAG_IO);
821  if (Buffer == NULL)
822  {
824  }
825 
827  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
828 
829  /*
830  * Generate filename without path (not needed by freeldr)
831  */
832  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
833  if (FileNameWithoutPath == NULL)
834  {
835  FileNameWithoutPath = Buffer;
836  }
837  else
838  {
839  FileNameWithoutPath++;
840  }
841 
842  /*
843  * Strip the file extension from ServiceName
844  */
845  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
847  if (!Success)
848  {
850  }
851 
852  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
853  if (FileExtension != NULL)
854  {
855  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
856  FileExtension[0] = UNICODE_NULL;
857  }
858 
859  /*
860  * Determine the right device object
861  */
862  /* Use IopRootDeviceNode for now */
864  NULL,
865  &ServiceName,
866  &DeviceNode);
868  if (!NT_SUCCESS(Status))
869  {
870  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
871  return Status;
872  }
873 
874  /* Lookup the new Ldr entry in PsLoadedModuleList */
875  NextEntry = PsLoadedModuleList.Flink;
876  while (NextEntry != &PsLoadedModuleList)
877  {
878  LdrEntry = CONTAINING_RECORD(NextEntry,
880  InLoadOrderLinks);
882  {
883  break;
884  }
885 
886  NextEntry = NextEntry->Flink;
887  }
888  ASSERT(NextEntry != &PsLoadedModuleList);
889 
890  /*
891  * Initialize the driver
892  */
894  LdrEntry,
895  &DeviceNode->ServiceName,
896  FALSE,
897  &DriverObject);
898 
899  if (!NT_SUCCESS(Status))
900  {
901  return Status;
902  }
903 
905  if (NT_SUCCESS(Status))
906  {
908  }
909 
910  /* Remove extra reference from IopInitializeDriverModule */
912 
913  return Status;
914 }
915 
916 /*
917  * IopInitializeBootDrivers
918  *
919  * Initialize boot drivers and free memory for boot files.
920  *
921  * Parameters
922  * None
923  *
924  * Return Value
925  * None
926  */
927 INIT_FUNCTION
928 VOID
929 FASTCALL
931 {
932  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
933  PLDR_DATA_TABLE_ENTRY LdrEntry;
936  LDR_DATA_TABLE_ENTRY ModuleObject;
938  UNICODE_STRING DriverName;
939  ULONG i, Index;
940  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
942  PBOOT_DRIVER_LIST_ENTRY BootEntry;
943  DPRINT("IopInitializeBootDrivers()\n");
944 
945  /* Use IopRootDeviceNode for now */
947  if (!NT_SUCCESS(Status)) return;
948 
949  /* Setup the module object for the RAW FS Driver */
950  ModuleObject.DllBase = NULL;
951  ModuleObject.SizeOfImage = 0;
952  ModuleObject.EntryPoint = RawFsDriverEntry;
953  RtlInitUnicodeString(&DriverName, L"RAW");
954 
955  /* Initialize it */
957  &ModuleObject,
958  &DriverName,
959  TRUE,
960  &DriverObject);
961  if (!NT_SUCCESS(Status))
962  {
963  /* Fail */
964  return;
965  }
966 
967  /* Now initialize the associated device */
969  if (!NT_SUCCESS(Status))
970  {
971  /* Fail */
973  return;
974  }
975 
976  /* Start it up */
978  if (!NT_SUCCESS(Status))
979  {
980  /* Fail */
982  return;
983  }
984 
985  /* Get highest group order index */
987  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
988 
989  /* Allocate the group table */
991  IopGroupIndex * sizeof(LIST_ENTRY),
992  TAG_IO);
993  if (IopGroupTable == NULL) ASSERT(FALSE);
994 
995  /* Initialize the group table lists */
996  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
997 
998  /* Loop the boot modules */
999  ListHead = &KeLoaderBlock->LoadOrderListHead;
1000  NextEntry = ListHead->Flink;
1001  while (ListHead != NextEntry)
1002  {
1003  /* Get the entry */
1004  LdrEntry = CONTAINING_RECORD(NextEntry,
1006  InLoadOrderLinks);
1007 
1008  /* Check if the DLL needs to be initialized */
1009  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1010  {
1011  /* Call its entrypoint */
1012  MmCallDllInitialize(LdrEntry, NULL);
1013  }
1014 
1015  /* Go to the next driver */
1016  NextEntry = NextEntry->Flink;
1017  }
1018 
1019  /* Loop the boot drivers */
1020  ListHead = &KeLoaderBlock->BootDriverListHead;
1021  NextEntry = ListHead->Flink;
1022  while (ListHead != NextEntry)
1023  {
1024  /* Get the entry */
1025  BootEntry = CONTAINING_RECORD(NextEntry,
1027  Link);
1028 
1029  /* Get the driver loader entry */
1030  LdrEntry = BootEntry->LdrEntry;
1031 
1032  /* Allocate our internal accounting structure */
1034  sizeof(DRIVER_INFORMATION),
1035  TAG_IO);
1036  if (DriverInfo)
1037  {
1038  /* Zero it and initialize it */
1041  DriverInfo->DataTableEntry = BootEntry;
1042 
1043  /* Open the registry key */
1045  NULL,
1046  &BootEntry->RegistryPath,
1047  KEY_READ);
1048  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1049 #if 0
1050  if (NT_SUCCESS(Status))
1051 #else // Hack still needed...
1052  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1053  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1054 #endif
1055  {
1056  /* Save the handle */
1058 
1059  /* Get the group oder index */
1061 
1062  /* Get the tag position */
1064 
1065  /* Insert it into the list, at the right place */
1067  NextEntry2 = IopGroupTable[Index].Flink;
1068  while (NextEntry2 != &IopGroupTable[Index])
1069  {
1070  /* Get the driver info */
1071  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1073  Link);
1074 
1075  /* Check if we found the right tag position */
1076  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1077  {
1078  /* We're done */
1079  break;
1080  }
1081 
1082  /* Next entry */
1083  NextEntry2 = NextEntry2->Flink;
1084  }
1085 
1086  /* Insert us right before the next entry */
1087  NextEntry2 = NextEntry2->Blink;
1088  InsertHeadList(NextEntry2, &DriverInfo->Link);
1089  }
1090  }
1091 
1092  /* Go to the next driver */
1093  NextEntry = NextEntry->Flink;
1094  }
1095 
1096  /* Loop each group index */
1097  for (i = 0; i < IopGroupIndex; i++)
1098  {
1099  /* Loop each group table */
1100  NextEntry = IopGroupTable[i].Flink;
1101  while (NextEntry != &IopGroupTable[i])
1102  {
1103  /* Get the entry */
1104  DriverInfo = CONTAINING_RECORD(NextEntry,
1106  Link);
1107 
1108  /* Get the driver loader entry */
1109  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1110 
1111  /* Initialize it */
1112  IopInitializeBuiltinDriver(LdrEntry);
1113 
1114  /* Next entry */
1115  NextEntry = NextEntry->Flink;
1116  }
1117  }
1118 
1119  /* In old ROS, the loader list became empty after this point. Simulate. */
1121 }
1122 
1123 INIT_FUNCTION
1124 VOID
1125 FASTCALL
1127 {
1128  PUNICODE_STRING *DriverList, *SavedList;
1129 
1130  /* No system drivers on the boot cd */
1131  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1132 
1133  /* Get the driver list */
1134  SavedList = DriverList = CmGetSystemDriverList();
1135  ASSERT(DriverList);
1136 
1137  /* Loop it */
1138  while (*DriverList)
1139  {
1140  /* Load the driver */
1141  ZwLoadDriver(*DriverList);
1142 
1143  /* Free the entry */
1144  RtlFreeUnicodeString(*DriverList);
1145  ExFreePool(*DriverList);
1146 
1147  /* Next entry */
1149  DriverList++;
1150  }
1151 
1152  /* Free the list */
1153  ExFreePool(SavedList);
1154 }
1155 
1156 /*
1157  * IopUnloadDriver
1158  *
1159  * Unloads a device driver.
1160  *
1161  * Parameters
1162  * DriverServiceName
1163  * Name of the service to unload (registry key).
1164  *
1165  * UnloadPnpDrivers
1166  * Whether to unload Plug & Plug or only legacy drivers. If this
1167  * parameter is set to FALSE, the routine will unload only legacy
1168  * drivers.
1169  *
1170  * Return Value
1171  * Status
1172  *
1173  * To do
1174  * Guard the whole function by SEH.
1175  */
1176 
1178 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
1179 {
1181  UNICODE_STRING ImagePath;
1186  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1187  NTSTATUS Status;
1188  PWSTR Start;
1189  BOOLEAN SafeToUnload = TRUE;
1191  UNICODE_STRING CapturedServiceName;
1192 
1193  PAGED_CODE();
1194 
1196 
1197  /* Need the appropriate priviliege */
1199  {
1200  DPRINT1("No unload privilege!\n");
1202  }
1203 
1204  /* Capture the service name */
1205  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, PreviousMode, DriverServiceName);
1206  if (!NT_SUCCESS(Status))
1207  {
1208  return Status;
1209  }
1210 
1211  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1212 
1213 
1214  /* We need a service name */
1215  if (CapturedServiceName.Length == 0)
1216  {
1217  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1218  return STATUS_INVALID_PARAMETER;
1219  }
1220 
1221  /*
1222  * Get the service name from the registry key name
1223  */
1224  Start = wcsrchr(CapturedServiceName.Buffer, L'\\');
1225  if (Start == NULL)
1226  Start = CapturedServiceName.Buffer;
1227  else
1228  Start++;
1229 
1231 
1232  /*
1233  * Construct the driver object name
1234  */
1235  ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
1236  ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
1238  ObjectName.MaximumLength,
1239  TAG_IO);
1240  if (!ObjectName.Buffer)
1241  {
1242  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1244  }
1246  memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
1247  ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = UNICODE_NULL;
1248 
1249  /*
1250  * Find the driver object
1251  */
1253  0,
1254  0,
1255  0,
1257  KernelMode,
1258  0,
1259  (PVOID*)&DriverObject);
1260 
1261  if (!NT_SUCCESS(Status))
1262  {
1263  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1265  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1266  return Status;
1267  }
1268 
1269  /* Free the buffer for driver object name */
1271 
1272  /* Check that driver is not already unloading */
1274  {
1275  DPRINT1("Driver deletion pending\n");
1277  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1278  return STATUS_DELETE_PENDING;
1279  }
1280 
1281  /*
1282  * Get path of service...
1283  */
1285 
1286  RtlInitUnicodeString(&ImagePath, NULL);
1287 
1288  QueryTable[0].Name = L"ImagePath";
1290  QueryTable[0].EntryContext = &ImagePath;
1291 
1293  CapturedServiceName.Buffer,
1294  QueryTable,
1295  NULL,
1296  NULL);
1297 
1298  /* We no longer need service name */
1299  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1300 
1301  if (!NT_SUCCESS(Status))
1302  {
1303  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1305  return Status;
1306  }
1307 
1308  /*
1309  * Normalize the image path for all later processing.
1310  */
1311  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1312 
1313  if (!NT_SUCCESS(Status))
1314  {
1315  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1317  return Status;
1318  }
1319 
1320  /* Free the service path */
1321  ExFreePool(ImagePath.Buffer);
1322 
1323  /*
1324  * Unload the module and release the references to the device object
1325  */
1326 
1327  /* Call the load/unload routine, depending on current process */
1329  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1330  {
1331  /* Loop through each device object of the driver
1332  and set DOE_UNLOAD_PENDING flag */
1334  while (DeviceObject)
1335  {
1336  /* Set the unload pending flag for the device */
1337  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1338  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1339 
1340  /* Make sure there are no attached devices or no reference counts */
1341  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1342  {
1343  /* Not safe to unload */
1344  DPRINT1("Drivers device object is referenced or has attached devices\n");
1345 
1346  SafeToUnload = FALSE;
1347  }
1348 
1349  DeviceObject = DeviceObject->NextDevice;
1350  }
1351 
1352  /* If not safe to unload, then return success */
1353  if (!SafeToUnload)
1354  {
1356  return STATUS_SUCCESS;
1357  }
1358 
1359  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1360 
1361  /* Set the unload invoked flag and call the unload routine */
1365 
1366  /* Mark the driver object temporary, so it could be deleted later */
1368 
1369  /* Dereference it 2 times */
1372 
1373  return Status;
1374  }
1375  else
1376  {
1377  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1378 
1379  /* Dereference one time (refd inside this function) */
1381 
1382  /* Return unloading failure */
1384  }
1385 }
1386 
1387 VOID
1388 NTAPI
1390 {
1391  PDRIVER_REINIT_ITEM ReinitItem;
1393 
1394  /* Get the first entry and start looping */
1397  while (Entry)
1398  {
1399  /* Get the item */
1400  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1401 
1402  /* Increment reinitialization counter */
1403  ReinitItem->DriverObject->DriverExtension->Count++;
1404 
1405  /* Remove the device object flag */
1406  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1407 
1408  /* Call the routine */
1409  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1410  ReinitItem->Context,
1411  ReinitItem->DriverObject->
1412  DriverExtension->Count);
1413 
1414  /* Free the entry */
1415  ExFreePool(Entry);
1416 
1417  /* Move to the next one */
1420  }
1421 }
1422 
1423 VOID
1424 NTAPI
1426 {
1427  PDRIVER_REINIT_ITEM ReinitItem;
1429 
1430  /* Get the first entry and start looping */
1433  while (Entry)
1434  {
1435  /* Get the item */
1436  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1437 
1438  /* Increment reinitialization counter */
1439  ReinitItem->DriverObject->DriverExtension->Count++;
1440 
1441  /* Remove the device object flag */
1443 
1444  /* Call the routine */
1445  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1446  ReinitItem->Context,
1447  ReinitItem->DriverObject->
1448  DriverExtension->Count);
1449 
1450  /* Free the entry */
1451  ExFreePool(Entry);
1452 
1453  /* Move to the next one */
1456  }
1457 }
1458 
1459 NTSTATUS
1460 NTAPI
1462  IN PDRIVER_INITIALIZE InitializationFunction,
1465  IN PLDR_DATA_TABLE_ENTRY ModuleObject OPTIONAL,
1466  OUT PDRIVER_OBJECT *pDriverObject)
1467 {
1468  WCHAR NameBuffer[100];
1469  USHORT NameLength;
1470  UNICODE_STRING LocalDriverName;
1471  NTSTATUS Status;
1473  ULONG ObjectSize;
1475  UNICODE_STRING ServiceKeyName;
1476  HANDLE hDriver;
1477  ULONG i, RetryCount = 0;
1478 
1479 try_again:
1480  /* First, create a unique name for the driver if we don't have one */
1481  if (!DriverName)
1482  {
1483  /* Create a random name and set up the string */
1484  NameLength = (USHORT)swprintf(NameBuffer,
1485  DRIVER_ROOT_NAME L"%08u",
1487  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1488  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1489  LocalDriverName.Buffer = NameBuffer;
1490  }
1491  else
1492  {
1493  /* So we can avoid another code path, use a local var */
1494  LocalDriverName = *DriverName;
1495  }
1496 
1497  /* Initialize the Attributes */
1498  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1500  &LocalDriverName,
1502  NULL,
1503  NULL);
1504 
1505  /* Create the Object */
1509  KernelMode,
1510  NULL,
1511  ObjectSize,
1512  0,
1513  0,
1514  (PVOID*)&DriverObject);
1515  if (!NT_SUCCESS(Status)) return Status;
1516 
1517  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1518 
1519  /* Set up the Object */
1520  RtlZeroMemory(DriverObject, ObjectSize);
1522  DriverObject->Size = sizeof(DRIVER_OBJECT);
1523 
1524  /*
1525  * Check whether RegistryPath and ModuleObject are both NULL because
1526  * IoCreateDriver() was called to initialize a built-in driver.
1527  */
1528  if ((RegistryPath != NULL) || (ModuleObject != NULL))
1530  else
1532 
1535  DriverObject->DriverInit = InitializationFunction;
1536  DriverObject->DriverSection = ModuleObject;
1537  /* Loop all Major Functions */
1538  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1539  {
1540  /* Invalidate each function */
1542  }
1543 
1544  /* Set up the service key name buffer */
1545  ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
1546  ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
1547  ServiceKeyName.MaximumLength,
1548  TAG_IO);
1549  if (!ServiceKeyName.Buffer)
1550  {
1551  /* Fail */
1555  }
1556 
1557  /* Copy the name and set it in the driver extension */
1558  RtlCopyUnicodeString(&ServiceKeyName,
1559  ServiceName);
1560  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1561 
1562  /* Make a copy of the driver name to store in the driver object */
1563  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1566  TAG_IO);
1568  {
1569  /* Fail */
1573  }
1574 
1576  &LocalDriverName);
1577 
1578  /* Add the Object and get its handle */
1580  NULL,
1582  0,
1583  NULL,
1584  &hDriver);
1585 
1586  /* Eliminate small possibility when this function is called more than
1587  once in a row, and KeTickCount doesn't get enough time to change */
1588  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1589  {
1590  RetryCount++;
1591  goto try_again;
1592  }
1593 
1594  if (!NT_SUCCESS(Status)) return Status;
1595 
1596  /* Now reference it */
1598  0,
1600  KernelMode,
1601  (PVOID*)&DriverObject,
1602  NULL);
1603 
1604  /* Close the extra handle */
1605  ZwClose(hDriver);
1606 
1607  if (!NT_SUCCESS(Status))
1608  {
1609  /* Fail */
1612  return Status;
1613  }
1614 
1616  DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
1617  DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
1618 
1619  /* Finally, call its init function */
1620  DPRINT("RegistryKey: %wZ\n", RegistryPath);
1621  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1622  Status = (*InitializationFunction)(DriverObject, RegistryPath);
1623  if (!NT_SUCCESS(Status))
1624  {
1625  /* If it didn't work, then kill the object */
1626  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1630  return Status;
1631  }
1632  else
1633  {
1634  /* Returns to caller the object */
1635  *pDriverObject = DriverObject;
1636  }
1637 
1638  /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
1639  * Other parts of the I/O manager depend on this behavior */
1641 
1642  /* Loop all Major Functions */
1643  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1644  {
1645  /*
1646  * Make sure the driver didn't set any dispatch entry point to NULL!
1647  * Doing so is illegal; drivers shouldn't touch entry points they
1648  * do not implement.
1649  */
1650 
1651  /* Check if it did so anyway */
1652  if (!DriverObject->MajorFunction[i])
1653  {
1654  /* Print a warning in the debug log */
1655  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1657 
1658  /* Fix it up */
1660  }
1661  }
1662 
1663  /* Return the Status */
1664  return Status;
1665 }
1666 
1667 /* PUBLIC FUNCTIONS ***********************************************************/
1668 
1669 /*
1670  * @implemented
1671  */
1672 NTSTATUS
1673 NTAPI
1675  IN PDRIVER_INITIALIZE InitializationFunction)
1676 {
1678  return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
1679 }
1680 
1681 /*
1682  * @implemented
1683  */
1684 VOID
1685 NTAPI
1687 {
1688  /* Simply dereference the Object */
1690 }
1691 
1692 /*
1693  * @implemented
1694  */
1695 VOID
1696 NTAPI
1698  IN PDRIVER_REINITIALIZE ReinitRoutine,
1699  IN PVOID Context)
1700 {
1701  PDRIVER_REINIT_ITEM ReinitItem;
1702 
1703  /* Allocate the entry */
1704  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1705  sizeof(DRIVER_REINIT_ITEM),
1706  TAG_REINIT);
1707  if (!ReinitItem) return;
1708 
1709  /* Fill it out */
1710  ReinitItem->DriverObject = DriverObject;
1711  ReinitItem->ReinitRoutine = ReinitRoutine;
1712  ReinitItem->Context = Context;
1713 
1714  /* Set the Driver Object flag and insert the entry into the list */
1717  &ReinitItem->ItemEntry,
1719 }
1720 
1721 /*
1722  * @implemented
1723  */
1724 VOID
1725 NTAPI
1727  IN PDRIVER_REINITIALIZE ReinitRoutine,
1728  IN PVOID Context)
1729 {
1730  PDRIVER_REINIT_ITEM ReinitItem;
1731 
1732  /* Allocate the entry */
1733  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1734  sizeof(DRIVER_REINIT_ITEM),
1735  TAG_REINIT);
1736  if (!ReinitItem) return;
1737 
1738  /* Fill it out */
1739  ReinitItem->DriverObject = DriverObject;
1740  ReinitItem->ReinitRoutine = ReinitRoutine;
1741  ReinitItem->Context = Context;
1742 
1743  /* Set the Driver Object flag and insert the entry into the list */
1746  &ReinitItem->ItemEntry,
1748 }
1749 
1750 /*
1751  * @implemented
1752  */
1753 NTSTATUS
1754 NTAPI
1757  IN ULONG DriverObjectExtensionSize,
1758  OUT PVOID *DriverObjectExtension)
1759 {
1760  KIRQL OldIrql;
1761  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1762  BOOLEAN Inserted = FALSE;
1763 
1764  /* Assume failure */
1765  *DriverObjectExtension = NULL;
1766 
1767  /* Allocate the extension */
1768  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1769  sizeof(IO_CLIENT_EXTENSION) +
1770  DriverObjectExtensionSize,
1772  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1773 
1774  /* Clear the extension for teh caller */
1775  RtlZeroMemory(NewDriverExtension,
1776  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1777 
1778  /* Acqure lock */
1780 
1781  /* Fill out the extension */
1783 
1784  /* Loop the current extensions */
1785  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1786  ClientDriverExtension;
1787  while (DriverExtensions)
1788  {
1789  /* Check if the identifier matches */
1790  if (DriverExtensions->ClientIdentificationAddress ==
1792  {
1793  /* We have a collision, break out */
1794  break;
1795  }
1796 
1797  /* Go to the next one */
1798  DriverExtensions = DriverExtensions->NextExtension;
1799  }
1800 
1801  /* Check if we didn't collide */
1802  if (!DriverExtensions)
1803  {
1804  /* Link this one in */
1805  NewDriverExtension->NextExtension =
1806  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1807  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1808  NewDriverExtension;
1809  Inserted = TRUE;
1810  }
1811 
1812  /* Release the lock */
1814 
1815  /* Check if insertion failed */
1816  if (!Inserted)
1817  {
1818  /* Free the entry and fail */
1819  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1821  }
1822 
1823  /* Otherwise, return the pointer */
1824  *DriverObjectExtension = NewDriverExtension + 1;
1825  return STATUS_SUCCESS;
1826 }
1827 
1828 /*
1829  * @implemented
1830  */
1831 PVOID
1832 NTAPI
1835 {
1836  KIRQL OldIrql;
1837  PIO_CLIENT_EXTENSION DriverExtensions;
1838 
1839  /* Acquire lock */
1841 
1842  /* Loop the list until we find the right one */
1843  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1844  while (DriverExtensions)
1845  {
1846  /* Check for a match */
1847  if (DriverExtensions->ClientIdentificationAddress ==
1849  {
1850  /* Break out */
1851  break;
1852  }
1853 
1854  /* Keep looping */
1855  DriverExtensions = DriverExtensions->NextExtension;
1856  }
1857 
1858  /* Release lock */
1860 
1861  /* Return nothing or the extension */
1862  if (!DriverExtensions) return NULL;
1863  return DriverExtensions + 1;
1864 }
1865 
1866 VOID
1867 NTAPI
1870 {
1871  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1872 
1874  LoadParams->Status = IopLoadUnloadDriver(LoadParams->RegistryPath,
1875  &LoadParams->DriverObject);
1876  KeSetEvent(&LoadParams->Event, 0, FALSE);
1877 }
1878 
1879 NTSTATUS
1880 NTAPI
1884 {
1886  UNICODE_STRING ImagePath;
1888  NTSTATUS Status;
1889  ULONG Type;
1891  PLDR_DATA_TABLE_ENTRY ModuleObject;
1893  WCHAR *cur;
1894 
1895  /* Load/Unload must be called from system process */
1897  {
1898  LOAD_UNLOAD_PARAMS LoadParams;
1899 
1900  /* Prepare parameters block */
1901  LoadParams.RegistryPath = RegistryPath;
1902  LoadParams.DriverObject = *DriverObject;
1904 
1905  /* Initialize and queue a work item */
1906  ExInitializeWorkItem(&LoadParams.WorkItem,
1908  &LoadParams);
1910 
1911  /* And wait till it completes */
1912  KeWaitForSingleObject(&LoadParams.Event,
1913  UserRequest,
1914  KernelMode,
1915  FALSE,
1916  NULL);
1917  return LoadParams.Status;
1918  }
1919 
1920  /* Check if it's an unload request */
1921  if (*DriverObject)
1922  {
1923  (*DriverObject)->DriverUnload(*DriverObject);
1924  return STATUS_SUCCESS;
1925  }
1926 
1927  RtlInitUnicodeString(&ImagePath, NULL);
1928 
1929  /*
1930  * Get the service name from the registry key name.
1931  */
1932  ASSERT(RegistryPath->Length >= sizeof(WCHAR));
1933 
1935  cur = RegistryPath->Buffer + RegistryPath->Length / sizeof(WCHAR) - 1;
1936  while (RegistryPath->Buffer != cur)
1937  {
1938  if (*cur == L'\\')
1939  {
1940  ServiceName.Buffer = cur + 1;
1941  ServiceName.Length = RegistryPath->Length -
1942  (USHORT)((ULONG_PTR)ServiceName.Buffer -
1944  break;
1945  }
1946  cur--;
1947  }
1948 
1949  /*
1950  * Get service type.
1951  */
1952  RtlZeroMemory(&QueryTable, sizeof(QueryTable));
1953 
1954  RtlInitUnicodeString(&ImagePath, NULL);
1955 
1956  QueryTable[0].Name = L"Type";
1959 
1960  QueryTable[1].Name = L"ImagePath";
1962  QueryTable[1].EntryContext = &ImagePath;
1963 
1966  QueryTable, NULL, NULL);
1967  if (!NT_SUCCESS(Status))
1968  {
1969  DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
1970  if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
1971  return Status;
1972  }
1973 
1974  /*
1975  * Normalize the image path for all later processing.
1976  */
1977  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1978  if (!NT_SUCCESS(Status))
1979  {
1980  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1981  return Status;
1982  }
1983 
1984  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1985  DPRINT("Type: %lx\n", Type);
1986 
1989  /*
1990  * Get existing DriverObject pointer (in case the driver
1991  * has already been loaded and initialized).
1992  */
1994  &ServiceName,
1997 
1998  if (!NT_SUCCESS(Status))
1999  {
2000  /*
2001  * Load the driver module
2002  */
2003  DPRINT("Loading module from %wZ\n", &ImagePath);
2004  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2005  if (!NT_SUCCESS(Status))
2006  {
2007  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2010  return Status;
2011  }
2012 
2013  /*
2014  * Initialize the driver module if it's loaded for the first time
2015  */
2017  if (!NT_SUCCESS(Status))
2018  {
2019  DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
2022  MmUnloadSystemImage(ModuleObject);
2023  return Status;
2024  }
2025 
2026  IopDisplayLoadingMessage(&DeviceNode->ServiceName);
2027 
2029  ModuleObject,
2030  &DeviceNode->ServiceName,
2033  DriverObject);
2034  if (!NT_SUCCESS(Status))
2035  {
2036  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2039  MmUnloadSystemImage(ModuleObject);
2040  return Status;
2041  }
2042 
2045 
2046  /* Initialize and start device */
2049  }
2050  else
2051  {
2054 
2055  DPRINT("DriverObject already exist in ObjectManager\n");
2057 
2058  /* IopGetDriverObject references the DriverObject, so dereference it */
2060  }
2061 
2062  return Status;
2063 }
2064 
2065 /*
2066  * NtLoadDriver
2067  *
2068  * Loads a device driver.
2069  *
2070  * Parameters
2071  * DriverServiceName
2072  * Name of the service to load (registry key).
2073  *
2074  * Return Value
2075  * Status
2076  *
2077  * Status
2078  * implemented
2079  */
2081 NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
2082 {
2083  UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
2086  NTSTATUS Status;
2087 
2088  PAGED_CODE();
2089 
2091 
2092  /*
2093  * Check security privileges
2094  */
2095 
2096  /* FIXME: Uncomment when privileges will be correctly implemented. */
2097 #if 0
2099  {
2100  DPRINT("Privilege not held\n");
2102  }
2103 #endif
2104 
2105  Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
2106  PreviousMode,
2107  DriverServiceName);
2108  if (!NT_SUCCESS(Status))
2109  {
2110  return Status;
2111  }
2112 
2113  DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
2114 
2115  /* Load driver and call its entry point */
2116  DriverObject = NULL;
2117  Status = IopLoadUnloadDriver(&CapturedDriverServiceName, &DriverObject);
2118 
2119  ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
2120  PreviousMode);
2121 
2122  return Status;
2123 }
2124 
2125 /*
2126  * NtUnloadDriver
2127  *
2128  * Unloads a legacy device driver.
2129  *
2130  * Parameters
2131  * DriverServiceName
2132  * Name of the service to unload (registry key).
2133  *
2134  * Return Value
2135  * Status
2136  *
2137  * Status
2138  * implemented
2139  */
2140 
2143 {
2144  return IopUnloadDriver(DriverServiceName, FALSE);
2145 }
2146 
2147 /* 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
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:1755
struct _Entry Entry
Definition: kefuncs.h:640
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1389
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:200
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:141
#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:799
#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:2966
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:1461
#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:307
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
_In_ PVOID Parameter
Definition: ldrtypes.h:239
KEVENT Event
Definition: io.h:402
VOID NTAPI IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
Definition: driver.c:1686
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: driver.c:10
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:54
#define WCHAR
Definition: msvc.h:43
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:1425
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:954
static int Link(const char **args)
Definition: vfdcmd.c:2414
#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:1726
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:1805
INIT_FUNCTION PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1782
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:207
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:239
_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:556
_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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
PLIST_ENTRY DriverReinitTailEntry
Definition: driver.c:23
#define MAX_PATH
Definition: compat.h:26
#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:32
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:1697
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:2142
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:1833
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1801
#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:1674
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:719
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:3662
INIT_FUNCTION VOID FASTCALL IopInitializeSystemDrivers(VOID)
Definition: driver.c:1126
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:460
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:143
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:211
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:642
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:470
INIT_FUNCTION VOID FASTCALL IopInitializeBootDrivers(VOID)
Definition: driver.c:930
#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:1178
return STATUS_SUCCESS
Definition: btrfs.c:2725
#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:2081
#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:1881
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:1868
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:166