ReactOS  0.4.13-dev-257-gfabbd7c
device.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/device.c
5  * PURPOSE: Device Object Management, including Notifications and Queues.
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Filip Navara (navaraf@reactos.org)
8  * HervĂ© Poussineau (hpoussin@reactos.org)
9  * Pierre Schweitzer
10  */
11 
12 /* INCLUDES *******************************************************************/
13 
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* GLOBALS ********************************************************************/
19 
27 
28 #define DACL_SET 4
29 
30 /* PRIVATE FUNCTIONS **********************************************************/
31 
32 VOID
33 NTAPI
35 {
37  PAGED_CODE();
38 
39  /* Set the driver as initialized */
40  Driver->Flags |= DRVO_INITIALIZED;
41  DeviceObject = Driver->DeviceObject;
42  while (DeviceObject)
43  {
44  /* Set every device as initialized too */
46  DeviceObject = DeviceObject->NextDevice;
47  }
48 }
49 
50 VOID
51 NTAPI
53 {
54  PDEVICE_OBJECT DeviceObject = ObjectBody;
56  PAGED_CODE();
57 
58  /* Cleanup and free the device node */
59  if (DeviceNode)
61 
62  /* Dereference the driver object, referenced in IoCreateDevice */
63  if (DeviceObject->DriverObject)
64  ObDereferenceObject(DeviceObject->DriverObject);
65 }
66 
67 
69 NTAPI
72  OUT PDEVICE_OBJECT *AttachedToDeviceObject OPTIONAL)
73 {
74  PDEVICE_OBJECT AttachedDevice;
75  PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension;
76 
77  /* Get the Attached Device and source extension */
78  AttachedDevice = IoGetAttachedDevice(TargetDevice);
79  SourceDeviceExtension = IoGetDevObjExtension(SourceDevice);
80  ASSERT(SourceDeviceExtension->AttachedTo == NULL);
81 
82  /* Make sure that it's in a correct state */
83  if ((AttachedDevice->Flags & DO_DEVICE_INITIALIZING) ||
84  (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &
89  {
90  /* Device was unloading or being removed */
91  AttachedDevice = NULL;
92  }
93  else
94  {
95  /* Update atached device fields */
96  AttachedDevice->AttachedDevice = SourceDevice;
97  AttachedDevice->Spare1++;
98 
99  /* Update the source with the attached data */
100  SourceDevice->StackSize = AttachedDevice->StackSize + 1;
101  SourceDevice->AlignmentRequirement = AttachedDevice->
102  AlignmentRequirement;
103  SourceDevice->SectorSize = AttachedDevice->SectorSize;
104 
105  /* Check for pending start flag */
106  if (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &
108  {
109  /* Propagate */
110  IoGetDevObjExtension(SourceDevice)->ExtensionFlags |=
112  }
113 
114  /* Set the attachment in the device extension */
115  SourceDeviceExtension->AttachedTo = AttachedDevice;
116  }
117 
118  /* Return the attached device */
119  if (AttachedToDeviceObject) *AttachedToDeviceObject = AttachedDevice;
120  return AttachedDevice;
121 }
122 
123 VOID
124 NTAPI
126 {
127  /* This routine is only used by Driver Verifier to validate shutdown */
128  return;
129 }
130 
131 VOID
132 NTAPI
134 {
135  PLIST_ENTRY ListEntry;
137  PSHUTDOWN_ENTRY ShutdownEntry;
138  IO_STATUS_BLOCK StatusBlock;
139  PIRP Irp;
140  KEVENT Event;
142 
143  /* Initialize an event to wait on */
145 
146  /* What phase? */
147  if (Phase == 0)
148  {
149  /* Shutdown PnP */
151 
152  /* Loop first-chance shutdown notifications */
155  while (ListEntry)
156  {
157  /* Get the shutdown entry */
158  ShutdownEntry = CONTAINING_RECORD(ListEntry,
160  ShutdownList);
161 
162  /* Get the attached device */
164 
165  /* Build the shutdown IRP and call the driver */
167  DeviceObject,
168  NULL,
169  0,
170  NULL,
171  &Event,
172  &StatusBlock);
173  if (Irp)
174  {
176  if (Status == STATUS_PENDING)
177  {
178  /* Wait on the driver */
180  }
181  }
182 
183  /* Remove the flag */
184  ShutdownEntry->DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
185 
186  /* Get rid of our reference to it */
187  ObDereferenceObject(ShutdownEntry->DeviceObject);
188 
189  /* Free the shutdown entry and reset the event */
190  ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
192 
193  /* Go to the next entry */
196  }
197  }
198  else if (Phase == 1)
199  {
200  /* Acquire resource forever */
202 
203  /* Shutdown disk file systems */
205 
206  /* Shutdown cdrom file systems */
208 
209  /* Shutdown tape filesystems */
211 
212  /* Loop last-chance shutdown notifications */
215  while (ListEntry)
216  {
217  /* Get the shutdown entry */
218  ShutdownEntry = CONTAINING_RECORD(ListEntry,
220  ShutdownList);
221 
222  /* Get the attached device */
224 
225  /* Build the shutdown IRP and call the driver */
227  DeviceObject,
228  NULL,
229  0,
230  NULL,
231  &Event,
232  &StatusBlock);
233  if (Irp)
234  {
236  if (Status == STATUS_PENDING)
237  {
238  /* Wait on the driver */
240  }
241  }
242 
243  /* Remove the flag */
244  ShutdownEntry->DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
245 
246  /* Get rid of our reference to it */
247  ObDereferenceObject(ShutdownEntry->DeviceObject);
248 
249  /* Free the shutdown entry and reset the event */
250  ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
252 
253  /* Go to the next entry */
256  }
257 
258  }
259 }
260 
261 NTSTATUS
262 NTAPI
267  IN ULONG AttachFlag)
268 {
270  IO_STATUS_BLOCK StatusBlock;
271  PFILE_OBJECT LocalFileObject;
274 
275  /* Open the Device */
277  ObjectName,
279  NULL,
280  NULL);
284  &StatusBlock,
285  0,
286  FILE_NON_DIRECTORY_FILE | AttachFlag);
287  if (!NT_SUCCESS(Status)) return Status;
288 
289  /* Get File Object */
291  0,
293  KernelMode,
294  (PVOID*)&LocalFileObject,
295  NULL);
296  if (NT_SUCCESS(Status))
297  {
298  /* Return the requested data */
299  *DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
300  *FileObject = LocalFileObject;
301  }
302 
303  /* Close the handle */
305 
306  return Status;
307 }
308 
310 NTAPI
312 {
313  PDEVICE_OBJECT LowestDevice;
314  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
315 
316  /* Get the current device and its extension */
317  LowestDevice = DeviceObject;
318  DeviceExtension = IoGetDevObjExtension(LowestDevice);
319 
320  /* Keep looping as long as we're attached */
321  while (DeviceExtension->AttachedTo)
322  {
323  /* Get the lowest device and its extension */
324  LowestDevice = DeviceExtension->AttachedTo;
325  DeviceExtension = IoGetDevObjExtension(LowestDevice);
326  }
327 
328  /* Return the lowest device */
329  return LowestDevice;
330 }
331 
332 VOID
333 NTAPI
337 {
338  PDEVICE_OBJECT Previous;
339  KIRQL OldIrql;
340 
341  /* Lock the Device list while we edit it */
343 
344  /* Check the type of operation */
345  if (Type == IopRemove)
346  {
347  /* Get the current device and check if it's the current one */
348  Previous = DeviceObject->DriverObject->DeviceObject;
349  if (Previous == DeviceObject)
350  {
351  /* It is, simply unlink this one directly */
352  DeviceObject->DriverObject->DeviceObject =
353  DeviceObject->NextDevice;
354  }
355  else
356  {
357  /* It's not, so loop until we find the device */
358  while (Previous->NextDevice != DeviceObject)
359  {
360  /* Not this one, keep moving */
361  if (!Previous->NextDevice)
362  {
363  DPRINT1("Failed to remove PDO %p (not found)\n",
364  DeviceObject);
365 
366  ASSERT(FALSE);
368  return;
369  }
370  Previous = Previous->NextDevice;
371  }
372 
373  /* We found it, now unlink us */
374  Previous->NextDevice = DeviceObject->NextDevice;
375  }
376  }
377  else
378  {
379  /* Link the device object and the driver object */
380  DeviceObject->NextDevice = DriverObject->DeviceObject;
382  }
383 
384  /* Release the device list lock */
386 }
387 
388 VOID
389 NTAPI
391 {
392  PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
394 
395  /* Check if deletion is pending */
396  if (ThisExtension->ExtensionFlags & DOE_DELETE_PENDING)
397  {
398  if (DeviceObject->AttachedDevice)
399  {
400  DPRINT("Device object is in the middle of a device stack\n");
401  return;
402  }
403 
404  if (DeviceObject->ReferenceCount)
405  {
406  DPRINT("Device object still has %d references\n", DeviceObject->ReferenceCount);
407  return;
408  }
409 
410  /* Check if we have a Security Descriptor */
411  if (DeviceObject->SecurityDescriptor)
412  {
413  /* Dereference it */
414  ObDereferenceSecurityDescriptor(DeviceObject->SecurityDescriptor, 1);
415  }
416 
417  /* Remove the device from the list */
419 
420  /* Dereference the keep-alive */
422  }
423 
424  /* We can't unload a non-PnP driver here */
426  {
427  DPRINT("Not a PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
428  return;
429  }
430 
431  /* Return if we've already called unload (maybe we're in it?) */
432  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) return;
433 
434  /* We can't unload unless there's an unload handler */
436  {
437  DPRINT1("No DriverUnload function on PnP driver! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
438  return;
439  }
440 
441  /* Bail if there are still devices present */
443  {
444  DPRINT("Devices still present! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
445  return;
446  }
447 
448  DPRINT1("Unloading driver '%wZ' (automatic)\n", &DriverObject->DriverName);
449 
450  /* Set the unload invoked flag */
452 
453  /* Unload it */
455 
456  /* Make object temporary so it can be deleted */
458 }
459 
460 VOID
461 NTAPI
463  IN BOOLEAN ForceUnload)
464 {
465  /* Sanity check */
466  ASSERT(DeviceObject->ReferenceCount);
467 
468  /* Dereference the device */
469  InterlockedDecrement(&DeviceObject->ReferenceCount);
470 
471  /*
472  * Check if we can unload it and it's safe to unload (or if we're forcing
473  * an unload, which is OK too).
474  */
475  ASSERT(!ForceUnload);
476  if (!(DeviceObject->ReferenceCount) &&
478  {
479  /* Unload it */
481  }
482 }
483 
484 VOID
485 NTAPI
488  IN ULONG Key)
489 {
491  PIRP Irp;
492  KIRQL OldIrql;
493 
494  /* Acquire the cancel lock if this is cancelable */
496 
497  /* Clear the current IRP */
498  DeviceObject->CurrentIrp = NULL;
499 
500  /* Remove an entry from the queue */
502  if (Entry)
503  {
504  /* Get the IRP and set it */
505  Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DeviceQueueEntry);
506  DeviceObject->CurrentIrp = Irp;
507 
508  /* Check if this is a cancelable packet */
509  if (Cancelable)
510  {
511  /* Check if the caller requested no cancellation */
512  if (IoGetDevObjExtension(DeviceObject)->StartIoFlags &
514  {
515  /* He did, so remove the cancel routine */
516  Irp->CancelRoutine = NULL;
517  }
518 
519  /* Release the cancel lock */
521  }
522 
523  /* Call the Start I/O Routine */
524  DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
525  }
526  else
527  {
528  /* Otherwise, release the cancel lock if we had acquired it */
530  }
531 }
532 
533 VOID
534 NTAPI
537 {
539  PIRP Irp;
540  KIRQL OldIrql;
541 
542  /* Acquire the cancel lock if this is cancelable */
544 
545  /* Clear the current IRP */
546  DeviceObject->CurrentIrp = NULL;
547 
548  /* Remove an entry from the queue */
549  Entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
550  if (Entry)
551  {
552  /* Get the IRP and set it */
553  Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DeviceQueueEntry);
554  DeviceObject->CurrentIrp = Irp;
555 
556  /* Check if this is a cancelable packet */
557  if (Cancelable)
558  {
559  /* Check if the caller requested no cancellation */
560  if (IoGetDevObjExtension(DeviceObject)->StartIoFlags &
562  {
563  /* He did, so remove the cancel routine */
564  Irp->CancelRoutine = NULL;
565  }
566 
567  /* Release the cancel lock */
569  }
570 
571  /* Call the Start I/O Routine */
572  DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
573  }
574  else
575  {
576  /* Otherwise, release the cancel lock if we had acquired it */
578  }
579 }
580 
581 VOID
582 NTAPI
584  IN ULONG Key,
585  IN ULONG Flags)
586 {
587  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
588  ULONG CurrentKey = Key;
589  ULONG CurrentFlags = Flags;
590 
591  /* Get the device extension and start the packet loop */
592  DeviceExtension = IoGetDevObjExtension(DeviceObject);
593  while (TRUE)
594  {
595  /* Increase the count */
596  if (InterlockedIncrement(&DeviceExtension->StartIoCount) > 1)
597  {
598  /*
599  * We've already called the routine once...
600  * All we have to do is save the key and add the new flags
601  */
602  DeviceExtension->StartIoFlags |= CurrentFlags;
603  DeviceExtension->StartIoKey = CurrentKey;
604  }
605  else
606  {
607  /* Mask out the current packet flags and key */
608  DeviceExtension->StartIoFlags &= ~(DOE_SIO_WITH_KEY |
611  DeviceExtension->StartIoKey = 0;
612 
613  /* Check if this is a packet start with key */
614  if (Flags & DOE_SIO_WITH_KEY)
615  {
616  /* Start the packet with a key */
619  TRUE : FALSE,
620  CurrentKey);
621  }
622  else if (Flags & DOE_SIO_NO_KEY)
623  {
624  /* Start the packet */
627  TRUE : FALSE);
628  }
629  }
630 
631  /* Decrease the Start I/O count and check if it's 0 now */
632  if (!InterlockedDecrement(&DeviceExtension->StartIoCount))
633  {
634  /* Get the current active key and flags */
635  CurrentKey = DeviceExtension->StartIoKey;
636  CurrentFlags = DeviceExtension->StartIoFlags & (DOE_SIO_WITH_KEY |
639 
640  /* Check if we should still loop */
641  if (!(CurrentFlags & (DOE_SIO_WITH_KEY | DOE_SIO_NO_KEY))) break;
642  }
643  else
644  {
645  /* There are still Start I/Os active, so quit this loop */
646  break;
647  }
648  }
649 }
650 
651 NTSTATUS
652 NTAPI
655 {
657  IO_STACK_LOCATION Stack = {0};
658  PDEVICE_RELATIONS DeviceRelations;
660 
662 
663  /* Get DeviceObject related to given FileObject */
665  if (!DeviceObject) return STATUS_NO_SUCH_DEVICE;
666 
667  /* Define input parameters */
668  Stack.MajorFunction = IRP_MJ_PNP;
670  Stack.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
671  Stack.FileObject = FileObject;
672 
673  /* Call the driver to query all relations (IRP_MJ_PNP) */
675  &Stack,
676  (PVOID)&DeviceRelations);
677  if (!NT_SUCCESS(Status)) return Status;
678 
679  /* Make sure it's not NULL and contains only one object */
680  ASSERT(DeviceRelations);
681  ASSERT(DeviceRelations->Count == 1);
682 
683  /* Finally get the device node */
684  *DeviceNode = IopGetDeviceNode(DeviceRelations->Objects[0]);
686 
687  /* Free the DEVICE_RELATIONS structure, it's not needed anymore */
688  ExFreePool(DeviceRelations);
689 
690  return Status;
691 }
692 
693 BOOLEAN
694 NTAPI
696  IN PDEVICE_OBJECT TopDeviceObjectHint)
697 {
698  KIRQL OldIrql;
699  BOOLEAN Result;
700  PDEVICE_OBJECT LoopObject;
701 
702  ASSERT(BaseDeviceObject != NULL);
703 
704  Result = FALSE;
705  /* Simply loop on the device stack and try to find our hint */
707  for (LoopObject = BaseDeviceObject; ; LoopObject = LoopObject->AttachedDevice)
708  {
709  /* It was found, it's a success */
710  if (LoopObject == TopDeviceObjectHint)
711  {
712  Result = TRUE;
713  break;
714  }
715 
716  /* End of the stack, that's a failure - default */
717  if (LoopObject == NULL)
718  {
719  break;
720  }
721  }
723 
724  return Result;
725 }
726 
727 NTSTATUS
728 NTAPI
731  OUT PULONG OutputFlags)
732 {
733  PACL Dacl;
735 
736  /* Select the DACL the caller wants */
737  switch (Type)
738  {
739  case RestrictedPublic:
741  break;
742 
743  case UnrestrictedPublic:
745  break;
746 
749  break;
750 
753  break;
754 
755  case SystemDefault:
757  break;
758 
759  default:
760  ASSERT(FALSE);
762  }
763 
764  /* Create the SD and set the DACL caller wanted */
768 
769  /* We've set DACL */
770  if (OutputFlags) *OutputFlags |= DACL_SET;
771 
772  /* Done */
773  return Status;
774 }
775 
777 NTAPI
779  IN ULONG DeviceCharacteristics,
780  IN BOOLEAN HasDeviceName,
782  OUT PACL * OutputDacl,
783  OUT PULONG OutputFlags)
784 {
785  PACL Dacl;
786  ULONG AceId;
789  BOOLEAN AdminsSet, WorldSet;
790 
791  PAGED_CODE();
792 
793  /* Zero our output vars */
794  if (OutputFlags) *OutputFlags = 0;
795 
796  *OutputDacl = NULL;
797 
798  /* For FSD, easy use SePublicDefaultUnrestrictedDacl */
803  {
806  OutputFlags);
807  goto Quit;
808  }
809  /* For storage devices with a name and floppy attribute,
810  * use SePublicOpenUnrestrictedDacl
811  */
812  else if ((DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
819  (HasDeviceName && BooleanFlagOn(DeviceCharacteristics, FILE_FLOPPY_DISKETTE)))
820  {
823  OutputFlags);
824  goto Quit;
825  }
826 
827  /* The rest...
828  * We will rely on SePublicDefaultUnrestrictedDacl as well
829  */
831  if (Dacl == NULL)
832  {
833  return NULL;
834  }
835 
836  /* Copy our DACL */
838 
839  /* Now, browse the DACL to make sure we have everything we want in them,
840  * including permissions
841  */
842  AceId = 0;
843  AdminsSet = FALSE;
844  WorldSet = FALSE;
845  while (NT_SUCCESS(RtlGetAce(Dacl, AceId, (PVOID *)&Ace)))
846  {
847  /* Admins must acess and in RWX, set it */
848  if (RtlEqualSid(SeAliasAdminsSid, &Ace->SidStart))
849  {
851  AdminsSet = TRUE;
852  }
853 
854  /* World can read a CD_ROM device */
855  if (DeviceType == FILE_DEVICE_CD_ROM && RtlEqualSid(SeWorldSid, &Ace->SidStart))
856  {
857  SetFlag(Ace->Mask, GENERIC_READ);
858  WorldSet = TRUE;
859  }
860 
861  ++AceId;
862  }
863 
864  /* AdminSid was present and set (otherwise, we have big trouble) */
865  ASSERT(AdminsSet);
866 
867  /* If CD_ROM device, we've set world permissions */
868  if (DeviceType == FILE_DEVICE_CD_ROM) ASSERT(WorldSet);
869 
870  /* Now our DACL is correct, setup the security descriptor */
873 
874  /* We've set DACL */
875  if (OutputFlags) *OutputFlags |= DACL_SET;
876 
877  /* Return DACL to allow later freeing */
878  *OutputDacl = Dacl;
880 
881 Quit:
882  /* Only return SD if we succeed */
883  if (!NT_SUCCESS(Status))
884  {
885  return NULL;
886  }
887 
888  return SecurityDescriptor;
889 }
890 
891 /* PUBLIC FUNCTIONS ***********************************************************/
892 
893 /*
894  * IoAttachDevice
895  *
896  * Layers a device over the highest device in a device stack.
897  *
898  * Parameters
899  * SourceDevice
900  * Device to be attached.
901  *
902  * TargetDevice
903  * Name of the target device.
904  *
905  * AttachedDevice
906  * Caller storage for the device attached to.
907  *
908  * Status
909  * @implemented
910  */
911 NTSTATUS
912 NTAPI
914  PUNICODE_STRING TargetDeviceName,
915  PDEVICE_OBJECT *AttachedDevice)
916 {
920 
921  /* Call the helper routine for an attach operation */
922  Status = IopGetDeviceObjectPointer(TargetDeviceName,
924  &FileObject,
925  &TargetDevice,
927  if (!NT_SUCCESS(Status)) return Status;
928 
929  /* Attach the device */
931  TargetDevice,
932  AttachedDevice);
933 
934  /* Dereference it */
936  return Status;
937 }
938 
939 /*
940  * IoAttachDeviceByPointer
941  *
942  * Status
943  * @implemented
944  */
945 NTSTATUS
946 NTAPI
949 {
950  PDEVICE_OBJECT AttachedDevice;
952 
953  /* Do the Attach */
955  if (!AttachedDevice) Status = STATUS_NO_SUCH_DEVICE;
956 
957  /* Return the status */
958  return Status;
959 }
960 
961 /*
962  * @implemented
963  */
965 NTAPI
968 {
969  /* Attach it safely */
971  TargetDevice,
972  NULL);
973 }
974 
975 /*
976  * @implemented
977  */
978 NTSTATUS
979 NTAPI
982  IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
983 {
984  /* Call the internal function */
986  TargetDevice,
987  AttachedToDeviceObject))
988  {
989  /* Nothing found */
990  return STATUS_NO_SUCH_DEVICE;
991  }
992 
993  /* Success! */
994  return STATUS_SUCCESS;
995 }
996 
997 /*
998  * IoCreateDevice
999  *
1000  * Allocates memory for and intializes a device object for use for
1001  * a driver.
1002  *
1003  * Parameters
1004  * DriverObject
1005  * Driver object passed by IO Manager when the driver was loaded.
1006  *
1007  * DeviceExtensionSize
1008  * Number of bytes for the device extension.
1009  *
1010  * DeviceName
1011  * Unicode name of device.
1012  *
1013  * DeviceType
1014  * Device type of the new device.
1015  *
1016  * DeviceCharacteristics
1017  * Bit mask of device characteristics.
1018  *
1019  * Exclusive
1020  * TRUE if only one thread can access the device at a time.
1021  *
1022  * DeviceObject
1023  * On successful return this parameter is filled by pointer to
1024  * allocated device object.
1025  *
1026  * Status
1027  * @implemented
1028  */
1029 NTSTATUS
1030 NTAPI
1032  IN ULONG DeviceExtensionSize,
1035  IN ULONG DeviceCharacteristics,
1036  IN BOOLEAN Exclusive,
1038 {
1039  WCHAR AutoNameBuffer[20];
1040  UNICODE_STRING AutoName;
1041  PDEVICE_OBJECT CreatedDeviceObject;
1042  PDEVOBJ_EXTENSION DeviceObjectExtension;
1044  NTSTATUS Status;
1045  ULONG AlignedDeviceExtensionSize;
1046  ULONG TotalSize;
1047  HANDLE TempHandle;
1048  PACL Dacl;
1050  PAGED_CODE();
1051 
1052  /* Check if we have to generate a name */
1053  if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)
1054  {
1055  /* Generate it */
1056  swprintf(AutoNameBuffer,
1057  L"\\Device\\%08lx",
1059 
1060  /* Initialize the name */
1061  RtlInitUnicodeString(&AutoName, AutoNameBuffer);
1062  DeviceName = &AutoName;
1063  }
1064 
1065  /* Get the security descriptor */
1067  DeviceCharacteristics,
1068  DeviceName != NULL,
1070  &Dacl,
1071  NULL);
1072 
1073  /* Initialize the Object Attributes */
1075  DeviceName,
1077  NULL,
1078  ReturnedSD);
1079 
1080  /* Honor exclusive flag */
1081  if (Exclusive) ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
1082 
1083  /* Create a permanent object for named devices */
1084  if (DeviceName) ObjectAttributes.Attributes |= OBJ_PERMANENT;
1085 
1086  /* Align the Extension Size to 8-bytes */
1087  AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7;
1088 
1089  /* Total Size */
1090  TotalSize = AlignedDeviceExtensionSize +
1091  sizeof(DEVICE_OBJECT) +
1092  sizeof(EXTENDED_DEVOBJ_EXTENSION);
1093 
1094  /* Create the Device Object */
1095  *DeviceObject = NULL;
1099  KernelMode,
1100  NULL,
1101  TotalSize,
1102  0,
1103  0,
1104  (PVOID*)&CreatedDeviceObject);
1105  if (!NT_SUCCESS(Status))
1106  {
1107  if (Dacl != NULL) ExFreePoolWithTag(Dacl, 'eSoI');
1108 
1109  return Status;
1110  }
1111 
1112  /* Clear the whole Object and extension so we don't null stuff manually */
1113  RtlZeroMemory(CreatedDeviceObject, TotalSize);
1114 
1115  /*
1116  * Setup the Type and Size. Note that we don't use the aligned size,
1117  * because that's only padding for the DevObjExt and not part of the Object.
1118  */
1119  CreatedDeviceObject->Type = IO_TYPE_DEVICE;
1120  CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + (USHORT)DeviceExtensionSize;
1121 
1122  /* The kernel extension is after the driver internal extension */
1123  DeviceObjectExtension = (PDEVOBJ_EXTENSION)
1124  ((ULONG_PTR)(CreatedDeviceObject + 1) +
1125  AlignedDeviceExtensionSize);
1126 
1127  /* Set the Type and Size. Question: why is Size 0 on Windows? */
1128  DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION;
1129  DeviceObjectExtension->Size = 0;
1130 
1131  /* Initialize with Power Manager */
1132  PoInitializeDeviceObject(DeviceObjectExtension);
1133 
1134  /* Link the Object and Extension */
1135  DeviceObjectExtension->DeviceObject = CreatedDeviceObject;
1136  CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension;
1137 
1138  /* Set Device Object Data */
1139  CreatedDeviceObject->DeviceType = DeviceType;
1140  CreatedDeviceObject->Characteristics = DeviceCharacteristics;
1141  CreatedDeviceObject->DeviceExtension = DeviceExtensionSize ?
1142  CreatedDeviceObject + 1 :
1143  NULL;
1144  CreatedDeviceObject->StackSize = 1;
1145  CreatedDeviceObject->AlignmentRequirement = 0;
1146 
1147  /* Set the Flags */
1148  CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING;
1149  if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE;
1150  if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME;
1151 
1152  /* Attach a Vpb for Disks and Tapes, and create the Device Lock */
1153  if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
1154  (CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK) ||
1155  (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) ||
1156  (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE))
1157  {
1158  /* Create Vpb */
1159  Status = IopCreateVpb(CreatedDeviceObject);
1160  if (!NT_SUCCESS(Status))
1161  {
1162  if (Dacl != NULL) ExFreePoolWithTag(Dacl, 'eSoI');
1163 
1164  /* Dereference the device object and fail */
1165  ObDereferenceObject(CreatedDeviceObject);
1166  return Status;
1167  }
1168 
1169  /* Initialize Lock Event */
1170  KeInitializeEvent(&CreatedDeviceObject->DeviceLock,
1172  TRUE);
1173  }
1174 
1175  /* Set the right Sector Size */
1176  switch (DeviceType)
1177  {
1178  /* All disk systems */
1180  case FILE_DEVICE_DISK:
1182 
1183  /* The default is 512 bytes */
1184  CreatedDeviceObject->SectorSize = 512;
1185  break;
1186 
1187  /* CD-ROM file systems */
1189 
1190  /* The default is 2048 bytes */
1191  CreatedDeviceObject->SectorSize = 2048;
1192  }
1193 
1194  /* Create the Device Queue */
1195  if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
1196  (CreatedDeviceObject->DeviceType == FILE_DEVICE_FILE_SYSTEM) ||
1197  (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
1198  (CreatedDeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) ||
1199  (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM))
1200  {
1201  /* Simple FS Devices, they don't need a real Device Queue */
1202  InitializeListHead(&CreatedDeviceObject->Queue.ListEntry);
1203  }
1204  else
1205  {
1206  /* An actual Device, initialize its DQ */
1207  KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
1208  }
1209 
1210  /* Insert the Object */
1211  Status = ObInsertObject(CreatedDeviceObject,
1212  NULL,
1214  1,
1215  (PVOID*)&CreatedDeviceObject,
1216  &TempHandle);
1217  if (!NT_SUCCESS(Status))
1218  {
1219  if (Dacl != NULL) ExFreePoolWithTag(Dacl, 'eSoI');
1220 
1221  return Status;
1222  }
1223 
1224  /* Now do the final linking */
1227  CreatedDeviceObject->DriverObject = DriverObject;
1228  IopEditDeviceList(DriverObject, CreatedDeviceObject, IopAdd);
1229 
1230  /* Link with the power manager */
1231  if (CreatedDeviceObject->Vpb) PoVolumeDevice(CreatedDeviceObject);
1232 
1233  /* Close the temporary handle and return to caller */
1234  ObCloseHandle(TempHandle, KernelMode);
1235  *DeviceObject = CreatedDeviceObject;
1236 
1237  if (Dacl != NULL) ExFreePoolWithTag(Dacl, 'eSoI');
1238 
1239  return STATUS_SUCCESS;
1240 }
1241 
1242 /*
1243  * IoDeleteDevice
1244  *
1245  * Status
1246  * @implemented
1247  */
1248 VOID
1249 NTAPI
1251 {
1252  PIO_TIMER Timer;
1253 
1254  /* Check if the device is registered for shutdown notifications */
1256  {
1257  /* Call the shutdown notifications */
1259  }
1260 
1261  /* Check if it has a timer */
1262  Timer = DeviceObject->Timer;
1263  if (Timer)
1264  {
1265  /* Remove it and free it */
1268  }
1269 
1270  /* Check if the device has a name */
1272  {
1273  /* It does, make it temporary so we can remove it */
1275  }
1276 
1277  /* Set the pending delete flag */
1279 
1280  /* Unlink with the power manager */
1282 
1283  /* Check if the device object can be unloaded */
1284  if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject);
1285 }
1286 
1287 /*
1288  * IoDetachDevice
1289  *
1290  * Status
1291  * @implemented
1292  */
1293 VOID
1294 NTAPI
1296 {
1297  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1298 
1299  /* Sanity check */
1300  DeviceExtension = IoGetDevObjExtension(TargetDevice->AttachedDevice);
1301  ASSERT(DeviceExtension->AttachedTo == TargetDevice);
1302 
1303  /* Remove the attachment */
1304  DeviceExtension->AttachedTo = NULL;
1305  TargetDevice->AttachedDevice = NULL;
1306 
1307  /* Check if it's ok to delete this device */
1308  if ((IoGetDevObjExtension(TargetDevice)->ExtensionFlags & DOE_DELETE_PENDING) &&
1309  !(TargetDevice->ReferenceCount))
1310  {
1311  /* It is, do it */
1313  }
1314 }
1315 
1316 /*
1317  * @implemented
1318  */
1319 NTSTATUS
1320 NTAPI
1322  IN PDEVICE_OBJECT *DeviceObjectList,
1323  IN ULONG DeviceObjectListSize,
1324  OUT PULONG ActualNumberDeviceObjects)
1325 {
1326  ULONG ActualDevices = 1;
1327  PDEVICE_OBJECT CurrentDevice = DriverObject->DeviceObject;
1328  KIRQL OldIrql;
1329 
1330  /* Lock the Device list while we enumerate it */
1332 
1333  /* Find out how many devices we'll enumerate */
1334  while ((CurrentDevice = CurrentDevice->NextDevice)) ActualDevices++;
1335 
1336  /* Go back to the first */
1337  CurrentDevice = DriverObject->DeviceObject;
1338 
1339  /* Start by at least returning this */
1340  *ActualNumberDeviceObjects = ActualDevices;
1341 
1342  /* Check if we can support so many */
1343  if ((ActualDevices * sizeof(PDEVICE_OBJECT)) > DeviceObjectListSize)
1344  {
1345  /* Fail because the buffer was too small */
1347  return STATUS_BUFFER_TOO_SMALL;
1348  }
1349 
1350  /* Check if the caller wanted the device list */
1351  if (DeviceObjectList)
1352  {
1353  /* Loop through all the devices */
1354  while (ActualDevices)
1355  {
1356  /* Reference each Device */
1357  ObReferenceObject(CurrentDevice);
1358 
1359  /* Add it to the list */
1360  *DeviceObjectList = CurrentDevice;
1361 
1362  /* Go to the next one */
1363  CurrentDevice = CurrentDevice->NextDevice;
1364  ActualDevices--;
1365  DeviceObjectList++;
1366  }
1367  }
1368 
1369  /* Release the device list lock */
1371 
1372  /* Return the status */
1373  return STATUS_SUCCESS;
1374 }
1375 
1376 /*
1377  * IoGetAttachedDevice
1378  *
1379  * Status
1380  * @implemented
1381  */
1383 NTAPI
1385 {
1386  /* Get the last attached device */
1387  while (DeviceObject->AttachedDevice)
1388  {
1389  /* Move to the next one */
1390  DeviceObject = DeviceObject->AttachedDevice;
1391  }
1392 
1393  /* Return it */
1394  return DeviceObject;
1395 }
1396 
1397 /*
1398  * IoGetAttachedDeviceReference
1399  *
1400  * Status
1401  * @implemented
1402  */
1404 NTAPI
1406 {
1407  /* Reference the Attached Device */
1410  return DeviceObject;
1411 }
1412 
1413 /*
1414  * @implemented
1415  */
1417 NTAPI
1419 {
1420  /* Reference the lowest attached device */
1423  return DeviceObject;
1424 }
1425 
1426 /*
1427  * IoGetDeviceObjectPointer
1428  *
1429  * Status
1430  * @implemented
1431  */
1432 NTSTATUS
1433 NTAPI
1438 {
1439  /* Call the helper routine for a normal operation */
1441  DesiredAccess,
1442  FileObject,
1443  DeviceObject,
1444  0);
1445 }
1446 
1447 /*
1448  * @implemented
1449  */
1450 NTSTATUS
1451 NTAPI
1452 IoGetDiskDeviceObject(IN PDEVICE_OBJECT FileSystemDeviceObject,
1454 {
1455  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1456  PVPB Vpb;
1457  KIRQL OldIrql;
1458  NTSTATUS Status;
1459 
1460  /* Make sure there's a VPB */
1461  if (!FileSystemDeviceObject->Vpb) return STATUS_INVALID_PARAMETER;
1462 
1463  /* Acquire it */
1465 
1466  /* Get the Device Extension */
1467  DeviceExtension = IoGetDevObjExtension(FileSystemDeviceObject);
1468 
1469  /* Make sure this one has a VPB too */
1470  Vpb = DeviceExtension->Vpb;
1471  if (Vpb)
1472  {
1473  /* Make sure that it's mounted */
1474  if ((Vpb->ReferenceCount) &&
1475  (Vpb->Flags & VPB_MOUNTED))
1476  {
1477  /* Return the Disk Device Object */
1478  *DiskDeviceObject = Vpb->RealDevice;
1479 
1480  /* Reference it and return success */
1481  ObReferenceObject(Vpb->RealDevice);
1483  }
1484  else
1485  {
1486  /* It's not, so return failure */
1488  }
1489  }
1490  else
1491  {
1492  /* Fail */
1494  }
1495 
1496  /* Release the lock */
1498  return Status;
1499 }
1500 
1501 /*
1502  * @implemented
1503  */
1505 NTAPI
1507 {
1508  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1510 
1511  /* Make sure it's not getting deleted */
1512  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1513  if (!(DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |
1517  {
1518  /* Get the Lower Device Object */
1519  LowerDeviceObject = DeviceExtension->AttachedTo;
1520 
1521  /* Check that we got a valid device object */
1522  if (LowerDeviceObject)
1523  {
1524  /* We did so let's reference it */
1526  }
1527  }
1528 
1529  /* Return it */
1530  return LowerDeviceObject;
1531 }
1532 
1533 /*
1534  * @implemented
1535  */
1537 NTAPI
1539 {
1540  PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
1541 
1542  /* Check if we have a VPB with a device object */
1543  if ((FileObject->Vpb) && (FileObject->Vpb->DeviceObject))
1544  {
1545  /* Then use the DO from the VPB */
1547  DeviceObject = FileObject->Vpb->DeviceObject;
1548  }
1549  else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
1550  (FileObject->DeviceObject->Vpb) &&
1551  (FileObject->DeviceObject->Vpb->DeviceObject))
1552  {
1553  /* The disk device actually has a VPB, so get the DO from there */
1554  DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
1555  }
1556  else
1557  {
1558  /* Otherwise, this was a direct open */
1559  DeviceObject = FileObject->DeviceObject;
1560  }
1561 
1562  /* Sanity check */
1563  ASSERT(DeviceObject != NULL);
1564 
1565  /* Check if we were attached */
1566  if (DeviceObject->AttachedDevice)
1567  {
1568  /* Check if the file object has an extension present */
1570  {
1571  /* Sanity check, direct open files can't have this */
1573 
1574  /* Check if the extension is really present */
1575  if (FileObject->FileObjectExtension)
1576  {
1577  PFILE_OBJECT_EXTENSION FileObjectExtension;
1578 
1579  /* Cast the buffer to something we understand */
1580  FileObjectExtension = FileObject->FileObjectExtension;
1581 
1582  /* Check if have a valid replacement top level device */
1583  if (FileObjectExtension->TopDeviceObjectHint &&
1585  FileObjectExtension->TopDeviceObjectHint))
1586  {
1587  /* Use this instead of returning the top level device */
1588  return FileObjectExtension->TopDeviceObjectHint;
1589  }
1590  }
1591  }
1592 
1593  /* Return the highest attached device */
1595  }
1596 
1597  /* Return the DO we found */
1598  return DeviceObject;
1599 }
1600 
1601 /*
1602  * @implemented
1603  */
1604 NTSTATUS
1605 NTAPI
1608 {
1609  NTSTATUS Status;
1611 
1612  /* Call the internal helper function */
1614  if (NT_SUCCESS(Status) && DeviceNode)
1615  {
1616  *DeviceObject = DeviceNode->PhysicalDeviceObject;
1617  }
1618  return Status;
1619 }
1620 
1621 /*
1622  * @implemented
1623  */
1625 NTAPI
1627 {
1629 
1630  /*
1631  * If the FILE_OBJECT's VPB is defined,
1632  * get the device from it.
1633  */
1634  if ((FileObject->Vpb) && (FileObject->Vpb->DeviceObject))
1635  {
1636  /* Use the VPB's Device Object's */
1637  DeviceObject = FileObject->Vpb->DeviceObject;
1638  }
1639  else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
1640  (FileObject->DeviceObject->Vpb) &&
1641  (FileObject->DeviceObject->Vpb->DeviceObject))
1642  {
1643  /* Use the VPB's File System Object */
1644  DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
1645  }
1646  else
1647  {
1648  /* Use the FO's Device Object */
1649  DeviceObject = FileObject->DeviceObject;
1650  }
1651 
1652  /* Return the device object we found */
1653  ASSERT(DeviceObject != NULL);
1654  return DeviceObject;
1655 }
1656 
1657 /*
1658  * @implemented
1659  */
1660 NTSTATUS
1661 NTAPI
1663 {
1665 
1666  /* Allocate the shutdown entry */
1668  sizeof(SHUTDOWN_ENTRY),
1670  if (!Entry) return STATUS_INSUFFICIENT_RESOURCES;
1671 
1672  /* Set the DO */
1673  Entry->DeviceObject = DeviceObject;
1674 
1675  /* Reference it so it doesn't go away */
1677 
1678  /* Insert it into the list */
1680  &Entry->ShutdownList,
1681  &ShutdownListLock);
1682 
1683  /* Set the shutdown registered flag */
1685  return STATUS_SUCCESS;
1686 }
1687 
1688 /*
1689  * @implemented
1690  */
1691 NTSTATUS
1692 NTAPI
1694 {
1696 
1697  /* Allocate the shutdown entry */
1699  sizeof(SHUTDOWN_ENTRY),
1701  if (!Entry) return STATUS_INSUFFICIENT_RESOURCES;
1702 
1703  /* Set the DO */
1704  Entry->DeviceObject = DeviceObject;
1705 
1706  /* Reference it so it doesn't go away */
1708 
1709  /* Insert it into the list */
1711  &Entry->ShutdownList,
1712  &ShutdownListLock);
1713 
1714  /* Set the shutdown registered flag */
1716  return STATUS_SUCCESS;
1717 }
1718 
1719 /*
1720  * @implemented
1721  */
1722 VOID
1723 NTAPI
1725 {
1726  PSHUTDOWN_ENTRY ShutdownEntry;
1727  PLIST_ENTRY NextEntry;
1728  KIRQL OldIrql;
1729 
1730  /* Remove the flag */
1732 
1733  /* Acquire the shutdown lock and loop the shutdown list */
1735  NextEntry = ShutdownListHead.Flink;
1736  while (NextEntry != &ShutdownListHead)
1737  {
1738  /* Get the entry */
1739  ShutdownEntry = CONTAINING_RECORD(NextEntry,
1741  ShutdownList);
1742 
1743  /* Get if the DO matches */
1744  if (ShutdownEntry->DeviceObject == DeviceObject)
1745  {
1746  /* Remove it from the list */
1747  RemoveEntryList(NextEntry);
1748  NextEntry = NextEntry->Blink;
1749 
1750  /* Free the entry */
1751  ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
1752 
1753  /* Get rid of our reference to it */
1755  }
1756 
1757  /* Go to the next entry */
1758  NextEntry = NextEntry->Flink;
1759  }
1760 
1761  /* Now loop the last chance list */
1762  NextEntry = LastChanceShutdownListHead.Flink;
1763  while (NextEntry != &LastChanceShutdownListHead)
1764  {
1765  /* Get the entry */
1766  ShutdownEntry = CONTAINING_RECORD(NextEntry,
1768  ShutdownList);
1769 
1770  /* Get if the DO matches */
1771  if (ShutdownEntry->DeviceObject == DeviceObject)
1772  {
1773  /* Remove it from the list */
1774  RemoveEntryList(NextEntry);
1775  NextEntry = NextEntry->Blink;
1776 
1777  /* Free the entry */
1778  ExFreePoolWithTag(ShutdownEntry, TAG_SHUTDOWN_ENTRY);
1779 
1780  /* Get rid of our reference to it */
1782  }
1783 
1784  /* Go to the next entry */
1785  NextEntry = NextEntry->Flink;
1786  }
1787 
1788  /* Release the shutdown lock */
1790 }
1791 
1792 /*
1793  * @implemented
1794  */
1795 VOID
1796 NTAPI
1798  IN BOOLEAN DeferredStartIo,
1799  IN BOOLEAN NonCancelable)
1800 {
1801  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1802 
1803  /* Get the Device Extension */
1804  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1805 
1806  /* Set the flags the caller requested */
1807  DeviceExtension->StartIoFlags |= (DeferredStartIo) ? DOE_SIO_DEFERRED : 0;
1808  DeviceExtension->StartIoFlags |= (NonCancelable) ? DOE_SIO_NO_CANCEL : 0;
1809 }
1810 
1811 /*
1812  * @implemented
1813  */
1814 VOID
1815 NTAPI
1818  IN ULONG Key)
1819 {
1820  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1821 
1822  /* Get the Device Extension */
1823  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1824 
1825  /* Check if deferred start was requested */
1826  if (DeviceExtension->StartIoFlags & DOE_SIO_DEFERRED)
1827  {
1828  /* Call our internal function to handle the defered case */
1830  Key,
1832  (Cancelable ? DOE_SIO_CANCELABLE : 0));
1833  }
1834  else
1835  {
1836  /* Call the normal routine */
1838  }
1839 }
1840 
1841 /*
1842  * @implemented
1843  */
1844 VOID
1845 NTAPI
1848 {
1849  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1850 
1851  /* Get the Device Extension */
1852  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1853 
1854  /* Check if deferred start was requested */
1855  if (DeviceExtension->StartIoFlags & DOE_SIO_DEFERRED)
1856  {
1857  /* Call our internal function to handle the defered case */
1859  0,
1860  DOE_SIO_NO_KEY |
1861  (Cancelable ? DOE_SIO_CANCELABLE : 0));
1862  }
1863  else
1864  {
1865  /* Call the normal routine */
1867  }
1868 }
1869 
1870 /*
1871  * @implemented
1872  */
1873 VOID
1874 NTAPI
1876  IN PIRP Irp,
1877  IN PULONG Key,
1879 {
1880  BOOLEAN Stat;
1881  KIRQL OldIrql, CancelIrql;
1882 
1883  /* Raise to dispatch level */
1885 
1886  /* Check if we should acquire the cancel lock */
1887  if (CancelFunction)
1888  {
1889  /* Acquire and set it */
1890  IoAcquireCancelSpinLock(&CancelIrql);
1891  Irp->CancelRoutine = CancelFunction;
1892  }
1893 
1894  /* Check if we have a key */
1895  if (Key)
1896  {
1897  /* Insert by key */
1898  Stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
1899  &Irp->Tail.Overlay.DeviceQueueEntry,
1900  *Key);
1901  }
1902  else
1903  {
1904  /* Insert without a key */
1905  Stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
1906  &Irp->Tail.Overlay.DeviceQueueEntry);
1907  }
1908 
1909  /* Check if this was a first insert */
1910  if (!Stat)
1911  {
1912  /* Set the IRP */
1913  DeviceObject->CurrentIrp = Irp;
1914 
1915  /* Check if this is a cancelable packet */
1916  if (CancelFunction)
1917  {
1918  /* Check if the caller requested no cancellation */
1919  if (IoGetDevObjExtension(DeviceObject)->StartIoFlags &
1921  {
1922  /* He did, so remove the cancel routine */
1923  Irp->CancelRoutine = NULL;
1924  }
1925 
1926  /* Release the cancel lock */
1927  IoReleaseCancelSpinLock(CancelIrql);
1928  }
1929 
1930  /* Call the Start I/O function */
1931  DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
1932  }
1933  else
1934  {
1935  /* The packet was inserted... check if we have a cancel function */
1936  if (CancelFunction)
1937  {
1938  /* Check if the IRP got cancelled */
1939  if (Irp->Cancel)
1940  {
1941  /*
1942  * Set the cancel IRQL, clear the currnet cancel routine and
1943  * call ours
1944  */
1945  Irp->CancelIrql = CancelIrql;
1946  Irp->CancelRoutine = NULL;
1948  }
1949  else
1950  {
1951  /* Otherwise, release the lock */
1952  IoReleaseCancelSpinLock(CancelIrql);
1953  }
1954  }
1955  }
1956 
1957  /* Return back to previous IRQL */
1959 }
1960 
1961 #if defined (_WIN64)
1962 ULONG
1963 NTAPI
1966 {
1967  UNIMPLEMENTED;
1968  return 0;
1969 }
1970 #endif
1971 
1972 /* EOF */
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:27
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:98
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
PDEVICE_OBJECT DeviceObject
Definition: io.h:450
LIST_ENTRY ShutdownListHead
Definition: device.c:21
#define IN
Definition: typedefs.h:38
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2117
DRIVER_CANCEL * PDRIVER_CANCEL
Definition: iotypes.h:2404
PSECURITY_DESCRIPTOR NTAPI IopCreateDefaultDeviceSecurityDescriptor(IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN HasDeviceName, IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PACL *OutputDacl, OUT PULONG OutputFlags)
Definition: device.c:778
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PDEVICE_OBJECT NTAPI IopGetLowestDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:311
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:1420
ERESOURCE IopDatabaseResource
Definition: volume.c:25
NTSTATUS NTAPI IoAttachDevice(PDEVICE_OBJECT SourceDevice, PUNICODE_STRING TargetDeviceName, PDEVICE_OBJECT *AttachedDevice)
Definition: device.c:913
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI ObDereferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count)
Definition: obsdcach.c:287
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
PACL SePublicDefaultUnrestrictedDacl
Definition: acl.c:24
#define FILE_DEVICE_NETWORK
Definition: winioctl.h:123
Type
Definition: Type.h:6
struct _Entry Entry
Definition: kefuncs.h:640
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:137
VOID NTAPI IopEditDeviceList(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN IOP_DEVICE_LIST_OPERATION Type)
Definition: device.c:334
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT _In_ PDEVICE_OBJECT TargetDevice
Definition: iofuncs.h:688
KSPIN_LOCK ShutdownListLock
Definition: device.c:22
#define DOE_SIO_NO_CANCEL
Definition: iotypes.h:162
#define FO_DIRECT_DEVICE_OPEN
Definition: iotypes.h:1743
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define FILE_DEVICE_DFS_FILE_SYSTEM
Definition: winioctl.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
USHORT AclSize
Definition: ms-dtyp.idl:296
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
PACL SeSystemDefaultDacl
Definition: acl.c:23
DeviceType
Definition: mmdrv.h:41
#define FILE_DEVICE_FILE_SYSTEM
Definition: winioctl.h:114
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI IopGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject, IN ULONG AttachFlag)
Definition: device.c:263
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:26
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1201
#define OBJ_PERMANENT
Definition: winternl.h:226
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1295
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1434
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT SourceDevice
Definition: iofuncs.h:688
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
#define FILE_DEVICE_MASS_STORAGE
Definition: imports.h:62
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1538
IRP
Definition: iotypes.h:2462
#define TAG_IO_TIMER
Definition: tag.h:101
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS NTAPI IoEnumerateDeviceObjectList(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT *DeviceObjectList, IN ULONG DeviceObjectListSize, OUT PULONG ActualNumberDeviceObjects)
Definition: device.c:1321
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 DOE_START_PENDING
Definition: iotypes.h:153
#define PAGED_CODE()
Definition: video.h:57
LIST_ENTRY LastChanceShutdownListHead
Definition: device.c:21
#define DOE_SIO_WITH_KEY
Definition: iotypes.h:159
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
PDEVICE_OBJECT NTAPI IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1418
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
VOID NTAPI IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
Definition: device.c:34
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG IopDeviceObjectNumber
Definition: device.c:20
HANDLE FileHandle
Definition: stats.c:38
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID NTAPI IopDeleteDevice(IN PVOID ObjectBody)
Definition: device.c:52
PDEVICE_OBJECT NTAPI IopAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, OUT PDEVICE_OBJECT *AttachedToDeviceObject OPTIONAL)
Definition: device.c:70
PACL SePublicOpenDacl
Definition: acl.c:25
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:27
#define FILE_READ_DATA
Definition: nt_native.h:628
#define GENERIC_WRITE
Definition: nt_native.h:90
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
Definition: card.h:12
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
#define IO_TYPE_DEVICE
BOOLEAN NTAPI KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey)
Definition: devqueue.c:83
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1875
#define TAG_SHUTDOWN_ENTRY
Definition: tag.h:37
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IO_TYPE_DEVICE_OBJECT_EXTENSION
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
void DPRINT(...)
Definition: polytest.cpp:61
PDEVICE_OBJECT NTAPI IoGetLowerDeviceObject(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1506
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
VOID NTAPI IopStartNextPacketByKeyEx(IN PDEVICE_OBJECT DeviceObject, IN ULONG Key, IN ULONG Flags)
Definition: device.c:583
_In_ PCUNICODE_STRING _In_ PVOID Driver
Definition: cmfuncs.h:32
#define FILE_WRITE_DATA
Definition: nt_native.h:631
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
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1405
#define DO_SHUTDOWN_REGISTERED
Definition: env_spec_w32.h:403
BOOLEAN NTAPI IopVerifyDeviceObjectOnStack(IN PDEVICE_OBJECT BaseDeviceObject, IN PDEVICE_OBJECT TopDeviceObjectHint)
Definition: device.c:695
#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
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
Definition: io.h:248
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
PDEVICE_OBJECT AttachedTo
Definition: iotypes.h:920
_Outptr_ PDEVICE_OBJECT * DiskDeviceObject
Definition: fltkernel.h:1673
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define DO_DEVICE_HAS_NAME
Definition: env_spec_w32.h:398
#define DOE_SIO_DEFERRED
Definition: iotypes.h:161
#define DRVO_INITIALIZED
Definition: iotypes.h:4113
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:980
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1797
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
VOID NTAPI IoShutdownPnpDevices(VOID)
Definition: device.c:125
VOID NTAPI IopRemoveTimerFromTimerList(IN PIO_TIMER Timer)
Definition: iotimer.c:70
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
BOOLEAN NTAPI KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
Definition: devqueue.c:41
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
NTSTATUS NTAPI IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1662
#define IO_ATTACH_DEVICE_API
Definition: iotypes.h:209
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1724
VOID NTAPI PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: povolume.c:83
* PFILE_OBJECT
Definition: iotypes.h:1954
VOID NTAPI IoShutdownSystem(IN ULONG Phase)
Definition: device.c:133
Definition: Node.h:9
_In_ BOOLEAN Cancelable
Definition: iofuncs.h:1255
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2060
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
NTSTATUS NTAPI IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:155
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
struct _DEVICE_OBJECT DEVICE_OBJECT
PSID SeAliasAdminsSid
Definition: sid.c:47
NTSTATUS NTAPI IoGetDiskDeviceObject(IN PDEVICE_OBJECT FileSystemDeviceObject, OUT PDEVICE_OBJECT *DiskDeviceObject)
Definition: device.c:1452
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI IopGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, OUT PDEVICE_NODE *DeviceNode)
Definition: device.c:653
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define FO_FILE_OBJECT_HAS_EXTENSION
Definition: iotypes.h:144
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2179
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:789
NTSTATUS NTAPI IoGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1606
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define GENERIC_READ
Definition: compat.h:124
Definition: typedefs.h:117
#define DOE_REMOVE_PROCESSED
Definition: iotypes.h:152
PSID SeWorldSid
Definition: sid.c:31
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define Stat
Definition: syshdrs.h:78
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
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
UINT Timer
Definition: capclock.c:11
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
Definition: volume.c:346
_In_ PIRP _In_opt_ PULONG _In_opt_ PDRIVER_CANCEL CancelFunction
Definition: iofuncs.h:1272
Definition: ketypes.h:566
unsigned short USHORT
Definition: pedump.c:61
PACL SePublicDefaultDacl
Definition: acl.c:22
#define DACL_SET
Definition: device.c:28
VOID NTAPI IoStartNextPacketByKey(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable, IN ULONG Key)
Definition: device.c:1816
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1384
VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:390
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1513
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
enum _IOP_DEVICE_LIST_OPERATION IOP_DEVICE_LIST_OPERATION
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
#define DEVICE_TYPE
Definition: guid.c:10
PDEVICE_OBJECT NTAPI IoGetBaseFileSystemDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1626
unsigned int * PULONG
Definition: retypes.h:1
#define DOE_SIO_CANCELABLE
Definition: iotypes.h:160
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MN_QUERY_DEVICE_RELATIONS
struct _DEVOBJ_EXTENSION * PDEVOBJ_EXTENSION
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey)
Definition: devqueue.c:197
#define DPRINT1
Definition: precomp.h:8
enum _SECURITY_DESCRIPTOR_TYPE SECURITY_DESCRIPTOR_TYPE
VOID NTAPI PoRemoveVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: povolume.c:105
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1693
#define FILE_DEVICE_TAPE
Definition: winioctl.h:136
Definition: iotypes.h:166
#define OUT
Definition: typedefs.h:39
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
#define ObReferenceObject
Definition: obfuncs.h:204
PACL SePublicOpenUnrestrictedDacl
Definition: acl.c:26
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:733
VOID NTAPI IopStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:535
NTSTATUS NTAPI IopCreateSecurityDescriptorPerType(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN SECURITY_DESCRIPTOR_TYPE Type, OUT PULONG OutputFlags)
Definition: device.c:729
#define DO_EXCLUSIVE
Definition: env_spec_w32.h:395
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IopStartNextPacketByKey(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable, IN ULONG Key)
Definition: device.c:486
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS IopFreeDeviceNode(IN PDEVICE_NODE DeviceNode)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define DOE_SIO_NO_KEY
Definition: iotypes.h:158
NTSTATUS NTAPI IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:947
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define GENERIC_EXECUTE
Definition: nt_native.h:91
return STATUS_SUCCESS
Definition: btrfs.c:2745
Definition: io.h:447
#define IoWMIDeviceObjectToProviderId(DeviceObject)
Definition: io.h:249
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define VPB_MOUNTED
Definition: iotypes.h:1763
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI PoInitializeDeviceObject(IN OUT PDEVOBJ_EXTENSION DeviceObjectExtension)
Definition: povolume.c:363
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1212
POBJECT_TYPE IoDeviceObjectType
Definition: iomgr.c:35
ULONG ACCESS_MASK
Definition: nt_native.h:40
base of all file and directory entries
Definition: entries.h:82
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING DriverName
Definition: iotypes.h:2174
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2168
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1846
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68