ReactOS  0.4.14-dev-50-g13bb5e2
file.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/file.c
5  * PURPOSE: Functions that deal with managing the FILE_OBJECT itself.
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Gunnar Dalsnes
8  * Eric Kohl
9  * Filip Navara (navaraf@reactos.org)
10  * Pierre Schweitzer
11  */
12 
13 /* INCLUDES *****************************************************************/
14 
15 #include <ntoskrnl.h>
16 #define NDEBUG
17 #include <debug.h>
18 
20 
21 /* PRIVATE FUNCTIONS *********************************************************/
22 
23 VOID
24 NTAPI
29 {
32  BOOLEAN AccessGranted, HaveBackupPriv = FALSE, CheckRestore = FALSE;
33  PAGED_CODE();
34 
35  /* Don't do anything if privileges were checked already */
36  if (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED) return;
37 
38  /* Check if the file was actually opened for backup purposes */
40  {
41  /* Set the check flag since were doing it now */
43 
44  /* Set the access masks required */
50  WRITE_OWNER |
55  DELETE;
56  DesiredAccess = AccessState->RemainingDesiredAccess;
57 
58  /* Check if desired access was the maximum */
60  {
61  /* Then add all the access masks required */
63  }
64 
65  /* Check if the file already exists */
66  if (Disposition & FILE_OPEN)
67  {
68  /* Check if desired access has the read mask */
70  {
71  /* Setup the privilege check lookup */
72  Privileges.PrivilegeCount = 1;
74  Privileges.Privilege[0].Luid = SeBackupPrivilege;
75  Privileges.Privilege[0].Attributes = 0;
77  &AccessState->
79  PreviousMode);
80  if (AccessGranted)
81  {
82  /* Remember that backup was allowed */
83  HaveBackupPriv = TRUE;
84 
85  /* Append the privileges and update the access state */
87  AccessState->PreviouslyGrantedAccess |= (DesiredAccess & ReadAccess);
88  AccessState->RemainingDesiredAccess &= ~ReadAccess;
90 
91  /* Set backup privilege for the token */
93  }
94  }
95  }
96  else
97  {
98  /* Caller is creating the file, check restore privileges later */
99  CheckRestore = TRUE;
100  }
101 
102  /* Check if caller wants write access or if it's creating a file */
103  if ((WriteAccess & DesiredAccess) || (CheckRestore))
104  {
105  /* Setup the privilege lookup and do it */
106  Privileges.PrivilegeCount = 1;
108  Privileges.Privilege[0].Luid = SeRestorePrivilege;
109  Privileges.Privilege[0].Attributes = 0;
111  &AccessState->SubjectSecurityContext,
112  PreviousMode);
113  if (AccessGranted)
114  {
115  /* Remember that privilege was given */
116  HaveBackupPriv = TRUE;
117 
118  /* Append the privileges and update the access state */
120  AccessState->PreviouslyGrantedAccess |= (DesiredAccess & WriteAccess);
121  AccessState->RemainingDesiredAccess &= ~WriteAccess;
122 
123  /* Set restore privilege for the token */
125  }
126  }
127 
128  /* If we don't have the privilege, remove the option */
129  if (!HaveBackupPriv) *CreateOptions &= ~FILE_OPEN_FOR_BACKUP_INTENT;
130  }
131 }
132 
133 NTSTATUS
134 NTAPI
137 {
138  /* Make sure the object is valid */
139  if ((IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
145  {
146  /* It's unloading or initializing, so fail */
147  DPRINT1("You are seeing this because the following ROS driver: %wZ\n"
148  " sucks. Please fix it's AddDevice Routine\n",
149  &DeviceObject->DriverObject->DriverName);
150  return STATUS_NO_SUCH_DEVICE;
151  }
152  else if ((DeviceObject->Flags & DO_EXCLUSIVE) &&
153  (DeviceObject->ReferenceCount) &&
154  !(OpenPacket->RelatedFileObject) &&
155  !(OpenPacket->Options & IO_ATTACH_DEVICE))
156  {
157  return STATUS_ACCESS_DENIED;
158  }
159 
160  else
161  {
162  /* Increase reference count */
163  InterlockedIncrement(&DeviceObject->ReferenceCount);
164  return STATUS_SUCCESS;
165  }
166 }
167 
168 VOID
169 NTAPI
172  IN PREPARSE_DATA_BUFFER DataBuffer)
173 {
174  PWSTR Buffer;
175  USHORT Length;
177  PWSTR NewBuffer;
178 
179  PAGED_CODE();
180 
181  ASSERT(Irp->IoStatus.Status == STATUS_REPARSE);
182  ASSERT(Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT);
183  ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
184  ASSERT(DataBuffer != NULL);
185  ASSERT(DataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT);
186  ASSERT(DataBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
187  ASSERT(DataBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
188 
189  /* First of all, validate data */
190  if (DataBuffer->ReparseDataLength < REPARSE_DATA_BUFFER_HEADER_SIZE ||
191  (DataBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
192  DataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength +
194  {
195  Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
196  }
197 
198  /* Everything went right */
199  if (NT_SUCCESS(Irp->IoStatus.Status))
200  {
201  /* Compute buffer & length */
202  Buffer = (PWSTR)((ULONG_PTR)DataBuffer->MountPointReparseBuffer.PathBuffer +
203  DataBuffer->MountPointReparseBuffer.SubstituteNameOffset);
204  Length = DataBuffer->MountPointReparseBuffer.SubstituteNameLength;
205 
206  /* Check we don't overflow */
207  if (((ULONG)MAXUSHORT - DataBuffer->Reserved) <= (Length + sizeof(UNICODE_NULL)))
208  {
209  Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
210  }
211  else
212  {
213  /* Compute how much memory we'll need */
214  RequiredLength = DataBuffer->Reserved + Length + sizeof(UNICODE_NULL);
215 
216  /* Check if FileObject can already hold what we need */
217  if (FileObject->FileName.MaximumLength >= RequiredLength)
218  {
219  NewBuffer = FileObject->FileName.Buffer;
220  }
221  else
222  {
223  /* Allocate otherwise */
225  if (NewBuffer == NULL)
226  {
227  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
228  }
229  }
230  }
231  }
232 
233  /* Everything went right */
234  if (NT_SUCCESS(Irp->IoStatus.Status))
235  {
236  /* Copy the reserved data */
237  if (DataBuffer->Reserved)
238  {
239  RtlMoveMemory((PWSTR)((ULONG_PTR)NewBuffer + Length),
240  (PWSTR)((ULONG_PTR)FileObject->FileName.Buffer + FileObject->FileName.Length - DataBuffer->Reserved),
241  DataBuffer->Reserved);
242  }
243 
244  /* Then the buffer */
245  if (Length)
246  {
247  RtlCopyMemory(NewBuffer, Buffer, Length);
248  }
249 
250  /* And finally replace buffer if new one was allocated */
251  FileObject->FileName.Length = RequiredLength - sizeof(UNICODE_NULL);
252  if (NewBuffer != FileObject->FileName.Buffer)
253  {
254  if (FileObject->FileName.Buffer)
255  {
256  /*
257  * Don't use TAG_IO_NAME since the FileObject's FileName
258  * may have been re-allocated using a different tag
259  * by a filesystem.
260  */
261  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
262  }
263 
264  FileObject->FileName.Buffer = NewBuffer;
265  FileObject->FileName.MaximumLength = RequiredLength;
266  FileObject->FileName.Buffer[RequiredLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
267  }
268  }
269 
270  /* We don't need them anymore - it was allocated by the driver */
271  ExFreePool(DataBuffer);
272 }
273 
274 NTSTATUS
276  IN POPEN_PACKET OpenPacket,
277  BOOLEAN DirectOpen)
278 {
281 
283 
284  /* Direct open is not allowed */
285  if (DirectOpen)
286  {
288  }
289 
290  /* Validate we have a file system device */
291  DeviceType = LocalDevice->DeviceType;
297  {
299  }
300 
301  /* Verify the hint and if it's OK, return it */
302  if (IopVerifyDeviceObjectOnStack(LocalDevice, OpenPacket->TopDeviceObjectHint))
303  {
304  *DeviceObject = OpenPacket->TopDeviceObjectHint;
305  return STATUS_SUCCESS;
306  }
307 
308  /* Failure case here */
309  /* If we thought was had come through a mount point,
310  * actually update we didn't and return the error
311  */
312  if (OpenPacket->TraversedMountPoint)
313  {
314  OpenPacket->TraversedMountPoint = FALSE;
316  }
317 
318  /* Otherwise, just return the fact the hint is invalid */
320 }
321 
322 NTSTATUS
323 NTAPI
324 IopParseDevice(IN PVOID ParseObject,
329  IN OUT PUNICODE_STRING CompleteName,
333  OUT PVOID *Object)
334 {
335  POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
336  PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject;
337  PDEVICE_OBJECT DeviceObject, OwnerDevice;
340  PVPB Vpb = NULL;
341  PIRP Irp;
342  PIO_STACK_LOCATION StackLoc;
343  IO_SECURITY_CONTEXT SecurityContext;
345  BOOLEAN DirectOpen = FALSE, OpenCancelled, UseDummyFile;
347  KIRQL OldIrql;
348  PDUMMY_FILE_OBJECT LocalFileObject;
349  PFILE_BASIC_INFORMATION FileBasicInfo;
351  KPROCESSOR_MODE CheckMode;
352  BOOLEAN VolumeOpen = FALSE;
354  BOOLEAN AccessGranted, LockHeld = FALSE;
356  UNICODE_STRING FileString;
357  USHORT Attempt;
358  IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n",
359  ParseObject, RemainingName);
360 
361  for (Attempt = 0; Attempt < IOP_MAX_REPARSE_TRAVERSAL; ++Attempt)
362  {
363  /* Assume failure */
364  *Object = NULL;
365 
366  /* Validate the open packet */
367  if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
368 
369  /* Valide reparse point in case we traversed a mountpoint */
370  if (OpenPacket->TraversedMountPoint)
371  {
372  /* This is a reparse point we understand */
374 
375  /* Make sure we're dealing with correct DO */
376  if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK &&
377  OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM &&
378  OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
379  OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE)
380  {
383  }
384  }
385 
386  /* Check if we have a related file object */
387  if (OpenPacket->RelatedFileObject)
388  {
389  /* Use the related file object's device object */
390  OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
391  }
392 
393  /* Validate device status */
394  Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject);
395  if (!NT_SUCCESS(Status))
396  {
397  /* We failed, return status */
398  OpenPacket->FinalStatus = Status;
399  return Status;
400  }
401 
402  /* Map the generic mask and set the new mapping in the access state */
403  RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
405  RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
409  DesiredAccess = AccessState->RemainingDesiredAccess;
410 
411  /* Check what kind of access checks to do */
412  if ((AccessMode != KernelMode) ||
413  (OpenPacket->Options & IO_FORCE_ACCESS_CHECK))
414  {
415  /* Call is from user-mode or kernel is forcing checks */
416  CheckMode = UserMode;
417  }
418  else
419  {
420  /* Call is from the kernel */
421  CheckMode = KernelMode;
422  }
423 
424  /* Check privilege for backup or restore operation */
426  &OpenPacket->CreateOptions,
427  CheckMode,
428  OpenPacket->Disposition);
429 
430  /* Check if we are re-parsing */
431  if (((OpenPacket->Override) && !(RemainingName->Length)) ||
433  {
434  /* Get granted access from the last call */
435  DesiredAccess |= AccessState->PreviouslyGrantedAccess;
436  }
437 
438  /* Check if this is a volume open */
439  if ((OpenPacket->RelatedFileObject) &&
440  (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
441  !(RemainingName->Length))
442  {
443  /* It is */
444  VolumeOpen = TRUE;
445  }
446 
447  /* Now check if we need access checks */
448  if (((AccessMode != KernelMode) ||
449  (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) &&
450  (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) &&
451  !(OpenPacket->Override))
452  {
455 
456  /* Check if a device object is being parsed */
457  if (!RemainingName->Length)
458  {
459  /* Lock the subject context */
460  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
461  LockHeld = TRUE;
462 
463  /* Do access check */
464  AccessGranted = SeAccessCheck(OriginalDeviceObject->
466  &AccessState->SubjectSecurityContext,
467  LockHeld,
469  0,
470  &Privileges,
472  TypeInfo.GenericMapping,
473  UserMode,
474  &GrantedAccess,
475  &Status);
476  if (Privileges)
477  {
478  /* Append and free the privileges */
481  }
482 
483  /* Check if we got access */
484  if (AccessGranted)
485  {
486  /* Update access state */
487  AccessState->PreviouslyGrantedAccess |= GrantedAccess;
488  AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
490  OpenPacket->Override= TRUE;
491  }
492 
493  FileString.Length = 8;
494  FileString.MaximumLength = 8;
495  FileString.Buffer = L"File";
496 
497  /* Do Audit/Alarm for open operation */
498  SeOpenObjectAuditAlarm(&FileString,
499  OriginalDeviceObject,
500  CompleteName,
501  OriginalDeviceObject->SecurityDescriptor,
502  AccessState,
503  FALSE,
505  UserMode,
506  &AccessState->GenerateOnClose);
507  }
508  else
509  {
510  /* Check if we need to do traverse validation */
511  if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) ||
512  ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
513  (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM)))
514  {
515  /* Check if this is a restricted token */
516  if (!(AccessState->Flags & TOKEN_IS_RESTRICTED))
517  {
518  /* Do the FAST traverse check */
519  AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor,
520  AccessState,
522  UserMode);
523  }
524  else
525  {
526  /* Fail */
528  }
529 
530  /* Check if we failed to get access */
531  if (!AccessGranted)
532  {
533  /* Lock the subject context */
534  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
535  LockHeld = TRUE;
536 
537  /* Do access check */
538  AccessGranted = SeAccessCheck(OriginalDeviceObject->
540  &AccessState->SubjectSecurityContext,
541  LockHeld,
543  0,
544  &Privileges,
546  TypeInfo.GenericMapping,
547  UserMode,
548  &GrantedAccess,
549  &Status);
550  if (Privileges)
551  {
552  /* Append and free the privileges */
555  }
556  }
557 
558  /* FIXME: Do Audit/Alarm for traverse check */
559  }
560  else
561  {
562  /* Access automatically granted */
564  }
565  }
566 
569 
570  /* Check if we hold the lock */
571  if (LockHeld)
572  {
573  /* Release it */
574  SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
575  }
576 
577  /* Check if access failed */
578  if (!AccessGranted)
579  {
580  /* Dereference the device and fail */
581  DPRINT1("Traverse access failed!\n");
582  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
583  return STATUS_ACCESS_DENIED;
584  }
585  }
586 
587  /* Check if we can simply use a dummy file */
588  UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
589 
590  /* Check if this is a direct open */
591  if (!(RemainingName->Length) &&
592  !(OpenPacket->RelatedFileObject) &&
593  ((DesiredAccess & ~(SYNCHRONIZE |
595  READ_CONTROL |
597  WRITE_OWNER |
598  WRITE_DAC)) == 0) &&
599  !(UseDummyFile))
600  {
601  /* Remember this for later */
602  DirectOpen = TRUE;
603  }
604 
605  /* Check if we have a related FO that wasn't a direct open */
606  if ((OpenPacket->RelatedFileObject) &&
607  !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
608  {
609  /* The device object is the one we were given */
610  DeviceObject = ParseObject;
611 
612  /* Check if the related FO had a VPB */
613  if (OpenPacket->RelatedFileObject->Vpb)
614  {
615  /* Yes, remember it */
616  Vpb = OpenPacket->RelatedFileObject->Vpb;
617 
618  /* Reference it */
619  InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
620 
621  /* Check if we were given a specific top level device to use */
623  {
624  DeviceObject = Vpb->DeviceObject;
625  }
626  }
627  }
628  else
629  {
630  /* Check if it has a VPB */
631  if ((OriginalDeviceObject->Vpb) && !(DirectOpen))
632  {
633  /* Check if the VPB is mounted, and mount it */
634  Vpb = IopCheckVpbMounted(OpenPacket,
635  OriginalDeviceObject,
637  &Status);
638  if (!Vpb) return Status;
639 
640  /* Get the VPB's device object */
641  DeviceObject = Vpb->DeviceObject;
642  }
643  else
644  {
645  /* The device object is the one we were given */
646  DeviceObject = OriginalDeviceObject;
647  }
648 
649  /* If we weren't given a specific top level device, look for an attached device */
650  if (!(OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT) &&
651  DeviceObject->AttachedDevice)
652  {
653  /* Get the attached device */
655  }
656  }
657 
658  /* If we have a top level device hint, verify it */
660  {
661  Status = IopCheckTopDeviceHint(&DeviceObject, OpenPacket, DirectOpen);
662  if (!NT_SUCCESS(Status))
663  {
664  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
666  return Status;
667  }
668  }
669 
670  /* If we traversed a mount point, reset the information */
671  if (OpenPacket->TraversedMountPoint)
672  {
673  OpenPacket->TraversedMountPoint = FALSE;
674  }
675 
676  /* Check if this is a secure FSD */
677  if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
678  ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) &&
679  (!VolumeOpen))
680  {
681  Privileges = NULL;
682  GrantedAccess = 0;
683 
686 
687  /* Lock the subject context */
688  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
689 
690  /* Do access check */
691  AccessGranted = SeAccessCheck(OriginalDeviceObject->SecurityDescriptor,
692  &AccessState->SubjectSecurityContext,
693  TRUE,
695  0,
696  &Privileges,
698  UserMode,
699  &GrantedAccess,
700  &Status);
701  if (Privileges != NULL)
702  {
703  /* Append and free the privileges */
706  }
707 
708  /* Check if we got access */
709  if (GrantedAccess)
710  {
711  AccessState->PreviouslyGrantedAccess |= GrantedAccess;
712  AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED);
713  }
714 
715  FileString.Length = 8;
716  FileString.MaximumLength = 8;
717  FileString.Buffer = L"File";
718 
719  /* Do Audit/Alarm for open operation
720  * NOTA: we audit target device object
721  */
722  SeOpenObjectAuditAlarm(&FileString,
723  DeviceObject,
724  CompleteName,
725  OriginalDeviceObject->SecurityDescriptor,
726  AccessState,
727  FALSE,
729  UserMode,
730  &AccessState->GenerateOnClose);
731 
732  SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
733 
736 
737  /* Check if access failed */
738  if (!AccessGranted)
739  {
740  /* Dereference the device and fail */
741  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
743  return STATUS_ACCESS_DENIED;
744  }
745  }
746 
747  /* Allocate the IRP */
749  if (!Irp)
750  {
751  /* Dereference the device and VPB, then fail */
752  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
755  }
756 
757  /* Now set the IRP data */
758  Irp->RequestorMode = AccessMode;
760  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
761  Irp->UserIosb = &IoStatusBlock;
762  Irp->MdlAddress = NULL;
763  Irp->PendingReturned = FALSE;
764  Irp->UserEvent = NULL;
765  Irp->Cancel = FALSE;
766  Irp->CancelRoutine = NULL;
767  Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
768 
769  /* Setup the security context */
770  SecurityContext.SecurityQos = SecurityQos;
771  SecurityContext.AccessState = AccessState;
772  SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
773  SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
774 
775  /* Get the I/O Stack location */
776  StackLoc = IoGetNextIrpStackLocation(Irp);
777  StackLoc->Control = 0;
778 
779  /* Check what kind of file this is */
780  switch (OpenPacket->CreateFileType)
781  {
782  /* Normal file */
783  case CreateFileTypeNone:
784 
785  /* Set the major function and EA Length */
786  StackLoc->MajorFunction = IRP_MJ_CREATE;
787  StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
788 
789  /* Set the flags */
790  StackLoc->Flags = (UCHAR)OpenPacket->Options;
792  break;
793 
794  /* Named pipe */
796 
797  /* Set the named pipe MJ and set the parameters */
799  StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters;
800  break;
801 
802  /* Mailslot */
804 
805  /* Set the mailslot MJ and set the parameters */
807  StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters;
808  break;
809  }
810 
811  /* Set the common data */
812  Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
813  Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer;
814  StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
815  (OpenPacket->CreateOptions &
816  0xFFFFFF);
817  StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
818  StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
819  StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
820 
821  /* Check if we really need to create an object */
822  if (!UseDummyFile)
823  {
824  ULONG ObjectSize = sizeof(FILE_OBJECT);
825 
826  /* Tag on space for a file object extension */
828  ObjectSize += sizeof(FILE_OBJECT_EXTENSION);
829 
830  /* Create the actual file object */
832  NULL,
833  Attributes,
834  NULL,
835  NULL);
839  AccessMode,
840  NULL,
841  ObjectSize,
842  0,
843  0,
844  (PVOID*)&FileObject);
845  if (!NT_SUCCESS(Status))
846  {
847  /* Create failed, free the IRP */
848  IoFreeIrp(Irp);
849 
850  /* Dereference the device and VPB */
851  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
853 
854  /* We failed, return status */
855  OpenPacket->FinalStatus = Status;
856  return Status;
857  }
858 
859  /* Clear the file object */
861 
862  /* Check if this is Synch I/O */
863  if (OpenPacket->CreateOptions &
865  {
866  /* Set the synch flag */
867  FileObject->Flags |= FO_SYNCHRONOUS_IO;
868 
869  /* Check if it's also alertable */
870  if (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
871  {
872  /* It is, set the alertable flag */
873  FileObject->Flags |= FO_ALERTABLE_IO;
874  }
875  }
876 
877  /* Check if this is synch I/O */
878  if (FileObject->Flags & FO_SYNCHRONOUS_IO)
879  {
880  /* Initialize the event */
882  }
883 
884  /* Check if the caller requested no intermediate buffering */
886  {
887  /* Set the correct flag for the FSD to read */
889  }
890 
891  /* Check if the caller requested write through support */
892  if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH)
893  {
894  /* Set the correct flag for the FSD to read */
895  FileObject->Flags |= FO_WRITE_THROUGH;
896  }
897 
898  /* Check if the caller says the file will be only read sequentially */
899  if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
900  {
901  /* Set the correct flag for the FSD to read */
902  FileObject->Flags |= FO_SEQUENTIAL_ONLY;
903  }
904 
905  /* Check if the caller believes the file will be only read randomly */
906  if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
907  {
908  /* Set the correct flag for the FSD to read */
909  FileObject->Flags |= FO_RANDOM_ACCESS;
910  }
911 
912  /* Check if we were asked to setup a file object extension */
914  {
915  PFILE_OBJECT_EXTENSION FileObjectExtension;
916 
917  /* Make sure the file object knows it has an extension */
919 
920  FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
921  FileObject->FileObjectExtension = FileObjectExtension;
922 
923  /* Add the top level device which we'll send the request to */
925  {
926  FileObjectExtension->TopDeviceObjectHint = DeviceObject;
927  }
928  }
929  }
930  else
931  {
932  /* Use the dummy object instead */
933  LocalFileObject = OpenPacket->LocalFileObject;
934  RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT));
935 
936  /* Set it up */
937  FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body;
938  LocalFileObject->ObjectHeader.Type = IoFileObjectType;
939  LocalFileObject->ObjectHeader.PointerCount = 1;
940  }
941 
942  /* Setup the file header */
943  FileObject->Type = IO_TYPE_FILE;
944  FileObject->Size = sizeof(FILE_OBJECT);
945  FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
946  FileObject->DeviceObject = OriginalDeviceObject;
947 
948  /* Check if this is a direct device open */
949  if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
950 
951  /* Check if the caller wants case sensitivity */
953  {
954  /* Tell the driver about it */
956  }
957 
958  /* Now set the file object */
959  Irp->Tail.Overlay.OriginalFileObject = FileObject;
960  StackLoc->FileObject = FileObject;
961 
962  /* Check if the file object has a name */
963  if (RemainingName->Length)
964  {
965  /* Setup the unicode string */
966  FileObject->FileName.MaximumLength = RemainingName->Length + sizeof(WCHAR);
967  FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool,
968  FileObject->FileName.MaximumLength,
969  TAG_IO_NAME);
970  if (!FileObject->FileName.Buffer)
971  {
972  /* Failed to allocate the name, free the IRP */
973  IoFreeIrp(Irp);
974 
975  /* Dereference the device object and VPB */
976  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
978 
979  /* Clear the FO and dereference it */
980  FileObject->DeviceObject = NULL;
981  if (!UseDummyFile) ObDereferenceObject(FileObject);
982 
983  /* Fail */
985  }
986  }
987 
988  /* Copy the name */
990 
991  /* Initialize the File Object event and set the FO */
993  OpenPacket->FileObject = FileObject;
994 
995  /* Queue the IRP and call the driver */
998  if (Status == STATUS_PENDING)
999  {
1000  /* Wait for the driver to complete the create */
1002  Executive,
1003  KernelMode,
1004  FALSE,
1005  NULL);
1006 
1007  /* Get the new status */
1009  }
1010  else
1011  {
1012  /* We'll have to complete it ourselves */
1013  ASSERT(!Irp->PendingReturned);
1014  ASSERT(!Irp->MdlAddress);
1015 
1016  /* Handle name change if required */
1017  if (Status == STATUS_REPARSE)
1018  {
1019  /* Check this is a mount point */
1020  if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1021  {
1022  PREPARSE_DATA_BUFFER ReparseData;
1023 
1024  /* Reparse point attributes were passed by the driver in the auxiliary buffer */
1025  ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1026  ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1027 
1028  ASSERT(ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT);
1031 
1032  IopDoNameTransmogrify(Irp, FileObject, ReparseData);
1033  }
1034  }
1035 
1036  /* Completion happens at APC_LEVEL */
1038 
1039  /* Get the new I/O Status block ourselves */
1040  IoStatusBlock = Irp->IoStatus;
1042 
1043  /* Manually signal the even, we can't have any waiters */
1044  FileObject->Event.Header.SignalState = 1;
1045 
1046  /* Now that we've signaled the events, de-associate the IRP */
1048 
1049  /* Check if the IRP had an input buffer */
1050  if ((Irp->Flags & IRP_BUFFERED_IO) &&
1051  (Irp->Flags & IRP_DEALLOCATE_BUFFER))
1052  {
1053  /* Free it. A driver might've tacked one on */
1054  ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1055  }
1056 
1057  /* Free the IRP and bring the IRQL back down */
1058  IoFreeIrp(Irp);
1060  }
1061 
1062  /* Copy the I/O Status */
1063  OpenPacket->Information = IoStatusBlock.Information;
1064 
1065  /* The driver failed to create the file */
1066  if (!NT_SUCCESS(Status))
1067  {
1068  /* Check if we have a name and if so, free it */
1069  if (FileObject->FileName.Length)
1070  {
1071  /*
1072  * Don't use TAG_IO_NAME since the FileObject's FileName
1073  * may have been re-allocated using a different tag
1074  * by a filesystem.
1075  */
1076  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1077  FileObject->FileName.Buffer = NULL;
1078  FileObject->FileName.Length = 0;
1079  }
1080 
1081  /* Clear its device object */
1082  FileObject->DeviceObject = NULL;
1083 
1084  /* Save this now because the FO might go away */
1085  OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ?
1086  TRUE : FALSE;
1087 
1088  /* Clear the file object in the open packet */
1089  OpenPacket->FileObject = NULL;
1090 
1091  /* Dereference the file object */
1092  if (!UseDummyFile) ObDereferenceObject(FileObject);
1093 
1094  /* Dereference the device object */
1095  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1096 
1097  /* Unless the driver cancelled the open, dereference the VPB */
1098  if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb);
1099 
1100  /* Set the status and return */
1101  OpenPacket->FinalStatus = Status;
1102  return Status;
1103  }
1104  else if (Status == STATUS_REPARSE)
1105  {
1106  if (OpenPacket->Information == IO_REPARSE ||
1107  OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1108  {
1109  /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */
1110  if (CompleteName->MaximumLength < FileObject->FileName.Length)
1111  {
1112  PWSTR NewCompleteName;
1113 
1114  /* Allocate a new buffer for the string */
1115  NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME);
1116  if (NewCompleteName == NULL)
1117  {
1120  }
1121 
1122  /* Release the old one */
1123  if (CompleteName->Buffer != NULL)
1124  {
1125  /*
1126  * Don't use TAG_IO_NAME since the FileObject's FileName
1127  * may have been re-allocated using a different tag
1128  * by a filesystem.
1129  */
1130  ExFreePoolWithTag(CompleteName->Buffer, 0);
1131  }
1132 
1133  /* And setup the new one */
1134  CompleteName->Buffer = NewCompleteName;
1135  CompleteName->MaximumLength = FileObject->FileName.Length;
1136  }
1137 
1138  /* Copy our new complete name */
1139  RtlCopyUnicodeString(CompleteName, &FileObject->FileName);
1140 
1141  if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1142  {
1143  OpenPacket->RelatedFileObject = NULL;
1144  }
1145  }
1146 
1147  /* Check if we have a name and if so, free it */
1148  if (FileObject->FileName.Length)
1149  {
1150  /*
1151  * Don't use TAG_IO_NAME since the FileObject's FileName
1152  * may have been re-allocated using a different tag
1153  * by a filesystem.
1154  */
1155  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1156  FileObject->FileName.Buffer = NULL;
1157  FileObject->FileName.Length = 0;
1158  }
1159 
1160  /* Clear its device object */
1161  FileObject->DeviceObject = NULL;
1162 
1163  /* Clear the file object in the open packet */
1164  OpenPacket->FileObject = NULL;
1165 
1166  /* Dereference the file object */
1167  if (!UseDummyFile) ObDereferenceObject(FileObject);
1168 
1169  /* Dereference the device object */
1170  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1171 
1172  /* Unless the driver cancelled the open, dereference the VPB */
1174 
1175  if (OpenPacket->Information != IO_REMOUNT)
1176  {
1177  OpenPacket->RelatedFileObject = NULL;
1178 
1179  /* Inform we traversed a mount point for later attempt */
1180  if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1181  {
1182  OpenPacket->TraversedMountPoint = 1;
1183  }
1184 
1185  /* In case we override checks, but got this on volume open, fail hard */
1186  if (OpenPacket->Override)
1187  {
1188  KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN,
1189  (ULONG_PTR)OriginalDeviceObject,
1191  (ULONG_PTR)CompleteName,
1192  OpenPacket->Information);
1193  }
1194 
1195  /* Return to IO/OB so that information can be upgraded */
1196  return STATUS_REPARSE;
1197  }
1198 
1199  /* Loop again and reattempt an opening */
1200  continue;
1201  }
1202 
1203  break;
1204  }
1205 
1206  if (Attempt == IOP_MAX_REPARSE_TRAVERSAL)
1207  return STATUS_UNSUCCESSFUL;
1208 
1209  /* Get the owner of the File Object */
1210  OwnerDevice = IoGetRelatedDeviceObject(FileObject);
1211 
1212  /*
1213  * It's possible that the device to whom we sent the IRP to
1214  * isn't actually the device that ended opening the file object
1215  * internally.
1216  */
1217  if (OwnerDevice != DeviceObject)
1218  {
1219  /* We have to de-reference the VPB we had associated */
1221 
1222  /* And re-associate with the actual one */
1223  Vpb = FileObject->Vpb;
1224  if (Vpb) InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
1225  }
1226 
1227  /* Make sure we are not using a dummy */
1228  if (!UseDummyFile)
1229  {
1230  /* Check if this was a volume open */
1231  if ((!(FileObject->RelatedFileObject) ||
1232  (FileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN)) &&
1233  !(FileObject->FileName.Length))
1234  {
1235  /* All signs point to it, but make sure it was actually an FSD */
1236  if ((OwnerDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
1237  (OwnerDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
1238  (OwnerDevice->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) ||
1239  (OwnerDevice->DeviceType == FILE_DEVICE_FILE_SYSTEM))
1240  {
1241  /* The owner device is an FSD, so this is a volume open for real */
1242  FileObject->Flags |= FO_VOLUME_OPEN;
1243  }
1244  }
1245 
1246  /* Reference the object and set the parse check */
1248  *Object = FileObject;
1249  OpenPacket->FinalStatus = IoStatusBlock.Status;
1250  OpenPacket->ParseCheck = TRUE;
1251  return OpenPacket->FinalStatus;
1252  }
1253  else
1254  {
1255  /* Check if this was a query */
1256  if (OpenPacket->QueryOnly)
1257  {
1258  /* Check if the caller wants basic info only */
1259  if (!OpenPacket->FullAttributes)
1260  {
1261  /* Allocate the buffer */
1262  FileBasicInfo = ExAllocatePoolWithTag(NonPagedPool,
1263  sizeof(*FileBasicInfo),
1264  TAG_IO);
1265  if (FileBasicInfo)
1266  {
1267  /* Do the query */
1270  sizeof(*FileBasicInfo),
1271  FileBasicInfo,
1272  &ReturnLength);
1273  if (NT_SUCCESS(Status))
1274  {
1275  /* Copy the data */
1276  RtlCopyMemory(OpenPacket->BasicInformation,
1277  FileBasicInfo,
1278  ReturnLength);
1279  }
1280 
1281  /* Free our buffer */
1282  ExFreePoolWithTag(FileBasicInfo, TAG_IO);
1283  }
1284  else
1285  {
1286  /* Fail */
1288  }
1289  }
1290  else
1291  {
1292  /* This is a full query */
1294  FileObject,
1297  OpenPacket->NetworkInformation,
1298  &ReturnLength);
1300  }
1301  }
1302 
1303  /* Delete the file object */
1305 
1306  /* Clear out the file */
1307  OpenPacket->FileObject = NULL;
1308 
1309  /* Set and return status */
1310  OpenPacket->FinalStatus = Status;
1311  OpenPacket->ParseCheck = TRUE;
1312  return Status;
1313  }
1314 }
1315 
1316 NTSTATUS
1317 NTAPI
1318 IopParseFile(IN PVOID ParseObject,
1323  IN OUT PUNICODE_STRING CompleteName,
1327  OUT PVOID *Object)
1328 {
1330  POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
1331 
1332  /* Validate the open packet */
1333  if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
1334 
1335  /* Get the device object */
1336  DeviceObject = IoGetRelatedDeviceObject(ParseObject);
1337  OpenPacket->RelatedFileObject = ParseObject;
1338 
1339  /* Call the main routine */
1341  ObjectType,
1342  AccessState,
1343  AccessMode,
1344  Attributes,
1345  CompleteName,
1346  RemainingName,
1347  OpenPacket,
1348  SecurityQos,
1349  Object);
1350 }
1351 
1352 VOID
1353 NTAPI
1355 {
1356  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1357  PIRP Irp;
1358  PIO_STACK_LOCATION StackPtr;
1359  NTSTATUS Status;
1360  KEVENT Event;
1362  BOOLEAN DereferenceDone = FALSE;
1363  PVPB Vpb;
1364  KIRQL OldIrql;
1365  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1366 
1367  /* Check if the file has a device object */
1368  if (FileObject->DeviceObject)
1369  {
1370  /* Check if this is a direct open or not */
1371  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1372  {
1373  /* Get the attached device */
1374  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
1375  }
1376  else
1377  {
1378  /* Use the file object's device object */
1380  }
1381 
1382  /* Sanity check */
1383  ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
1384  (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE));
1385 
1386  /* Check if the handle wasn't created yet */
1387  if (!(FileObject->Flags & FO_HANDLE_CREATED))
1388  {
1389  /* Send the cleanup IRP */
1390  IopCloseFile(NULL, ObjectBody, 0, 1, 1);
1391  }
1392 
1393  /* Clear and set up Events */
1394  KeClearEvent(&FileObject->Event);
1396 
1397  /* Allocate an IRP */
1399 
1400  /* Set it up */
1401  Irp->UserEvent = &Event;
1402  Irp->UserIosb = &Irp->IoStatus;
1403  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1404  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1406 
1407  /* Set up Stack Pointer Data */
1408  StackPtr = IoGetNextIrpStackLocation(Irp);
1409  StackPtr->MajorFunction = IRP_MJ_CLOSE;
1410  StackPtr->FileObject = FileObject;
1411 
1412  /* Queue the IRP */
1414 
1415  /* Get the VPB and check if this isn't a direct open */
1416  Vpb = FileObject->Vpb;
1417  if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1418  {
1419  /* Dereference the VPB before the close */
1420  InterlockedDecrement((PLONG)&Vpb->ReferenceCount);
1421  }
1422 
1423  /* Check if the FS will never disappear by itself */
1424  if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
1425  {
1426  /* Dereference it */
1427  InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
1428  DereferenceDone = TRUE;
1429  }
1430 
1431  /* Call the FS Driver */
1433  if (Status == STATUS_PENDING)
1434  {
1435  /* Wait for completion */
1437  }
1438 
1439  /* De-queue the IRP */
1443 
1444  /* Free the IRP */
1445  IoFreeIrp(Irp);
1446 
1447  /* Clear the file name */
1448  if (FileObject->FileName.Buffer)
1449  {
1450  /*
1451  * Don't use TAG_IO_NAME since the FileObject's FileName
1452  * may have been re-allocated using a different tag
1453  * by a filesystem.
1454  */
1455  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1456  FileObject->FileName.Buffer = NULL;
1457  }
1458 
1459  /* Check if the FO had a completion port */
1460  if (FileObject->CompletionContext)
1461  {
1462  /* Free it */
1463  ObDereferenceObject(FileObject->CompletionContext->Port);
1464  ExFreePool(FileObject->CompletionContext);
1465  }
1466 
1467  /* Check if the FO had extension */
1469  {
1470  /* Release filter context structure if any */
1472  }
1473 
1474  /* Check if dereference has been done yet */
1475  if (!DereferenceDone)
1476  {
1477  /* Dereference device object */
1479  }
1480  }
1481 }
1482 
1484 NTAPI
1486 {
1488 
1489  /* Go down the stack to attempt to get the PDO */
1490  for (; ((PEXTENDED_DEVOBJ_EXTENSION)PDO->DeviceObjectExtension)->AttachedTo != NULL;
1491  PDO = ((PEXTENDED_DEVOBJ_EXTENSION)PDO->DeviceObjectExtension)->AttachedTo);
1492 
1493  return PDO;
1494 }
1495 
1497 NTAPI
1499 {
1500  KIRQL OldIrql;
1501  PDEVICE_OBJECT PDO;
1502 
1503  ASSERT(DeviceObject != NULL);
1504 
1506  /* Get the base DO */
1508  /* Check whether that's really a PDO and if so, keep it */
1510  {
1511  PDO = NULL;
1512  }
1513  else
1514  {
1515  ObReferenceObject(PDO);
1516  }
1518 
1519  return PDO;
1520 }
1521 
1522 NTSTATUS
1523 NTAPI
1529 {
1530  NTSTATUS Status;
1531  PSECURITY_DESCRIPTOR OldSecurityDescriptor, CachedSecurityDescriptor, NewSecurityDescriptor;
1532 
1533  PAGED_CODE();
1534 
1535  /* Keep attempting till we find our old SD or fail */
1536  while (TRUE)
1537  {
1540 
1541  /* Get our old SD and reference it */
1542  OldSecurityDescriptor = DeviceObject->SecurityDescriptor;
1543  if (OldSecurityDescriptor != NULL)
1544  {
1545  ObReferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1546  }
1547 
1550 
1551  /* Set the SD information */
1552  NewSecurityDescriptor = OldSecurityDescriptor;
1554  SecurityDescriptor, &NewSecurityDescriptor,
1556 
1557  if (!NT_SUCCESS(Status))
1558  {
1559  if (OldSecurityDescriptor != NULL)
1560  {
1561  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1562  }
1563 
1564  break;
1565  }
1566 
1567  /* Add the new DS to the internal cache */
1568  Status = ObLogSecurityDescriptor(NewSecurityDescriptor,
1569  &CachedSecurityDescriptor, 1);
1570  ExFreePool(NewSecurityDescriptor);
1571  if (!NT_SUCCESS(Status))
1572  {
1573  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1574  break;
1575  }
1576 
1579  /* Check if someone changed it in our back */
1580  if (DeviceObject->SecurityDescriptor == OldSecurityDescriptor)
1581  {
1582  /* We're clear, do the swap */
1583  DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1586 
1587  /* And dereference old SD (twice - us + not in use) */
1588  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 2);
1589 
1590  break;
1591  }
1594 
1595  /* If so, try again */
1596  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1597  ObDereferenceSecurityDescriptor(CachedSecurityDescriptor, 1);
1598  }
1599 
1600  return Status;
1601 }
1602 
1603 NTSTATUS
1604 NTAPI
1611 {
1612  PDEVICE_OBJECT CurrentDO = PhysicalDeviceObject, NextDevice;
1613  NTSTATUS Status = STATUS_SUCCESS, TmpStatus;
1614 
1615  PAGED_CODE();
1616 
1618 
1619  /* We always reference the DO we're working on */
1620  ObReferenceObject(CurrentDO);
1621 
1622  /* Go up from PDO to latest DO */
1623  do
1624  {
1625  /* Attempt to set the new SD on it */
1626  TmpStatus = IopSetDeviceSecurityDescriptor(CurrentDO, SecurityInformation,
1628  GenericMapping);
1629  /* Was our last one? Remember that status then */
1630  if (CurrentDO == UpperDeviceObject)
1631  {
1632  Status = TmpStatus;
1633  }
1634 
1635  /* Try to move to the next DO (and thus, reference it) */
1636  NextDevice = CurrentDO->AttachedDevice;
1637  if (NextDevice)
1638  {
1639  ObReferenceObject(NextDevice);
1640  }
1641 
1642  /* Dereference current DO and move to the next one */
1643  ObDereferenceObject(CurrentDO);
1644  CurrentDO = NextDevice;
1645  }
1646  while (CurrentDO != NULL);
1647 
1648  return Status;
1649 }
1650 
1651 NTSTATUS
1652 NTAPI
1654  IN SECURITY_OPERATION_CODE OperationCode,
1658  IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1661 {
1663  PIO_STACK_LOCATION StackPtr;
1666  PIRP Irp;
1667  BOOLEAN LocalEvent = FALSE;
1668  KEVENT Event;
1670  PAGED_CODE();
1671  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1672 
1673  /* Check if this is a device or file */
1674  if (((PFILE_OBJECT)ObjectBody)->Type == IO_TYPE_DEVICE)
1675  {
1676  /* It's a device */
1677  DeviceObject = (PDEVICE_OBJECT)ObjectBody;
1678  FileObject = NULL;
1679  }
1680  else
1681  {
1682  /* It's a file */
1683  FileObject = (PFILE_OBJECT)ObjectBody;
1684 
1685  /* Check if this is a direct open */
1686  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1687  {
1688  /* Get the Device Object */
1689  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
1690  }
1691  else
1692  {
1693  /* Otherwise, use the direct device*/
1694  DeviceObject = FileObject->DeviceObject;
1695  }
1696  }
1697 
1698  /* Check if the request was for a device object */
1699  if (!(FileObject) ||
1700  (!(FileObject->FileName.Length) && !(FileObject->RelatedFileObject)) ||
1701  (FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1702  {
1703  /* Check what kind of request this was */
1704  if (OperationCode == QuerySecurityDescriptor)
1705  {
1708  BufferLength,
1709  &DeviceObject->SecurityDescriptor);
1710  }
1711  else if (OperationCode == DeleteSecurityDescriptor)
1712  {
1713  /* Simply return success */
1714  return STATUS_SUCCESS;
1715  }
1716  else if (OperationCode == AssignSecurityDescriptor)
1717  {
1719 
1720  /* Make absolutely sure this is a device object */
1721  if (!(FileObject) || !(FileObject->Flags & FO_STREAM_FILE))
1722  {
1723  PSECURITY_DESCRIPTOR CachedSecurityDescriptor;
1724 
1725  /* Add the security descriptor in cache */
1726  Status = ObLogSecurityDescriptor(SecurityDescriptor, &CachedSecurityDescriptor, 1);
1727  if (NT_SUCCESS(Status))
1728  {
1731 
1732  /* Assign the Security Descriptor */
1733  DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1734 
1737  }
1738  }
1739 
1740  /* Return status */
1741  return Status;
1742  }
1743  else if (OperationCode == SetSecurityDescriptor)
1744  {
1745  /* Get the Physical Device Object if any */
1747 
1748  if (PDO != NULL)
1749  {
1750  /* Apply the new SD to any DO in the path from PDO to current DO */
1755  ObDereferenceObject(PDO);
1756  }
1757  else
1758  {
1759  /* Otherwise, just set for ourselves */
1764  }
1765 
1766  return STATUS_SUCCESS;
1767  }
1768 
1769  /* Shouldn't happen */
1770  return STATUS_SUCCESS;
1771  }
1772  else if (OperationCode == DeleteSecurityDescriptor)
1773  {
1774  /* Same as for devices, do nothing */
1775  return STATUS_SUCCESS;
1776  }
1777 
1778  /* At this point, we know we're a file. Reference it */
1780 
1781  /* Check if we should use Sync IO or not */
1782  if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1783  {
1784  /* Lock the file object */
1786  if (Status != STATUS_SUCCESS)
1787  {
1789  return Status;
1790  }
1791  }
1792  else
1793  {
1794  /* Use local event */
1796  LocalEvent = TRUE;
1797  }
1798 
1799  /* Clear the File Object event */
1800  KeClearEvent(&FileObject->Event);
1801 
1802  /* Get the device object */
1804 
1805  /* Allocate the IRP */
1807  if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);
1808 
1809  /* Set the IRP */
1810  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1811  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1812  Irp->RequestorMode = ExGetPreviousMode();
1813  Irp->UserIosb = &IoStatusBlock;
1814  Irp->UserEvent = (LocalEvent) ? &Event : NULL;
1815  Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
1816  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
1817 
1818  /* Set Stack Parameters */
1819  StackPtr = IoGetNextIrpStackLocation(Irp);
1820  StackPtr->FileObject = FileObject;
1821 
1822  /* Check if this is a query or set */
1823  if (OperationCode == QuerySecurityDescriptor)
1824  {
1825  /* Set the major function and parameters */
1827  StackPtr->Parameters.QuerySecurity.SecurityInformation =
1829  StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
1830  Irp->UserBuffer = SecurityDescriptor;
1831  }
1832  else
1833  {
1834  /* Set the major function and parameters for a set */
1835  StackPtr->MajorFunction = IRP_MJ_SET_SECURITY;
1836  StackPtr->Parameters.SetSecurity.SecurityInformation =
1838  StackPtr->Parameters.SetSecurity.SecurityDescriptor =
1840  }
1841 
1842  /* Queue the IRP */
1844 
1845  /* Update operation counts */
1847 
1848  /* Call the Driver */
1850 
1851  /* Check if this was async I/O */
1852  if (LocalEvent)
1853  {
1854  /* Check if the IRP is pending completion */
1855  if (Status == STATUS_PENDING)
1856  {
1857  /* Wait on the local event */
1859  Executive,
1860  KernelMode,
1861  FALSE,
1862  NULL);
1864  }
1865  }
1866  else
1867  {
1868  /* Check if the IRP is pending completion */
1869  if (Status == STATUS_PENDING)
1870  {
1871  /* Wait on the file object */
1873  Executive,
1874  KernelMode,
1875  FALSE,
1876  NULL);
1877  Status = FileObject->FinalStatus;
1878  }
1879 
1880  /* Release the lock */
1882  }
1883 
1884  /* This Driver doesn't implement Security, so try to give it a default */
1886  {
1887  /* Was this a query? */
1888  if (OperationCode == QuerySecurityDescriptor)
1889  {
1890  /* Set a World Security Descriptor */
1893  BufferLength);
1894  }
1895  else
1896  {
1897  /* It wasn't a query, so just fake success */
1899  }
1900  }
1901  else if (OperationCode == QuerySecurityDescriptor)
1902  {
1903  /* Callers usually expect the normalized form */
1905 
1906  _SEH2_TRY
1907  {
1908  /* Return length */
1910  }
1912  {
1913  /* Get the exception code */
1915  }
1916  _SEH2_END;
1917  }
1918 
1919  /* Return Status */
1920  return Status;
1921 }
1922 
1923 NTSTATUS
1924 NTAPI
1925 IopQueryName(IN PVOID ObjectBody,
1926  IN BOOLEAN HasName,
1927  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1928  IN ULONG Length,
1931 {
1932  return IopQueryNameInternal(ObjectBody,
1933  HasName,
1934  FALSE,
1935  ObjectNameInfo,
1936  Length,
1937  ReturnLength,
1938  PreviousMode);
1939 }
1940 
1941 NTSTATUS
1942 NTAPI
1944  IN BOOLEAN HasName,
1945  IN BOOLEAN QueryDosName,
1946  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1947  IN ULONG Length,
1950 {
1951  POBJECT_NAME_INFORMATION LocalInfo;
1952  PFILE_NAME_INFORMATION LocalFileInfo;
1953  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1954  ULONG LocalReturnLength, FileLength;
1955  BOOLEAN LengthMismatch = FALSE;
1956  NTSTATUS Status;
1957  PWCHAR p;
1959  BOOLEAN NoObCall;
1960 
1961  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1962 
1963  /* Validate length */
1964  if (Length < sizeof(OBJECT_NAME_INFORMATION))
1965  {
1966  /* Wrong length, fail */
1969  }
1970 
1971  /* Allocate Buffer */
1973  if (!LocalInfo) return STATUS_INSUFFICIENT_RESOURCES;
1974 
1975  /* Query DOS name if the caller asked to */
1976  NoObCall = FALSE;
1977  if (QueryDosName)
1978  {
1979  DeviceObject = FileObject->DeviceObject;
1980 
1981  /* In case of a network file system, don't call mountmgr */
1982  if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
1983  {
1984  /* We'll store separator and terminator */
1985  LocalReturnLength = sizeof(OBJECT_NAME_INFORMATION) + 2 * sizeof(WCHAR);
1986  if (Length < LocalReturnLength)
1987  {
1989  }
1990  else
1991  {
1992  LocalInfo->Name.Length = sizeof(WCHAR);
1993  LocalInfo->Name.MaximumLength = sizeof(WCHAR);
1994  LocalInfo->Name.Buffer = (PVOID)((ULONG_PTR)LocalInfo + sizeof(OBJECT_NAME_INFORMATION));
1995  LocalInfo->Name.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
1997  }
1998  }
1999  /* Otherwise, call mountmgr to get DOS name */
2000  else
2001  {
2003  LocalReturnLength = LocalInfo->Name.Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
2004  }
2005  }
2006 
2007  /* Fall back if querying DOS name failed or if caller never wanted it ;-) */
2008  if (!QueryDosName || !NT_SUCCESS(Status))
2009  {
2010  /* Query the name */
2011  Status = ObQueryNameString(FileObject->DeviceObject,
2012  LocalInfo,
2013  Length,
2014  &LocalReturnLength);
2015  }
2016  else
2017  {
2018  NoObCall = TRUE;
2019  }
2020 
2022  {
2023  /* Free the buffer and fail */
2024  ExFreePoolWithTag(LocalInfo, TAG_IO);
2025  return Status;
2026  }
2027 
2028  /* Get buffer pointer */
2029  p = (PWCHAR)(ObjectNameInfo + 1);
2030 
2031  _SEH2_TRY
2032  {
2033  /* Copy the information */
2034  if (QueryDosName && NoObCall)
2035  {
2037 
2038  /* Copy structure first */
2039  RtlCopyMemory(ObjectNameInfo,
2040  LocalInfo,
2041  (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length));
2042  /* Name then */
2043  RtlCopyMemory(p, LocalInfo->Name.Buffer,
2044  (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION)));
2045 
2046  if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
2047  {
2048  ExFreePool(LocalInfo->Name.Buffer);
2049  }
2050  }
2051  else
2052  {
2053  RtlCopyMemory(ObjectNameInfo,
2054  LocalInfo,
2055  (LocalReturnLength > Length) ?
2056  Length : LocalReturnLength);
2057  }
2058 
2059  /* Set buffer pointer */
2060  ObjectNameInfo->Name.Buffer = p;
2061 
2062  /* Advance in buffer */
2063  p += (LocalInfo->Name.Length / sizeof(WCHAR));
2064 
2065  /* Check if this already filled our buffer */
2066  if (LocalReturnLength > Length)
2067  {
2068  /* Set the length mismatch to true, so that we can return
2069  * the proper buffer size to the caller later
2070  */
2071  LengthMismatch = TRUE;
2072 
2073  /* Save the initial buffer length value */
2074  *ReturnLength = LocalReturnLength;
2075  }
2076 
2077  /* Now get the file name buffer and check the length needed */
2078  LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
2079  FileLength = Length -
2080  LocalReturnLength +
2082 
2083  /* Query the File name */
2084  if (PreviousMode == KernelMode &&
2086  {
2088  LengthMismatch ? Length : FileLength,
2090  LocalFileInfo,
2091  &LocalReturnLength);
2092  }
2093  else
2094  {
2097  LengthMismatch ? Length : FileLength,
2098  LocalFileInfo,
2099  &LocalReturnLength);
2100  }
2101  if (NT_ERROR(Status))
2102  {
2103  /* Allow status that would mean it's not implemented in the storage stack */
2106  {
2107  _SEH2_LEAVE;
2108  }
2109 
2110  /* In such case, zero output */
2111  LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2112  LocalFileInfo->FileNameLength = 0;
2113  LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
2114  }
2115  else
2116  {
2117  /* We'll at least return the name length */
2118  if (LocalReturnLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
2119  {
2120  LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2121  }
2122  }
2123 
2124  /* If the provided buffer is too small, return the required size */
2125  if (LengthMismatch)
2126  {
2127  /* Add the required length */
2128  *ReturnLength += LocalFileInfo->FileNameLength;
2129 
2130  /* Free the allocated buffer and return failure */
2132  _SEH2_LEAVE;
2133  }
2134 
2135  /* Now calculate the new lengths left */
2136  FileLength = LocalReturnLength -
2138  LocalReturnLength = (ULONG)((ULONG_PTR)p -
2139  (ULONG_PTR)ObjectNameInfo +
2140  LocalFileInfo->FileNameLength);
2141 
2142  /* Don't copy the name if it's not valid */
2143  if (LocalFileInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR)
2144  {
2145  /* Free the allocated buffer and return failure */
2147  _SEH2_LEAVE;
2148  }
2149 
2150  /* Write the Name and null-terminate it */
2151  RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
2152  p += (FileLength / sizeof(WCHAR));
2153  *p = UNICODE_NULL;
2154  LocalReturnLength += sizeof(UNICODE_NULL);
2155 
2156  /* Return the length needed */
2157  *ReturnLength = LocalReturnLength;
2158 
2159  /* Setup the length and maximum length */
2160  FileLength = (ULONG)((ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo);
2161  ObjectNameInfo->Name.Length = (USHORT)FileLength -
2162  sizeof(OBJECT_NAME_INFORMATION);
2163  ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
2164  sizeof(UNICODE_NULL);
2165  }
2167  {
2168  /* Free buffer and return */
2169  ExFreePoolWithTag(LocalInfo, TAG_IO);
2170  } _SEH2_END;
2171 
2172  return Status;
2173 }
2174 
2175 VOID
2176 NTAPI
2178  IN PVOID ObjectBody,
2180  IN ULONG HandleCount,
2181  IN ULONG SystemHandleCount)
2182 {
2183  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
2184  KEVENT Event;
2185  PIRP Irp;
2186  PIO_STACK_LOCATION StackPtr;
2187  NTSTATUS Status;
2189  KIRQL OldIrql;
2191  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
2192 
2193  /* If this isn't the last handle for the current process, quit */
2194  if (HandleCount != 1) return;
2195 
2196  /* Check if the file is locked and has more then one handle opened */
2197  if ((FileObject->LockOperation) && (SystemHandleCount != 1))
2198  {
2199  /* Check if this is a direct open or not */
2201  {
2202  /* Get the attached device */
2203  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
2204  }
2205  else
2206  {
2207  /* Get the FO's device */
2209  }
2210 
2211  /* Check if this is a sync FO and lock it */
2213  {
2215  }
2216 
2217  /* Go the FastIO path if possible, otherwise fall back to IRP */
2218  if (DeviceObject->DriverObject->FastIoDispatch == NULL ||
2219  DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll == NULL ||
2220  !DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll(FileObject, PsGetCurrentProcess(), &IoStatusBlock, DeviceObject))
2221  {
2222  /* Clear and set up Events */
2223  KeClearEvent(&FileObject->Event);
2225 
2226  /* Allocate an IRP */
2228 
2229  /* Set it up */
2230  Irp->UserEvent = &Event;
2231  Irp->UserIosb = &Irp->IoStatus;
2232  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2233  Irp->Tail.Overlay.OriginalFileObject = FileObject;
2234  Irp->RequestorMode = KernelMode;
2235  Irp->Flags = IRP_SYNCHRONOUS_API;
2236  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2238 
2239  /* Set up Stack Pointer Data */
2240  StackPtr = IoGetNextIrpStackLocation(Irp);
2241  StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
2242  StackPtr->MinorFunction = IRP_MN_UNLOCK_ALL;
2243  StackPtr->FileObject = FileObject;
2244 
2245  /* Queue the IRP */
2247 
2248  /* Call the FS Driver */
2250  if (Status == STATUS_PENDING)
2251  {
2252  /* Wait for completion */
2254  }
2255 
2256  /* IO will unqueue & free for us */
2257  }
2258 
2259  /* Release the lock if we were holding it */
2261  {
2263  }
2264  }
2265 
2266  /* Make sure this is the last handle */
2267  if (SystemHandleCount != 1) return;
2268 
2269  /* Check if this is a direct open or not */
2270  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
2271  {
2272  /* Get the attached device */
2273  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
2274  }
2275  else
2276  {
2277  /* Get the FO's device */
2279  }
2280 
2281  /* Set the handle created flag */
2282  FileObject->Flags |= FO_HANDLE_CREATED;
2283 
2284  /* Check if this is a sync FO and lock it */
2285  if (Process != NULL &&
2287  {
2289  }
2290 
2291  /* Clear and set up Events */
2292  KeClearEvent(&FileObject->Event);
2294 
2295  /* Allocate an IRP */
2297 
2298  /* Set it up */
2299  Irp->UserEvent = &Event;
2300  Irp->UserIosb = &Irp->IoStatus;
2301  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2302  Irp->Tail.Overlay.OriginalFileObject = FileObject;
2303  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2305 
2306  /* Set up Stack Pointer Data */
2307  StackPtr = IoGetNextIrpStackLocation(Irp);
2308  StackPtr->MajorFunction = IRP_MJ_CLEANUP;
2309  StackPtr->FileObject = FileObject;
2310 
2311  /* Queue the IRP */
2313 
2314  /* Update operation counts */
2316 
2317  /* Call the FS Driver */
2319  if (Status == STATUS_PENDING)
2320  {
2321  /* Wait for completion */
2323  }
2324 
2325  /* Unqueue the IRP */
2329 
2330  /* Free the IRP */
2331  IoFreeIrp(Irp);
2332 
2333  /* Release the lock if we were holding it */
2334  if (Process != NULL &&
2336  {
2338  }
2339 }
2340 
2341 NTSTATUS
2342 NTAPI
2345  IN ULONG FileInformationSize,
2347 {
2348  NTSTATUS Status;
2350  DUMMY_FILE_OBJECT LocalFileObject;
2351  FILE_NETWORK_OPEN_INFORMATION NetworkOpenInfo;
2352  HANDLE Handle;
2353  OPEN_PACKET OpenPacket;
2354  BOOLEAN IsBasic;
2355  PAGED_CODE();
2356  IOTRACE(IO_FILE_DEBUG, "Class: %lx\n", FileInformationClass);
2357 
2358  /* Check if the caller was user mode */
2359  if (AccessMode != KernelMode)
2360  {
2361  /* Protect probe in SEH */
2362  _SEH2_TRY
2363  {
2364  /* Probe the buffer */
2365  ProbeForWrite(FileInformation, FileInformationSize, sizeof(ULONG));
2366  }
2368  {
2369  /* Return the exception code */
2371  }
2372  _SEH2_END;
2373  }
2374 
2375  /* Check if this is a basic or full request */
2376  IsBasic = (FileInformationSize == sizeof(FILE_BASIC_INFORMATION));
2377 
2378  /* Setup the Open Packet */
2379  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
2380  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
2381  OpenPacket.Size = sizeof(OPEN_PACKET);
2384  OpenPacket.Disposition = FILE_OPEN;
2385  OpenPacket.BasicInformation = IsBasic ? FileInformation : NULL;
2386  OpenPacket.NetworkInformation = IsBasic ? &NetworkOpenInfo :
2387  (AccessMode != KernelMode) ?
2388  &NetworkOpenInfo : FileInformation;
2389  OpenPacket.QueryOnly = TRUE;
2390  OpenPacket.FullAttributes = IsBasic ? FALSE : TRUE;
2391  OpenPacket.LocalFileObject = &LocalFileObject;
2392 
2393  /* Update the operation count */
2395 
2396  /*
2397  * Attempt opening the file. This will call the I/O Parse Routine for
2398  * the File Object (IopParseDevice) which will use the dummy file obejct
2399  * send the IRP to its device object. Note that we have two statuses
2400  * to worry about: the Object Manager's status (in Status) and the I/O
2401  * status, which is in the Open Packet's Final Status, and determined
2402  * by the Parse Check member.
2403  */
2405  NULL,
2406  AccessMode,
2407  NULL,
2409  &OpenPacket,
2410  &Handle);
2411  if (OpenPacket.ParseCheck == FALSE)
2412  {
2413  /* Parse failed */
2414  DPRINT("IopQueryAttributesFile failed for '%wZ' with 0x%lx\n",
2415  ObjectAttributes->ObjectName, Status);
2416  return Status;
2417  }
2418  else
2419  {
2420  /* Use the Io status */
2421  Status = OpenPacket.FinalStatus;
2422  }
2423 
2424  /* Check if we were succesful and this was user mode and a full query */
2425  if ((NT_SUCCESS(Status)) && (AccessMode != KernelMode) && !(IsBasic))
2426  {
2427  /* Enter SEH for copy */
2428  _SEH2_TRY
2429  {
2430  /* Copy the buffer back */
2432  &NetworkOpenInfo,
2433  FileInformationSize);
2434  }
2436  {
2437  /* Get exception code */
2439  }
2440  _SEH2_END;
2441  }
2442 
2443  /* Return status */
2444  return Status;
2445 }
2446 
2447 NTSTATUS
2448 NTAPI
2451  _In_ KPROCESSOR_MODE WaitMode,
2453  _Out_ PBOOLEAN LockFailed)
2454 {
2455  NTSTATUS Status;
2456 
2457  PAGED_CODE();
2458 
2460 
2462  do
2463  {
2464  if (!InterlockedExchange((PLONG)&FileObject->Busy, TRUE))
2465  {
2466  break;
2467  }
2469  Executive,
2470  WaitMode,
2471  Alertable,
2472  NULL);
2473  } while (Status == STATUS_SUCCESS);
2474 
2476  if (Status == STATUS_SUCCESS)
2477  {
2479  *LockFailed = FALSE;
2480  }
2481  else
2482  {
2483  if (!FileObject->Busy && FileObject->Waiters)
2484  {
2486  }
2487  *LockFailed = TRUE;
2488  }
2489 
2490  return Status;
2491 }
2492 
2493 PVOID
2494 NTAPI
2496 {
2498  {
2499  PFILE_OBJECT_EXTENSION FileObjectExtension;
2500 
2501  FileObjectExtension = FileObject->FileObjectExtension;
2502  return FileObjectExtension->FilterContext;
2503  }
2504 
2505  return NULL;
2506 }
2507 
2508 NTSTATUS
2509 NTAPI
2512  IN BOOLEAN Define)
2513 {
2515  PFILE_OBJECT_EXTENSION FileObjectExtension;
2516 
2518  {
2519  return STATUS_INVALID_PARAMETER;
2520  }
2521 
2522  FileObjectExtension = FileObject->FileObjectExtension;
2523  if (Define)
2524  {
2525  /* If define, just set the new value if not value is set
2526  * Success will only contain old value. It is valid if it is NULL
2527  */
2529  }
2530  else
2531  {
2532  /* If not define, we want to reset filter context.
2533  * We will remove value (provided by the caller) and set NULL instead.
2534  * This will only success if caller provides correct previous value.
2535  * To catch whether it worked, we substract previous value to expect value:
2536  * If it matches (and thus, we reset), Success will contain 0
2537  * Otherwise, it will contain a non-zero value.
2538  */
2540  }
2541 
2542  /* If success isn't 0, it means we failed somewhere (set or unset) */
2543  if (Success != 0)
2544  {
2545  return STATUS_ALREADY_COMMITTED;
2546  }
2547 
2548  return STATUS_SUCCESS;
2549 }
2550 
2551 NTSTATUS
2552 NTAPI
2563  IN ULONG EaLength,
2565  IN PVOID ExtraCreateParameters OPTIONAL,
2566  IN ULONG Options,
2567  IN ULONG Flags,
2569 {
2571  HANDLE LocalHandle = 0;
2572  LARGE_INTEGER SafeAllocationSize;
2574  PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters;
2575  POPEN_PACKET OpenPacket;
2576  ULONG EaErrorOffset;
2577  PAGED_CODE();
2578 
2579  IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
2580 
2581 
2582  /* Check if we have no parameter checking to do */
2584  {
2585  /* Then force kernel-mode access to avoid checks */
2587  }
2588  else
2589  {
2590  /* Otherwise, use the actual mode */
2592  }
2593 
2594  /* Check if we need to do parameter checking */
2596  {
2597  /* Validate parameters */
2599  {
2600  DPRINT1("File Create 'FileAttributes' Parameter contains invalid flags!\n");
2601  return STATUS_INVALID_PARAMETER;
2602  }
2603 
2605  {
2606  DPRINT1("File Create 'ShareAccess' Parameter contains invalid flags!\n");
2607  return STATUS_INVALID_PARAMETER;
2608  }
2609 
2611  {
2612  DPRINT1("File Create 'Disposition' Parameter is out of range!\n");
2613  return STATUS_INVALID_PARAMETER;
2614  }
2615 
2617  {
2618  DPRINT1("File Create 'CreateOptions' parameter contains invalid flags!\n");
2619  return STATUS_INVALID_PARAMETER;
2620  }
2621 
2623  (!(DesiredAccess & SYNCHRONIZE)))
2624  {
2625  DPRINT1("File Create 'CreateOptions' parameter FILE_SYNCHRONOUS_IO_* requested, but 'DesiredAccess' does not have SYNCHRONIZE!\n");
2626  return STATUS_INVALID_PARAMETER;
2627  }
2628 
2630  {
2631  DPRINT1("File Create 'CreateOptions' parameter FILE_DELETE_ON_CLOSE requested, but 'DesiredAccess' does not have DELETE!\n");
2632  return STATUS_INVALID_PARAMETER;
2633  }
2634 
2637  {
2638  DPRINT1("File Create 'FileAttributes' parameter both FILE_SYNCHRONOUS_IO_NONALERT and FILE_SYNCHRONOUS_IO_ALERT specified!\n");
2639  return STATUS_INVALID_PARAMETER;
2640  }
2641 
2654  {
2655  DPRINT1("File Create 'CreateOptions' Parameter has flags incompatible with FILE_DIRECTORY_FILE!\n");
2656  return STATUS_INVALID_PARAMETER;
2657  }
2658 
2661  {
2662  DPRINT1("File Create 'CreateOptions' Parameter FILE_DIRECTORY_FILE requested, but 'Disposition' is not FILE_CREATE/FILE_OPEN/FILE_OPEN_IF!\n");
2663  return STATUS_INVALID_PARAMETER;
2664  }
2665 
2667  {
2668  DPRINT1("File Create 'CreateOptions' Parameter both FILE_COMPLETE_IF_OPLOCKED and FILE_RESERVE_OPFILTER specified!\n");
2669  return STATUS_INVALID_PARAMETER;
2670  }
2671 
2673  {
2674  DPRINT1("File Create 'CreateOptions' parameter FILE_NO_INTERMEDIATE_BUFFERING requested, but 'DesiredAccess' FILE_APPEND_DATA requires it!\n");
2675  return STATUS_INVALID_PARAMETER;
2676  }
2677 
2678  /* Now check if this is a named pipe */
2680  {
2681  /* Make sure we have extra parameters */
2682  if (!ExtraCreateParameters)
2683  {
2684  DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2685  return STATUS_INVALID_PARAMETER;
2686  }
2687 
2688  /* Get the parameters and validate them */
2689  NamedPipeCreateParameters = ExtraCreateParameters;
2690  if ((NamedPipeCreateParameters->NamedPipeType > FILE_PIPE_MESSAGE_TYPE) ||
2691  (NamedPipeCreateParameters->ReadMode > FILE_PIPE_MESSAGE_MODE) ||
2692  (NamedPipeCreateParameters->CompletionMode > FILE_PIPE_COMPLETE_OPERATION) ||
2696  {
2697  /* Invalid named pipe create */
2698  DPRINT1("Invalid named pipe create\n");
2699  return STATUS_INVALID_PARAMETER;
2700  }
2701  }
2703  {
2704  /* Make sure we have extra parameters */
2705  if (!ExtraCreateParameters)
2706  {
2707  DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2708  return STATUS_INVALID_PARAMETER;
2709  }
2710 
2711  /* Get the parameters and validate them */
2712  if ((ShareAccess & FILE_SHARE_DELETE) ||
2713  !(ShareAccess & ~FILE_SHARE_WRITE) ||
2714  (Disposition != FILE_CREATE) ||
2716  {
2717  /* Invalid mailslot create */
2718  DPRINT1("Invalid mailslot create\n");
2719  return STATUS_INVALID_PARAMETER;
2720  }
2721  }
2722  }
2723 
2724  /* Allocate the open packet */
2725  OpenPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*OpenPacket), 'pOoI');
2726  if (!OpenPacket) return STATUS_INSUFFICIENT_RESOURCES;
2727  RtlZeroMemory(OpenPacket, sizeof(*OpenPacket));
2728 
2729  /* Check if the call came from user mode */
2730  if (AccessMode != KernelMode)
2731  {
2732  _SEH2_TRY
2733  {
2734  /* Probe the output parameters */
2737 
2738  /* Probe the allocation size if one was passed in */
2739  if (AllocationSize)
2740  {
2741  SafeAllocationSize = ProbeForReadLargeInteger(AllocationSize);
2742  }
2743  else
2744  {
2745  SafeAllocationSize.QuadPart = 0;
2746  }
2747 
2748  /* Make sure it's valid */
2749  if (SafeAllocationSize.QuadPart < 0)
2750  {
2752  }
2753 
2754  /* Check if EA was passed in */
2755  if ((EaBuffer) && (EaLength))
2756  {
2757  /* Probe it */
2758  ProbeForRead(EaBuffer, EaLength, sizeof(ULONG));
2759 
2760  /* And marshall it */
2762  EaLength,
2763  TAG_EA);
2764  OpenPacket->EaLength = EaLength;
2765  RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2766 
2767  /* Validate the buffer */
2768  Status = IoCheckEaBufferValidity(OpenPacket->EaBuffer,
2769  EaLength,
2770  &EaErrorOffset);
2771  if (!NT_SUCCESS(Status))
2772  {
2773  /* Undo everything if it's invalid */
2774  DPRINT1("Invalid EA buffer\n");
2776  IoStatusBlock->Information = EaErrorOffset;
2778  }
2779  }
2780  }
2782  {
2783  /* Return the exception code */
2784  if (OpenPacket->EaBuffer != NULL) ExFreePool(OpenPacket->EaBuffer);
2785  ExFreePool(OpenPacket);
2787  }
2788  _SEH2_END;
2789  }
2790  else
2791  {
2792  /* Check if this is a device attach */
2794  {
2795  /* Set the flag properly */
2798  }
2799 
2800  /* Check if we have allocation size */
2801  if (AllocationSize)
2802  {
2803  /* Capture it */
2804  SafeAllocationSize = *AllocationSize;
2805  }
2806  else
2807  {
2808  /* Otherwise, no size */
2809  SafeAllocationSize.QuadPart = 0;
2810  }
2811 
2812  /* Check if we have an EA packet */
2813  if ((EaBuffer) && (EaLength))
2814  {
2815  /* Allocate the kernel copy */
2817  EaLength,
2818  TAG_EA);
2819  if (!OpenPacket->EaBuffer)
2820  {
2821  ExFreePool(OpenPacket);
2822  DPRINT1("Failed to allocate open packet EA buffer\n");
2824  }
2825 
2826  /* Copy the data */
2827  OpenPacket->EaLength = EaLength;
2828  RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2829 
2830  /* Validate the buffer */
2831  Status = IoCheckEaBufferValidity(OpenPacket->EaBuffer,
2832  EaLength,
2833  &EaErrorOffset);
2834  if (!NT_SUCCESS(Status))
2835  {
2836  /* Undo everything if it's invalid */
2837  DPRINT1("Invalid EA buffer\n");
2838  ExFreePool(OpenPacket->EaBuffer);
2840  IoStatusBlock->Information = EaErrorOffset;
2841  ExFreePool(OpenPacket);
2842  return Status;
2843  }
2844  }
2845  }
2846 
2847  /* Setup the Open Packet */
2848  OpenPacket->Type = IO_TYPE_OPEN_PACKET;
2849  OpenPacket->Size = sizeof(*OpenPacket);
2850  OpenPacket->AllocationSize = SafeAllocationSize;
2851  OpenPacket->CreateOptions = CreateOptions;
2852  OpenPacket->FileAttributes = (USHORT)FileAttributes;
2853  OpenPacket->ShareAccess = (USHORT)ShareAccess;
2854  OpenPacket->Options = Options;
2855  OpenPacket->Disposition = Disposition;
2856  OpenPacket->CreateFileType = CreateFileType;
2857  OpenPacket->ExtraCreateParameters = ExtraCreateParameters;
2858  OpenPacket->InternalFlags = Flags;
2859  OpenPacket->TopDeviceObjectHint = DeviceObject;
2860 
2861  /* Update the operation count */
2863 
2864  /*
2865  * Attempt opening the file. This will call the I/O Parse Routine for
2866  * the File Object (IopParseDevice) which will create the object and
2867  * send the IRP to its device object. Note that we have two statuses
2868  * to worry about: the Object Manager's status (in Status) and the I/O
2869  * status, which is in the Open Packet's Final Status, and determined
2870  * by the Parse Check member.
2871  */
2873  NULL,
2874  AccessMode,
2875  NULL,
2876  DesiredAccess,
2877  OpenPacket,
2878  &LocalHandle);
2879 
2880  /* Free the EA Buffer */
2881  if (OpenPacket->EaBuffer) ExFreePool(OpenPacket->EaBuffer);
2882 
2883  /* Now check for Ob or Io failure */
2884  if (!(NT_SUCCESS(Status)) || (OpenPacket->ParseCheck == FALSE))
2885  {
2886  /* Check if Ob thinks well went well */
2887  if (NT_SUCCESS(Status))
2888  {
2889  /*
2890  * Tell it otherwise. Because we didn't use an ObjectType,
2891  * it incorrectly returned us a handle to God knows what.
2892  */
2895  }
2896 
2897  /* Now check the Io status */
2898  if (!NT_SUCCESS(OpenPacket->FinalStatus))
2899  {
2900  /* Use this status instead of Ob's */
2901  Status = OpenPacket->FinalStatus;
2902 
2903  /* Check if it was only a warning */
2904  if (NT_WARNING(Status))
2905  {
2906  /* Protect write with SEH */
2907  _SEH2_TRY
2908  {
2909  /* In this case, we copy the I/O Status back */
2910  IoStatusBlock->Information = OpenPacket->Information;
2911  IoStatusBlock->Status = OpenPacket->FinalStatus;
2912  }
2914  {
2915  /* Get exception code */
2917  }
2918  _SEH2_END;
2919  }
2920  }
2921  else if ((OpenPacket->FileObject) && (OpenPacket->ParseCheck == FALSE))
2922  {
2923  /*
2924  * This can happen in the very bizarre case where the parse routine
2925  * actually executed more then once (due to a reparse) and ended
2926  * up failing after already having created the File Object.
2927  */
2928  if (OpenPacket->FileObject->FileName.Length)
2929  {
2930  /* It had a name, free it */
2931  ExFreePoolWithTag(OpenPacket->FileObject->FileName.Buffer, TAG_IO_NAME);
2932  }
2933 
2934  /* Clear the device object to invalidate the FO, and dereference */
2935  OpenPacket->FileObject->DeviceObject = NULL;
2936  ObDereferenceObject(OpenPacket->FileObject);
2937  }
2938  }
2939  else
2940  {
2941  /* We reached success and have a valid file handle */
2942  OpenPacket->FileObject->Flags |= FO_HANDLE_CREATED;
2943  ASSERT(OpenPacket->FileObject->Type == IO_TYPE_FILE);
2944 
2945  /* Enter SEH for write back */
2946  _SEH2_TRY
2947  {
2948  /* Write back the handle and I/O Status */
2950  IoStatusBlock->Information = OpenPacket->Information;
2951  IoStatusBlock->Status = OpenPacket->FinalStatus;
2952 
2953  /* Get the Io status */
2954  Status = OpenPacket->FinalStatus;
2955  }
2957  {
2958  /* Get the exception status */
2960  }
2961  _SEH2_END;
2962  }
2963 
2964  /* Check if we were 100% successful */
2965  if ((OpenPacket->ParseCheck != FALSE) && (OpenPacket->FileObject))
2966  {
2967  /* Dereference the File Object */
2968  ObDereferenceObject(OpenPacket->FileObject);
2969  }
2970 
2971  /* Return status */
2972  ExFreePool(OpenPacket);
2973  return Status;
2974 }
2975 
2976 /* FUNCTIONS *****************************************************************/
2977 
2978 /*
2979  * @unimplemented
2980  */
2981 NTSTATUS
2982 NTAPI
2984  IN ULONG Length,
2985  IN BOOLEAN SetOperation)
2986 {
2987  UNIMPLEMENTED;
2988  return STATUS_NOT_IMPLEMENTED;
2989 }
2990 
2991 /*
2992  * @unimplemented
2993  */
2994 NTSTATUS
2995 NTAPI
2997  IN ULONG QuotaLength,
2998  OUT PULONG ErrorOffset)
2999 {
3000  UNIMPLEMENTED;
3001  return STATUS_NOT_IMPLEMENTED;
3002 }
3003 
3004 /*
3005  * @implemented
3006  */
3007 NTSTATUS
3008 NTAPI
3019  IN ULONG EaLength,
3021  IN PVOID ExtraCreateParameters OPTIONAL,
3022  IN ULONG Options)
3023 {
3024  PAGED_CODE();
3025 
3026  return IopCreateFile(FileHandle,
3027  DesiredAccess,
3029  IoStatusBlock,
3032  ShareAccess,
3033  Disposition,
3034  CreateOptions,
3035  EaBuffer,
3036  EaLength,
3038  ExtraCreateParameters,
3039  Options,
3040  0,
3041  NULL);
3042 }
3043 
3044 /*
3045  * @unimplemented
3046  */
3047 NTSTATUS
3048 NTAPI
3059  IN ULONG EaLength,
3061  IN PVOID ExtraCreateParameters OPTIONAL,
3062  IN ULONG Options,
3064 {
3065  ULONG Flags = 0;
3066 
3067  PAGED_CODE();
3068 
3069  /* Check if we were passed a device to send the create request to*/
3070  if (DeviceObject)
3071  {
3072  /* We'll tag this request into a file object extension */
3074  }
3075 
3076  return IopCreateFile(FileHandle,
3077  DesiredAccess,
3079  IoStatusBlock,
3082  ShareAccess,
3083  Disposition,
3084  CreateOptions,
3085  EaBuffer,
3086  EaLength,
3088  ExtraCreateParameters,
3090  Flags,
3091  DeviceObject);
3092 }
3093 
3094 /*
3095  * @implemented
3096  */
3098 NTAPI
3102 {
3103  PFILE_OBJECT CreatedFileObject;
3104  NTSTATUS Status;
3107  PAGED_CODE();
3108  IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3109 
3110  /* Choose Device Object */
3111  if (FileObject) DeviceObject = FileObject->DeviceObject;
3112 
3113  /* Reference the device object and initialize attributes */
3114  InterlockedIncrement(&DeviceObject->ReferenceCount);
3116 
3117  /* Create the File Object */
3121  KernelMode,
3122  NULL,
3123  sizeof(FILE_OBJECT),
3124  sizeof(FILE_OBJECT),
3125  0,
3126  (PVOID*)&CreatedFileObject);
3127  if (!NT_SUCCESS(Status))
3128  {
3129  /* Fail */
3132  }
3133 
3134  /* Set File Object Data */
3135  RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3136  CreatedFileObject->DeviceObject = DeviceObject;
3137  CreatedFileObject->Type = IO_TYPE_FILE;
3138  CreatedFileObject->Size = sizeof(FILE_OBJECT);
3139  CreatedFileObject->Flags = FO_STREAM_FILE;
3140 
3141  /* Initialize the wait event */
3142  KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3143 
3144  /* Insert it to create a handle for it */
3145  Status = ObInsertObject(CreatedFileObject,
3146  NULL,
3148  1,
3149  (PVOID*)&CreatedFileObject,
3150  &FileHandle);
3152 
3153  /* Set the handle created flag */
3154  CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3155  ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3156 
3157  /* Check if we have a VPB */
3158  if (DeviceObject->Vpb)
3159  {
3160  /* Reference it */
3161  InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3162  }
3163 
3164  /* Check if the caller wants the handle */
3165  if (FileObjectHandle)
3166  {
3167  /* Return it */
3169  ObDereferenceObject(CreatedFileObject);
3170  }
3171  else
3172  {
3173  /* Otherwise, close it */
3175  }
3176 
3177  /* Return the file object */
3178  return CreatedFileObject;
3179 }
3180 
3181 /*
3182  * @implemented
3183  */
3185 NTAPI
3188 {
3189  /* Call the newer function */
3191 }
3192 
3193 /*
3194  * @implemented
3195  */
3197 NTAPI
3200 {
3201  PFILE_OBJECT CreatedFileObject;
3202  NTSTATUS Status;
3204  PAGED_CODE();
3205  IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3206 
3207  /* Choose Device Object */
3208  if (FileObject) DeviceObject = FileObject->DeviceObject;
3209 
3210  /* Reference the device object and initialize attributes */
3211  InterlockedIncrement(&DeviceObject->ReferenceCount);
3213 
3214  /* Create the File Object */
3218  KernelMode,
3219  NULL,
3220  sizeof(FILE_OBJECT),
3221  sizeof(FILE_OBJECT),
3222  0,
3223  (PVOID*)&CreatedFileObject);
3224  if (!NT_SUCCESS(Status))
3225  {
3226  /* Fail */
3229  }
3230 
3231  /* Set File Object Data */
3232  RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3233  CreatedFileObject->DeviceObject = DeviceObject;
3234  CreatedFileObject->Type = IO_TYPE_FILE;
3235  CreatedFileObject->Size = sizeof(FILE_OBJECT);
3236  CreatedFileObject->Flags = FO_STREAM_FILE;
3237 
3238  /* Initialize the wait event */
3239  KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3240 
3241  /* Destroy create information */
3243  ObjectCreateInfo);
3244  OBJECT_TO_OBJECT_HEADER(CreatedFileObject)->ObjectCreateInfo = NULL;
3245 
3246  /* Set the handle created flag */
3247  CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3248  ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3249 
3250  /* Check if we have a VPB */
3251  if (DeviceObject->Vpb)
3252  {
3253  /* Reference it */
3254  InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3255  }
3256 
3257  /* Return the file object */
3258  return CreatedFileObject;
3259 }
3260 
3261 /*
3262  * @implemented
3263  */
3265 NTAPI
3267 {
3268  /* Return the mapping */
3269  return &IopFileMapping;
3270 }
3271 
3272 /*
3273  * @implemented
3274  */
3275 BOOLEAN
3276 NTAPI
3278 {
3279  /* Return the flag status */
3280  return FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3281 }
3282 
3283 /*
3284  * @implemented
3285  */
3286 BOOLEAN
3287 NTAPI
3293 {
3294  NTSTATUS Status;
3295  DUMMY_FILE_OBJECT LocalFileObject;
3296  HANDLE Handle;
3297  OPEN_PACKET OpenPacket;
3298  PAGED_CODE();
3299  IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
3300 
3301  /* Setup the Open Packet */
3302  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
3303  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
3304  OpenPacket.Size = sizeof(OPEN_PACKET);
3307  OpenPacket.Options = IO_FORCE_ACCESS_CHECK;
3308  OpenPacket.Disposition = FILE_OPEN;
3309  OpenPacket.NetworkInformation = Buffer;
3310  OpenPacket.QueryOnly = TRUE;
3311  OpenPacket.FullAttributes = TRUE;
3312  OpenPacket.LocalFileObject = &LocalFileObject;
3313 
3314  /*
3315  * Attempt opening the file. This will call the I/O Parse Routine for
3316  * the File Object (IopParseDevice) which will use the dummy file obejct
3317  * send the IRP to its device object. Note that we have two statuses
3318  * to worry about: the Object Manager's status (in Status) and the I/O
3319  * status, which is in the Open Packet's Final Status, and determined
3320  * by the Parse Check member.
3321  */
3323  NULL,
3324  KernelMode,
3325  NULL,
3326  DesiredAccess,
3327  &OpenPacket,
3328  &Handle);
3329  if (OpenPacket.ParseCheck == FALSE)
3330  {
3331  /* Parse failed */
3332  IoStatus->Status = Status;
3333  }
3334  else
3335  {
3336  /* Use the Io status */
3337  IoStatus->Status = OpenPacket.FinalStatus;
3338  IoStatus->Information = OpenPacket.Information;
3339  }
3340 
3341  /* Return success */
3342  return TRUE;
3343 }
3344 
3345 /*
3346  * @implemented
3347  */
3348 VOID
3349 NTAPI
3352 {
3353  PAGED_CODE();
3354 
3355  /* Check if the file has an extension */
3357  {
3358  /* Check if caller specified to ignore access checks */
3359  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3360  {
3361  /* Don't update share access */
3362  return;
3363  }
3364  }
3365 
3366  /* Otherwise, check if there's any access present */
3367  if ((FileObject->ReadAccess) ||
3368  (FileObject->WriteAccess) ||
3369  (FileObject->DeleteAccess))
3370  {
3371  /* Increase the open count */
3372  ShareAccess->OpenCount++;
3373 
3374  /* Add new share access */
3375  ShareAccess->Readers += FileObject->ReadAccess;
3376  ShareAccess->Writers += FileObject->WriteAccess;
3377  ShareAccess->Deleters += FileObject->DeleteAccess;
3378  ShareAccess->SharedRead += FileObject->SharedRead;
3379  ShareAccess->SharedWrite += FileObject->SharedWrite;
3380  ShareAccess->SharedDelete += FileObject->SharedDelete;
3381  }
3382 }
3383 
3384 /*
3385  * @implemented
3386  */
3387 NTSTATUS
3388 NTAPI
3393  IN BOOLEAN Update)
3394 {
3397  BOOLEAN DeleteAccess;
3398  BOOLEAN SharedRead;
3399  BOOLEAN SharedWrite;
3400  BOOLEAN SharedDelete;
3401  PAGED_CODE();
3402 
3403  /* Get access masks */
3406  DeleteAccess = (DesiredAccess & DELETE) != 0;
3407 
3408  /* Set them in the file object */
3409  FileObject->ReadAccess = ReadAccess;
3410  FileObject->WriteAccess = WriteAccess;
3411  FileObject->DeleteAccess = DeleteAccess;
3412 
3413  /* Check if the file has an extension */
3415  {
3416  /* Check if caller specified to ignore access checks */
3417  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3418  {
3419  /* Don't check share access */
3420  return STATUS_SUCCESS;
3421  }
3422  }
3423 
3424  /* Check if we have any access */
3425  if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
3426  {
3427  /* Get shared access masks */
3428  SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3429  SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3430  SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3431 
3432  /* Set them */
3433  FileObject->SharedRead = SharedRead;
3434  FileObject->SharedWrite = SharedWrite;
3435  FileObject->SharedDelete = SharedDelete;
3436 
3437  /* Check if the shared access is violated */
3438  if ((ReadAccess &&
3439  (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
3440  (WriteAccess &&
3441  (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
3442  (DeleteAccess &&
3443  (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
3444  ((ShareAccess->Readers != 0) && !SharedRead) ||
3445  ((ShareAccess->Writers != 0) && !SharedWrite) ||
3446  ((ShareAccess->Deleters != 0) && !SharedDelete))
3447  {
3448  /* Sharing violation, fail */
3449  return STATUS_SHARING_VIOLATION;
3450  }
3451 
3452  /* It's not, check if caller wants us to update it */
3453  if (Update)
3454  {
3455  /* Increase open count */
3456  ShareAccess->OpenCount++;
3457 
3458  /* Update shared access */
3459  ShareAccess->Readers += ReadAccess;
3460  ShareAccess->Writers += WriteAccess;
3461  ShareAccess->Deleters += DeleteAccess;
3462  ShareAccess->SharedRead += SharedRead;
3463  ShareAccess->SharedWrite += SharedWrite;
3464  ShareAccess->SharedDelete += SharedDelete;
3465  }
3466  }
3467 
3468  /* Validation successful */
3469  return STATUS_SUCCESS;
3470 }
3471 
3472 /*
3473  * @implemented
3474  */
3475 VOID
3476 NTAPI
3479 {
3480  PAGED_CODE();
3481 
3482  /* Check if the file has an extension */
3484  {
3485  /* Check if caller specified to ignore access checks */
3486  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3487  {
3488  /* Don't update share access */
3489  return;
3490  }
3491  }
3492 
3493  /* Otherwise, check if there's any access present */
3494  if ((FileObject->ReadAccess) ||
3495  (FileObject->WriteAccess) ||
3496  (FileObject->DeleteAccess))
3497  {
3498  /* Decrement the open count */
3499  ShareAccess->OpenCount--;
3500 
3501  /* Remove share access */
3502  ShareAccess->Readers -= FileObject->ReadAccess;
3503  ShareAccess->Writers -= FileObject->WriteAccess;
3504  ShareAccess->Deleters -= FileObject->DeleteAccess;
3505  ShareAccess->SharedRead -= FileObject->SharedRead;
3506  ShareAccess->SharedWrite -= FileObject->SharedWrite;
3507  ShareAccess->SharedDelete -= FileObject->SharedDelete;
3508  }
3509 }
3510 
3511 /*
3512  * @implemented
3513  */
3514 VOID
3515 NTAPI
3520 {
3523  BOOLEAN DeleteAccess;
3524  BOOLEAN SharedRead;
3525  BOOLEAN SharedWrite;
3526  BOOLEAN SharedDelete;
3527  BOOLEAN Update = TRUE;
3528  PAGED_CODE();
3529 
3532  DeleteAccess = (DesiredAccess & DELETE) != 0;
3533 
3534  /* Check if the file has an extension */
3536  {
3537  /* Check if caller specified to ignore access checks */
3538  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3539  {
3540  /* Don't update share access */
3541  Update = FALSE;
3542  }
3543  }
3544 
3545  /* Update basic access */
3546  FileObject->ReadAccess = ReadAccess;
3547  FileObject->WriteAccess = WriteAccess;
3548  FileObject->DeleteAccess = DeleteAccess;
3549 
3550  /* Check if we have no access as all */
3551  if (!(ReadAccess) && !(WriteAccess) && !(DeleteAccess))
3552  {
3553  /* Check if we need to update the structure */
3554  if (!Update) return;
3555 
3556  /* Otherwise, clear data */
3557  ShareAccess->OpenCount = 0;
3558  ShareAccess->Readers = 0;
3559  ShareAccess->Writers = 0;
3560  ShareAccess->Deleters = 0;
3561  ShareAccess->SharedRead = 0;
3562  ShareAccess->SharedWrite = 0;
3563  ShareAccess->SharedDelete = 0;
3564  }
3565  else
3566  {
3567  /* Calculate shared access */
3568  SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3569  SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3570  SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3571 
3572  /* Set it in the FO */
3573  FileObject->SharedRead = SharedRead;
3574  FileObject->SharedWrite = SharedWrite;
3575  FileObject->SharedDelete = SharedDelete;
3576 
3577  /* Check if we need to update the structure */
3578  if (!Update) return;
3579 
3580  /* Otherwise, set data */
3581  ShareAccess->OpenCount = 1;
3582  ShareAccess->Readers = ReadAccess;
3583  ShareAccess->Writers = WriteAccess;
3584  ShareAccess->Deleters = DeleteAccess;
3585  ShareAccess->SharedRead = SharedRead;
3586  ShareAccess->SharedWrite = SharedWrite;
3587  ShareAccess->SharedDelete = SharedDelete;
3588  }
3589 }
3590 
3591 /*
3592  * @implemented
3593  */
3594 VOID
3595 NTAPI
3598 {
3599  PIRP Irp;
3600  KEVENT Event;
3601  KIRQL OldIrql;
3602  NTSTATUS Status;
3603  PIO_STACK_LOCATION Stack;
3604 
3605  /* Check if handles were already created for the
3606  * open file. If so, that's over.
3607  */
3608  if (FileObject->Flags & FO_HANDLE_CREATED)
3609  KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN,
3611  (ULONG_PTR)DeviceObject, 0, 0);
3612 
3613  /* Reset the events */
3615  KeClearEvent(&FileObject->Event);
3616 
3617  /* Allocate the IRP we'll use */
3619  /* Properly set it */
3620  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
3621  Irp->UserEvent = &Event;
3622  Irp->UserIosb = &Irp->IoStatus;
3623  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
3624  Irp->Tail.Overlay.OriginalFileObject = FileObject;
3625  Irp->RequestorMode = KernelMode;
3627 
3628  Stack = IoGetNextIrpStackLocation(Irp);
3629  Stack->MajorFunction = IRP_MJ_CLEANUP;
3630  Stack->FileObject = FileObject;
3631 
3632  /* Put on top of IRPs list of the thread */
3634 
3635  /* Call the driver */
3637  if (Status == STATUS_PENDING)
3638  {
3640  KernelMode, FALSE, NULL);
3641  }
3642 
3643  /* Remove from IRPs list */
3647 
3648  /* Free the IRP */
3649  IoFreeIrp(Irp);
3650 
3651  /* Clear the event */
3652  KeClearEvent(&FileObject->Event);
3653  /* And finally, mark the open operation as canceled */
3655 }
3656 
3657 /*
3658  * @implemented
3659  */
3660 NTSTATUS
3661 NTAPI
3664 {
3665  NTSTATUS Status;
3667  POBJECT_NAME_INFORMATION LocalInfo;
3668 
3669  /* Start with a buffer length of 200 */
3670  ReturnLength = 200;
3671  /*
3672  * We'll loop until query works.
3673  * We will use returned length for next loop
3674  * iteration, trying to have a big enough buffer.
3675  */
3676  for (Length = 200; ; Length = ReturnLength)
3677  {
3678  /* Allocate our work buffer */
3679  LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, 'nDoI');
3680  if (LocalInfo == NULL)
3681  {
3683  }
3684 
3685  /* Query the DOS name */
3687  TRUE,
3688  TRUE,
3689  LocalInfo,
3690  Length,
3691  &ReturnLength,
3692  KernelMode);
3693  /* If it succeed, nothing more to do */
3694  if (Status == STATUS_SUCCESS)
3695  {
3696  break;
3697  }
3698 
3699  /* Otherwise, prepare for re-allocation */
3700  ExFreePoolWithTag(LocalInfo, 'nDoI');
3701 
3702  /*
3703  * If we failed because of something else
3704  * than memory, simply stop and fail here
3705  */
3707  {
3708  return Status;
3709  }
3710  }
3711 
3712  /* Success case here: return our buffer */
3713  *ObjectNameInformation = LocalInfo;
3714  return STATUS_SUCCESS;
3715 }
3716 
3717 /*
3718  * @implemented
3719  */
3720 NTSTATUS
3721 NTAPI
3723  IN BOOLEAN Remote)
3724 {
3726  BOOLEAN FlagSet;
3727 
3728  /* Get the flag status */
3729  FlagSet = FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3730 
3731  /* Don't set the flag if it was set already, and don't remove it if it wasn't set */
3732  if (Remote && !FlagSet)
3733  {
3734  /* Set the flag */
3735  FileObject->Flags |= FO_REMOTE_ORIGIN;
3736  }
3737  else if (!Remote && FlagSet)
3738  {
3739  /* Remove the flag */
3740  FileObject->Flags &= ~FO_REMOTE_ORIGIN;
3741  }
3742  else
3743  {
3744  /* Fail */
3746  }
3747 
3748  /* Return status */
3749  return Status;
3750 }
3751 
3752 /*
3753  * @implemented
3754  */
3755 NTSTATUS
3756 NTAPI
3761  PLARGE_INTEGER AllocateSize,
3766  PVOID EaBuffer,
3767  ULONG EaLength)
3768 {
3769  /* Call the I/O Function */
3770  return IoCreateFile(FileHandle,
3771  DesiredAccess,
3773  IoStatusBlock,
3774  AllocateSize,
3776  ShareAccess,
3778  CreateOptions,
3779  EaBuffer,
3780  EaLength,
3782  NULL,
3783  0);
3784 }
3785 
3786 NTSTATUS
3787 NTAPI
3793  IN ULONG MailslotQuota,
3794  IN ULONG MaxMessageSize,
3795  IN PLARGE_INTEGER TimeOut)
3796 {
3798  PAGED_CODE();
3799 
3800  /* Check for Timeout */
3801  if (TimeOut)
3802  {
3803  /* check if the call came from user mode */
3804  if (KeGetPreviousMode() != KernelMode)
3805  {
3806  /* Enter SEH for Probe */
3807  _SEH2_TRY
3808  {
3809  /* Probe the timeout */
3810  Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
3811  }
3813  {
3814  /* Return the exception code */
3816  }
3817  _SEH2_END;
3818  }
3819  else
3820  {
3821  /* Otherwise, capture directly */
3822  Buffer.ReadTimeout = *TimeOut;
3823  }
3824 
3825  /* Set the correct setting */
3826  Buffer.TimeoutSpecified = TRUE;
3827  }
3828  else
3829  {
3830  /* Tell the FSD we don't have a timeout */
3831  Buffer.TimeoutSpecified = FALSE;
3832  }
3833 
3834  /* Set Settings */
3835  Buffer.MailslotQuota = MailslotQuota;
3836  Buffer.MaximumMessageSize = MaxMessageSize;
3837 
3838  /* Call I/O */
3839  return IoCreateFile(FileHandle,
3840  DesiredAccess,
3842  IoStatusBlock,
3843  NULL,
3844  0,
3846  FILE_CREATE,
3847  CreateOptions,
3848  NULL,
3849  0,
3851  (PVOID)&Buffer,
3852  0);
3853 }
3854 
3855 NTSTATUS
3856 NTAPI
3864  IN ULONG NamedPipeType,
3865  IN ULONG ReadMode,
3866  IN ULONG CompletionMode,
3867  IN ULONG MaximumInstances,
3868  IN ULONG InboundQuota,
3869  IN ULONG OutboundQuota,
3870  IN PLARGE_INTEGER DefaultTimeout)
3871 {
3873  PAGED_CODE();
3874 
3875  /* Check for Timeout */
3876  if (DefaultTimeout)
3877  {
3878  /* check if the call came from user mode */
3879  if (KeGetPreviousMode() != KernelMode)
3880  {
3881  /* Enter SEH for Probe */
3882  _SEH2_TRY
3883  {
3884  /* Probe the timeout */
3885  Buffer.DefaultTimeout =
3886  ProbeForReadLargeInteger(DefaultTimeout);
3887  }
3889  {
3890  /* Return the exception code */
3892  }
3893  _SEH2_END;
3894  }
3895  else
3896  {
3897  /* Otherwise, capture directly */
3898  Buffer.DefaultTimeout = *DefaultTimeout;
3899  }
3900 
3901  /* Set the correct setting */
3902  Buffer.TimeoutSpecified = TRUE;
3903  }
3904  else
3905  {
3906  /* Tell the FSD we don't have a timeout */
3907  Buffer.TimeoutSpecified = FALSE;
3908  }
3909 
3910  /* Set Settings */
3911  Buffer.NamedPipeType = NamedPipeType;
3912  Buffer.ReadMode = ReadMode;
3913  Buffer.CompletionMode = CompletionMode;
3914  Buffer.MaximumInstances = MaximumInstances;
3915  Buffer.InboundQuota = InboundQuota;
3916  Buffer.OutboundQuota = OutboundQuota;
3917 
3918  /* Call I/O */
3919  return IoCreateFile(FileHandle,
3920  DesiredAccess,
3922  IoStatusBlock,
3923  NULL,
3924  0,
3925  ShareAccess,
3927  CreateOptions,
3928  NULL,
3929  0,
3931  (PVOID)&Buffer,
3932  0);
3933 }
3934 
3935 NTSTATUS
3936 NTAPI
3938 {
3939  PAGED_CODE();
3940 
3941  /* Call the kernel */
3943  return STATUS_SUCCESS;
3944 }
3945 
3946 /*
3947  * @implemented
3948  */
3949 NTSTATUS
3950 NTAPI
3957 {
3958  /* Call the I/O Function */
3959  return IoCreateFile(FileHandle,
3960  DesiredAccess,
3962  IoStatusBlock,
3963  NULL,
3964  0,
3965  ShareAccess,
3966  FILE_OPEN,
3967  OpenOptions,
3968  NULL,
3969  0,
3971  NULL,
3972  0);
3973 }
3974 
3975 NTSTATUS
3976 NTAPI
3979 {
3980  /* Call the internal helper API */
3983  sizeof(FILE_BASIC_INFORMATION),
3984  FileInformation);
3985 }
3986 
3987 NTSTATUS
3988 NTAPI
3991 {
3992  /* Call the internal helper API */
3996  FileInformation);
3997 }
3998 
4016 NTSTATUS
4017 NTAPI
4020 {
4022  PETHREAD Thread;
4023  PIRP Irp;
4024  KIRQL OldIrql;
4025  BOOLEAN OurIrpsInList = FALSE;
4028  NTSTATUS Status;
4029  PLIST_ENTRY ListHead, NextEntry;
4030  PAGED_CODE();
4031  IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
4032 
4033  /* Check the previous mode */
4034  if (PreviousMode != KernelMode)
4035  {
4036  /* Enter SEH for probing */
4037  _SEH2_TRY
4038  {
4039  /* Probe the I/O Status Block */
4041  }
4043  {
4044  /* Return the exception code */
4046  }
4047  _SEH2_END;
4048  }
4049 
4050  /* Reference the file object */
4052  0,
4054  PreviousMode,
4055  (PVOID*)&FileObject,
4056  NULL);
4057  if (!NT_SUCCESS(Status)) return Status;
4058 
4059  /* IRP cancellations are synchronized at APC_LEVEL. */
4061 
4062  /* Get the current thread */
4064 
4065  /* Update the operation counts */
4067 
4068  /* Loop the list */
4069  ListHead = &Thread->IrpList;
4070  NextEntry = ListHead->Flink;
4071  while (ListHead != NextEntry)
4072  {
4073  /* Get the IRP and check if the File Object matches */
4074  Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4075  if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4076  {
4077  /* Cancel this IRP and keep looping */
4078  IoCancelIrp(Irp);
4079  OurIrpsInList = TRUE;
4080  }
4081 
4082  /* Go to the next entry */
4083  NextEntry = NextEntry->Flink;
4084  }
4085 
4086  /* Lower the IRQL */
4088 
4089  /* Check if we had found an IRP */
4090  if (OurIrpsInList)
4091  {
4092  /* Setup a 10ms wait */
4093  Interval.QuadPart = -100000;
4094 
4095  /* Start looping */
4096  while (OurIrpsInList)
4097  {
4098  /* Do the wait */
4100  OurIrpsInList = FALSE;
4101 
4102  /* Raise IRQL */
4104 
4105  /* Now loop the list again */
4106  NextEntry = ListHead->Flink;
4107  while (NextEntry != ListHead)
4108  {
4109  /* Get the IRP and check if the File Object matches */
4110  Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4111  if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4112  {
4113  /* Keep looping */
4114  OurIrpsInList = TRUE;
4115  break;
4116  }
4117 
4118  /* Go to the next entry */
4119  NextEntry = NextEntry->Flink;
4120  }
4121 
4122  /* Lower the IRQL */
4124  }
4125  }
4126 
4127  /* Enter SEH for writing back the I/O Status */
4128  _SEH2_TRY
4129  {
4130  /* Write success */
4133  }
4135  {
4136  /* Ignore exception */
4137  }
4138  _SEH2_END;
4139 
4140  /* Dereference the file object and return success */
4142  return STATUS_SUCCESS;
4143 }
4144 
4145 /*
4146  * @implemented
4147  */
4148 NTSTATUS
4149 NTAPI
4151 {
4152  NTSTATUS Status;
4153  DUMMY_FILE_OBJECT LocalFileObject;
4154  HANDLE Handle;
4156  OPEN_PACKET OpenPacket;
4157  PAGED_CODE();
4158  IOTRACE(IO_API_DEBUG, "FileMame: %wZ\n", ObjectAttributes->ObjectName);
4159 
4160  /* Setup the Open Packet */
4161  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
4162  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
4163  OpenPacket.Size = sizeof(OPEN_PACKET);
4164  OpenPacket.CreateOptions = FILE_DELETE_ON_CLOSE;
4165  OpenPacket.ShareAccess = FILE_SHARE_READ |
4168  OpenPacket.Disposition = FILE_OPEN;
4169  OpenPacket.DeleteOnly = TRUE;
4170  OpenPacket.LocalFileObject = &LocalFileObject;
4171 
4172  /* Update the operation counts */
4174 
4175  /*
4176  * Attempt opening the file. This will call the I/O Parse Routine for
4177  * the File Object (IopParseDevice) which will use the dummy file obejct
4178  * send the IRP to its device object. Note that we have two statuses
4179  * to worry about: the Object Manager's status (in Status) and the I/O
4180  * status, which is in the Open Packet's Final Status, and determined
4181  * by the Parse Check member.
4182  */
4184  NULL,
4185  AccessMode,
4186  NULL,
4187  DELETE,
4188  &OpenPacket,
4189  &Handle);
4190  if (OpenPacket.ParseCheck == FALSE) return Status;
4191 
4192  /* Retrn the Io status */
4193  return OpenPacket.FinalStatus;
4194 }
4195 
4196 /* EOF */
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2529
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3266
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:98
#define FILE_GENERIC_READ
Definition: nt_native.h:653
NTSTATUS NTAPI IopGetFileInformation(IN PFILE_OBJECT FileObject, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInfoClass, OUT PVOID Buffer, OUT PULONG ReturnedLength)
Definition: iofunc.c:775
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
BOOLEAN NTAPI SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked, IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK PreviouslyGrantedAccess, OUT PPRIVILEGE_SET *Privileges, IN PGENERIC_MAPPING GenericMapping, IN KPROCESSOR_MODE AccessMode, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus)
Definition: accesschk.c:340
ObjectType
Definition: metafile.c:80
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:452
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define FO_HANDLE_CREATED
Definition: iotypes.h:1751
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define ProbeForWriteIoStatusBlock(Ptr)
Definition: probe.h:52
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3227
USHORT ShareAccess
Definition: io.h:375
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTKERNELAPI NTSTATUS NTAPI SeSetSecurityDescriptorInfo(_In_opt_ PVOID Object, _In_ PSECURITY_INFORMATION SecurityInformation, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping)
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1777
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#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
#define IRP_MJ_CREATE_MAILSLOT
ULONG Options
Definition: io.h:378
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define TAG_IO
Definition: tag.h:69
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSTATUS NTAPI NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
Definition: file.c:3989
VOID NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:336
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:508
Type
Definition: Type.h:6
NTSTATUS NTAPI IopCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options, IN ULONG Flags, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:2553
#define IRP_CLOSE_OPERATION
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_opt_ PVOID FilterContext
Definition: fsrtlfuncs.h:738
#define IRP_MJ_QUERY_SECURITY
static PVOID
Definition: file.c:43
static __inline BOOLEAN IopValidateOpenPacket(IN POPEN_PACKET OpenPacket)
Definition: io_x.h:149
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:137
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE _Out_ PUINT _In_ UINT _In_ NDIS_HANDLE _In_ NDIS_HANDLE _In_ PNDIS_STRING _In_ UINT OpenOptions
Definition: ndis.h:6013
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONG_PTR Information
Definition: io.h:368
#define FILE_VALID_MAILSLOT_OPTION_FLAGS
Definition: nt_native.h:761
VOID NTAPI FsRtlPTeardownPerFileObjectContexts(IN PFILE_OBJECT FileObject)
Definition: filtrctx.c:28
ULONG EaLength
Definition: io.h:377
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI IopQueryNameInternal(IN PVOID ObjectBody, IN BOOLEAN HasName, IN BOOLEAN QueryDosName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: file.c:1943
#define IO_TYPE_FILE
NTSTATUS NTAPI NtCreateMailslotFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG CreateOptions, IN ULONG MailslotQuota, IN ULONG MaxMessageSize, IN PLARGE_INTEGER TimeOut)
Definition: file.c:3788
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define FO_DIRECT_DEVICE_OPEN
Definition: iotypes.h:1744
#define TAG_IO_NAME
Definition: tag.h:72
const LUID SeBackupPrivilege
Definition: priv.c:38
_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
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
DeviceType
Definition: mmdrv.h:41
#define IO_TYPE_OPEN_PACKET
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
NTSTATUS NTAPI IoSetFileOrigin(IN PFILE_OBJECT FileObject, IN BOOLEAN Remote)
Definition: file.c:3722
PVOID NTAPI IoGetFileObjectFilterContext(IN PFILE_OBJECT FileObject)
Definition: file.c:2495
PDEVICE_OBJECT NTAPI IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1485
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2513
#define IRP_MJ_SET_SECURITY
#define FILE_DEVICE_FILE_SYSTEM
Definition: winioctl.h:114
static ULONG
Definition: file.c:43
struct _OPEN_PACKET OPEN_PACKET
#define KeGetPreviousMode()
Definition: ketypes.h:1107
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_opt_ PVOID EaBuffer
Definition: iofuncs.h:835
LONG NTSTATUS
Definition: precomp.h:26
ULONG ParseCheck
Definition: io.h:369
PVOID ExtraCreateParameters
Definition: io.h:383
PFILE_BASIC_INFORMATION BasicInformation
Definition: io.h:380
#define FILE_CREATE
Definition: from_kernel.h:55
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
OBJECT_HEADER ObjectHeader
Definition: io.h:354
LARGE_INTEGER AllocationSize
Definition: io.h:372
VOID NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:314
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1753
#define IOP_USE_TOP_LEVEL_DEVICE_HINT
Definition: io.h:92
#define ExRaiseStatus
Definition: ntoskrnl.h:95
#define FILE_PIPE_MESSAGE_TYPE
Definition: iotypes.h:76
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
CSHORT Type
Definition: io.h:364
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2511
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1124
VOID NTAPI IopCheckBackupRestorePrivilege(IN PACCESS_STATE AccessState, IN OUT PULONG CreateOptions, IN KPROCESSOR_MODE PreviousMode, IN ULONG Disposition)
Definition: file.c:25
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
NTSTATUS NTAPI IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options, IN PVOID DeviceObject)
Definition: file.c:3049
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
VOID NTAPI IopDoNameTransmogrify(IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER DataBuffer)
Definition: file.c:170
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3516
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
BOOLEAN NTAPI IopVerifyDeviceObjectOnStack(IN PDEVICE_OBJECT BaseDeviceObject, IN PDEVICE_OBJECT TopDeviceObjectHint)
Definition: device.c:695
IRP
Definition: iotypes.h:2463
uint16_t * PWCHAR
Definition: typedefs.h:54
#define WRITE_OWNER
Definition: nt_native.h:60
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:271
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
UNICODE_STRING Name
Definition: nt_native.h:1270
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1114
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1735
#define FILE_APPEND_DATA
Definition: nt_native.h:634
enum OPTION_FLAGS Options
Definition: stats.c:44
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
BOOLEAN TraversedMountPoint
Definition: io.h:389
PFILE_OBJECT NTAPI IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:3198
#define FILE_RESERVE_OPFILTER
Definition: from_kernel.h:45
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_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 _In_ USHORT ShareAccess
Definition: create.c:4157
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3477
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
NTSTATUS NTAPI IoQueryFileInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength)
Definition: iofunc.c:1272
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define PAGED_CODE()
Definition: video.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IO_API_DEBUG
Definition: io.h:21
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
CSHORT Size
Definition: io.h:365
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_ ULONG _In_ CREATE_FILE_TYPE CreateFileType
Definition: iofuncs.h:835
NTSTATUS NTAPI IopParseFile(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: file.c:1318
uint32_t ULONG_PTR
Definition: typedefs.h:63
PFILE_OBJECT FileObject
Definition: io.h:366
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:256
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1733
PVOID EaBuffer
Definition: io.h:376
NTSTATUS NTAPI IopParseDevice(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: file.c:324
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6875
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define NT_WARNING(Status)
Definition: umtypes.h:105
NTSTATUS NTAPI IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, IN ULONG QuotaLength, OUT PULONG ErrorOffset)
Definition: file.c:2996
NTSTATUS NTAPI IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)
Definition: volume.c:1284
#define IO_FILE_DEBUG
Definition: io.h:20
static __inline NTSTATUS IopLockFileObject(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode)
Definition: io_x.h:12
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI IopDeleteFile(IN PVOID ObjectBody)
Definition: file.c:1354
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define STATUS_MOUNT_POINT_NOT_RESOLVED
Definition: ntstatus.h:900
HANDLE FileHandle
Definition: stats.c:38
WCHAR PathBuffer[1]
Definition: shellext.h:152
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
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
PFILE_OBJECT RelatedFileObject
Definition: io.h:370
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
PFILE_OBJECT NTAPI IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, OUT PHANDLE FileObjectHandle OPTIONAL)
Definition: file.c:3099
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3277
#define UNICODE_NULL
BOOLEAN Override
Definition: io.h:384
NTSTATUS NTAPI IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject, IN PVOID FilterContext, IN BOOLEAN Define)
Definition: file.c:2510
CREATE_FILE_TYPE CreateFileType
Definition: io.h:382
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:509
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define FO_REMOTE_ORIGIN
Definition: iotypes.h:1756
#define FILE_READ_DATA
Definition: nt_native.h:628
_In_opt_ PDEVICE_OBJECT _Out_opt_ PHANDLE FileObjectHandle
Definition: iofuncs.h:2170
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI SeAppendPrivileges(IN OUT PACCESS_STATE AccessState, IN PPRIVILEGE_SET Privileges)
Definition: priv.c:407
#define IO_TYPE_DEVICE
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define STATUS_IO_REPARSE_DATA_INVALID
Definition: ntstatus.h:742
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
PVOID FilterContext
Definition: io.h:99
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI IopSetDeviceSecurityDescriptors(IN PDEVICE_OBJECT UpperDeviceObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
Definition: file.c:1605
#define DO_BUS_ENUMERATED_DEVICE
#define IOP_MAX_REPARSE_TRAVERSAL
Definition: io.h:87
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
struct _OPEN_PACKET * POPEN_PACKET
VOID NTAPI IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject)
Definition: file.c:3596
#define _Out_
Definition: no_sal2.h:323
void DPRINT(...)
Definition: polytest.cpp:61
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1339
Definition: bufpool.h:45
FORCEINLINE VOID IopQueueIrpToThread(IN PIRP Irp)
Definition: io_x.h:49
NTSTATUS NTAPI IopSetDeviceSecurityDescriptor(IN PDEVICE_OBJECT DeviceObject, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
Definition: file.c:1524
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1230
NTSTATUS NTAPI IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN BOOLEAN SetOperation)
Definition: file.c:2983
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#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
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3186
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 FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1737
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
DWORD Interval
Definition: netstat.c:33
BOOLEAN DeleteOnly
Definition: io.h:386
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
NTSTATUS NTAPI NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: file.c:4150
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1126
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
PIRP NTAPI IopAllocateIrpMustSucceed(IN CCHAR StackSize)
Definition: irp.c:716
BOOLEAN QueryOnly
Definition: io.h:385
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:866
VOID NTAPI ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: oblife.c:604
const LUID SeRestorePrivilege
Definition: priv.c:39
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
DWORD * PSECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
USHORT FileAttributes
Definition: io.h:374
INT POOL_TYPE
Definition: typedefs.h:76
#define FO_FILE_OPEN_CANCELLED
Definition: iotypes.h:1754
VOID NTAPI IopCloseFile(IN PEPROCESS Process OPTIONAL, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount, IN ULONG SystemHandleCount)
Definition: file.c:2177
#define IO_ATTACH_DEVICE
Definition: iotypes.h:4074
#define IO_REPARSE
Definition: iotypes.h:511
NTSTATUS NTAPI IopCheckDeviceAndDriver(IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:135
#define DO_NEVER_LAST_DEVICE
Definition: env_spec_w32.h:402
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define IO_ATTACH_DEVICE_API
Definition: iotypes.h:209
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define WRITE_DAC
Definition: nt_native.h:59
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
PVPB NTAPI IopCheckVpbMounted(IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING RemainingName, OUT PNTSTATUS Status)
Definition: volume.c:81
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145