ReactOS  0.4.11-dev-721-g95bc44e
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 */
39  if (*CreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)
40  {
41  /* Set the check flag since were doing it now */
42  AccessState->Flags |= SE_BACKUP_PRIVILEGES_CHECKED;
43 
44  /* Set the access masks required */
45  ReadAccess = READ_CONTROL |
49  WriteAccess = WRITE_DAC |
50  WRITE_OWNER |
55  DELETE;
56  DesiredAccess = AccessState->RemainingDesiredAccess;
57 
58  /* Check if desired access was the maximum */
59  if (DesiredAccess & MAXIMUM_ALLOWED)
60  {
61  /* Then add all the access masks required */
62  DesiredAccess |= (ReadAccess | WriteAccess);
63  }
64 
65  /* Check if the file already exists */
66  if (Disposition & FILE_OPEN)
67  {
68  /* Check if desired access has the read mask */
69  if (ReadAccess & DesiredAccess)
70  {
71  /* Setup the privilege check lookup */
72  Privileges.PrivilegeCount = 1;
74  Privileges.Privilege[0].Luid = SeBackupPrivilege;
75  Privileges.Privilege[0].Attributes = 0;
76  AccessGranted = SePrivilegeCheck(&Privileges,
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 */
86  SeAppendPrivileges(AccessState, &Privileges);
87  AccessState->PreviouslyGrantedAccess |= (DesiredAccess & ReadAccess);
88  AccessState->RemainingDesiredAccess &= ~ReadAccess;
89  DesiredAccess &= ~ReadAccess;
90 
91  /* Set backup privilege for the token */
92  AccessState->Flags |= TOKEN_HAS_BACKUP_PRIVILEGE;
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;
110  AccessGranted = SePrivilegeCheck(&Privileges,
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 */
119  SeAppendPrivileges(AccessState, &Privileges);
120  AccessState->PreviouslyGrantedAccess |= (DesiredAccess & WriteAccess);
121  AccessState->RemainingDesiredAccess &= ~WriteAccess;
122 
123  /* Set restore privilege for the token */
124  AccessState->Flags |= TOKEN_HAS_RESTORE_PRIVILEGE;
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 &
144  (DeviceObject->Flags & DO_DEVICE_INITIALIZING))
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 mem 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 */
224  NewBuffer = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_IO_NAME);
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 reserved */
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, 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  ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME);
257  }
258 
259  FileObject->FileName.Buffer = NewBuffer;
260  FileObject->FileName.MaximumLength = RequiredLength;
261  FileObject->FileName.Buffer[RequiredLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
262  }
263  }
264 
265  /* We don't need them anymore - it was allocated by the driver */
266  ExFreePool(DataBuffer);
267 }
268 
269 NTSTATUS
271  IN POPEN_PACKET OpenPacket,
272  BOOLEAN DirectOpen)
273 {
276 
277  LocalDevice = *DeviceObject;
278 
279  /* Direct open is not allowed */
280  if (DirectOpen)
281  {
283  }
284 
285  /* Validate we have a file system device */
286  DeviceType = LocalDevice->DeviceType;
287  if (DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM &&
288  DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM &&
289  DeviceType != FILE_DEVICE_TAPE_FILE_SYSTEM &&
290  DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM &&
291  DeviceType != FILE_DEVICE_DFS_FILE_SYSTEM)
292  {
294  }
295 
296  /* Verify the hint and if it's OK, return it */
297  if (IopVerifyDeviceObjectOnStack(LocalDevice, OpenPacket->TopDeviceObjectHint))
298  {
299  *DeviceObject = OpenPacket->TopDeviceObjectHint;
300  return STATUS_SUCCESS;
301  }
302 
303  /* Failure case here */
304  /* If we thought was had come through a mount point,
305  * actually update we didn't and return the error
306  */
307  if (OpenPacket->TraversedMountPoint)
308  {
309  OpenPacket->TraversedMountPoint = FALSE;
311  }
312 
313  /* Otherwise, just return the fact the hint is invalid */
315 }
316 
317 NTSTATUS
318 NTAPI
319 IopParseDevice(IN PVOID ParseObject,
324  IN OUT PUNICODE_STRING CompleteName,
328  OUT PVOID *Object)
329 {
330  POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
331  PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject;
332  PDEVICE_OBJECT DeviceObject, OwnerDevice;
335  PVPB Vpb = NULL;
336  PIRP Irp;
337  PIO_STACK_LOCATION StackLoc;
338  IO_SECURITY_CONTEXT SecurityContext;
340  BOOLEAN DirectOpen = FALSE, OpenCancelled, UseDummyFile;
342  KIRQL OldIrql;
343  PDUMMY_FILE_OBJECT LocalFileObject;
344  PFILE_BASIC_INFORMATION FileBasicInfo;
346  KPROCESSOR_MODE CheckMode;
347  BOOLEAN VolumeOpen = FALSE;
349  BOOLEAN AccessGranted, LockHeld = FALSE;
351  UNICODE_STRING FileString;
352  USHORT Attempt;
353  IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n",
354  ParseObject, RemainingName);
355 
356  for (Attempt = 0; Attempt < IOP_MAX_REPARSE_TRAVERSAL; ++Attempt)
357  {
358  /* Assume failure */
359  *Object = NULL;
360 
361  /* Validate the open packet */
362  if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
363 
364  /* Valide reparse point in case we traversed a mountpoint */
365  if (OpenPacket->TraversedMountPoint)
366  {
367  /* This is a reparse point we understand */
369 
370  /* Make sure we're dealing with correct DO */
371  if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK &&
372  OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM &&
373  OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
374  OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE)
375  {
378  }
379  }
380 
381  /* Check if we have a related file object */
382  if (OpenPacket->RelatedFileObject)
383  {
384  /* Use the related file object's device object */
385  OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
386  }
387 
388  /* Validate device status */
389  Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject);
390  if (!NT_SUCCESS(Status))
391  {
392  /* We failed, return status */
393  OpenPacket->FinalStatus = Status;
394  return Status;
395  }
396 
397  /* Map the generic mask and set the new mapping in the access state */
398  RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
400  RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
402  SeSetAccessStateGenericMapping(AccessState,
404  DesiredAccess = AccessState->RemainingDesiredAccess;
405 
406  /* Check what kind of access checks to do */
407  if ((AccessMode != KernelMode) ||
408  (OpenPacket->Options & IO_FORCE_ACCESS_CHECK))
409  {
410  /* Call is from user-mode or kernel is forcing checks */
411  CheckMode = UserMode;
412  }
413  else
414  {
415  /* Call is from the kernel */
416  CheckMode = KernelMode;
417  }
418 
419  /* Check privilege for backup or restore operation */
420  IopCheckBackupRestorePrivilege(AccessState,
421  &OpenPacket->CreateOptions,
422  CheckMode,
423  OpenPacket->Disposition);
424 
425  /* Check if we are re-parsing */
426  if (((OpenPacket->Override) && !(RemainingName->Length)) ||
427  (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED))
428  {
429  /* Get granted access from the last call */
430  DesiredAccess |= AccessState->PreviouslyGrantedAccess;
431  }
432 
433  /* Check if this is a volume open */
434  if ((OpenPacket->RelatedFileObject) &&
435  (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
436  !(RemainingName->Length))
437  {
438  /* It is */
439  VolumeOpen = TRUE;
440  }
441 
442  /* Now check if we need access checks */
443  if (((AccessMode != KernelMode) ||
444  (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) &&
445  (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) &&
446  !(OpenPacket->Override))
447  {
450 
451  /* Check if a device object is being parsed */
452  if (!RemainingName->Length)
453  {
454  /* Lock the subject context */
455  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
456  LockHeld = TRUE;
457 
458  /* Do access check */
459  AccessGranted = SeAccessCheck(OriginalDeviceObject->
461  &AccessState->SubjectSecurityContext,
462  LockHeld,
463  DesiredAccess,
464  0,
465  &Privileges,
467  TypeInfo.GenericMapping,
468  UserMode,
469  &GrantedAccess,
470  &Status);
471  if (Privileges)
472  {
473  /* Append and free the privileges */
474  SeAppendPrivileges(AccessState, Privileges);
475  SeFreePrivileges(Privileges);
476  }
477 
478  /* Check if we got access */
479  if (AccessGranted)
480  {
481  /* Update access state */
482  AccessState->PreviouslyGrantedAccess |= GrantedAccess;
483  AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
485  OpenPacket->Override= TRUE;
486  }
487 
488  FileString.Length = 8;
489  FileString.MaximumLength = 8;
490  FileString.Buffer = L"File";
491 
492  /* Do Audit/Alarm for open operation */
493  SeOpenObjectAuditAlarm(&FileString,
494  OriginalDeviceObject,
495  CompleteName,
496  OriginalDeviceObject->SecurityDescriptor,
497  AccessState,
498  FALSE,
499  AccessGranted,
500  UserMode,
501  &AccessState->GenerateOnClose);
502  }
503  else
504  {
505  /* Check if we need to do traverse validation */
506  if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) ||
507  ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
508  (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM)))
509  {
510  /* Check if this is a restricted token */
511  if (!(AccessState->Flags & TOKEN_IS_RESTRICTED))
512  {
513  /* Do the FAST traverse check */
514  AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor,
515  AccessState,
517  UserMode);
518  }
519  else
520  {
521  /* Fail */
522  AccessGranted = FALSE;
523  }
524 
525  /* Check if we failed to get access */
526  if (!AccessGranted)
527  {
528  /* Lock the subject context */
529  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
530  LockHeld = TRUE;
531 
532  /* Do access check */
533  AccessGranted = SeAccessCheck(OriginalDeviceObject->
535  &AccessState->SubjectSecurityContext,
536  LockHeld,
538  0,
539  &Privileges,
541  TypeInfo.GenericMapping,
542  UserMode,
543  &GrantedAccess,
544  &Status);
545  if (Privileges)
546  {
547  /* Append and free the privileges */
548  SeAppendPrivileges(AccessState, Privileges);
549  SeFreePrivileges(Privileges);
550  }
551  }
552 
553  /* FIXME: Do Audit/Alarm for traverse check */
554  }
555  else
556  {
557  /* Access automatically granted */
558  AccessGranted = TRUE;
559  }
560  }
561 
564 
565  /* Check if we hold the lock */
566  if (LockHeld)
567  {
568  /* Release it */
569  SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
570  }
571 
572  /* Check if access failed */
573  if (!AccessGranted)
574  {
575  /* Dereference the device and fail */
576  DPRINT1("Traverse access failed!\n");
577  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
578  return STATUS_ACCESS_DENIED;
579  }
580  }
581 
582  /* Check if we can simply use a dummy file */
583  UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
584 
585 #if 1
586  /* FIXME: Small hack still exists, have to check why...
587  * This is triggered multiple times by usetup and then once per boot.
588  */
589  if (ExpInTextModeSetup &&
590  !(DirectOpen) &&
591  !(RemainingName->Length) &&
592  !(OpenPacket->RelatedFileObject) &&
593  ((wcsstr(CompleteName->Buffer, L"Harddisk")) ||
594  (wcsstr(CompleteName->Buffer, L"Floppy"))) &&
595  !(UseDummyFile))
596  {
597  DPRINT1("Using IopParseDevice() hack. Requested invalid attributes: %lx\n",
598  DesiredAccess & ~(SYNCHRONIZE |
600  READ_CONTROL |
602  WRITE_OWNER |
603  WRITE_DAC));
604  DirectOpen = TRUE;
605  }
606 #endif
607 
608  /* Check if this is a direct open */
609  if (!(RemainingName->Length) &&
610  !(OpenPacket->RelatedFileObject) &&
611  ((DesiredAccess & ~(SYNCHRONIZE |
613  READ_CONTROL |
615  WRITE_OWNER |
616  WRITE_DAC)) == 0) &&
617  !(UseDummyFile))
618  {
619  /* Remember this for later */
620  DirectOpen = TRUE;
621  }
622 
623  /* Check if we have a related FO that wasn't a direct open */
624  if ((OpenPacket->RelatedFileObject) &&
625  !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
626  {
627  /* The device object is the one we were given */
628  DeviceObject = ParseObject;
629 
630  /* Check if the related FO had a VPB */
631  if (OpenPacket->RelatedFileObject->Vpb)
632  {
633  /* Yes, remember it */
634  Vpb = OpenPacket->RelatedFileObject->Vpb;
635 
636  /* Reference it */
638 
639  /* Check if we were given a specific top level device to use */
641  {
642  DeviceObject = Vpb->DeviceObject;
643  }
644  }
645  }
646  else
647  {
648  /* Check if it has a VPB */
649  if ((OriginalDeviceObject->Vpb) && !(DirectOpen))
650  {
651  /* Check if the VPB is mounted, and mount it */
652  Vpb = IopCheckVpbMounted(OpenPacket,
653  OriginalDeviceObject,
654  RemainingName,
655  &Status);
656  if (!Vpb) return Status;
657 
658  /* Get the VPB's device object */
659  DeviceObject = Vpb->DeviceObject;
660  }
661  else
662  {
663  /* The device object is the one we were given */
664  DeviceObject = OriginalDeviceObject;
665  }
666 
667  /* If we weren't given a specific top level device, look for an attached device */
668  if (!(OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT) &&
669  DeviceObject->AttachedDevice)
670  {
671  /* Get the attached device */
672  DeviceObject = IoGetAttachedDevice(DeviceObject);
673  }
674  }
675 
676  /* If we have a top level device hint, verify it */
678  {
679  Status = IopCheckTopDeviceHint(&DeviceObject, OpenPacket, DirectOpen);
680  if (!NT_SUCCESS(Status))
681  {
682  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
683  if (Vpb) IopDereferenceVpbAndFree(Vpb);
684  return Status;
685  }
686  }
687 
688  /* If we traversed a mount point, reset the information */
689  if (OpenPacket->TraversedMountPoint)
690  {
691  OpenPacket->TraversedMountPoint = FALSE;
692  }
693 
694  /* Check if this is a secure FSD */
695  if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
696  ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) &&
697  (!VolumeOpen))
698  {
699  Privileges = NULL;
700  GrantedAccess = 0;
701 
704 
705  /* Lock the subject context */
706  SeLockSubjectContext(&AccessState->SubjectSecurityContext);
707 
708  /* Do access check */
709  AccessGranted = SeAccessCheck(OriginalDeviceObject->SecurityDescriptor,
710  &AccessState->SubjectSecurityContext,
711  TRUE,
712  DesiredAccess,
713  0,
714  &Privileges,
716  UserMode,
717  &GrantedAccess,
718  &Status);
719  if (Privileges != NULL)
720  {
721  /* Append and free the privileges */
722  SeAppendPrivileges(AccessState, Privileges);
723  SeFreePrivileges(Privileges);
724  }
725 
726  /* Check if we got access */
727  if (GrantedAccess)
728  {
729  AccessState->PreviouslyGrantedAccess |= GrantedAccess;
730  AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED);
731  }
732 
733  FileString.Length = 8;
734  FileString.MaximumLength = 8;
735  FileString.Buffer = L"File";
736 
737  /* Do Audit/Alarm for open operation
738  * NOTA: we audit target device object
739  */
740  SeOpenObjectAuditAlarm(&FileString,
741  DeviceObject,
742  CompleteName,
743  OriginalDeviceObject->SecurityDescriptor,
744  AccessState,
745  FALSE,
746  AccessGranted,
747  UserMode,
748  &AccessState->GenerateOnClose);
749 
750  SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
751 
754 
755  /* Check if access failed */
756  if (!AccessGranted)
757  {
758  /* Dereference the device and fail */
759  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
760  if (Vpb) IopDereferenceVpbAndFree(Vpb);
761  return STATUS_ACCESS_DENIED;
762  }
763  }
764 
765  /* Allocate the IRP */
766  Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
767  if (!Irp)
768  {
769  /* Dereference the device and VPB, then fail */
770  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
771  if (Vpb) IopDereferenceVpbAndFree(Vpb);
773  }
774 
775  /* Now set the IRP data */
776  Irp->RequestorMode = AccessMode;
778  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
779  Irp->UserIosb = &IoStatusBlock;
780  Irp->MdlAddress = NULL;
781  Irp->PendingReturned = FALSE;
782  Irp->UserEvent = NULL;
783  Irp->Cancel = FALSE;
784  Irp->CancelRoutine = NULL;
785  Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
786 
787  /* Setup the security context */
788  SecurityContext.SecurityQos = SecurityQos;
789  SecurityContext.AccessState = AccessState;
790  SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
791  SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
792 
793  /* Get the I/O Stack location */
794  StackLoc = IoGetNextIrpStackLocation(Irp);
795  StackLoc->Control = 0;
796 
797  /* Check what kind of file this is */
798  switch (OpenPacket->CreateFileType)
799  {
800  /* Normal file */
801  case CreateFileTypeNone:
802 
803  /* Set the major function and EA Length */
804  StackLoc->MajorFunction = IRP_MJ_CREATE;
805  StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
806 
807  /* Set the flags */
808  StackLoc->Flags = (UCHAR)OpenPacket->Options;
809  StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ? SL_CASE_SENSITIVE: 0;
810  break;
811 
812  /* Named pipe */
814 
815  /* Set the named pipe MJ and set the parameters */
817  StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters;
818  break;
819 
820  /* Mailslot */
822 
823  /* Set the mailslot MJ and set the parameters */
825  StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters;
826  break;
827  }
828 
829  /* Set the common data */
830  Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
831  Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer;
832  StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
833  (OpenPacket->CreateOptions &
834  0xFFFFFF);
835  StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
836  StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
837  StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
838 
839  /* Check if we really need to create an object */
840  if (!UseDummyFile)
841  {
842  ULONG ObjectSize = sizeof(FILE_OBJECT);
843 
844  /* Tag on space for a file object extension */
846  ObjectSize += sizeof(FILE_OBJECT_EXTENSION);
847 
848  /* Create the actual file object */
849  InitializeObjectAttributes(&ObjectAttributes,
850  NULL,
851  Attributes,
852  NULL,
853  NULL);
854  Status = ObCreateObject(KernelMode,
856  &ObjectAttributes,
857  AccessMode,
858  NULL,
859  ObjectSize,
860  0,
861  0,
862  (PVOID*)&FileObject);
863  if (!NT_SUCCESS(Status))
864  {
865  /* Create failed, free the IRP */
866  IoFreeIrp(Irp);
867 
868  /* Dereference the device and VPB */
869  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
870  if (Vpb) IopDereferenceVpbAndFree(Vpb);
871 
872  /* We failed, return status */
873  OpenPacket->FinalStatus = Status;
874  return Status;
875  }
876 
877  /* Clear the file object */
878  RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
879 
880  /* Check if this is Synch I/O */
881  if (OpenPacket->CreateOptions &
883  {
884  /* Set the synch flag */
885  FileObject->Flags |= FO_SYNCHRONOUS_IO;
886 
887  /* Check if it's also alertable */
888  if (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
889  {
890  /* It is, set the alertable flag */
891  FileObject->Flags |= FO_ALERTABLE_IO;
892  }
893  }
894 
895  /* Check if this is synch I/O */
896  if (FileObject->Flags & FO_SYNCHRONOUS_IO)
897  {
898  /* Initialize the event */
899  KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE);
900  }
901 
902  /* Check if the caller requested no intermediate buffering */
904  {
905  /* Set the correct flag for the FSD to read */
906  FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
907  }
908 
909  /* Check if the caller requested write through support */
910  if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH)
911  {
912  /* Set the correct flag for the FSD to read */
913  FileObject->Flags |= FO_WRITE_THROUGH;
914  }
915 
916  /* Check if the caller says the file will be only read sequentially */
917  if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
918  {
919  /* Set the correct flag for the FSD to read */
920  FileObject->Flags |= FO_SEQUENTIAL_ONLY;
921  }
922 
923  /* Check if the caller believes the file will be only read randomly */
924  if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
925  {
926  /* Set the correct flag for the FSD to read */
927  FileObject->Flags |= FO_RANDOM_ACCESS;
928  }
929 
930  /* Check if we were asked to setup a file object extension */
932  {
933  PFILE_OBJECT_EXTENSION FileObjectExtension;
934 
935  /* Make sure the file object knows it has an extension */
936  FileObject->Flags |= FO_FILE_OBJECT_HAS_EXTENSION;
937 
938  FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
939  FileObject->FileObjectExtension = FileObjectExtension;
940 
941  /* Add the top level device which we'll send the request to */
943  {
944  FileObjectExtension->TopDeviceObjectHint = DeviceObject;
945  }
946  }
947  }
948  else
949  {
950  /* Use the dummy object instead */
951  LocalFileObject = OpenPacket->LocalFileObject;
952  RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT));
953 
954  /* Set it up */
955  FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body;
956  LocalFileObject->ObjectHeader.Type = IoFileObjectType;
957  LocalFileObject->ObjectHeader.PointerCount = 1;
958  }
959 
960  /* Setup the file header */
961  FileObject->Type = IO_TYPE_FILE;
962  FileObject->Size = sizeof(FILE_OBJECT);
963  FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
964  FileObject->DeviceObject = OriginalDeviceObject;
965 
966  /* Check if this is a direct device open */
967  if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
968 
969  /* Check if the caller wants case sensitivity */
970  if (!(Attributes & OBJ_CASE_INSENSITIVE))
971  {
972  /* Tell the driver about it */
973  FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
974  }
975 
976  /* Now set the file object */
977  Irp->Tail.Overlay.OriginalFileObject = FileObject;
978  StackLoc->FileObject = FileObject;
979 
980  /* Check if the file object has a name */
981  if (RemainingName->Length)
982  {
983  /* Setup the unicode string */
984  FileObject->FileName.MaximumLength = RemainingName->Length +
985  sizeof(WCHAR);
986  FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool,
987  FileObject->
988  FileName.
990  TAG_IO_NAME);
991  if (!FileObject->FileName.Buffer)
992  {
993  /* Failed to allocate the name, free the IRP */
994  IoFreeIrp(Irp);
995 
996  /* Dereference the device object and VPB */
997  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
998  if (Vpb) IopDereferenceVpbAndFree(Vpb);
999 
1000  /* Clear the FO and dereference it */
1001  FileObject->DeviceObject = NULL;
1002  if (!UseDummyFile) ObDereferenceObject(FileObject);
1003 
1004  /* Fail */
1006  }
1007  }
1008 
1009  /* Copy the name */
1010  RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
1011 
1012  /* Initialize the File Object event and set the FO */
1013  KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
1014  OpenPacket->FileObject = FileObject;
1015 
1016  /* Queue the IRP and call the driver */
1017  IopQueueIrpToThread(Irp);
1018  Status = IoCallDriver(DeviceObject, Irp);
1019  if (Status == STATUS_PENDING)
1020  {
1021  /* Wait for the driver to complete the create */
1022  KeWaitForSingleObject(&FileObject->Event,
1023  Executive,
1024  KernelMode,
1025  FALSE,
1026  NULL);
1027 
1028  /* Get the new status */
1029  Status = IoStatusBlock.Status;
1030  }
1031  else
1032  {
1033  /* We'll have to complete it ourselves */
1034  ASSERT(!Irp->PendingReturned);
1035  ASSERT(!Irp->MdlAddress);
1036 
1037  /* Handle name change if required */
1038  if (Status == STATUS_REPARSE)
1039  {
1040  /* Check this is a mount point */
1041  if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1042  {
1043  PREPARSE_DATA_BUFFER ReparseData;
1044 
1045  /* Reparse point attributes were passed by the driver in the auxiliary buffer */
1046  ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1047  ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1048 
1049  ASSERT(ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT);
1052 
1053  IopDoNameTransmogrify(Irp, FileObject, ReparseData);
1054  }
1055  }
1056 
1057  /* Completion happens at APC_LEVEL */
1058  KeRaiseIrql(APC_LEVEL, &OldIrql);
1059 
1060  /* Get the new I/O Status block ourselves */
1061  IoStatusBlock = Irp->IoStatus;
1062  Status = IoStatusBlock.Status;
1063 
1064  /* Manually signal the even, we can't have any waiters */
1065  FileObject->Event.Header.SignalState = 1;
1066 
1067  /* Now that we've signaled the events, de-associate the IRP */
1069 
1070  /* Check if the IRP had an input buffer */
1071  if ((Irp->Flags & IRP_BUFFERED_IO) &&
1072  (Irp->Flags & IRP_DEALLOCATE_BUFFER))
1073  {
1074  /* Free it. A driver might've tacked one on */
1075  ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1076  }
1077 
1078  /* Free the IRP and bring the IRQL back down */
1079  IoFreeIrp(Irp);
1080  KeLowerIrql(OldIrql);
1081  }
1082 
1083  /* Copy the I/O Status */
1084  OpenPacket->Information = IoStatusBlock.Information;
1085 
1086  /* The driver failed to create the file */
1087  if (!NT_SUCCESS(Status))
1088  {
1089  /* Check if we have a name */
1090  if (FileObject->FileName.Length)
1091  {
1092  /* Free it */
1093  ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME);
1094  FileObject->FileName.Length = 0;
1095  }
1096 
1097  /* Clear its device object */
1098  FileObject->DeviceObject = NULL;
1099 
1100  /* Save this now because the FO might go away */
1101  OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ?
1102  TRUE : FALSE;
1103 
1104  /* Clear the file object in the open packet */
1105  OpenPacket->FileObject = NULL;
1106 
1107  /* Dereference the file object */
1108  if (!UseDummyFile) ObDereferenceObject(FileObject);
1109 
1110  /* Dereference the device object */
1111  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1112 
1113  /* Unless the driver cancelled the open, dereference the VPB */
1114  if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb);
1115 
1116  /* Set the status and return */
1117  OpenPacket->FinalStatus = Status;
1118  return Status;
1119  }
1120  else if (Status == STATUS_REPARSE)
1121  {
1122  if (OpenPacket->Information == IO_REPARSE ||
1123  OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1124  {
1125  /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */
1126  if (CompleteName->MaximumLength < FileObject->FileName.Length)
1127  {
1128  PWSTR NewCompleteName;
1129 
1130  /* Allocate a new buffer for the string */
1131  NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME);
1132  if (NewCompleteName == NULL)
1133  {
1136  }
1137 
1138  /* Release the old one */
1139  if (CompleteName->Buffer != NULL)
1140  {
1141  ExFreePoolWithTag(CompleteName->Buffer, 0);
1142  }
1143 
1144  /* And setup the new one */
1145  CompleteName->Buffer = NewCompleteName;
1146  CompleteName->MaximumLength = FileObject->FileName.Length;
1147  }
1148 
1149  /* Copy our new complete name */
1150  RtlCopyUnicodeString(CompleteName, &FileObject->FileName);
1151 
1152  if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1153  {
1154  OpenPacket->RelatedFileObject = NULL;
1155  }
1156  }
1157 
1158  /* Check if we have a name */
1159  if (FileObject->FileName.Length)
1160  {
1161  /* Free it */
1162  ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1163  FileObject->FileName.Length = 0;
1164  }
1165 
1166  /* Clear its device object */
1167  FileObject->DeviceObject = NULL;
1168 
1169  /* Clear the file object in the open packet */
1170  OpenPacket->FileObject = NULL;
1171 
1172  /* Dereference the file object */
1173  if (!UseDummyFile) ObDereferenceObject(FileObject);
1174 
1175  /* Dereference the device object */
1176  IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1177 
1178  /* Unless the driver cancelled the open, dereference the VPB */
1179  if (Vpb != NULL) IopDereferenceVpbAndFree(Vpb);
1180 
1181  if (OpenPacket->Information != IO_REMOUNT)
1182  {
1183  OpenPacket->RelatedFileObject = NULL;
1184 
1185  /* Inform we traversed a mount point for later attempt */
1186  if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1187  {
1188  OpenPacket->TraversedMountPoint = 1;
1189  }
1190 
1191  /* In case we override checks, but got this on volume open, fail hard */
1192  if (OpenPacket->Override)
1193  {
1194  KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN,
1195  (ULONG_PTR)OriginalDeviceObject,
1196  (ULONG_PTR)DeviceObject,
1197  (ULONG_PTR)CompleteName,
1198  OpenPacket->Information);
1199  }
1200 
1201  /* Return to IO/OB so that information can be upgraded */
1202  return STATUS_REPARSE;
1203  }
1204 
1205  /* Loop again and reattempt an opening */
1206  continue;
1207  }
1208 
1209  break;
1210  }
1211 
1212  if (Attempt == IOP_MAX_REPARSE_TRAVERSAL)
1213  return STATUS_UNSUCCESSFUL;
1214 
1215  /* Get the owner of the File Object */
1216  OwnerDevice = IoGetRelatedDeviceObject(FileObject);
1217 
1218  /*
1219  * It's possible that the device to whom we sent the IRP to
1220  * isn't actually the device that ended opening the file object
1221  * internally.
1222  */
1223  if (OwnerDevice != DeviceObject)
1224  {
1225  /* We have to de-reference the VPB we had associated */
1226  if (Vpb) IopDereferenceVpbAndFree(Vpb);
1227 
1228  /* And re-associate with the actual one */
1229  Vpb = FileObject->Vpb;
1230  if (Vpb) InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
1231  }
1232 
1233  /* Make sure we are not using a dummy */
1234  if (!UseDummyFile)
1235  {
1236  /* Check if this was a volume open */
1237  if ((!(FileObject->RelatedFileObject) ||
1238  (FileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN)) &&
1239  !(FileObject->FileName.Length))
1240  {
1241  /* All signs point to it, but make sure it was actually an FSD */
1242  if ((OwnerDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
1243  (OwnerDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
1244  (OwnerDevice->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) ||
1245  (OwnerDevice->DeviceType == FILE_DEVICE_FILE_SYSTEM))
1246  {
1247  /* The owner device is an FSD, so this is a volume open for real */
1248  FileObject->Flags |= FO_VOLUME_OPEN;
1249  }
1250  }
1251 
1252  /* Reference the object and set the parse check */
1253  ObReferenceObject(FileObject);
1254  *Object = FileObject;
1255  OpenPacket->FinalStatus = IoStatusBlock.Status;
1256  OpenPacket->ParseCheck = TRUE;
1257  return OpenPacket->FinalStatus;
1258  }
1259  else
1260  {
1261  /* Check if this was a query */
1262  if (OpenPacket->QueryOnly)
1263  {
1264  /* Check if the caller wants basic info only */
1265  if (!OpenPacket->FullAttributes)
1266  {
1267  /* Allocate the buffer */
1268  FileBasicInfo = ExAllocatePoolWithTag(NonPagedPool,
1269  sizeof(*FileBasicInfo),
1270  TAG_IO);
1271  if (FileBasicInfo)
1272  {
1273  /* Do the query */
1274  Status = IoQueryFileInformation(FileObject,
1276  sizeof(*FileBasicInfo),
1277  FileBasicInfo,
1278  &ReturnLength);
1279  if (NT_SUCCESS(Status))
1280  {
1281  /* Copy the data */
1282  RtlCopyMemory(OpenPacket->BasicInformation,
1283  FileBasicInfo,
1284  ReturnLength);
1285  }
1286 
1287  /* Free our buffer */
1288  ExFreePoolWithTag(FileBasicInfo, TAG_IO);
1289  }
1290  else
1291  {
1292  /* Fail */
1294  }
1295  }
1296  else
1297  {
1298  /* This is a full query */
1299  Status = IoQueryFileInformation(
1300  FileObject,
1303  OpenPacket->NetworkInformation,
1304  &ReturnLength);
1305  if (!NT_SUCCESS(Status)) ASSERT(Status != STATUS_NOT_IMPLEMENTED);
1306  }
1307  }
1308 
1309  /* Delete the file object */
1310  IopDeleteFile(FileObject);
1311 
1312  /* Clear out the file */
1313  OpenPacket->FileObject = NULL;
1314 
1315  /* Set and return status */
1316  OpenPacket->FinalStatus = Status;
1317  OpenPacket->ParseCheck = TRUE;
1318  return Status;
1319  }
1320 }
1321 
1322 NTSTATUS
1323 NTAPI
1324 IopParseFile(IN PVOID ParseObject,
1329  IN OUT PUNICODE_STRING CompleteName,
1332  IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1333  OUT PVOID *Object)
1334 {
1336  POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
1337 
1338  /* Validate the open packet */
1339  if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
1340 
1341  /* Get the device object */
1342  DeviceObject = IoGetRelatedDeviceObject(ParseObject);
1343  OpenPacket->RelatedFileObject = ParseObject;
1344 
1345  /* Call the main routine */
1346  return IopParseDevice(DeviceObject,
1347  ObjectType,
1348  AccessState,
1349  AccessMode,
1350  Attributes,
1351  CompleteName,
1352  RemainingName,
1353  OpenPacket,
1354  SecurityQos,
1355  Object);
1356 }
1357 
1358 VOID
1359 NTAPI
1361 {
1362  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1363  PIRP Irp;
1364  PIO_STACK_LOCATION StackPtr;
1365  NTSTATUS Status;
1366  KEVENT Event;
1368  BOOLEAN DereferenceDone = FALSE;
1369  PVPB Vpb;
1370  KIRQL OldIrql;
1371  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1372 
1373  /* Check if the file has a device object */
1374  if (FileObject->DeviceObject)
1375  {
1376  /* Check if this is a direct open or not */
1377  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1378  {
1379  /* Get the attached device */
1380  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
1381  }
1382  else
1383  {
1384  /* Use the file object's device object */
1385  DeviceObject = IoGetRelatedDeviceObject(FileObject);
1386  }
1387 
1388  /* Sanity check */
1389  ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
1390  (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE));
1391 
1392  /* Check if the handle wasn't created yet */
1393  if (!(FileObject->Flags & FO_HANDLE_CREATED))
1394  {
1395  /* Send the cleanup IRP */
1396  IopCloseFile(NULL, ObjectBody, 0, 1, 1);
1397  }
1398 
1399  /* Clear and set up Events */
1400  KeClearEvent(&FileObject->Event);
1402 
1403  /* Allocate an IRP */
1404  Irp = IopAllocateIrpMustSucceed(DeviceObject->StackSize);
1405 
1406  /* Set it up */
1407  Irp->UserEvent = &Event;
1408  Irp->UserIosb = &Irp->IoStatus;
1409  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1410  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1412 
1413  /* Set up Stack Pointer Data */
1414  StackPtr = IoGetNextIrpStackLocation(Irp);
1415  StackPtr->MajorFunction = IRP_MJ_CLOSE;
1416  StackPtr->FileObject = FileObject;
1417 
1418  /* Queue the IRP */
1419  IopQueueIrpToThread(Irp);
1420 
1421  /* Get the VPB and check if this isn't a direct open */
1422  Vpb = FileObject->Vpb;
1423  if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1424  {
1425  /* Dereference the VPB before the close */
1427  }
1428 
1429  /* Check if the FS will never disappear by itself */
1430  if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
1431  {
1432  /* Dereference it */
1433  InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
1434  DereferenceDone = TRUE;
1435  }
1436 
1437  /* Call the FS Driver */
1438  Status = IoCallDriver(DeviceObject, Irp);
1439  if (Status == STATUS_PENDING)
1440  {
1441  /* Wait for completion */
1443  }
1444 
1445  /* De-queue the IRP */
1446  KeRaiseIrql(APC_LEVEL, &OldIrql);
1448  KeLowerIrql(OldIrql);
1449 
1450  /* Free the IRP */
1451  IoFreeIrp(Irp);
1452 
1453  /* Clear the file name */
1454  if (FileObject->FileName.Buffer)
1455  {
1456  ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME);
1457  FileObject->FileName.Buffer = NULL;
1458  }
1459 
1460  /* Check if the FO had a completion port */
1461  if (FileObject->CompletionContext)
1462  {
1463  /* Free it */
1464  ObDereferenceObject(FileObject->CompletionContext->Port);
1465  ExFreePool(FileObject->CompletionContext);
1466  }
1467 
1468  /* Check if the FO had extension */
1469  if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
1470  {
1471  /* Release filter context structure if any */
1473  }
1474 
1475  /* Check if dereference has been done yet */
1476  if (!DereferenceDone)
1477  {
1478  /* Dereference device object */
1479  IopDereferenceDeviceObject(FileObject->DeviceObject, FALSE);
1480  }
1481  }
1482 }
1483 
1485 NTAPI
1487 {
1489 
1490  /* Go down the stack to attempt to get the PDO */
1491  for (; ((PEXTENDED_DEVOBJ_EXTENSION)PDO->DeviceObjectExtension)->AttachedTo != NULL;
1492  PDO = ((PEXTENDED_DEVOBJ_EXTENSION)PDO->DeviceObjectExtension)->AttachedTo);
1493 
1494  return PDO;
1495 }
1496 
1498 NTAPI
1500 {
1501  KIRQL OldIrql;
1502  PDEVICE_OBJECT PDO;
1503 
1504  ASSERT(DeviceObject != NULL);
1505 
1507  /* Get the base DO */
1508  PDO = IopGetDeviceAttachmentBase(DeviceObject);
1509  /* Check whether that's really a PDO and if so, keep it */
1511  {
1512  PDO = NULL;
1513  }
1514  else
1515  {
1516  ObReferenceObject(PDO);
1517  }
1519 
1520  return PDO;
1521 }
1522 
1523 NTSTATUS
1524 NTAPI
1530 {
1531  NTSTATUS Status;
1532  PSECURITY_DESCRIPTOR OldSecurityDescriptor, CachedSecurityDescriptor, NewSecurityDescriptor;
1533 
1534  PAGED_CODE();
1535 
1536  /* Keep attempting till we find our old SD or fail */
1537  while (TRUE)
1538  {
1541 
1542  /* Get our old SD and reference it */
1543  OldSecurityDescriptor = DeviceObject->SecurityDescriptor;
1544  if (OldSecurityDescriptor != NULL)
1545  {
1546  ObReferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1547  }
1548 
1551 
1552  /* Set the SD information */
1553  NewSecurityDescriptor = OldSecurityDescriptor;
1554  Status = SeSetSecurityDescriptorInfo(NULL, SecurityInformation,
1555  SecurityDescriptor, &NewSecurityDescriptor,
1556  PoolType, GenericMapping);
1557 
1558  if (!NT_SUCCESS(Status))
1559  {
1560  if (OldSecurityDescriptor != NULL)
1561  {
1562  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1563  }
1564 
1565  break;
1566  }
1567 
1568  /* Add the new DS to the internal cache */
1569  Status = ObLogSecurityDescriptor(NewSecurityDescriptor,
1570  &CachedSecurityDescriptor, 1);
1571  ExFreePool(NewSecurityDescriptor);
1572  if (!NT_SUCCESS(Status))
1573  {
1574  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1575  break;
1576  }
1577 
1580  /* Check if someone changed it in our back */
1581  if (DeviceObject->SecurityDescriptor == OldSecurityDescriptor)
1582  {
1583  /* We're clear, do the swap */
1584  DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1587 
1588  /* And dereference old SD (twice - us + not in use) */
1589  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 2);
1590 
1591  break;
1592  }
1595 
1596  /* If so, try again */
1597  ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1598  ObDereferenceSecurityDescriptor(CachedSecurityDescriptor, 1);
1599  }
1600 
1601  return Status;
1602 }
1603 
1604 NTSTATUS
1605 NTAPI
1612 {
1613  PDEVICE_OBJECT CurrentDO = PhysicalDeviceObject, NextDevice;
1614  NTSTATUS Status = STATUS_SUCCESS, TmpStatus;
1615 
1616  PAGED_CODE();
1617 
1618  ASSERT(PhysicalDeviceObject != NULL);
1619 
1620  /* We always reference the DO we're working on */
1621  ObReferenceObject(CurrentDO);
1622 
1623  /* Go up from PDO to latest DO */
1624  do
1625  {
1626  /* Attempt to set the new SD on it */
1627  TmpStatus = IopSetDeviceSecurityDescriptor(CurrentDO, SecurityInformation,
1628  SecurityDescriptor, PoolType,
1629  GenericMapping);
1630  /* Was our last one? Remember that status then */
1631  if (CurrentDO == UpperDeviceObject)
1632  {
1633  Status = TmpStatus;
1634  }
1635 
1636  /* Try to move to the next DO (and thus, reference it) */
1637  NextDevice = CurrentDO->AttachedDevice;
1638  if (NextDevice)
1639  {
1640  ObReferenceObject(NextDevice);
1641  }
1642 
1643  /* Dereference current DO and move to the next one */
1644  ObDereferenceObject(CurrentDO);
1645  CurrentDO = NextDevice;
1646  }
1647  while (CurrentDO != NULL);
1648 
1649  return Status;
1650 }
1651 
1652 NTSTATUS
1653 NTAPI
1655  IN SECURITY_OPERATION_CODE OperationCode,
1659  IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1662 {
1664  PIO_STACK_LOCATION StackPtr;
1667  PIRP Irp;
1668  BOOLEAN LocalEvent = FALSE;
1669  KEVENT Event;
1671  PAGED_CODE();
1672  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1673 
1674  /* Check if this is a device or file */
1675  if (((PFILE_OBJECT)ObjectBody)->Type == IO_TYPE_DEVICE)
1676  {
1677  /* It's a device */
1678  DeviceObject = (PDEVICE_OBJECT)ObjectBody;
1679  FileObject = NULL;
1680  }
1681  else
1682  {
1683  /* It's a file */
1684  FileObject = (PFILE_OBJECT)ObjectBody;
1685 
1686  /* Check if this is a direct open */
1687  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1688  {
1689  /* Get the Device Object */
1690  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
1691  }
1692  else
1693  {
1694  /* Otherwise, use the direct device*/
1695  DeviceObject = FileObject->DeviceObject;
1696  }
1697  }
1698 
1699  /* Check if the request was for a device object */
1700  if (!(FileObject) ||
1701  (!(FileObject->FileName.Length) && !(FileObject->RelatedFileObject)) ||
1702  (FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1703  {
1704  /* Check what kind of request this was */
1705  if (OperationCode == QuerySecurityDescriptor)
1706  {
1707  return SeQuerySecurityDescriptorInfo(SecurityInformation,
1708  SecurityDescriptor,
1709  BufferLength,
1710  &DeviceObject->SecurityDescriptor);
1711  }
1712  else if (OperationCode == DeleteSecurityDescriptor)
1713  {
1714  /* Simply return success */
1715  return STATUS_SUCCESS;
1716  }
1717  else if (OperationCode == AssignSecurityDescriptor)
1718  {
1719  Status = STATUS_SUCCESS;
1720 
1721  /* Make absolutely sure this is a device object */
1722  if (!(FileObject) || !(FileObject->Flags & FO_STREAM_FILE))
1723  {
1724  PSECURITY_DESCRIPTOR CachedSecurityDescriptor;
1725 
1726  /* Add the security descriptor in cache */
1727  Status = ObLogSecurityDescriptor(SecurityDescriptor, &CachedSecurityDescriptor, 1);
1728  if (NT_SUCCESS(Status))
1729  {
1732 
1733  /* Assign the Security Descriptor */
1734  DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1735 
1738  }
1739  }
1740 
1741  /* Return status */
1742  return Status;
1743  }
1744  else if (OperationCode == SetSecurityDescriptor)
1745  {
1746  /* Get the Physical Device Object if any */
1747  PDEVICE_OBJECT PDO = IopGetDevicePDO(DeviceObject);
1748 
1749  if (PDO != NULL)
1750  {
1751  /* Apply the new SD to any DO in the path from PDO to current DO */
1752  Status = IopSetDeviceSecurityDescriptors(DeviceObject, PDO,
1753  SecurityInformation,
1754  SecurityDescriptor,
1755  PoolType, GenericMapping);
1756  ObDereferenceObject(PDO);
1757  }
1758  else
1759  {
1760  /* Otherwise, just set for ourselves */
1761  Status = IopSetDeviceSecurityDescriptor(DeviceObject,
1762  SecurityInformation,
1763  SecurityDescriptor,
1764  PoolType, GenericMapping);
1765  }
1766 
1767  return STATUS_SUCCESS;
1768  }
1769 
1770  /* Shouldn't happen */
1771  return STATUS_SUCCESS;
1772  }
1773  else if (OperationCode == DeleteSecurityDescriptor)
1774  {
1775  /* Same as for devices, do nothing */
1776  return STATUS_SUCCESS;
1777  }
1778 
1779  /* At this point, we know we're a file. Reference it */
1780  ObReferenceObject(FileObject);
1781 
1782  /* Check if we should use Sync IO or not */
1783  if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1784  {
1785  /* Lock the file object */
1786  Status = IopLockFileObject(FileObject, ExGetPreviousMode());
1787  if (Status != STATUS_SUCCESS)
1788  {
1789  ObDereferenceObject(FileObject);
1790  return Status;
1791  }
1792  }
1793  else
1794  {
1795  /* Use local event */
1797  LocalEvent = TRUE;
1798  }
1799 
1800  /* Clear the File Object event */
1801  KeClearEvent(&FileObject->Event);
1802 
1803  /* Get the device object */
1804  DeviceObject = IoGetRelatedDeviceObject(FileObject);
1805 
1806  /* Allocate the IRP */
1807  Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1808  if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);
1809 
1810  /* Set the IRP */
1811  Irp->Tail.Overlay.OriginalFileObject = FileObject;
1812  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1813  Irp->RequestorMode = ExGetPreviousMode();
1814  Irp->UserIosb = &IoStatusBlock;
1815  Irp->UserEvent = (LocalEvent) ? &Event : NULL;
1816  Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
1817  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
1818 
1819  /* Set Stack Parameters */
1820  StackPtr = IoGetNextIrpStackLocation(Irp);
1821  StackPtr->FileObject = FileObject;
1822 
1823  /* Check if this is a query or set */
1824  if (OperationCode == QuerySecurityDescriptor)
1825  {
1826  /* Set the major function and parameters */
1828  StackPtr->Parameters.QuerySecurity.SecurityInformation =
1830  StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
1831  Irp->UserBuffer = SecurityDescriptor;
1832  }
1833  else
1834  {
1835  /* Set the major function and parameters for a set */
1836  StackPtr->MajorFunction = IRP_MJ_SET_SECURITY;
1837  StackPtr->Parameters.SetSecurity.SecurityInformation =
1839  StackPtr->Parameters.SetSecurity.SecurityDescriptor =
1841  }
1842 
1843  /* Queue the IRP */
1844  IopQueueIrpToThread(Irp);
1845 
1846  /* Update operation counts */
1848 
1849  /* Call the Driver */
1850  Status = IoCallDriver(DeviceObject, Irp);
1851 
1852  /* Check if this was async I/O */
1853  if (LocalEvent)
1854  {
1855  /* Check if the IRP is pending completion */
1856  if (Status == STATUS_PENDING)
1857  {
1858  /* Wait on the local event */
1859  KeWaitForSingleObject(&Event,
1860  Executive,
1861  KernelMode,
1862  FALSE,
1863  NULL);
1864  Status = IoStatusBlock.Status;
1865  }
1866  }
1867  else
1868  {
1869  /* Check if the IRP is pending completion */
1870  if (Status == STATUS_PENDING)
1871  {
1872  /* Wait on the file object */
1873  KeWaitForSingleObject(&FileObject->Event,
1874  Executive,
1875  KernelMode,
1876  FALSE,
1877  NULL);
1878  Status = FileObject->FinalStatus;
1879  }
1880 
1881  /* Release the lock */
1882  IopUnlockFileObject(FileObject);
1883  }
1884 
1885  /* This Driver doesn't implement Security, so try to give it a default */
1886  if (Status == STATUS_INVALID_DEVICE_REQUEST)
1887  {
1888  /* Was this a query? */
1889  if (OperationCode == QuerySecurityDescriptor)
1890  {
1891  /* Set a World Security Descriptor */
1892  Status = SeSetWorldSecurityDescriptor(*SecurityInformation,
1893  SecurityDescriptor,
1894  BufferLength);
1895  }
1896  else
1897  {
1898  /* It wasn't a query, so just fake success */
1899  Status = STATUS_SUCCESS;
1900  }
1901  }
1902  else if (OperationCode == QuerySecurityDescriptor)
1903  {
1904  /* Callers usually expect the normalized form */
1905  if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_BUFFER_TOO_SMALL;
1906 
1907  _SEH2_TRY
1908  {
1909  /* Return length */
1910  *BufferLength = (ULONG)IoStatusBlock.Information;
1911  }
1913  {
1914  /* Get the exception code */
1915  Status = _SEH2_GetExceptionCode();
1916  }
1917  _SEH2_END;
1918  }
1919 
1920  /* Return Status */
1921  return Status;
1922 }
1923 
1924 NTSTATUS
1925 NTAPI
1926 IopQueryName(IN PVOID ObjectBody,
1927  IN BOOLEAN HasName,
1928  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1929  IN ULONG Length,
1932 {
1933  return IopQueryNameInternal(ObjectBody,
1934  HasName,
1935  FALSE,
1936  ObjectNameInfo,
1937  Length,
1938  ReturnLength,
1939  PreviousMode);
1940 }
1941 
1942 NTSTATUS
1943 NTAPI
1945  IN BOOLEAN HasName,
1946  IN BOOLEAN QueryDosName,
1947  OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1948  IN ULONG Length,
1951 {
1952  POBJECT_NAME_INFORMATION LocalInfo;
1953  PFILE_NAME_INFORMATION LocalFileInfo;
1954  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1955  ULONG LocalReturnLength, FileLength;
1956  BOOLEAN LengthMismatch = FALSE;
1957  NTSTATUS Status;
1958  PWCHAR p;
1960  BOOLEAN NoObCall;
1961 
1962  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1963 
1964  /* Validate length */
1965  if (Length < sizeof(OBJECT_NAME_INFORMATION))
1966  {
1967  /* Wrong length, fail */
1968  *ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
1970  }
1971 
1972  /* Allocate Buffer */
1973  LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, TAG_IO);
1974  if (!LocalInfo) return STATUS_INSUFFICIENT_RESOURCES;
1975 
1976  /* Query DOS name if the caller asked to */
1977  NoObCall = FALSE;
1978  if (QueryDosName)
1979  {
1980  DeviceObject = FileObject->DeviceObject;
1981 
1982  /* In case of a network file system, don't call mountmgr */
1983  if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
1984  {
1985  /* We'll store separator and terminator */
1986  LocalReturnLength = sizeof(OBJECT_NAME_INFORMATION) + 2 * sizeof(WCHAR);
1987  if (Length < LocalReturnLength)
1988  {
1989  Status = STATUS_BUFFER_OVERFLOW;
1990  }
1991  else
1992  {
1993  LocalInfo->Name.Length = sizeof(WCHAR);
1994  LocalInfo->Name.MaximumLength = sizeof(WCHAR);
1995  LocalInfo->Name.Buffer = (PVOID)((ULONG_PTR)LocalInfo + sizeof(OBJECT_NAME_INFORMATION));
1996  LocalInfo->Name.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
1997  Status = STATUS_SUCCESS;
1998  }
1999  }
2000  /* Otherwise, call mountmgr to get DOS name */
2001  else
2002  {
2003  Status = IoVolumeDeviceToDosName(DeviceObject, &LocalInfo->Name);
2004  LocalReturnLength = LocalInfo->Name.Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
2005  }
2006  }
2007 
2008  /* Fall back if querying DOS name failed or if caller never wanted it ;-) */
2009  if (!QueryDosName || !NT_SUCCESS(Status))
2010  {
2011  /* Query the name */
2012  Status = ObQueryNameString(FileObject->DeviceObject,
2013  LocalInfo,
2014  Length,
2015  &LocalReturnLength);
2016  }
2017  else
2018  {
2019  NoObCall = TRUE;
2020  }
2021 
2022  if (!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH))
2023  {
2024  /* Free the buffer and fail */
2025  ExFreePoolWithTag(LocalInfo, TAG_IO);
2026  return Status;
2027  }
2028 
2029  /* Get buffer pointer */
2030  p = (PWCHAR)(ObjectNameInfo + 1);
2031 
2032  _SEH2_TRY
2033  {
2034  /* Copy the information */
2035  if (QueryDosName && NoObCall)
2036  {
2037  ASSERT(PreviousMode == KernelMode);
2038 
2039  /* Copy structure first */
2040  RtlCopyMemory(ObjectNameInfo,
2041  LocalInfo,
2042  (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length));
2043  /* Name then */
2044  RtlCopyMemory(p, LocalInfo->Name.Buffer,
2045  (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION)));
2046 
2047  if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
2048  {
2049  ExFreePool(LocalInfo->Name.Buffer);
2050  }
2051  }
2052  else
2053  {
2054  RtlCopyMemory(ObjectNameInfo,
2055  LocalInfo,
2056  (LocalReturnLength > Length) ?
2057  Length : LocalReturnLength);
2058  }
2059 
2060  /* Set buffer pointer */
2061  ObjectNameInfo->Name.Buffer = p;
2062 
2063  /* Advance in buffer */
2064  p += (LocalInfo->Name.Length / sizeof(WCHAR));
2065 
2066  /* Check if this already filled our buffer */
2067  if (LocalReturnLength > Length)
2068  {
2069  /* Set the length mismatch to true, so that we can return
2070  * the proper buffer size to the caller later
2071  */
2072  LengthMismatch = TRUE;
2073 
2074  /* Save the initial buffer length value */
2075  *ReturnLength = LocalReturnLength;
2076  }
2077 
2078  /* Now get the file name buffer and check the length needed */
2079  LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
2080  FileLength = Length -
2081  LocalReturnLength +
2083 
2084  /* Query the File name */
2085  if (PreviousMode == KernelMode &&
2086  BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
2087  {
2088  Status = IopGetFileInformation(FileObject,
2089  LengthMismatch ? Length : FileLength,
2091  LocalFileInfo,
2092  &LocalReturnLength);
2093  }
2094  else
2095  {
2096  Status = IoQueryFileInformation(FileObject,
2098  LengthMismatch ? Length : FileLength,
2099  LocalFileInfo,
2100  &LocalReturnLength);
2101  }
2102  if (NT_ERROR(Status))
2103  {
2104  /* Allow status that would mean it's not implemented in the storage stack */
2105  if (Status != STATUS_INVALID_PARAMETER && Status != STATUS_INVALID_DEVICE_REQUEST &&
2106  Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_INFO_CLASS)
2107  {
2108  _SEH2_LEAVE;
2109  }
2110 
2111  /* In such case, zero output */
2112  LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2113  LocalFileInfo->FileNameLength = 0;
2114  LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
2115  }
2116  else
2117  {
2118  /* We'll at least return the name length */
2119  if (LocalReturnLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
2120  {
2121  LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2122  }
2123  }
2124 
2125  /* If the provided buffer is too small, return the required size */
2126  if (LengthMismatch)
2127  {
2128  /* Add the required length */
2129  *ReturnLength += LocalFileInfo->FileNameLength;
2130 
2131  /* Free the allocated buffer and return failure */
2132  Status = STATUS_BUFFER_OVERFLOW;
2133  _SEH2_LEAVE;
2134  }
2135 
2136  /* Now calculate the new lengths left */
2137  FileLength = LocalReturnLength -
2139  LocalReturnLength = (ULONG)((ULONG_PTR)p -
2140  (ULONG_PTR)ObjectNameInfo +
2141  LocalFileInfo->FileNameLength);
2142 
2143  /* Don't copy the name if it's not valid */
2144  if (LocalFileInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR)
2145  {
2146  /* Free the allocated buffer and return failure */
2147  Status = STATUS_OBJECT_PATH_INVALID;
2148  _SEH2_LEAVE;
2149  }
2150 
2151  /* Write the Name and null-terminate it */
2152  RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
2153  p += (FileLength / sizeof(WCHAR));
2154  *p = UNICODE_NULL;
2155  LocalReturnLength += sizeof(UNICODE_NULL);
2156 
2157  /* Return the length needed */
2158  *ReturnLength = LocalReturnLength;
2159 
2160  /* Setup the length and maximum length */
2161  FileLength = (ULONG)((ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo);
2162  ObjectNameInfo->Name.Length = (USHORT)FileLength -
2163  sizeof(OBJECT_NAME_INFORMATION);
2164  ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
2165  sizeof(UNICODE_NULL);
2166  }
2168  {
2169  /* Free buffer and return */
2170  ExFreePoolWithTag(LocalInfo, TAG_IO);
2171  } _SEH2_END;
2172 
2173  return Status;
2174 }
2175 
2176 VOID
2177 NTAPI
2179  IN PVOID ObjectBody,
2181  IN ULONG HandleCount,
2182  IN ULONG SystemHandleCount)
2183 {
2184  PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
2185  KEVENT Event;
2186  PIRP Irp;
2187  PIO_STACK_LOCATION StackPtr;
2188  NTSTATUS Status;
2190  KIRQL OldIrql;
2192  IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
2193 
2194  /* If this isn't the last handle for the current process, quit */
2195  if (HandleCount != 1) return;
2196 
2197  /* Check if the file is locked and has more then one handle opened */
2198  if ((FileObject->LockOperation) && (SystemHandleCount != 1))
2199  {
2200  /* Check if this is a direct open or not */
2201  if (BooleanFlagOn(FileObject->Flags, FO_DIRECT_DEVICE_OPEN))
2202  {
2203  /* Get the attached device */
2204  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
2205  }
2206  else
2207  {
2208  /* Get the FO's device */
2209  DeviceObject = IoGetRelatedDeviceObject(FileObject);
2210  }
2211 
2212  /* Check if this is a sync FO and lock it */
2213  if (BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
2214  {
2215  (VOID)IopLockFileObject(FileObject, KernelMode);
2216  }
2217 
2218  /* Go the FastIO path if possible, otherwise fall back to IRP */
2219  if (DeviceObject->DriverObject->FastIoDispatch == NULL ||
2220  DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll == NULL ||
2221  !DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll(FileObject, PsGetCurrentProcess(), &IoStatusBlock, DeviceObject))
2222  {
2223  /* Clear and set up Events */
2224  KeClearEvent(&FileObject->Event);
2226 
2227  /* Allocate an IRP */
2228  Irp = IopAllocateIrpMustSucceed(DeviceObject->StackSize);
2229 
2230  /* Set it up */
2231  Irp->UserEvent = &Event;
2232  Irp->UserIosb = &Irp->IoStatus;
2233  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2234  Irp->Tail.Overlay.OriginalFileObject = FileObject;
2235  Irp->RequestorMode = KernelMode;
2236  Irp->Flags = IRP_SYNCHRONOUS_API;
2237  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2238  ObReferenceObject(FileObject);
2239 
2240  /* Set up Stack Pointer Data */
2241  StackPtr = IoGetNextIrpStackLocation(Irp);
2242  StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
2243  StackPtr->MinorFunction = IRP_MN_UNLOCK_ALL;
2244  StackPtr->FileObject = FileObject;
2245 
2246  /* Queue the IRP */
2247  IopQueueIrpToThread(Irp);
2248 
2249  /* Call the FS Driver */
2250  Status = IoCallDriver(DeviceObject, Irp);
2251  if (Status == STATUS_PENDING)
2252  {
2253  /* Wait for completion */
2255  }
2256 
2257  /* IO will unqueue & free for us */
2258  }
2259 
2260  /* Release the lock if we were holding it */
2261  if (BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
2262  {
2263  IopUnlockFileObject(FileObject);
2264  }
2265  }
2266 
2267  /* Make sure this is the last handle */
2268  if (SystemHandleCount != 1) return;
2269 
2270  /* Check if this is a direct open or not */
2271  if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
2272  {
2273  /* Get the attached device */
2274  DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
2275  }
2276  else
2277  {
2278  /* Get the FO's device */
2279  DeviceObject = IoGetRelatedDeviceObject(FileObject);
2280  }
2281 
2282  /* Set the handle created flag */
2283  FileObject->Flags |= FO_HANDLE_CREATED;
2284 
2285  /* Check if this is a sync FO and lock it */
2286  if (Process != NULL &&
2287  BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
2288  {
2289  (VOID)IopLockFileObject(FileObject, KernelMode);
2290  }
2291 
2292  /* Clear and set up Events */
2293  KeClearEvent(&FileObject->Event);
2295 
2296  /* Allocate an IRP */
2297  Irp = IopAllocateIrpMustSucceed(DeviceObject->StackSize);
2298 
2299  /* Set it up */
2300  Irp->UserEvent = &Event;
2301  Irp->UserIosb = &Irp->IoStatus;
2302  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2303  Irp->Tail.Overlay.OriginalFileObject = FileObject;
2304  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2306 
2307  /* Set up Stack Pointer Data */
2308  StackPtr = IoGetNextIrpStackLocation(Irp);
2309  StackPtr->MajorFunction = IRP_MJ_CLEANUP;
2310  StackPtr->FileObject = FileObject;
2311 
2312  /* Queue the IRP */
2313  IopQueueIrpToThread(Irp);
2314 
2315  /* Update operation counts */
2317 
2318  /* Call the FS Driver */
2319  Status = IoCallDriver(DeviceObject, Irp);
2320  if (Status == STATUS_PENDING)
2321  {
2322  /* Wait for completion */
2324  }
2325 
2326  /* Unqueue the IRP */
2327  KeRaiseIrql(APC_LEVEL, &OldIrql);
2329  KeLowerIrql(OldIrql);
2330 
2331  /* Free the IRP */
2332  IoFreeIrp(Irp);
2333 
2334  /* Release the lock if we were holding it */
2335  if (Process != NULL &&
2336  BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
2337  {
2338  IopUnlockFileObject(FileObject);
2339  }
2340 }
2341 
2342 NTSTATUS
2343 NTAPI
2346  IN ULONG FileInformationSize,
2348 {
2349  NTSTATUS Status;
2351  DUMMY_FILE_OBJECT LocalFileObject;
2352  FILE_NETWORK_OPEN_INFORMATION NetworkOpenInfo;
2353  HANDLE Handle;
2354  OPEN_PACKET OpenPacket;
2355  BOOLEAN IsBasic;
2356  PAGED_CODE();
2357  IOTRACE(IO_FILE_DEBUG, "Class: %lx\n", FileInformationClass);
2358 
2359  /* Check if the caller was user mode */
2360  if (AccessMode != KernelMode)
2361  {
2362  /* Protect probe in SEH */
2363  _SEH2_TRY
2364  {
2365  /* Probe the buffer */
2366  ProbeForWrite(FileInformation, FileInformationSize, sizeof(ULONG));
2367  }
2369  {
2370  /* Return the exception code */
2372  }
2373  _SEH2_END;
2374  }
2375 
2376  /* Check if this is a basic or full request */
2377  IsBasic = (FileInformationSize == sizeof(FILE_BASIC_INFORMATION));
2378 
2379  /* Setup the Open Packet */
2380  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
2381  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
2382  OpenPacket.Size = sizeof(OPEN_PACKET);
2385  OpenPacket.Disposition = FILE_OPEN;
2386  OpenPacket.BasicInformation = IsBasic ? FileInformation : NULL;
2387  OpenPacket.NetworkInformation = IsBasic ? &NetworkOpenInfo :
2388  (AccessMode != KernelMode) ?
2389  &NetworkOpenInfo : FileInformation;
2390  OpenPacket.QueryOnly = TRUE;
2391  OpenPacket.FullAttributes = IsBasic ? FALSE : TRUE;
2392  OpenPacket.LocalFileObject = &LocalFileObject;
2393 
2394  /* Update the operation count */
2396 
2397  /*
2398  * Attempt opening the file. This will call the I/O Parse Routine for
2399  * the File Object (IopParseDevice) which will use the dummy file obejct
2400  * send the IRP to its device object. Note that we have two statuses
2401  * to worry about: the Object Manager's status (in Status) and the I/O
2402  * status, which is in the Open Packet's Final Status, and determined
2403  * by the Parse Check member.
2404  */
2405  Status = ObOpenObjectByName(ObjectAttributes,
2406  NULL,
2407  AccessMode,
2408  NULL,
2410  &OpenPacket,
2411  &Handle);
2412  if (OpenPacket.ParseCheck == FALSE)
2413  {
2414  /* Parse failed */
2415  DPRINT("IopQueryAttributesFile failed for '%wZ' with 0x%lx\n",
2416  ObjectAttributes->ObjectName, Status);
2417  return Status;
2418  }
2419  else
2420  {
2421  /* Use the Io status */
2422  Status = OpenPacket.FinalStatus;
2423  }
2424 
2425  /* Check if we were succesful and this was user mode and a full query */
2426  if ((NT_SUCCESS(Status)) && (AccessMode != KernelMode) && !(IsBasic))
2427  {
2428  /* Enter SEH for copy */
2429  _SEH2_TRY
2430  {
2431  /* Copy the buffer back */
2432  RtlCopyMemory(FileInformation,
2433  &NetworkOpenInfo,
2434  FileInformationSize);
2435  }
2437  {
2438  /* Get exception code */
2439  Status = _SEH2_GetExceptionCode();
2440  }
2441  _SEH2_END;
2442  }
2443 
2444  /* Return status */
2445  return Status;
2446 }
2447 
2448 NTSTATUS
2449 NTAPI
2452  _In_ KPROCESSOR_MODE WaitMode,
2454  _Out_ PBOOLEAN LockFailed)
2455 {
2456  NTSTATUS Status;
2457 
2458  PAGED_CODE();
2459 
2460  InterlockedIncrement((PLONG)&FileObject->Waiters);
2461 
2462  Status = STATUS_SUCCESS;
2463  do
2464  {
2465  if (!InterlockedExchange((PLONG)&FileObject->Busy, TRUE))
2466  {
2467  break;
2468  }
2469  Status = KeWaitForSingleObject(&FileObject->Lock,
2470  Executive,
2471  WaitMode,
2472  Alertable,
2473  NULL);
2474  } while (Status == STATUS_SUCCESS);
2475 
2476  InterlockedDecrement((PLONG)&FileObject->Waiters);
2477  if (Status == STATUS_SUCCESS)
2478  {
2479  ObReferenceObject(FileObject);
2480  *LockFailed = FALSE;
2481  }
2482  else
2483  {
2484  if (!FileObject->Busy && FileObject->Waiters)
2485  {
2486  KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE);
2487  }
2488  *LockFailed = TRUE;
2489  }
2490 
2491  return Status;
2492 }
2493 
2494 PVOID
2495 NTAPI
2497 {
2498  if (BooleanFlagOn(FileObject->Flags, FO_FILE_OBJECT_HAS_EXTENSION))
2499  {
2500  PFILE_OBJECT_EXTENSION FileObjectExtension;
2501 
2502  FileObjectExtension = FileObject->FileObjectExtension;
2503  return FileObjectExtension->FilterContext;
2504  }
2505 
2506  return NULL;
2507 }
2508 
2509 NTSTATUS
2510 NTAPI
2513  IN BOOLEAN Define)
2514 {
2516  PFILE_OBJECT_EXTENSION FileObjectExtension;
2517 
2518  if (!BooleanFlagOn(FileObject->Flags, FO_FILE_OBJECT_HAS_EXTENSION))
2519  {
2520  return STATUS_INVALID_PARAMETER;
2521  }
2522 
2523  FileObjectExtension = FileObject->FileObjectExtension;
2524  if (Define)
2525  {
2526  /* If define, just set the new value if not value is set
2527  * Success will only contain old value. It is valid if it is NULL
2528  */
2529  Success = (ULONG_PTR)InterlockedCompareExchangePointer(&FileObjectExtension->FilterContext, FilterContext, NULL);
2530  }
2531  else
2532  {
2533  /* If not define, we want to reset filter context.
2534  * We will remove value (provided by the caller) and set NULL instead.
2535  * This will only success if caller provides correct previous value.
2536  * To catch whether it worked, we substract previous value to expect value:
2537  * If it matches (and thus, we reset), Success will contain 0
2538  * Otherwise, it will contain a non-zero value.
2539  */
2540  Success = (ULONG_PTR)InterlockedCompareExchangePointer(&FileObjectExtension->FilterContext, NULL, FilterContext) - (ULONG_PTR)FilterContext;
2541  }
2542 
2543  /* If success isn't 0, it means we failed somewhere (set or unset) */
2544  if (Success != 0)
2545  {
2546  return STATUS_ALREADY_COMMITTED;
2547  }
2548 
2549  return STATUS_SUCCESS;
2550 }
2551 
2552 NTSTATUS
2553 NTAPI
2563  IN PVOID EaBuffer OPTIONAL,
2564  IN ULONG EaLength,
2566  IN PVOID ExtraCreateParameters OPTIONAL,
2567  IN ULONG Options,
2568  IN ULONG Flags,
2569  IN PDEVICE_OBJECT DeviceObject OPTIONAL)
2570 {
2572  HANDLE LocalHandle = 0;
2573  LARGE_INTEGER SafeAllocationSize;
2575  PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters;
2576  POPEN_PACKET OpenPacket;
2577  ULONG EaErrorOffset;
2578  PAGED_CODE();
2579 
2580  IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
2581 
2582 
2583  /* Check if we have no parameter checking to do */
2584  if (Options & IO_NO_PARAMETER_CHECKING)
2585  {
2586  /* Then force kernel-mode access to avoid checks */
2587  AccessMode = KernelMode;
2588  }
2589  else
2590  {
2591  /* Otherwise, use the actual mode */
2592  AccessMode = ExGetPreviousMode();
2593  }
2594 
2595  /* Check if we need to do parameter checking */
2596  if ((AccessMode != KernelMode) || (Options & IO_CHECK_CREATE_PARAMETERS))
2597  {
2598  /* Validate parameters */
2599  if (FileAttributes & ~FILE_ATTRIBUTE_VALID_FLAGS)
2600  {
2601  DPRINT1("File Create 'FileAttributes' Parameter contains invalid flags!\n");
2602  return STATUS_INVALID_PARAMETER;
2603  }
2604 
2605  if (ShareAccess & ~FILE_SHARE_VALID_FLAGS)
2606  {
2607  DPRINT1("File Create 'ShareAccess' Parameter contains invalid flags!\n");
2608  return STATUS_INVALID_PARAMETER;
2609  }
2610 
2611  if (Disposition > FILE_MAXIMUM_DISPOSITION)
2612  {
2613  DPRINT1("File Create 'Disposition' Parameter is out of range!\n");
2614  return STATUS_INVALID_PARAMETER;
2615  }
2616 
2617  if (CreateOptions & ~FILE_VALID_OPTION_FLAGS)
2618  {
2619  DPRINT1("File Create 'CreateOptions' parameter contains invalid flags!\n");
2620  return STATUS_INVALID_PARAMETER;
2621  }
2622 
2623  if ((CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) &&
2624  (!(DesiredAccess & SYNCHRONIZE)))
2625  {
2626  DPRINT1("File Create 'CreateOptions' parameter FILE_SYNCHRONOUS_IO_* requested, but 'DesiredAccess' does not have SYNCHRONIZE!\n");
2627  return STATUS_INVALID_PARAMETER;
2628  }
2629 
2630  if ((CreateOptions & FILE_DELETE_ON_CLOSE) && (!(DesiredAccess & DELETE)))
2631  {
2632  DPRINT1("File Create 'CreateOptions' parameter FILE_DELETE_ON_CLOSE requested, but 'DesiredAccess' does not have DELETE!\n");
2633  return STATUS_INVALID_PARAMETER;
2634  }
2635 
2636  if ((CreateOptions & (FILE_SYNCHRONOUS_IO_NONALERT | FILE_SYNCHRONOUS_IO_ALERT)) ==
2638  {
2639  DPRINT1("File Create 'FileAttributes' parameter both FILE_SYNCHRONOUS_IO_NONALERT and FILE_SYNCHRONOUS_IO_ALERT specified!\n");
2640  return STATUS_INVALID_PARAMETER;
2641  }
2642 
2643  if ((CreateOptions & FILE_DIRECTORY_FILE) && !(CreateOptions & FILE_NON_DIRECTORY_FILE) &&
2644  (CreateOptions & ~(FILE_DIRECTORY_FILE |
2650  FILE_DELETE_ON_CLOSE |
2655  {
2656  DPRINT1("File Create 'CreateOptions' Parameter has flags incompatible with FILE_DIRECTORY_FILE!\n");
2657  return STATUS_INVALID_PARAMETER;
2658  }
2659 
2660  if ((CreateOptions & FILE_DIRECTORY_FILE) && !(CreateOptions & FILE_NON_DIRECTORY_FILE) &&
2661  (Disposition != FILE_CREATE) && (Disposition != FILE_OPEN) && (Disposition != FILE_OPEN_IF))
2662  {
2663  DPRINT1("File Create 'CreateOptions' Parameter FILE_DIRECTORY_FILE requested, but 'Disposition' is not FILE_CREATE/FILE_OPEN/FILE_OPEN_IF!\n");
2664  return STATUS_INVALID_PARAMETER;
2665  }
2666 
2667  if ((CreateOptions & FILE_COMPLETE_IF_OPLOCKED) && (CreateOptions & FILE_RESERVE_OPFILTER))
2668  {
2669  DPRINT1("File Create 'CreateOptions' Parameter both FILE_COMPLETE_IF_OPLOCKED and FILE_RESERVE_OPFILTER specified!\n");
2670  return STATUS_INVALID_PARAMETER;
2671  }
2672 
2673  if ((CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) && (DesiredAccess & FILE_APPEND_DATA))
2674  {
2675  DPRINT1("File Create 'CreateOptions' parameter FILE_NO_INTERMEDIATE_BUFFERING requested, but 'DesiredAccess' FILE_APPEND_DATA requires it!\n");
2676  return STATUS_INVALID_PARAMETER;
2677  }
2678 
2679  /* Now check if this is a named pipe */
2680  if (CreateFileType == CreateFileTypeNamedPipe)
2681  {
2682  /* Make sure we have extra parameters */
2683  if (!ExtraCreateParameters)
2684  {
2685  DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2686  return STATUS_INVALID_PARAMETER;
2687  }
2688 
2689  /* Get the parameters and validate them */
2690  NamedPipeCreateParameters = ExtraCreateParameters;
2691  if ((NamedPipeCreateParameters->NamedPipeType > FILE_PIPE_MESSAGE_TYPE) ||
2692  (NamedPipeCreateParameters->ReadMode > FILE_PIPE_MESSAGE_MODE) ||
2693  (NamedPipeCreateParameters->CompletionMode > FILE_PIPE_COMPLETE_OPERATION) ||
2694  (ShareAccess & FILE_SHARE_DELETE) ||
2695  ((Disposition < FILE_OPEN) || (Disposition > FILE_OPEN_IF)) ||
2696  (CreateOptions & ~FILE_VALID_PIPE_OPTION_FLAGS))
2697  {
2698  /* Invalid named pipe create */
2699  DPRINT1("Invalid named pipe create\n");
2700  return STATUS_INVALID_PARAMETER;
2701  }
2702  }
2703  else if (CreateFileType == CreateFileTypeMailslot)
2704  {
2705  /* Make sure we have extra parameters */
2706  if (!ExtraCreateParameters)
2707  {
2708  DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2709  return STATUS_INVALID_PARAMETER;
2710  }
2711 
2712  /* Get the parameters and validate them */
2713  if ((ShareAccess & FILE_SHARE_DELETE) ||
2714  !(ShareAccess & ~FILE_SHARE_WRITE) ||
2715  (Disposition != FILE_CREATE) ||
2716  (CreateOptions & ~FILE_VALID_MAILSLOT_OPTION_FLAGS))
2717  {
2718  /* Invalid mailslot create */
2719  DPRINT1("Invalid mailslot create\n");
2720  return STATUS_INVALID_PARAMETER;
2721  }
2722  }
2723  }
2724 
2725  /* Allocate the open packet */
2726  OpenPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*OpenPacket), 'pOoI');
2727  if (!OpenPacket) return STATUS_INSUFFICIENT_RESOURCES;
2728  RtlZeroMemory(OpenPacket, sizeof(*OpenPacket));
2729 
2730  /* Check if the call came from user mode */
2731  if (AccessMode != KernelMode)
2732  {
2733  _SEH2_TRY
2734  {
2735  /* Probe the output parameters */
2736  ProbeForWriteHandle(FileHandle);
2737  ProbeForWriteIoStatusBlock(IoStatusBlock);
2738 
2739  /* Probe the allocation size if one was passed in */
2740  if (AllocationSize)
2741  {
2742  SafeAllocationSize = ProbeForReadLargeInteger(AllocationSize);
2743  }
2744  else
2745  {
2746  SafeAllocationSize.QuadPart = 0;
2747  }
2748 
2749  /* Make sure it's valid */
2750  if (SafeAllocationSize.QuadPart < 0)
2751  {
2753  }
2754 
2755  /* Check if EA was passed in */
2756  if ((EaBuffer) && (EaLength))
2757  {
2758  /* Probe it */
2759  ProbeForRead(EaBuffer, EaLength, sizeof(ULONG));
2760 
2761  /* And marshall it */
2763  EaLength,
2764  TAG_EA);
2765  OpenPacket->EaLength = EaLength;
2766  RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2767 
2768  /* Validate the buffer */
2769  Status = IoCheckEaBufferValidity(OpenPacket->EaBuffer,
2770  EaLength,
2771  &EaErrorOffset);
2772  if (!NT_SUCCESS(Status))
2773  {
2774  /* Undo everything if it's invalid */
2775  DPRINT1("Invalid EA buffer\n");
2776  IoStatusBlock->Status = Status;
2777  IoStatusBlock->Information = EaErrorOffset;
2778  RtlRaiseStatus(Status);
2779  }
2780  }
2781  }
2783  {
2784  /* Return the exception code */
2785  if (OpenPacket->EaBuffer != NULL) ExFreePool(OpenPacket->EaBuffer);
2786  ExFreePool(OpenPacket);
2788  }
2789  _SEH2_END;
2790  }
2791  else
2792  {
2793  /* Check if this is a device attach */
2794  if (CreateOptions & IO_ATTACH_DEVICE_API)
2795  {
2796  /* Set the flag properly */
2797  Options |= IO_ATTACH_DEVICE;
2798  CreateOptions &= ~IO_ATTACH_DEVICE_API;
2799  }
2800 
2801  /* Check if we have allocation size */
2802  if (AllocationSize)
2803  {
2804  /* Capture it */
2805  SafeAllocationSize = *AllocationSize;
2806  }
2807  else
2808  {
2809  /* Otherwise, no size */
2810  SafeAllocationSize.QuadPart = 0;
2811  }
2812 
2813  /* Check if we have an EA packet */
2814  if ((EaBuffer) && (EaLength))
2815  {
2816  /* Allocate the kernel copy */
2818  EaLength,
2819  TAG_EA);
2820  if (!OpenPacket->EaBuffer)
2821  {
2822  ExFreePool(OpenPacket);
2823  DPRINT1("Failed to allocate open packet EA buffer\n");
2825  }
2826 
2827  /* Copy the data */
2828  OpenPacket->EaLength = EaLength;
2829  RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2830 
2831  /* Validate the buffer */
2832  Status = IoCheckEaBufferValidity(OpenPacket->EaBuffer,
2833  EaLength,
2834  &EaErrorOffset);
2835  if (!NT_SUCCESS(Status))
2836  {
2837  /* Undo everything if it's invalid */
2838  DPRINT1("Invalid EA buffer\n");
2839  ExFreePool(OpenPacket->EaBuffer);
2840  IoStatusBlock->Status = Status;
2841  IoStatusBlock->Information = EaErrorOffset;
2842  ExFreePool(OpenPacket);
2843  return Status;
2844  }
2845  }
2846  }
2847 
2848  /* Setup the Open Packet */
2849  OpenPacket->Type = IO_TYPE_OPEN_PACKET;
2850  OpenPacket->Size = sizeof(*OpenPacket);
2851  OpenPacket->AllocationSize = SafeAllocationSize;
2852  OpenPacket->CreateOptions = CreateOptions;
2853  OpenPacket->FileAttributes = (USHORT)FileAttributes;
2854  OpenPacket->ShareAccess = (USHORT)ShareAccess;
2855  OpenPacket->Options = Options;
2856  OpenPacket->Disposition = Disposition;
2857  OpenPacket->CreateFileType = CreateFileType;
2858  OpenPacket->ExtraCreateParameters = ExtraCreateParameters;
2859  OpenPacket->InternalFlags = Flags;
2860  OpenPacket->TopDeviceObjectHint = DeviceObject;
2861 
2862  /* Update the operation count */
2864 
2865  /*
2866  * Attempt opening the file. This will call the I/O Parse Routine for
2867  * the File Object (IopParseDevice) which will create the object and
2868  * send the IRP to its device object. Note that we have two statuses
2869  * to worry about: the Object Manager's status (in Status) and the I/O
2870  * status, which is in the Open Packet's Final Status, and determined
2871  * by the Parse Check member.
2872  */
2873  Status = ObOpenObjectByName(ObjectAttributes,
2874  NULL,
2875  AccessMode,
2876  NULL,
2877  DesiredAccess,
2878  OpenPacket,
2879  &LocalHandle);
2880 
2881  /* Free the EA Buffer */
2882  if (OpenPacket->EaBuffer) ExFreePool(OpenPacket->EaBuffer);
2883 
2884  /* Now check for Ob or Io failure */
2885  if (!(NT_SUCCESS(Status)) || (OpenPacket->ParseCheck == FALSE))
2886  {
2887  /* Check if Ob thinks well went well */
2888  if (NT_SUCCESS(Status))
2889  {
2890  /*
2891  * Tell it otherwise. Because we didn't use an ObjectType,
2892  * it incorrectly returned us a handle to God knows what.
2893  */
2894  ZwClose(LocalHandle);
2895  Status = STATUS_OBJECT_TYPE_MISMATCH;
2896  }
2897 
2898  /* Now check the Io status */
2899  if (!NT_SUCCESS(OpenPacket->FinalStatus))
2900  {
2901  /* Use this status instead of Ob's */
2902  Status = OpenPacket->FinalStatus;
2903 
2904  /* Check if it was only a warning */
2905  if (NT_WARNING(Status))
2906  {
2907  /* Protect write with SEH */
2908  _SEH2_TRY
2909  {
2910  /* In this case, we copy the I/O Status back */
2911  IoStatusBlock->Information = OpenPacket->Information;
2912  IoStatusBlock->Status = OpenPacket->FinalStatus;
2913  }
2915  {
2916  /* Get exception code */
2917  Status = _SEH2_GetExceptionCode();
2918  }
2919  _SEH2_END;
2920  }
2921  }
2922  else if ((OpenPacket->FileObject) && (OpenPacket->ParseCheck == FALSE))
2923  {
2924  /*
2925  * This can happen in the very bizarre case where the parse routine
2926  * actually executed more then once (due to a reparse) and ended
2927  * up failing after already having created the File Object.
2928  */
2929  if (OpenPacket->FileObject->FileName.Length)
2930  {
2931  /* It had a name, free it */
2932  ExFreePoolWithTag(OpenPacket->FileObject->FileName.Buffer, TAG_IO_NAME);
2933  }
2934 
2935  /* Clear the device object to invalidate the FO, and dereference */
2936  OpenPacket->FileObject->DeviceObject = NULL;
2937  ObDereferenceObject(OpenPacket->FileObject);
2938  }
2939  }
2940  else
2941  {
2942  /* We reached success and have a valid file handle */
2943  OpenPacket->FileObject->Flags |= FO_HANDLE_CREATED;
2944  ASSERT(OpenPacket->FileObject->Type == IO_TYPE_FILE);
2945 
2946  /* Enter SEH for write back */
2947  _SEH2_TRY
2948  {
2949  /* Write back the handle and I/O Status */
2950  *FileHandle = LocalHandle;
2951  IoStatusBlock->Information = OpenPacket->Information;
2952  IoStatusBlock->Status = OpenPacket->FinalStatus;
2953 
2954  /* Get the Io status */
2955  Status = OpenPacket->FinalStatus;
2956  }
2958  {
2959  /* Get the exception status */
2960  Status = _SEH2_GetExceptionCode();
2961  }
2962  _SEH2_END;
2963  }
2964 
2965  /* Check if we were 100% successful */
2966  if ((OpenPacket->ParseCheck != FALSE) && (OpenPacket->FileObject))
2967  {
2968  /* Dereference the File Object */
2969  ObDereferenceObject(OpenPacket->FileObject);
2970  }
2971 
2972  /* Return status */
2973  ExFreePool(OpenPacket);
2974  return Status;
2975 }
2976 
2977 /* FUNCTIONS *****************************************************************/
2978 
2979 /*
2980  * @unimplemented
2981  */
2982 NTSTATUS
2983 NTAPI
2985  IN ULONG Length,
2986  IN BOOLEAN SetOperation)
2987 {
2988  UNIMPLEMENTED;
2989  return STATUS_NOT_IMPLEMENTED;
2990 }
2991 
2992 /*
2993  * @unimplemented
2994  */
2995 NTSTATUS
2996 NTAPI
2998  IN ULONG QuotaLength,
2999  OUT PULONG ErrorOffset)
3000 {
3001  UNIMPLEMENTED;
3002  return STATUS_NOT_IMPLEMENTED;
3003 }
3004 
3005 /*
3006  * @implemented
3007  */
3008 NTSTATUS
3009 NTAPI
3019  IN PVOID EaBuffer OPTIONAL,
3020  IN ULONG EaLength,
3022  IN PVOID ExtraCreateParameters OPTIONAL,
3023  IN ULONG Options)
3024 {
3025  PAGED_CODE();
3026 
3027  return IopCreateFile(FileHandle,
3028  DesiredAccess,
3029  ObjectAttributes,
3030  IoStatusBlock,
3032  FileAttributes,
3033  ShareAccess,
3034  Disposition,
3035  CreateOptions,
3036  EaBuffer,
3037  EaLength,
3038  CreateFileType,
3039  ExtraCreateParameters,
3040  Options,
3041  0,
3042  NULL);
3043 }
3044 
3045 /*
3046  * @unimplemented
3047  */
3048 NTSTATUS
3049 NTAPI
3059  IN PVOID EaBuffer OPTIONAL,
3060  IN ULONG EaLength,
3062  IN PVOID ExtraCreateParameters OPTIONAL,
3063  IN ULONG Options,
3065 {
3066  ULONG Flags = 0;
3067 
3068  PAGED_CODE();
3069 
3070  /* Check if we were passed a device to send the create request to*/
3071  if (DeviceObject)
3072  {
3073  /* We'll tag this request into a file object extension */
3075  }
3076 
3077  return IopCreateFile(FileHandle,
3078  DesiredAccess,
3079  ObjectAttributes,
3080  IoStatusBlock,
3082  FileAttributes,
3083  ShareAccess,
3084  Disposition,
3085  CreateOptions,
3086  EaBuffer,
3087  EaLength,
3088  CreateFileType,
3089  ExtraCreateParameters,
3090  Options | IO_NO_PARAMETER_CHECKING,
3091  Flags,
3092  DeviceObject);
3093 }
3094 
3095 /*
3096  * @implemented
3097  */
3099 NTAPI
3101  IN PDEVICE_OBJECT DeviceObject OPTIONAL,
3102  OUT PHANDLE FileObjectHandle OPTIONAL)
3103 {
3104  PFILE_OBJECT CreatedFileObject;
3105  NTSTATUS Status;
3108  PAGED_CODE();
3109  IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3110 
3111  /* Choose Device Object */
3112  if (FileObject) DeviceObject = FileObject->DeviceObject;
3113 
3114  /* Reference the device object and initialize attributes */
3115  InterlockedIncrement(&DeviceObject->ReferenceCount);
3116  InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
3117 
3118  /* Create the File Object */
3119  Status = ObCreateObject(KernelMode,
3121  &ObjectAttributes,
3122  KernelMode,
3123  NULL,
3124  sizeof(FILE_OBJECT),
3125  sizeof(FILE_OBJECT),
3126  0,
3127  (PVOID*)&CreatedFileObject);
3128  if (!NT_SUCCESS(Status))
3129  {
3130  /* Fail */
3132  ExRaiseStatus(Status);
3133  }
3134 
3135  /* Set File Object Data */
3136  RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3137  CreatedFileObject->DeviceObject = DeviceObject;
3138  CreatedFileObject->Type = IO_TYPE_FILE;
3139  CreatedFileObject->Size = sizeof(FILE_OBJECT);
3140  CreatedFileObject->Flags = FO_STREAM_FILE;
3141 
3142  /* Initialize the wait event */
3143  KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3144 
3145  /* Insert it to create a handle for it */
3146  Status = ObInsertObject(CreatedFileObject,
3147  NULL,
3149  1,
3150  (PVOID*)&CreatedFileObject,
3151  &FileHandle);
3152  if (!NT_SUCCESS(Status)) ExRaiseStatus(Status);
3153 
3154  /* Set the handle created flag */
3155  CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3156  ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3157 
3158  /* Check if we have a VPB */
3159  if (DeviceObject->Vpb)
3160  {
3161  /* Reference it */
3162  InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3163  }
3164 
3165  /* Check if the caller wants the handle */
3166  if (FileObjectHandle)
3167  {
3168  /* Return it */
3170  ObDereferenceObject(CreatedFileObject);
3171  }
3172  else
3173  {
3174  /* Otherwise, close it */
3175  ObCloseHandle(FileHandle, KernelMode);
3176  }
3177 
3178  /* Return the file object */
3179  return CreatedFileObject;
3180 }
3181 
3182 /*
3183  * @implemented
3184  */
3186 NTAPI
3189 {
3190  /* Call the newer function */
3191  return IoCreateStreamFileObjectEx(FileObject, DeviceObject, NULL);
3192 }
3193 
3194 /*
3195  * @implemented
3196  */
3198 NTAPI
3200  IN PDEVICE_OBJECT DeviceObject OPTIONAL)
3201 {
3202  PFILE_OBJECT CreatedFileObject;
3203  NTSTATUS Status;
3205  PAGED_CODE();
3206  IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3207 
3208  /* Choose Device Object */
3209  if (FileObject) DeviceObject = FileObject->DeviceObject;
3210 
3211  /* Reference the device object and initialize attributes */
3212  InterlockedIncrement(&DeviceObject->ReferenceCount);
3213  InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
3214 
3215  /* Create the File Object */
3216  Status = ObCreateObject(KernelMode,
3218  &ObjectAttributes,
3219  KernelMode,
3220  NULL,
3221  sizeof(FILE_OBJECT),
3222  sizeof(FILE_OBJECT),
3223  0,
3224  (PVOID*)&CreatedFileObject);
3225  if (!NT_SUCCESS(Status))
3226  {
3227  /* Fail */
3229  ExRaiseStatus(Status);
3230  }
3231 
3232  /* Set File Object Data */
3233  RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3234  CreatedFileObject->DeviceObject = DeviceObject;
3235  CreatedFileObject->Type = IO_TYPE_FILE;
3236  CreatedFileObject->Size = sizeof(FILE_OBJECT);
3237  CreatedFileObject->Flags = FO_STREAM_FILE;
3238 
3239  /* Initialize the wait event */
3240  KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3241 
3242  /* Destroy create information */
3244  ObjectCreateInfo);
3245  OBJECT_TO_OBJECT_HEADER(CreatedFileObject)->ObjectCreateInfo = NULL;
3246 
3247  /* Set the handle created flag */
3248  CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3249  ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3250 
3251  /* Check if we have a VPB */
3252  if (DeviceObject->Vpb)
3253  {
3254  /* Reference it */
3255  InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3256  }
3257 
3258  /* Return the file object */
3259  return CreatedFileObject;
3260 }
3261 
3262 /*
3263  * @implemented
3264  */
3266 NTAPI
3268 {
3269  /* Return the mapping */
3270  return &IopFileMapping;
3271 }
3272 
3273 /*
3274  * @implemented
3275  */
3276 BOOLEAN
3277 NTAPI
3279 {
3280  /* Return the flag status */
3281  return FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3282 }
3283 
3284 /*
3285  * @implemented
3286  */
3287 BOOLEAN
3288 NTAPI
3294 {
3295  NTSTATUS Status;
3296  DUMMY_FILE_OBJECT LocalFileObject;
3297  HANDLE Handle;
3298  OPEN_PACKET OpenPacket;
3299  PAGED_CODE();
3300  IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
3301 
3302  /* Setup the Open Packet */
3303  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
3304  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
3305  OpenPacket.Size = sizeof(OPEN_PACKET);
3306  OpenPacket.CreateOptions = OpenOptions | FILE_OPEN_REPARSE_POINT;
3308  OpenPacket.Options = IO_FORCE_ACCESS_CHECK;
3309  OpenPacket.Disposition = FILE_OPEN;
3310  OpenPacket.NetworkInformation = Buffer;
3311  OpenPacket.QueryOnly = TRUE;
3312  OpenPacket.FullAttributes = TRUE;
3313  OpenPacket.LocalFileObject = &LocalFileObject;
3314 
3315  /*
3316  * Attempt opening the file. This will call the I/O Parse Routine for
3317  * the File Object (IopParseDevice) which will use the dummy file obejct
3318  * send the IRP to its device object. Note that we have two statuses
3319  * to worry about: the Object Manager's status (in Status) and the I/O
3320  * status, which is in the Open Packet's Final Status, and determined
3321  * by the Parse Check member.
3322  */
3323  Status = ObOpenObjectByName(ObjectAttributes,
3324  NULL,
3325  KernelMode,
3326  NULL,
3327  DesiredAccess,
3328  &OpenPacket,
3329  &Handle);
3330  if (OpenPacket.ParseCheck == FALSE)
3331  {
3332  /* Parse failed */
3333  IoStatus->Status = Status;
3334  }
3335  else
3336  {
3337  /* Use the Io status */
3338  IoStatus->Status = OpenPacket.FinalStatus;
3339  IoStatus->Information = OpenPacket.Information;
3340  }
3341 
3342  /* Return success */
3343  return TRUE;
3344 }
3345 
3346 /*
3347  * @implemented
3348  */
3349 VOID
3350 NTAPI
3353 {
3354  PAGED_CODE();
3355 
3356  /* Check if the file has an extension */
3357  if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
3358  {
3359  /* Check if caller specified to ignore access checks */
3360  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3361  {
3362  /* Don't update share access */
3363  return;
3364  }
3365  }
3366 
3367  /* Otherwise, check if there's any access present */
3368  if ((FileObject->ReadAccess) ||
3369  (FileObject->WriteAccess) ||
3370  (FileObject->DeleteAccess))
3371  {
3372  /* Increase the open count */
3373  ShareAccess->OpenCount++;
3374 
3375  /* Add new share access */
3376  ShareAccess->Readers += FileObject->ReadAccess;
3377  ShareAccess->Writers += FileObject->WriteAccess;
3378  ShareAccess->Deleters += FileObject->DeleteAccess;
3379  ShareAccess->SharedRead += FileObject->SharedRead;
3380  ShareAccess->SharedWrite += FileObject->SharedWrite;
3381  ShareAccess->SharedDelete += FileObject->SharedDelete;
3382  }
3383 }
3384 
3385 /*
3386  * @implemented
3387  */
3388 NTSTATUS
3389 NTAPI
3394  IN BOOLEAN Update)
3395 {
3398  BOOLEAN DeleteAccess;
3399  BOOLEAN SharedRead;
3400  BOOLEAN SharedWrite;
3401  BOOLEAN SharedDelete;
3402  PAGED_CODE();
3403 
3404  /* Get access masks */
3405  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
3406  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
3407  DeleteAccess = (DesiredAccess & DELETE) != 0;
3408 
3409  /* Set them in the file object */
3410  FileObject->ReadAccess = ReadAccess;
3411  FileObject->WriteAccess = WriteAccess;
3412  FileObject->DeleteAccess = DeleteAccess;
3413 
3414  /* Check if the file has an extension */
3415  if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
3416  {
3417  /* Check if caller specified to ignore access checks */
3418  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3419  {
3420  /* Don't check share access */
3421  return STATUS_SUCCESS;
3422  }
3423  }
3424 
3425  /* Check if we have any access */
3426  if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
3427  {
3428  /* Get shared access masks */
3429  SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3430  SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3431  SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3432 
3433  /* Set them */
3434  FileObject->SharedRead = SharedRead;
3435  FileObject->SharedWrite = SharedWrite;
3436  FileObject->SharedDelete = SharedDelete;
3437 
3438  /* Check if the shared access is violated */
3439  if ((ReadAccess &&
3440  (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
3441  (WriteAccess &&
3442  (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
3443  (DeleteAccess &&
3444  (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
3445  ((ShareAccess->Readers != 0) && !SharedRead) ||
3446  ((ShareAccess->Writers != 0) && !SharedWrite) ||
3447  ((ShareAccess->Deleters != 0) && !SharedDelete))
3448  {
3449  /* Sharing violation, fail */
3450  return STATUS_SHARING_VIOLATION;
3451  }
3452 
3453  /* It's not, check if caller wants us to update it */
3454  if (Update)
3455  {
3456  /* Increase open count */
3457  ShareAccess->OpenCount++;
3458 
3459  /* Update shared access */
3460  ShareAccess->Readers += ReadAccess;
3461  ShareAccess->Writers += WriteAccess;
3462  ShareAccess->Deleters += DeleteAccess;
3463  ShareAccess->SharedRead += SharedRead;
3464  ShareAccess->SharedWrite += SharedWrite;
3465  ShareAccess->SharedDelete += SharedDelete;
3466  }
3467  }
3468 
3469  /* Validation successful */
3470  return STATUS_SUCCESS;
3471 }
3472 
3473 /*
3474  * @implemented
3475  */
3476 VOID
3477 NTAPI
3480 {
3481  PAGED_CODE();
3482 
3483  /* Check if the file has an extension */
3484  if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
3485  {
3486  /* Check if caller specified to ignore access checks */
3487  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3488  {
3489  /* Don't update share access */
3490  return;
3491  }
3492  }
3493 
3494  /* Otherwise, check if there's any access present */
3495  if ((FileObject->ReadAccess) ||
3496  (FileObject->WriteAccess) ||
3497  (FileObject->DeleteAccess))
3498  {
3499  /* Decrement the open count */
3500  ShareAccess->OpenCount--;
3501 
3502  /* Remove share access */
3503  ShareAccess->Readers -= FileObject->ReadAccess;
3504  ShareAccess->Writers -= FileObject->WriteAccess;
3505  ShareAccess->Deleters -= FileObject->DeleteAccess;
3506  ShareAccess->SharedRead -= FileObject->SharedRead;
3507  ShareAccess->SharedWrite -= FileObject->SharedWrite;
3508  ShareAccess->SharedDelete -= FileObject->SharedDelete;
3509  }
3510 }
3511 
3512 /*
3513  * @implemented
3514  */
3515 VOID
3516 NTAPI
3521 {
3524  BOOLEAN DeleteAccess;
3525  BOOLEAN SharedRead;
3526  BOOLEAN SharedWrite;
3527  BOOLEAN SharedDelete;
3528  BOOLEAN Update = TRUE;
3529  PAGED_CODE();
3530 
3531  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
3532  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
3533  DeleteAccess = (DesiredAccess & DELETE) != 0;
3534 
3535  /* Check if the file has an extension */
3536  if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
3537  {
3538  /* Check if caller specified to ignore access checks */
3539  //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3540  {
3541  /* Don't update share access */
3542  Update = FALSE;
3543  }
3544  }
3545 
3546  /* Update basic access */
3547  FileObject->ReadAccess = ReadAccess;
3548  FileObject->WriteAccess = WriteAccess;
3549  FileObject->DeleteAccess = DeleteAccess;
3550 
3551  /* Check if we have no access as all */
3552  if (!(ReadAccess) && !(WriteAccess) && !(DeleteAccess))
3553  {
3554  /* Check if we need to update the structure */
3555  if (!Update) return;
3556 
3557  /* Otherwise, clear data */
3558  ShareAccess->OpenCount = 0;
3559  ShareAccess->Readers = 0;
3560  ShareAccess->Writers = 0;
3561  ShareAccess->Deleters = 0;
3562  ShareAccess->SharedRead = 0;
3563  ShareAccess->SharedWrite = 0;
3564  ShareAccess->SharedDelete = 0;
3565  }
3566  else
3567  {
3568  /* Calculate shared access */
3569  SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3570  SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3571  SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3572 
3573  /* Set it in the FO */
3574  FileObject->SharedRead = SharedRead;
3575  FileObject->SharedWrite = SharedWrite;
3576  FileObject->SharedDelete = SharedDelete;
3577 
3578  /* Check if we need to update the structure */
3579  if (!Update) return;
3580 
3581  /* Otherwise, set data */
3582  ShareAccess->OpenCount = 1;
3583  ShareAccess->Readers = ReadAccess;
3584  ShareAccess->Writers = WriteAccess;
3585  ShareAccess->Deleters = DeleteAccess;
3586  ShareAccess->SharedRead = SharedRead;
3587  ShareAccess->SharedWrite = SharedWrite;
3588  ShareAccess->SharedDelete = SharedDelete;
3589  }
3590 }
3591 
3592 /*
3593  * @implemented
3594  */
3595 VOID
3596 NTAPI
3599 {
3600  PIRP Irp;
3601  KEVENT Event;
3602  KIRQL OldIrql;
3603  NTSTATUS Status;
3604  PIO_STACK_LOCATION Stack;
3605 
3606  /* Check if handles were already created for the
3607  * open file. If so, that's over.
3608  */
3609  if (FileObject->Flags & FO_HANDLE_CREATED)
3610  KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN,
3611  (ULONG_PTR)FileObject,
3612  (ULONG_PTR)DeviceObject, 0, 0);
3613 
3614  /* Reset the events */
3616  KeClearEvent(&FileObject->Event);
3617 
3618  /* Allocate the IRP we'll use */
3619  Irp = IopAllocateIrpMustSucceed(DeviceObject->StackSize);
3620  /* Properly set it */
3621  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
3622  Irp->UserEvent = &Event;
3623  Irp->UserIosb = &Irp->IoStatus;
3624  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
3625  Irp->Tail.Overlay.OriginalFileObject = FileObject;
3626  Irp->RequestorMode = KernelMode;
3628 
3629  Stack = IoGetNextIrpStackLocation(Irp);
3630  Stack->MajorFunction = IRP_MJ_CLEANUP;
3631  Stack->FileObject = FileObject;
3632 
3633  /* Put on top of IRPs list of the thread */
3634  IopQueueIrpToThread(Irp);
3635 
3636  /* Call the driver */
3637  Status = IoCallDriver(DeviceObject, Irp);
3638  if (Status == STATUS_PENDING)
3639  {
3641  KernelMode, FALSE, NULL);
3642  }
3643 
3644  /* Remove from IRPs list */
3645  KeRaiseIrql(APC_LEVEL, &OldIrql);
3647  KeLowerIrql(OldIrql);
3648 
3649  /* Free the IRP */
3650  IoFreeIrp(Irp);
3651 
3652  /* Clear the event */
3653  KeClearEvent(&FileObject->Event);
3654  /* And finally, mark the open operation as canceled */
3655  FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
3656 }
3657 
3658 /*
3659  * @implemented
3660  */
3661 NTSTATUS
3662 NTAPI
3665 {
3666  NTSTATUS Status;
3668  POBJECT_NAME_INFORMATION LocalInfo;
3669 
3670  /* Start with a buffer length of 200 */
3671  ReturnLength = 200;
3672  /*
3673  * We'll loop until query works.
3674  * We will use returned length for next loop
3675  * iteration, trying to have a big enough buffer.
3676  */
3677  for (Length = 200; ; Length = ReturnLength)
3678  {
3679  /* Allocate our work buffer */
3680  LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, 'nDoI');
3681  if (LocalInfo == NULL)
3682  {
3684  }
3685 
3686  /* Query the DOS name */
3687  Status = IopQueryNameInternal(FileObject,
3688  TRUE,
3689  TRUE,
3690  LocalInfo,
3691  Length,
3692  &ReturnLength,
3693  KernelMode);
3694  /* If it succeed, nothing more to do */
3695  if (Status == STATUS_SUCCESS)
3696  {
3697  break;
3698  }
3699 
3700  /* Otherwise, prepare for re-allocation */
3701  ExFreePoolWithTag(LocalInfo, 'nDoI');
3702 
3703  /*
3704  * If we failed because of something else
3705  * than memory, simply stop and fail here
3706  */
3707  if (Status != STATUS_BUFFER_OVERFLOW)
3708  {
3709  return Status;
3710  }
3711  }
3712 
3713  /* Success case here: return our buffer */
3714  *ObjectNameInformation = LocalInfo;
3715  return STATUS_SUCCESS;
3716 }
3717 
3718 /*
3719  * @implemented
3720  */
3721 NTSTATUS
3722 NTAPI
3724  IN BOOLEAN Remote)
3725 {
3727  BOOLEAN FlagSet;
3728 
3729  /* Get the flag status */
3730  FlagSet = FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3731 
3732  /* Don't set the flag if it was set already, and don't remove it if it wasn't set */
3733  if (Remote && !FlagSet)
3734  {
3735  /* Set the flag */
3736  FileObject->Flags |= FO_REMOTE_ORIGIN;
3737  }
3738  else if (!Remote && FlagSet)
3739  {
3740  /* Remove the flag */
3741  FileObject->Flags &= ~FO_REMOTE_ORIGIN;
3742  }
3743  else
3744  {
3745  /* Fail */
3747  }
3748 
3749  /* Return status */
3750  return Status;
3751 }
3752 
3753 /*
3754  * @implemented
3755  */
3756 NTSTATUS
3757 NTAPI
3762  PLARGE_INTEGER AllocateSize,
3767  PVOID EaBuffer,
3768  ULONG EaLength)
3769 {
3770  /* Call the I/O Function */
3771  return IoCreateFile(FileHandle,
3772  DesiredAccess,
3773  ObjectAttributes,
3774  IoStatusBlock,
3775  AllocateSize,
3776  FileAttributes,
3777  ShareAccess,
3778  CreateDisposition,
3779  CreateOptions,
3780  EaBuffer,
3781  EaLength,
3783  NULL,
3784  0);
3785 }
3786 
3787 NTSTATUS
3788 NTAPI
3794  IN ULONG MailslotQuota,
3795  IN ULONG MaxMessageSize,
3796  IN PLARGE_INTEGER TimeOut)
3797 {
3799  PAGED_CODE();
3800 
3801  /* Check for Timeout */
3802  if (TimeOut)
3803  {
3804  /* check if the call came from user mode */
3805  if (KeGetPreviousMode() != KernelMode)
3806  {
3807  /* Enter SEH for Probe */
3808  _SEH2_TRY
3809  {
3810  /* Probe the timeout */
3811  Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
3812  }
3814  {
3815  /* Return the exception code */
3817  }
3818  _SEH2_END;
3819  }
3820  else
3821  {
3822  /* Otherwise, capture directly */
3823  Buffer.ReadTimeout = *TimeOut;
3824  }
3825 
3826  /* Set the correct setting */
3827  Buffer.TimeoutSpecified = TRUE;
3828  }
3829  else
3830  {
3831  /* Tell the FSD we don't have a timeout */
3832  Buffer.TimeoutSpecified = FALSE;
3833  }
3834 
3835  /* Set Settings */
3836  Buffer.MailslotQuota = MailslotQuota;
3837  Buffer.MaximumMessageSize = MaxMessageSize;
3838 
3839  /* Call I/O */
3840  return IoCreateFile(FileHandle,
3841  DesiredAccess,
3842  ObjectAttributes,
3843  IoStatusBlock,
3844  NULL,
3845  0,
3847  FILE_CREATE,
3848  CreateOptions,
3849  NULL,
3850  0,
3852  (PVOID)&Buffer,
3853  0);
3854 }
3855 
3856 NTSTATUS
3857 NTAPI
3865  IN ULONG NamedPipeType,
3866  IN ULONG ReadMode,
3867  IN ULONG CompletionMode,
3868  IN ULONG MaximumInstances,
3869  IN ULONG InboundQuota,
3870  IN ULONG OutboundQuota,
3871  IN PLARGE_INTEGER DefaultTimeout)
3872 {
3874  PAGED_CODE();
3875 
3876  /* Check for Timeout */
3877  if (DefaultTimeout)
3878  {
3879  /* check if the call came from user mode */
3880  if (KeGetPreviousMode() != KernelMode)
3881  {
3882  /* Enter SEH for Probe */
3883  _SEH2_TRY
3884  {
3885  /* Probe the timeout */
3886  Buffer.DefaultTimeout =
3887  ProbeForReadLargeInteger(DefaultTimeout);
3888  }
3890  {
3891  /* Return the exception code */
3893  }
3894  _SEH2_END;
3895  }
3896  else
3897  {
3898  /* Otherwise, capture directly */
3899  Buffer.DefaultTimeout = *DefaultTimeout;
3900  }
3901 
3902  /* Set the correct setting */
3903  Buffer.TimeoutSpecified = TRUE;
3904  }
3905  else
3906  {
3907  /* Tell the FSD we don't have a timeout */
3908  Buffer.TimeoutSpecified = FALSE;
3909  }
3910 
3911  /* Set Settings */
3912  Buffer.NamedPipeType = NamedPipeType;
3913  Buffer.ReadMode = ReadMode;
3914  Buffer.CompletionMode = CompletionMode;
3915  Buffer.MaximumInstances = MaximumInstances;
3916  Buffer.InboundQuota = InboundQuota;
3917  Buffer.OutboundQuota = OutboundQuota;
3918 
3919  /* Call I/O */
3920  return IoCreateFile(FileHandle,
3921  DesiredAccess,
3922  ObjectAttributes,
3923  IoStatusBlock,
3924  NULL,
3925  0,
3926  ShareAccess,
3927  CreateDisposition,
3928  CreateOptions,
3929  NULL,
3930  0,
3932  (PVOID)&Buffer,
3933  0);
3934 }
3935 
3936 NTSTATUS
3937 NTAPI
3939 {
3940  PAGED_CODE();
3941 
3942  /* Call the kernel */
3944  return STATUS_SUCCESS;
3945 }
3946 
3947 /*
3948  * @implemented
3949  */
3950 NTSTATUS
3951 NTAPI
3958 {
3959  /* Call the I/O Function */
3960  return IoCreateFile(FileHandle,
3961  DesiredAccess,
3962  ObjectAttributes,
3963  IoStatusBlock,
3964  NULL,
3965  0,
3966  ShareAccess,
3967  FILE_OPEN,
3968  OpenOptions,
3969  NULL,
3970  0,
3972  NULL,
3973  0);
3974 }
3975 
3976 NTSTATUS
3977 NTAPI
3980 {
3981  /* Call the internal helper API */
3982  return IopQueryAttributesFile(ObjectAttributes,
3984  sizeof(FILE_BASIC_INFORMATION),
3985  FileInformation);
3986 }
3987 
3988 NTSTATUS
3989 NTAPI
3992 {
3993  /* Call the internal helper API */
3994  return IopQueryAttributesFile(ObjectAttributes,
3997  FileInformation);
3998 }
3999 
4017 NTSTATUS
4018 NTAPI
4021 {
4023  PETHREAD Thread;
4024  PIRP Irp;
4025  KIRQL OldIrql;
4026  BOOLEAN OurIrpsInList = FALSE;
4029  NTSTATUS Status;
4030  PLIST_ENTRY ListHead, NextEntry;
4031  PAGED_CODE();
4032  IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
4033 
4034  /* Check the previous mode */
4035  if (PreviousMode != KernelMode)
4036  {
4037  /* Enter SEH for probing */
4038  _SEH2_TRY
4039  {
4040  /* Probe the I/O Status Block */
4041  ProbeForWriteIoStatusBlock(IoStatusBlock);
4042  }
4044  {
4045  /* Return the exception code */
4047  }
4048  _SEH2_END;
4049  }
4050 
4051  /* Reference the file object */
4052  Status = ObReferenceObjectByHandle(FileHandle,
4053  0,
4055  PreviousMode,
4056  (PVOID*)&FileObject,
4057  NULL);
4058  if (!NT_SUCCESS(Status)) return Status;
4059 
4060  /* IRP cancellations are synchronized at APC_LEVEL. */
4061  KeRaiseIrql(APC_LEVEL, &OldIrql);
4062 
4063  /* Get the current thread */
4064  Thread = PsGetCurrentThread();
4065 
4066  /* Update the operation counts */
4068 
4069  /* Loop the list */
4070  ListHead = &Thread->IrpList;
4071  NextEntry = ListHead->Flink;
4072  while (ListHead != NextEntry)
4073  {
4074  /* Get the IRP and check if the File Object matches */
4075  Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4076  if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4077  {
4078  /* Cancel this IRP and keep looping */
4079  IoCancelIrp(Irp);
4080  OurIrpsInList = TRUE;
4081  }
4082 
4083  /* Go to the next entry */
4084  NextEntry = NextEntry->Flink;
4085  }
4086 
4087  /* Lower the IRQL */
4088  KeLowerIrql(OldIrql);
4089 
4090  /* Check if we had found an IRP */
4091  if (OurIrpsInList)
4092  {
4093  /* Setup a 10ms wait */
4094  Interval.QuadPart = -100000;
4095 
4096  /* Start looping */
4097  while (OurIrpsInList)
4098  {
4099  /* Do the wait */
4101  OurIrpsInList = FALSE;
4102 
4103  /* Raise IRQL */
4104  KeRaiseIrql(APC_LEVEL, &OldIrql);
4105 
4106  /* Now loop the list again */
4107  NextEntry = ListHead->Flink;
4108  while (NextEntry != ListHead)
4109  {
4110  /* Get the IRP and check if the File Object matches */
4111  Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4112  if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4113  {
4114  /* Keep looping */
4115  OurIrpsInList = TRUE;
4116  break;
4117  }
4118 
4119  /* Go to the next entry */
4120  NextEntry = NextEntry->Flink;
4121  }
4122 
4123  /* Lower the IRQL */
4124  KeLowerIrql(OldIrql);
4125  }
4126  }
4127 
4128  /* Enter SEH for writing back the I/O Status */
4129  _SEH2_TRY
4130  {
4131  /* Write success */
4132  IoStatusBlock->Status = STATUS_SUCCESS;
4133  IoStatusBlock->Information = 0;
4134  }
4136  {
4137  /* Ignore exception */
4138  }
4139  _SEH2_END;
4140 
4141  /* Dereference the file object and return success */
4142  ObDereferenceObject(FileObject);
4143  return STATUS_SUCCESS;
4144 }
4145 
4146 /*
4147  * @implemented
4148  */
4149 NTSTATUS
4150 NTAPI
4152 {
4153  NTSTATUS Status;
4154  DUMMY_FILE_OBJECT LocalFileObject;
4155  HANDLE Handle;
4157  OPEN_PACKET OpenPacket;
4158  PAGED_CODE();
4159  IOTRACE(IO_API_DEBUG, "FileMame: %wZ\n", ObjectAttributes->ObjectName);
4160 
4161  /* Setup the Open Packet */
4162  RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
4163  OpenPacket.Type = IO_TYPE_OPEN_PACKET;
4164  OpenPacket.Size = sizeof(OPEN_PACKET);
4165  OpenPacket.CreateOptions = FILE_DELETE_ON_CLOSE;
4166  OpenPacket.ShareAccess = FILE_SHARE_READ |
4169  OpenPacket.Disposition = FILE_OPEN;
4170  OpenPacket.DeleteOnly = TRUE;
4171  OpenPacket.LocalFileObject = &LocalFileObject;
4172 
4173  /* Update the operation counts */
4175 
4176  /*
4177  * Attempt opening the file. This will call the I/O Parse Routine for
4178  * the File Object (IopParseDevice) which will use the dummy file obejct
4179  * send the IRP to its device object. Note that we have two statuses
4180  * to worry about: the Object Manager's status (in Status) and the I/O
4181  * status, which is in the Open Packet's Final Status, and determined
4182  * by the Parse Check member.
4183  */
4184  Status = ObOpenObjectByName(ObjectAttributes,
4185  NULL,
4186  AccessMode,
4187  NULL,
4188  DELETE,
4189  &OpenPacket,
4190  &Handle);
4191  if (OpenPacket.ParseCheck == FALSE) return Status;
4192 
4193  /* Retrn the Io status */
4194  return OpenPacket.FinalStatus;
4195 }
4196 
4197 /* 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:2523
DWORD *typedef PVOID
Definition: winlogon.h:61
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
#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:1750
#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:3209
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:1776
#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:3990
VOID NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:336
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:507
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:2554
#define IRP_CLOSE_OPERATION
#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:5995
#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:1944
#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:3789
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:1743
#define TAG_IO_NAME
Definition: tag.h:72
const LUID SeBackupPrivilege
Definition: priv.c:38
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
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:3723
PVOID NTAPI IoGetFileObjectFilterContext(IN PFILE_OBJECT FileObject)
Definition: file.c:2496
PDEVICE_OBJECT NTAPI IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1486
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2512
#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:1081
_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
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:460
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
PVOID *typedef PWSTR
Definition: winlogon.h:66
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1752
#define IOP_USE_TOP_LEVEL_DEVICE_HINT
Definition: io.h:92
#define ExRaiseStatus
Definition: ntoskrnl.h:94
#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:1135
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2510
#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:2927
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:3050
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:3517
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1347
$ULONG Control
Definition: setypes.h:87
BOOLEAN NTAPI IopVerifyDeviceObjectOnStack(IN PDEVICE_OBJECT BaseDeviceObject, IN PDEVICE_OBJECT TopDeviceObjectHint)
Definition: device.c:693
IRP
Definition: iotypes.h:2462
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
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1734
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define WCHAR
Definition: msvc.h:43
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:3199
#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:3478
_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:1164
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#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:52
_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:1324
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:1732
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:319
ACPI_EFI_EVENT Event
Definition: acefiex.h:633
#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:6874
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:2997
NTSTATUS NTAPI IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)
Definition: volume.c:1276
#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:1360
#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:132
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PVOID FilterContext
Definition: fsrtltypes.h:299
#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:3100
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3278
#define FALSE
Definition: types.h:117
#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:2511
CREATE_FILE_TYPE CreateFileType
Definition: io.h:382
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:508
_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
ULONG ReferenceCount
Definition: iotypes.h:174
#define FO_REMOTE_ORIGIN
Definition: iotypes.h:1755
#define FILE_READ_DATA
Definition: nt_native.h:628
SIZE_T AllocationSize
Definition: verifier.h:8
_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
LARGE_INTEGER DefaultTimeout
Definition: iotypes.h:790
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
#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
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:1606
#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:3597
#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:1525
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:171
_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:2984
_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:3187
$ULONG PrivilegeCount
Definition: setypes.h:86
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:1736
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
DWORD Interval
Definition: netstat.c:30
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
unsigned char BOOLEAN
NTSTATUS NTAPI NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: file.c:4151
_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
LONG NTSTATUS
Definition: precomp.h:26
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#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:1753
VOID NTAPI IopCloseFile(IN PEPROCESS Process OPTIONAL, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount, IN ULONG SystemHandleCount)
Definition: file.c:2178
#define IO_ATTACH_DEVICE
Definition: iotypes.h:4073
#define IO_REPARSE
Definition: iotypes.h:510
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
NTSTATUS NTAPI IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG FileInformationSize, OUT PVOID FileInformation)
Definition: file.c:2344
#define NT_ERROR(Status)
Definition: umtypes.h:106
PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
Definition: io.h:381
#define IRP_MN_UNLOCK_ALL
Definition: iotypes.h:4055
ULONG InternalFlags
Definition: io.h:390
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
* PFILE_OBJECT
Definition: iotypes.h:1954
_In_ ULONG DesiredShareAccess
Definition: iofuncs.h:779
static IUnknown Object
Definition: main.c:512
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IOTRACE(x, fmt,...)
Definition: io.h:47
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI NtFlushWriteBuffer(VOID)
Definition: file.c:3938
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, IN ULONG RefBias)
Definition: obsdcach.c:364
char * PBOOLEAN
Definition: retypes.h:11
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3370
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
USHORT ReparseDataLength
Definition: shellext.h:122
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define FILE_PIPE_COMPLETE_OPERATION
Definition: iotypes.h:80
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
static const WCHAR L[]
Definition: oid.c:1087
NTSTATUS NTAPI IopAcquireFileObjectLock(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode, _In_ BOOLEAN Alertable, _Out_ PBOOLEAN LockFailed)
Definition: file.c:2450
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
#define InterlockedDecrement
Definition: armddk.h:52
VOID UINTN Length
Definition: acefiex.h:744
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define FO_FILE_OBJECT_HAS_EXTENSION
Definition: iotypes.h:144
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_EXECUTE
Definition: nt_native.h:642
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
VOID NTAPI SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName, IN PVOID Object OPTIONAL, IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PACCESS_STATE AccessState, IN BOOLEAN ObjectCreated, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode, OUT PBOOLEAN GenerateOnClose)
Definition: audit.c:803
Definition: typedefs.h:117
NTSTATUS NTAPI SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PISECURITY_DESCRIPTOR SecurityDescriptor, PULONG BufferLength)
Definition: sd.c:119
#define DOE_REMOVE_PROCESSED
Definition: iotypes.h:152
#define SYNCHRONIZE
Definition: nt_native.h:61
BOOLEAN NTAPI SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PACCESS_STATE AccessState, IN ACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE AccessMode)
Definition: accesschk.c:460
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define FO_VOLUME_OPEN
Definition: iotypes.h:1754
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
struct _FILE_OBJECT_EXTENSION * PFILE_OBJECT_EXTENSION
struct _FILE_NAME_INFORMATION * PFILE_NAME_INFORMATION
BOOLEAN NTAPI SePrivilegeCheck(PPRIVILEGE_SET Privileges, PSECURITY_SUBJECT_CONTEXT SubjectContext, KPROCESSOR_MODE PreviousMode)
Definition: priv.c:491
#define InterlockedExchange
Definition: armddk.h:54
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
#define FILE_VALID_PIPE_OPTION_FLAGS
Definition: nt_native.h:760
Status
Definition: gdiplustypes.h:24
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define FILE_OPEN
Definition: from_kernel.h:54
VOID NTAPI KeFlushWriteBuffer(VOID)
Definition: misc.c:39
ERESOURCE IopSecurityResource
Definition: iomgr.c:60
#define _In_
Definition: no_sal2.h:204
FORCEINLINE VOID IopUnQueueIrpFromThread(IN PIRP Irp)
Definition: io_x.h:65
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3390
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
NTSTATUS NTAPI IopQueryName(IN PVOID ObjectBody, IN BOOLEAN HasName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: file.c:1926
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: iotypes.h:6842
PDEVICE_OBJECT NTAPI IopGetDevicePDO(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1499
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
BOOLEAN ExpInTextModeSetup
Definition: init.c:66
DWORD *typedef HANDLE
Definition: winlogon.h:61
_SEH2_END
Definition: create.c:4424
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2926
NTSTATUS NTAPI NtOpenFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions)
Definition: file.c:3952
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
#define IRP_BUFFERED_IO
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI SeFreePrivileges(IN PPRIVILEGE_SET Privileges)
Definition: priv.c:480
NTSTATUS NTAPI IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
Definition: file.c:3663
NTSTATUS NTAPI NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
Definition: file.c:3978
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:49
#define FILE_OPEN_FOR_FREE_SPACE_QUERY
Definition: constants.h:495
unsigned short USHORT
Definition: pedump.c:61
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
struct _FILE_OBJECT_EXTENSION FILE_OBJECT_EXTENSION
PDUMMY_FILE_OBJECT LocalFileObject
Definition: io.h:388
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1193
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1133
#define FILE_PIPE_MESSAGE_MODE
Definition: iotypes.h:78
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE _In_ BOOLEAN _In_ BOOLEAN AccessGranted
Definition: sefuncs.h:414
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define DEVICE_TYPE
Definition: guid.c:10
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_REPARSE
Definition: ntstatus.h:83
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocateSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
Definition: file.c:3758
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
unsigned int * PULONG
Definition: retypes.h:1
LONG_PTR PointerCount
Definition: obtypes.h:487
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:279
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER
Definition: ntstatus.h:901
#define FO_ALERTABLE_IO
Definition: iotypes.h:1733
BOOLEAN NTAPI IoFastQueryNetworkAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK DesiredAccess, IN ULONG OpenOptions, OUT PIO_STATUS_BLOCK IoStatus, OUT PFILE_NETWORK_OPEN_INFORMATION Buffer)
Definition: file.c:3289
VOID NTAPI ObReferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count)
Definition: obsdcach.c:256
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define MAXUSHORT
Definition: typedefs.h:81
static __inline VOID IopUnlockFileObject(IN PFILE_OBJECT FileObject)
Definition: io_x.h:36
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define DPRINT1
Definition: precomp.h:8
ULONG Flags
Definition: pstypes.h:1366
ULONG CreateOptions
Definition: io.h:373
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
NTSTATUS NTAPI IoCreateFile(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)
Definition: file.c:3010
#define IRP_DEALLOCATE_BUFFER
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_MAXIMUM_DISPOSITION
Definition: from_kernel.h:59
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define IRP_MJ_CLEANUP
#define TAG_EA
Definition: tag.h:71
#define FILE_DEVICE_TAPE
Definition: winioctl.h:136
Definition: iotypes.h:166
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
#define OUT
Definition: typedefs.h:39
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
#define ObReferenceObject
Definition: obfuncs.h:204
#define IOP_CREATE_FILE_OBJECT_EXTENSION
Definition: io.h:93
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
static __inline VOID IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type)
Definition: io_x.h:77
BOOLEAN FullAttributes
Definition: io.h:387
NTSTATUS NTAPI IopGetSetSecurityObject(IN PVOID ObjectBody, IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG BufferLength, IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, IN POOL_TYPE PoolType, IN OUT PGENERIC_MAPPING GenericMapping)
Definition: file.c:1654
ULONG Disposition
Definition: io.h:379
PVOID PIRP
Definition: usb.h:38
#define DO_EXCLUSIVE
Definition: env_spec_w32.h:395
NTSTATUS NTAPI NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: file.c:4019
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:183
VOID NTAPI SeSetAccessStateGenericMapping(IN PACCESS_STATE AccessState, IN PGENERIC_MAPPING GenericMapping)
Definition: access.c:492
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define IRP_SYNCHRONOUS_API
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IRP_CREATE_OPERATION
static VOID(WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING)
NTKERNELAPI NTSTATUS NTAPI SeQuerySecurityDescriptorInfo(_In_ PSECURITY_INFORMATION SecurityInformation, _Out_writes_bytes_(*Length) PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PULONG Length, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1588
#define FO_OPENED_CASE_SENSITIVE
Definition: iotypes.h:1749
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IRP_DEFER_IO_COMPLETION
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define IO_REMOUNT
Definition: iotypes.h:511
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1125
#define _SEH2_LEAVE
Definition: filesup.c:20
GLfloat GLfloat p
Definition: glext.h:8902
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:391
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
POBJECT_TYPE Type
Definition: obtypes.h:493
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:13
GENERIC_MAPPING IopFileMapping
Definition: iomgr.c:49
return STATUS_SUCCESS
Definition: btrfs.c:2710
NTSTATUS NTAPI NtCreateNamedPipeFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN ULONG NamedPipeType, IN ULONG ReadMode, IN ULONG CompletionMode, IN ULONG MaximumInstances, IN ULONG InboundQuota, IN ULONG OutboundQuota, IN PLARGE_INTEGER DefaultTimeout)
Definition: file.c:3858
static ULONG_PTR
Definition: file.c:106
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
signed int * PLONG
Definition: retypes.h:5