ReactOS 0.4.16-dev-197-g92996da
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
23VOID
29{
32 BOOLEAN AccessGranted, HaveBackupPriv = FALSE, CheckRestore = FALSE;
33 PAGED_CODE();
34
35 /* Don't do anything if privileges were checked already */
36 if (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED) return;
37
38 /* Check if the file was actually opened for backup purposes */
40 {
41 /* Set the check flag since were doing it now */
43
44 /* Set the access masks required */
55 DELETE;
56 DesiredAccess = AccessState->RemainingDesiredAccess;
57
58 /* Check if desired access was the maximum */
60 {
61 /* Then add all the access masks required */
63 }
64
65 /* Check if the file already exists */
67 {
68 /* Check if desired access has the read mask */
70 {
71 /* Setup the privilege check lookup */
72 Privileges.PrivilegeCount = 1;
74 Privileges.Privilege[0].Luid = SeBackupPrivilege;
75 Privileges.Privilege[0].Attributes = 0;
80 if (AccessGranted)
81 {
82 /* Remember that backup was allowed */
83 HaveBackupPriv = TRUE;
84
85 /* Append the privileges and update the access state */
87 AccessState->PreviouslyGrantedAccess |= (DesiredAccess & ReadAccess);
88 AccessState->RemainingDesiredAccess &= ~ReadAccess;
89 DesiredAccess &= ~ReadAccess;
90
91 /* Set backup privilege for the token */
93 }
94 }
95 }
96 else
97 {
98 /* Caller is creating the file, check restore privileges later */
99 CheckRestore = TRUE;
100 }
101
102 /* Check if caller wants write access or if it's creating a file */
103 if ((WriteAccess & DesiredAccess) || (CheckRestore))
104 {
105 /* Setup the privilege lookup and do it */
106 Privileges.PrivilegeCount = 1;
108 Privileges.Privilege[0].Luid = SeRestorePrivilege;
109 Privileges.Privilege[0].Attributes = 0;
111 &AccessState->SubjectSecurityContext,
113 if (AccessGranted)
114 {
115 /* Remember that privilege was given */
116 HaveBackupPriv = TRUE;
117
118 /* Append the privileges and update the access state */
120 AccessState->PreviouslyGrantedAccess |= (DesiredAccess & WriteAccess);
121 AccessState->RemainingDesiredAccess &= ~WriteAccess;
122
123 /* Set restore privilege for the token */
125 }
126 }
127
128 /* If we don't have the privilege, remove the option */
129 if (!HaveBackupPriv) *CreateOptions &= ~FILE_OPEN_FOR_BACKUP_INTENT;
130 }
131}
132
134NTAPI
137{
138 /* Make sure the object is valid */
139 if ((IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
145 {
146 /* It's unloading or initializing, so fail */
147 DPRINT1("You are seeing this because the following ROS driver: %wZ\n"
148 " sucks. Please fix it's AddDevice Routine\n",
149 &DeviceObject->DriverObject->DriverName);
151 }
152 else if ((DeviceObject->Flags & DO_EXCLUSIVE) &&
153 (DeviceObject->ReferenceCount) &&
154 !(OpenPacket->RelatedFileObject) &&
155 !(OpenPacket->Options & IO_ATTACH_DEVICE))
156 {
158 }
159
160 else
161 {
162 /* Increase reference count */
163 InterlockedIncrement(&DeviceObject->ReferenceCount);
164 return STATUS_SUCCESS;
165 }
166}
167
168VOID
169NTAPI
172 IN PREPARSE_DATA_BUFFER DataBuffer)
173{
177 PWSTR NewBuffer;
178
179 PAGED_CODE();
180
181 ASSERT(Irp->IoStatus.Status == STATUS_REPARSE);
182 ASSERT(Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT);
183 ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
184 ASSERT(DataBuffer != NULL);
185 ASSERT(DataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT);
186 ASSERT(DataBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
187 ASSERT(DataBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
188
189 /* First of all, validate data */
190 if (DataBuffer->ReparseDataLength < REPARSE_DATA_BUFFER_HEADER_SIZE ||
191 (DataBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
192 DataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength +
194 {
195 Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
196 }
197
198 /* Everything went right */
199 if (NT_SUCCESS(Irp->IoStatus.Status))
200 {
201 /* Compute buffer & length */
202 Buffer = (PWSTR)((ULONG_PTR)DataBuffer->MountPointReparseBuffer.PathBuffer +
203 DataBuffer->MountPointReparseBuffer.SubstituteNameOffset);
204 Length = DataBuffer->MountPointReparseBuffer.SubstituteNameLength;
205
206 /* Check we don't overflow */
207 if (((ULONG)MAXUSHORT - DataBuffer->Reserved) <= (Length + sizeof(UNICODE_NULL)))
208 {
209 Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
210 }
211 else
212 {
213 /* Compute how much memory we'll need */
214 RequiredLength = DataBuffer->Reserved + Length + sizeof(UNICODE_NULL);
215
216 /* Check if FileObject can already hold what we need */
217 if (FileObject->FileName.MaximumLength >= RequiredLength)
218 {
219 NewBuffer = FileObject->FileName.Buffer;
220 }
221 else
222 {
223 /* Allocate otherwise */
225 if (NewBuffer == NULL)
226 {
227 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
228 }
229 }
230 }
231 }
232
233 /* Everything went right */
234 if (NT_SUCCESS(Irp->IoStatus.Status))
235 {
236 /* Copy the reserved data */
237 if (DataBuffer->Reserved)
238 {
239 RtlMoveMemory((PWSTR)((ULONG_PTR)NewBuffer + Length),
240 (PWSTR)((ULONG_PTR)FileObject->FileName.Buffer + FileObject->FileName.Length - DataBuffer->Reserved),
241 DataBuffer->Reserved);
242 }
243
244 /* Then the buffer */
245 if (Length)
246 {
247 RtlCopyMemory(NewBuffer, Buffer, Length);
248 }
249
250 /* And finally replace buffer if new one was allocated */
251 FileObject->FileName.Length = RequiredLength - sizeof(UNICODE_NULL);
252 if (NewBuffer != FileObject->FileName.Buffer)
253 {
254 if (FileObject->FileName.Buffer)
255 {
256 /*
257 * Don't use TAG_IO_NAME since the FileObject's FileName
258 * may have been re-allocated using a different tag
259 * by a filesystem.
260 */
261 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
262 }
263
264 FileObject->FileName.Buffer = NewBuffer;
265 FileObject->FileName.MaximumLength = RequiredLength;
266 FileObject->FileName.Buffer[RequiredLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
267 }
268 }
269
270 /* We don't need them anymore - it was allocated by the driver */
271 ExFreePool(DataBuffer);
272}
273
276 IN POPEN_PACKET OpenPacket,
277 BOOLEAN DirectOpen)
278{
281
283
284 /* Direct open is not allowed */
285 if (DirectOpen)
286 {
288 }
289
290 /* Validate we have a file system device */
291 DeviceType = LocalDevice->DeviceType;
297 {
299 }
300
301 /* Verify the hint and if it's OK, return it */
302 if (IopVerifyDeviceObjectOnStack(LocalDevice, OpenPacket->TopDeviceObjectHint))
303 {
304 *DeviceObject = OpenPacket->TopDeviceObjectHint;
305 return STATUS_SUCCESS;
306 }
307
308 /* Failure case here */
309 /* If we thought was had come through a mount point,
310 * actually update we didn't and return the error
311 */
312 if (OpenPacket->TraversedMountPoint)
313 {
314 OpenPacket->TraversedMountPoint = FALSE;
316 }
317
318 /* Otherwise, just return the fact the hint is invalid */
320}
321
323NTAPI
329 IN OUT PUNICODE_STRING CompleteName,
334{
335 POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
336 PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject;
337 PDEVICE_OBJECT DeviceObject, OwnerDevice;
340 PVPB Vpb = NULL;
341 PIRP Irp;
342 PIO_STACK_LOCATION StackLoc;
343 IO_SECURITY_CONTEXT SecurityContext;
345 BOOLEAN DirectOpen = FALSE, OpenCancelled, UseDummyFile;
348 PDUMMY_FILE_OBJECT LocalFileObject;
349 PFILE_BASIC_INFORMATION FileBasicInfo;
351 KPROCESSOR_MODE CheckMode;
352 BOOLEAN VolumeOpen = FALSE;
354 BOOLEAN AccessGranted, LockHeld = FALSE;
356 UNICODE_STRING FileString;
357 USHORT Attempt;
358 IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n",
359 ParseObject, RemainingName);
360
361 for (Attempt = 0; Attempt < IOP_MAX_REPARSE_TRAVERSAL; ++Attempt)
362 {
363 /* Assume failure */
364 *Object = NULL;
365
366 /* Validate the open packet */
367 if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
368
369 /* Valide reparse point in case we traversed a mountpoint */
370 if (OpenPacket->TraversedMountPoint)
371 {
372 /* This is a reparse point we understand */
374
375 /* Make sure we're dealing with correct DO */
376 if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK &&
377 OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM &&
378 OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
379 OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE)
380 {
383 }
384 }
385
386 /* Check if we have a related file object */
387 if (OpenPacket->RelatedFileObject)
388 {
389 /* Use the related file object's device object */
390 OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
391 }
392
393 /* Validate device status */
394 Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject);
395 if (!NT_SUCCESS(Status))
396 {
397 /* We failed, return status */
398 OpenPacket->FinalStatus = Status;
399 return Status;
400 }
401
402 /* Map the generic mask and set the new mapping in the access state */
403 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
405 RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
409 DesiredAccess = AccessState->RemainingDesiredAccess;
410
411 /* Check what kind of access checks to do */
412 if ((AccessMode != KernelMode) ||
413 (OpenPacket->Options & IO_FORCE_ACCESS_CHECK))
414 {
415 /* Call is from user-mode or kernel is forcing checks */
416 CheckMode = UserMode;
417 }
418 else
419 {
420 /* Call is from the kernel */
421 CheckMode = KernelMode;
422 }
423
424 /* Check privilege for backup or restore operation */
426 &OpenPacket->CreateOptions,
427 CheckMode,
428 OpenPacket->Disposition);
429
430 /* Check if we are re-parsing */
431 if (((OpenPacket->Override) && !(RemainingName->Length)) ||
433 {
434 /* Get granted access from the last call */
435 DesiredAccess |= AccessState->PreviouslyGrantedAccess;
436 }
437
438 /* Check if this is a volume open */
439 if ((OpenPacket->RelatedFileObject) &&
440 (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
441 !(RemainingName->Length))
442 {
443 /* It is */
444 VolumeOpen = TRUE;
445 }
446
447 /* Now check if we need access checks */
448 if (((AccessMode != KernelMode) ||
449 (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) &&
450 (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) &&
451 !(OpenPacket->Override))
452 {
455
456 /* Check if a device object is being parsed */
457 if (!RemainingName->Length)
458 {
459 /* Lock the subject context */
460 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
461 LockHeld = TRUE;
462
463 /* Do access check */
464 AccessGranted = SeAccessCheck(OriginalDeviceObject->
466 &AccessState->SubjectSecurityContext,
467 LockHeld,
469 0,
470 &Privileges,
472 TypeInfo.GenericMapping,
473 UserMode,
475 &Status);
476 if (Privileges)
477 {
478 /* Append and free the privileges */
481 }
482
483 /* Check if we got access */
484 if (AccessGranted)
485 {
486 /* Update access state */
487 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
488 AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
490 OpenPacket->Override= TRUE;
491 }
492
493 FileString.Length = 8;
494 FileString.MaximumLength = 8;
495 FileString.Buffer = L"File";
496
497 /* Do Audit/Alarm for open operation */
498 SeOpenObjectAuditAlarm(&FileString,
499 OriginalDeviceObject,
500 CompleteName,
501 OriginalDeviceObject->SecurityDescriptor,
503 FALSE,
505 UserMode,
506 &AccessState->GenerateOnClose);
507 }
508 else
509 {
510 /* Check if we need to do traverse validation */
512 ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
513 (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM)))
514 {
515 /* Check if this is a restricted token */
516 if (!(AccessState->Flags & TOKEN_IS_RESTRICTED))
517 {
518 /* Do the FAST traverse check */
519 AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor,
522 UserMode);
523 }
524 else
525 {
526 /* Fail */
528 }
529
530 /* Check if we failed to get access */
531 if (!AccessGranted)
532 {
533 /* Lock the subject context */
534 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
535 LockHeld = TRUE;
536
537 /* Do access check */
538 AccessGranted = SeAccessCheck(OriginalDeviceObject->
540 &AccessState->SubjectSecurityContext,
541 LockHeld,
543 0,
544 &Privileges,
546 TypeInfo.GenericMapping,
547 UserMode,
549 &Status);
550 if (Privileges)
551 {
552 /* Append and free the privileges */
555 }
556 }
557
558 /* FIXME: Do Audit/Alarm for traverse check */
559 }
560 else
561 {
562 /* Access automatically granted */
564 }
565 }
566
569
570 /* Check if we hold the lock */
571 if (LockHeld)
572 {
573 /* Release it */
574 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
575 }
576
577 /* Check if access failed */
578 if (!AccessGranted)
579 {
580 /* Dereference the device and fail */
581 DPRINT1("Traverse access failed!\n");
582 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
584 }
585 }
586
587 /* Check if we can simply use a dummy file */
588 UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
589
590 /* Check if this is a direct open */
591 if (!(RemainingName->Length) &&
592 !(OpenPacket->RelatedFileObject) &&
598 WRITE_DAC)) == 0) &&
599 !(UseDummyFile))
600 {
601 /* Remember this for later */
602 DirectOpen = TRUE;
603 }
604
605 /* Check if we have a related FO that wasn't a direct open */
606 if ((OpenPacket->RelatedFileObject) &&
607 !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
608 {
609 /* The device object is the one we were given */
610 DeviceObject = ParseObject;
611
612 /* Check if the related FO had a VPB */
613 if (OpenPacket->RelatedFileObject->Vpb)
614 {
615 /* Yes, remember it */
616 Vpb = OpenPacket->RelatedFileObject->Vpb;
617
618 /* Reference it */
619 InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
620
621 /* Check if we were given a specific top level device to use */
623 {
624 DeviceObject = Vpb->DeviceObject;
625 }
626 }
627 }
628 else
629 {
630 /* Check if it has a VPB */
631 if ((OriginalDeviceObject->Vpb) && !(DirectOpen))
632 {
633 /* Check if the VPB is mounted, and mount it */
634 Vpb = IopCheckVpbMounted(OpenPacket,
635 OriginalDeviceObject,
637 &Status);
638 if (!Vpb) return Status;
639
640 /* Get the VPB's device object */
641 DeviceObject = Vpb->DeviceObject;
642 }
643 else
644 {
645 /* The device object is the one we were given */
646 DeviceObject = OriginalDeviceObject;
647 }
648
649 /* If we weren't given a specific top level device, look for an attached device */
650 if (!(OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT) &&
651 DeviceObject->AttachedDevice)
652 {
653 /* Get the attached device */
655 }
656 }
657
658 /* If we have a top level device hint, verify it */
660 {
661 Status = IopCheckTopDeviceHint(&DeviceObject, OpenPacket, DirectOpen);
662 if (!NT_SUCCESS(Status))
663 {
664 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
666 return Status;
667 }
668 }
669
670 /* If we traversed a mount point, reset the information */
671 if (OpenPacket->TraversedMountPoint)
672 {
673 OpenPacket->TraversedMountPoint = FALSE;
674 }
675
676 /* Check if this is a secure FSD */
677 if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
678 ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) &&
679 (!VolumeOpen))
680 {
682 GrantedAccess = 0;
683
686
687 /* Lock the subject context */
688 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
689
690 /* Do access check */
691 AccessGranted = SeAccessCheck(OriginalDeviceObject->SecurityDescriptor,
692 &AccessState->SubjectSecurityContext,
693 TRUE,
695 0,
696 &Privileges,
698 UserMode,
700 &Status);
701 if (Privileges != NULL)
702 {
703 /* Append and free the privileges */
706 }
707
708 /* Check if we got access */
709 if (GrantedAccess)
710 {
711 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
712 AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED);
713 }
714
715 FileString.Length = 8;
716 FileString.MaximumLength = 8;
717 FileString.Buffer = L"File";
718
719 /* Do Audit/Alarm for open operation
720 * NOTA: we audit target device object
721 */
722 SeOpenObjectAuditAlarm(&FileString,
724 CompleteName,
725 OriginalDeviceObject->SecurityDescriptor,
727 FALSE,
729 UserMode,
730 &AccessState->GenerateOnClose);
731
732 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
733
736
737 /* Check if access failed */
738 if (!AccessGranted)
739 {
740 /* Dereference the device and fail */
741 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
744 }
745 }
746
747 /* Allocate the IRP */
748 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
749 if (!Irp)
750 {
751 /* Dereference the device and VPB, then fail */
752 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
755 }
756
757 /* Now set the IRP data */
758 Irp->RequestorMode = AccessMode;
760 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
761 Irp->UserIosb = &IoStatusBlock;
762 Irp->MdlAddress = NULL;
763 Irp->PendingReturned = FALSE;
764 Irp->UserEvent = NULL;
765 Irp->Cancel = FALSE;
766 Irp->CancelRoutine = NULL;
767 Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
768
769 /* Setup the security context */
770 SecurityContext.SecurityQos = SecurityQos;
771 SecurityContext.AccessState = AccessState;
772 SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
773 SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
774
775 /* Get the I/O Stack location */
776 StackLoc = IoGetNextIrpStackLocation(Irp);
777 StackLoc->Control = 0;
778
779 /* Check what kind of file this is */
780 switch (OpenPacket->CreateFileType)
781 {
782 /* Normal file */
784
785 /* Set the major function and EA Length */
786 StackLoc->MajorFunction = IRP_MJ_CREATE;
787 StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
788
789 /* Set the flags */
790 StackLoc->Flags = (UCHAR)OpenPacket->Options;
792 break;
793
794 /* Named pipe */
796
797 /* Set the named pipe MJ and set the parameters */
799 StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters;
800 break;
801
802 /* Mailslot */
804
805 /* Set the mailslot MJ and set the parameters */
807 StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters;
808 break;
809 }
810
811 /* Set the common data */
812 Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
813 Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer;
814 StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
815 (OpenPacket->CreateOptions &
816 0xFFFFFF);
817 StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
818 StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
819 StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
820
821 /* Check if we really need to create an object */
822 if (!UseDummyFile)
823 {
824 ULONG ObjectSize = sizeof(FILE_OBJECT);
825
826 /* Tag on space for a file object extension */
828 ObjectSize += sizeof(FILE_OBJECT_EXTENSION);
829
830 /* Create the actual file object */
832 NULL,
834 NULL,
835 NULL);
840 NULL,
841 ObjectSize,
842 0,
843 0,
844 (PVOID*)&FileObject);
845 if (!NT_SUCCESS(Status))
846 {
847 /* Create failed, free the IRP */
848 IoFreeIrp(Irp);
849
850 /* Dereference the device and VPB */
851 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
853
854 /* We failed, return status */
855 OpenPacket->FinalStatus = Status;
856 return Status;
857 }
858
859 /* Clear the file object */
860 RtlZeroMemory(FileObject, ObjectSize);
861
862 /* Check if this is Synch I/O */
863 if (OpenPacket->CreateOptions &
865 {
866 /* Set the synch flag */
868
869 /* Check if it's also alertable */
871 {
872 /* It is, set the alertable flag */
873 FileObject->Flags |= FO_ALERTABLE_IO;
874 }
875 }
876
877 /* Check if this is synch I/O */
878 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
879 {
880 /* Initialize the event */
882 }
883
884 /* Check if the caller requested no intermediate buffering */
886 {
887 /* Set the correct flag for the FSD to read */
889 }
890
891 /* Check if the caller requested write through support */
892 if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH)
893 {
894 /* Set the correct flag for the FSD to read */
896 }
897
898 /* Check if the caller says the file will be only read sequentially */
899 if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
900 {
901 /* Set the correct flag for the FSD to read */
903 }
904
905 /* Check if the caller believes the file will be only read randomly */
906 if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
907 {
908 /* Set the correct flag for the FSD to read */
910 }
911
912 /* Check if we were asked to setup a file object extension */
914 {
915 PFILE_OBJECT_EXTENSION FileObjectExtension;
916
917 /* Make sure the file object knows it has an extension */
919
920 /* Initialize file object extension */
921 FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
922 FileObject->FileObjectExtension = FileObjectExtension;
923
924 /* Add the top level device which we'll send the request to */
926 {
927 FileObjectExtension->TopDeviceObjectHint = DeviceObject;
928 }
929 }
930 }
931 else
932 {
933 /* Use the dummy object instead */
934 LocalFileObject = OpenPacket->LocalFileObject;
935 RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT));
936
937 /* Set it up */
938 FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body;
939 LocalFileObject->ObjectHeader.Type = IoFileObjectType;
940 LocalFileObject->ObjectHeader.PointerCount = 1;
941 }
942
943 /* Setup the file header */
944 FileObject->Type = IO_TYPE_FILE;
945 FileObject->Size = sizeof(FILE_OBJECT);
946 FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
947 FileObject->DeviceObject = OriginalDeviceObject;
948
949 /* Check if this is a direct device open */
950 if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
951
952 /* Check if the caller wants case sensitivity */
954 {
955 /* Tell the driver about it */
957 }
958
959 /* Now set the file object */
960 Irp->Tail.Overlay.OriginalFileObject = FileObject;
961 StackLoc->FileObject = FileObject;
962
963 /* Check if the file object has a name */
964 if (RemainingName->Length)
965 {
966 /* Setup the unicode string */
967 FileObject->FileName.MaximumLength = RemainingName->Length + sizeof(WCHAR);
968 FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool,
969 FileObject->FileName.MaximumLength,
971 if (!FileObject->FileName.Buffer)
972 {
973 /* Failed to allocate the name, free the IRP */
974 IoFreeIrp(Irp);
975
976 /* Dereference the device object and VPB */
977 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
979
980 /* Clear the FO and dereference it */
981 FileObject->DeviceObject = NULL;
982 if (!UseDummyFile) ObDereferenceObject(FileObject);
983
984 /* Fail */
986 }
987 }
988
989 /* Copy the name */
991
992 /* Initialize the File Object event and set the FO */
994 OpenPacket->FileObject = FileObject;
995
996 /* Queue the IRP and call the driver */
999 if (Status == STATUS_PENDING)
1000 {
1001 /* Wait for the driver to complete the create */
1003 Executive,
1004 KernelMode,
1005 FALSE,
1006 NULL);
1007
1008 /* Get the new status */
1010 }
1011 else
1012 {
1013 /* We'll have to complete it ourselves */
1014 ASSERT(!Irp->PendingReturned);
1015 ASSERT(!Irp->MdlAddress);
1016
1017 /* Handle name change if required */
1018 if (Status == STATUS_REPARSE)
1019 {
1020 /* Check this is a mount point */
1021 if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1022 {
1023 PREPARSE_DATA_BUFFER ReparseData;
1024
1025 /* Reparse point attributes were passed by the driver in the auxiliary buffer */
1026 ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1027 ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1028
1032
1033 IopDoNameTransmogrify(Irp, FileObject, ReparseData);
1034 }
1035 }
1036
1037 /* Completion happens at APC_LEVEL */
1039
1040 /* Get the new I/O Status block ourselves */
1041 IoStatusBlock = Irp->IoStatus;
1043
1044 /* Manually signal the even, we can't have any waiters */
1045 FileObject->Event.Header.SignalState = 1;
1046
1047 /* Now that we've signaled the events, de-associate the IRP */
1049
1050 /* Check if the IRP had an input buffer */
1051 if ((Irp->Flags & IRP_BUFFERED_IO) &&
1052 (Irp->Flags & IRP_DEALLOCATE_BUFFER))
1053 {
1054 /* Free it. A driver might've tacked one on */
1055 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1056 }
1057
1058 /* Free the IRP and bring the IRQL back down */
1059 IoFreeIrp(Irp);
1061 }
1062
1063 /* Copy the I/O Status */
1065
1066 /* The driver failed to create the file */
1067 if (!NT_SUCCESS(Status))
1068 {
1069 /* Check if we have a name and if so, free it */
1070 if (FileObject->FileName.Length)
1071 {
1072 /*
1073 * Don't use TAG_IO_NAME since the FileObject's FileName
1074 * may have been re-allocated using a different tag
1075 * by a filesystem.
1076 */
1077 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1078 FileObject->FileName.Buffer = NULL;
1079 FileObject->FileName.Length = 0;
1080 }
1081
1082 /* Clear its device object */
1083 FileObject->DeviceObject = NULL;
1084
1085 /* Save this now because the FO might go away */
1086 OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ?
1087 TRUE : FALSE;
1088
1089 /* Clear the file object in the open packet */
1090 OpenPacket->FileObject = NULL;
1091
1092 /* Dereference the file object */
1093 if (!UseDummyFile) ObDereferenceObject(FileObject);
1094
1095 /* Dereference the device object */
1096 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1097
1098 /* Unless the driver cancelled the open, dereference the VPB */
1099 if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb);
1100
1101 /* Set the status and return */
1102 OpenPacket->FinalStatus = Status;
1103 return Status;
1104 }
1105 else if (Status == STATUS_REPARSE)
1106 {
1107 if (OpenPacket->Information == IO_REPARSE ||
1109 {
1110 /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */
1111 if (CompleteName->MaximumLength < FileObject->FileName.Length)
1112 {
1113 PWSTR NewCompleteName;
1114
1115 /* Allocate a new buffer for the string */
1116 NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME);
1117 if (NewCompleteName == NULL)
1118 {
1121 }
1122
1123 /* Release the old one */
1124 if (CompleteName->Buffer != NULL)
1125 {
1126 /*
1127 * Don't use TAG_IO_NAME since the FileObject's FileName
1128 * may have been re-allocated using a different tag
1129 * by a filesystem.
1130 */
1131 ExFreePoolWithTag(CompleteName->Buffer, 0);
1132 }
1133
1134 /* And setup the new one */
1135 CompleteName->Buffer = NewCompleteName;
1136 CompleteName->MaximumLength = FileObject->FileName.Length;
1137 }
1138
1139 /* Copy our new complete name */
1140 RtlCopyUnicodeString(CompleteName, &FileObject->FileName);
1141
1142 if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1143 {
1144 OpenPacket->RelatedFileObject = NULL;
1145 }
1146 }
1147
1148 /* Check if we have a name and if so, free it */
1149 if (FileObject->FileName.Length)
1150 {
1151 /*
1152 * Don't use TAG_IO_NAME since the FileObject's FileName
1153 * may have been re-allocated using a different tag
1154 * by a filesystem.
1155 */
1156 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1157 FileObject->FileName.Buffer = NULL;
1158 FileObject->FileName.Length = 0;
1159 }
1160
1161 /* Clear its device object */
1162 FileObject->DeviceObject = NULL;
1163
1164 /* Clear the file object in the open packet */
1165 OpenPacket->FileObject = NULL;
1166
1167 /* Dereference the file object */
1168 if (!UseDummyFile) ObDereferenceObject(FileObject);
1169
1170 /* Dereference the device object */
1171 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1172
1173 /* Unless the driver cancelled the open, dereference the VPB */
1175
1176 if (OpenPacket->Information != IO_REMOUNT)
1177 {
1178 OpenPacket->RelatedFileObject = NULL;
1179
1180 /* Inform we traversed a mount point for later attempt */
1181 if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1182 {
1183 OpenPacket->TraversedMountPoint = 1;
1184 }
1185
1186 /* In case we override checks, but got this on volume open, fail hard */
1187 if (OpenPacket->Override)
1188 {
1189 KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN,
1190 (ULONG_PTR)OriginalDeviceObject,
1192 (ULONG_PTR)CompleteName,
1193 OpenPacket->Information);
1194 }
1195
1196 /* Return to IO/OB so that information can be upgraded */
1197 return STATUS_REPARSE;
1198 }
1199
1200 /* Loop again and reattempt an opening */
1201 continue;
1202 }
1203
1204 break;
1205 }
1206
1207 if (Attempt == IOP_MAX_REPARSE_TRAVERSAL)
1208 return STATUS_UNSUCCESSFUL;
1209
1210 /* Get the owner of the File Object */
1211 OwnerDevice = IoGetRelatedDeviceObject(FileObject);
1212
1213 /*
1214 * It's possible that the device to whom we sent the IRP to
1215 * isn't actually the device that ended opening the file object
1216 * internally.
1217 */
1218 if (OwnerDevice != DeviceObject)
1219 {
1220 /* We have to de-reference the VPB we had associated */
1222
1223 /* And re-associate with the actual one */
1224 Vpb = FileObject->Vpb;
1225 if (Vpb) InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
1226 }
1227
1228 /* Make sure we are not using a dummy */
1229 if (!UseDummyFile)
1230 {
1231 /* Check if this was a volume open */
1232 if ((!(FileObject->RelatedFileObject) ||
1233 (FileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN)) &&
1234 !(FileObject->FileName.Length))
1235 {
1236 /* All signs point to it, but make sure it was actually an FSD */
1237 if ((OwnerDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
1238 (OwnerDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
1239 (OwnerDevice->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) ||
1240 (OwnerDevice->DeviceType == FILE_DEVICE_FILE_SYSTEM))
1241 {
1242 /* The owner device is an FSD, so this is a volume open for real */
1243 FileObject->Flags |= FO_VOLUME_OPEN;
1244 }
1245 }
1246
1247 /* Reference the object and set the parse check */
1249 *Object = FileObject;
1250 OpenPacket->FinalStatus = IoStatusBlock.Status;
1251 OpenPacket->ParseCheck = TRUE;
1252 return OpenPacket->FinalStatus;
1253 }
1254 else
1255 {
1256 /* Check if this was a query */
1257 if (OpenPacket->QueryOnly)
1258 {
1259 /* Check if the caller wants basic info only */
1260 if (!OpenPacket->FullAttributes)
1261 {
1262 /* Allocate the buffer */
1263 FileBasicInfo = ExAllocatePoolWithTag(NonPagedPool,
1264 sizeof(*FileBasicInfo),
1265 TAG_IO);
1266 if (FileBasicInfo)
1267 {
1268 /* Do the query */
1271 sizeof(*FileBasicInfo),
1272 FileBasicInfo,
1273 &ReturnLength);
1274 if (NT_SUCCESS(Status))
1275 {
1276 /* Copy the data */
1277 RtlCopyMemory(OpenPacket->BasicInformation,
1278 FileBasicInfo,
1279 ReturnLength);
1280 }
1281
1282 /* Free our buffer */
1283 ExFreePoolWithTag(FileBasicInfo, TAG_IO);
1284 }
1285 else
1286 {
1287 /* Fail */
1289 }
1290 }
1291 else
1292 {
1293 /* This is a full query */
1295 FileObject,
1298 OpenPacket->NetworkInformation,
1299 &ReturnLength);
1301 }
1302 }
1303
1304 /* Delete the file object */
1306
1307 /* Clear out the file */
1308 OpenPacket->FileObject = NULL;
1309
1310 /* Set and return status */
1311 OpenPacket->FinalStatus = Status;
1312 OpenPacket->ParseCheck = TRUE;
1313 return Status;
1314 }
1315}
1316
1318NTAPI
1324 IN OUT PUNICODE_STRING CompleteName,
1328 OUT PVOID *Object)
1329{
1331 POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
1332
1333 /* Validate the open packet */
1334 if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
1335
1336 /* Get the device object */
1338 OpenPacket->RelatedFileObject = ParseObject;
1339
1340 /* Call the main routine */
1342 ObjectType,
1344 AccessMode,
1345 Attributes,
1346 CompleteName,
1348 OpenPacket,
1349 SecurityQos,
1350 Object);
1351}
1352
1353VOID
1354NTAPI
1356{
1357 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1358 PIRP Irp;
1359 PIO_STACK_LOCATION StackPtr;
1361 KEVENT Event;
1363 BOOLEAN DereferenceDone = FALSE;
1364 PVPB Vpb;
1365 KIRQL OldIrql;
1366 IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1367
1368 /* Check if the file has a device object */
1369 if (FileObject->DeviceObject)
1370 {
1371 /* Check if this is a direct open or not */
1372 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1373 {
1374 /* Get the attached device */
1376 }
1377 else
1378 {
1379 /* Use the file object's device object */
1381 }
1382
1383 /* Sanity check */
1384 ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
1386
1387 /* Check if the handle wasn't created yet */
1388 if (!(FileObject->Flags & FO_HANDLE_CREATED))
1389 {
1390 /* Send the cleanup IRP */
1391 IopCloseFile(NULL, ObjectBody, 0, 1, 1);
1392 }
1393
1394 /* Clear and set up Events */
1395 KeClearEvent(&FileObject->Event);
1397
1398 /* Allocate an IRP */
1400
1401 /* Set it up */
1402 Irp->UserEvent = &Event;
1403 Irp->UserIosb = &Irp->IoStatus;
1404 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1405 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1407
1408 /* Set up Stack Pointer Data */
1409 StackPtr = IoGetNextIrpStackLocation(Irp);
1410 StackPtr->MajorFunction = IRP_MJ_CLOSE;
1411 StackPtr->FileObject = FileObject;
1412
1413 /* Queue the IRP */
1415
1416 /* Get the VPB and check if this isn't a direct open */
1417 Vpb = FileObject->Vpb;
1418 if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1419 {
1420 /* Dereference the VPB before the close */
1421 InterlockedDecrement((PLONG)&Vpb->ReferenceCount);
1422 }
1423
1424 /* Check if the FS will never disappear by itself */
1425 if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
1426 {
1427 /* Dereference it */
1428 InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
1429 DereferenceDone = TRUE;
1430 }
1431
1432 /* Call the FS Driver */
1434 if (Status == STATUS_PENDING)
1435 {
1436 /* Wait for completion */
1438 }
1439
1440 /* De-queue the IRP */
1444
1445 /* Free the IRP */
1446 IoFreeIrp(Irp);
1447
1448 /* Clear the file name */
1449 if (FileObject->FileName.Buffer)
1450 {
1451 /*
1452 * Don't use TAG_IO_NAME since the FileObject's FileName
1453 * may have been re-allocated using a different tag
1454 * by a filesystem.
1455 */
1456 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
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 */
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 */
1480 }
1481 }
1482}
1483
1485NTAPI
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
1498NTAPI
1500{
1501 KIRQL OldIrql;
1502 PDEVICE_OBJECT PDO;
1503
1505
1507 /* Get the base DO */
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
1524NTAPI
1530{
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;
1555 SecurityDescriptor, &NewSecurityDescriptor,
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
1605NTAPI
1612{
1613 PDEVICE_OBJECT CurrentDO = PhysicalDeviceObject, NextDevice;
1614 NTSTATUS Status = STATUS_SUCCESS, TmpStatus;
1615
1616 PAGED_CODE();
1617
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 */
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
1653NTAPI
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 */
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)) ||
1703 {
1704 /* Check what kind of request this was */
1705 if (OperationCode == QuerySecurityDescriptor)
1706 {
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 {
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 */
1748
1749 if (PDO != NULL)
1750 {
1751 /* Apply the new SD to any DO in the path from PDO to current DO */
1757 }
1758 else
1759 {
1760 /* Otherwise, just set for ourselves */
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 */
1781
1782 /* Check if we should use Sync IO or not */
1783 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1784 {
1785 /* Lock the file object */
1787 if (Status != STATUS_SUCCESS)
1788 {
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 */
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 */
1837 StackPtr->Parameters.SetSecurity.SecurityInformation =
1839 StackPtr->Parameters.SetSecurity.SecurityDescriptor =
1841 }
1842
1843 /* Queue the IRP */
1845
1846 /* Update operation counts */
1848
1849 /* Call the Driver */
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 */
1860 Executive,
1861 KernelMode,
1862 FALSE,
1863 NULL);
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 */
1874 Executive,
1875 KernelMode,
1876 FALSE,
1877 NULL);
1878 Status = FileObject->FinalStatus;
1879 }
1880
1881 /* Release the lock */
1883 }
1884
1885 /* This Driver doesn't implement Security, so try to give it a default */
1887 {
1888 /* Was this a query? */
1889 if (OperationCode == QuerySecurityDescriptor)
1890 {
1891 /* Set a World Security Descriptor */
1894 BufferLength);
1895 }
1896 else
1897 {
1898 /* It wasn't a query, so just fake success */
1900 }
1901 }
1902 else if (OperationCode == QuerySecurityDescriptor)
1903 {
1904 /* Callers usually expect the normalized form */
1906
1907 _SEH2_TRY
1908 {
1909 /* Return length */
1911 }
1913 {
1914 /* Get the exception code */
1916 }
1917 _SEH2_END;
1918 }
1919
1920 /* Return Status */
1921 return Status;
1922}
1923
1925NTAPI
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,
1939 PreviousMode);
1940}
1941
1943NTAPI
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;
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 */
1970 }
1971
1972 /* Allocate Buffer */
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 */
1984 {
1985 /* We'll store separator and terminator */
1986 LocalReturnLength = sizeof(OBJECT_NAME_INFORMATION) + 2 * sizeof(WCHAR);
1987 if (Length < LocalReturnLength)
1988 {
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;
1998 }
1999 }
2000 /* Otherwise, call mountmgr to get DOS name */
2001 else
2002 {
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
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 {
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 &&
2087 {
2089 LengthMismatch ? Length : FileLength,
2091 LocalFileInfo,
2092 &LocalReturnLength);
2093 }
2094 else
2095 {
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 */
2107 {
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 */
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 */
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 -
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
2176VOID
2177NTAPI
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;
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 */
2202 {
2203 /* Get the attached device */
2205 }
2206 else
2207 {
2208 /* Get the FO's device */
2210 }
2211
2212 /* Check if this is a sync FO and lock it */
2214 {
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 */
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;
2239
2240 /* Set up Stack Pointer Data */
2241 StackPtr = IoGetNextIrpStackLocation(Irp);
2243 StackPtr->MinorFunction = IRP_MN_UNLOCK_ALL;
2244 StackPtr->FileObject = FileObject;
2245
2246 /* Queue the IRP */
2248
2249 /* Call the FS Driver */
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 */
2262 {
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 */
2275 }
2276 else
2277 {
2278 /* Get the FO's device */
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 &&
2288 {
2290 }
2291
2292 /* Clear and set up Events */
2293 KeClearEvent(&FileObject->Event);
2295
2296 /* Allocate an IRP */
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 */
2314
2315 /* Update operation counts */
2317
2318 /* Call the FS Driver */
2320 if (Status == STATUS_PENDING)
2321 {
2322 /* Wait for completion */
2324 }
2325
2326 /* Unqueue the IRP */
2330
2331 /* Free the IRP */
2332 IoFreeIrp(Irp);
2333
2334 /* Release the lock if we were holding it */
2335 if (Process != NULL &&
2337 {
2339 }
2340}
2341
2343NTAPI
2346 IN ULONG FileInformationSize,
2348{
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 */
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 */
2433 &NetworkOpenInfo,
2434 FileInformationSize);
2435 }
2437 {
2438 /* Get exception code */
2440 }
2441 _SEH2_END;
2442 }
2443
2444 /* Return status */
2445 return Status;
2446}
2447
2449NTAPI
2452 _In_ KPROCESSOR_MODE WaitMode,
2454 _Out_ PBOOLEAN LockFailed)
2455{
2457
2458 PAGED_CODE();
2459
2461
2463 do
2464 {
2466 {
2467 break;
2468 }
2470 Executive,
2471 WaitMode,
2472 Alertable,
2473 NULL);
2474 } while (Status == STATUS_SUCCESS);
2475
2477 if (Status == STATUS_SUCCESS)
2478 {
2480 *LockFailed = FALSE;
2481 }
2482 else
2483 {
2484 if (!FileObject->Busy && FileObject->Waiters)
2485 {
2487 }
2488 *LockFailed = TRUE;
2489 }
2490
2491 return Status;
2492}
2493
2494PVOID
2495NTAPI
2497{
2499 {
2500 PFILE_OBJECT_EXTENSION FileObjectExtension;
2501
2502 FileObjectExtension = FileObject->FileObjectExtension;
2503 return FileObjectExtension->FilterContext;
2504 }
2505
2506 return NULL;
2507}
2508
2510NTAPI
2513 IN BOOLEAN Define)
2514{
2516 PFILE_OBJECT_EXTENSION FileObjectExtension;
2517
2519 {
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 */
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 */
2541 }
2542
2543 /* If success isn't 0, it means we failed somewhere (set or unset) */
2544 if (Success != 0)
2545 {
2547 }
2548
2549 return STATUS_SUCCESS;
2550}
2551
2553NTAPI
2566 IN PVOID ExtraCreateParameters OPTIONAL,
2568 IN ULONG Flags,
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 */
2585 {
2586 /* Then force kernel-mode access to avoid checks */
2588 }
2589 else
2590 {
2591 /* Otherwise, use the actual mode */
2593 }
2594
2595 /* Check if we need to do parameter checking */
2597 {
2598 /* Validate parameters */
2600 {
2601 DPRINT1("File Create 'FileAttributes' Parameter contains invalid flags!\n");
2603 }
2604
2606 {
2607 DPRINT1("File Create 'ShareAccess' Parameter contains invalid flags!\n");
2609 }
2610
2612 {
2613 DPRINT1("File Create 'Disposition' Parameter is out of range!\n");
2615 }
2616
2618 {
2619 DPRINT1("File Create 'CreateOptions' parameter contains invalid flags!\n");
2621 }
2622
2625 {
2626 DPRINT1("File Create 'CreateOptions' parameter FILE_SYNCHRONOUS_IO_* requested, but 'DesiredAccess' does not have SYNCHRONIZE!\n");
2628 }
2629
2631 {
2632 DPRINT1("File Create 'CreateOptions' parameter FILE_DELETE_ON_CLOSE requested, but 'DesiredAccess' does not have DELETE!\n");
2634 }
2635
2638 {
2639 DPRINT1("File Create 'FileAttributes' parameter both FILE_SYNCHRONOUS_IO_NONALERT and FILE_SYNCHRONOUS_IO_ALERT specified!\n");
2641 }
2642
2655 {
2656 DPRINT1("File Create 'CreateOptions' Parameter has flags incompatible with FILE_DIRECTORY_FILE!\n");
2658 }
2659
2662 {
2663 DPRINT1("File Create 'CreateOptions' Parameter FILE_DIRECTORY_FILE requested, but 'Disposition' is not FILE_CREATE/FILE_OPEN/FILE_OPEN_IF!\n");
2665 }
2666
2668 {
2669 DPRINT1("File Create 'CreateOptions' Parameter both FILE_COMPLETE_IF_OPLOCKED and FILE_RESERVE_OPFILTER specified!\n");
2671 }
2672
2674 {
2675 DPRINT1("File Create 'CreateOptions' parameter FILE_NO_INTERMEDIATE_BUFFERING requested, but 'DesiredAccess' FILE_APPEND_DATA requires it!\n");
2677 }
2678
2679 /* Now check if this is a named pipe */
2681 {
2682 /* Make sure we have extra parameters */
2683 if (!ExtraCreateParameters)
2684 {
2685 DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
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) ||
2697 {
2698 /* Invalid named pipe create */
2699 DPRINT1("Invalid named pipe create\n");
2701 }
2702 }
2704 {
2705 /* Make sure we have extra parameters */
2706 if (!ExtraCreateParameters)
2707 {
2708 DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2710 }
2711
2712 /* Get the parameters and validate them */
2715 (Disposition != FILE_CREATE) ||
2717 {
2718 /* Invalid mailslot create */
2719 DPRINT1("Invalid mailslot create\n");
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 */
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 */
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 */
2770 EaLength,
2771 &EaErrorOffset);
2772 if (!NT_SUCCESS(Status))
2773 {
2774 /* Undo everything if it's invalid */
2775 DPRINT1("Invalid EA buffer\n");
2777 IoStatusBlock->Information = EaErrorOffset;
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 */
2795 {
2796 /* Set the flag properly */
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 */
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);
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 */
2874 NULL,
2875 AccessMode,
2876 NULL,
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 */
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 */
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 */
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 */
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 */
2983NTAPI
2985 IN ULONG Length,
2986 IN BOOLEAN SetOperation)
2987{
2990}
2991
2992/*
2993 * @unimplemented
2994 */
2996NTAPI
2998 IN ULONG QuotaLength,
2999 OUT PULONG ErrorOffset)
3000{
3003}
3004
3005/*
3006 * @implemented
3007 */
3009NTAPI
3022 IN PVOID ExtraCreateParameters OPTIONAL,
3024{
3025 PAGED_CODE();
3026
3036 EaBuffer,
3037 EaLength,
3039 ExtraCreateParameters,
3040 Options,
3041 0,
3042 NULL);
3043}
3044
3045/*
3046 * @unimplemented
3047 */
3049NTAPI
3062 IN PVOID ExtraCreateParameters OPTIONAL,
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
3086 EaBuffer,
3087 EaLength,
3089 ExtraCreateParameters,
3091 Flags,
3092 DeviceObject);
3093}
3094
3095/*
3096 * @implemented
3097 */
3099NTAPI
3103{
3104 PFILE_OBJECT CreatedFileObject;
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);
3117
3118 /* Create the File Object */
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 */
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);
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 */
3176 }
3177
3178 /* Return the file object */
3179 return CreatedFileObject;
3180}
3181
3182/*
3183 * @implemented
3184 */
3186NTAPI
3189{
3190 /* Call the newer function */
3192}
3193
3194/*
3195 * @implemented
3196 */
3198NTAPI
3201{
3202 PFILE_OBJECT CreatedFileObject;
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);
3214
3215 /* Create the File Object */
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 */
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 */
3266NTAPI
3268{
3269 /* Return the mapping */
3270 return &IopFileMapping;
3271}
3272
3273/*
3274 * @implemented
3275 */
3276BOOLEAN
3277NTAPI
3279{
3280 /* Return the flag status */
3281 return FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3282}
3283
3284/*
3285 * @implemented
3286 */
3287BOOLEAN
3288NTAPI
3294{
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);
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 */
3324 NULL,
3325 KernelMode,
3326 NULL,
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 */
3349VOID
3350NTAPI
3353{
3354 PAGED_CODE();
3355
3356 /* Check if the file has an 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 */
3389NTAPI
3395{
3398 BOOLEAN DeleteAccess;
3399 BOOLEAN SharedRead;
3400 BOOLEAN SharedWrite;
3401 BOOLEAN SharedDelete;
3402 PAGED_CODE();
3403
3404 /* Get access masks */
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 */
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 /* Check if the shared access is violated */
3434 if ((ReadAccess &&
3435 (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
3436 (WriteAccess &&
3437 (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
3438 (DeleteAccess &&
3439 (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
3440 ((ShareAccess->Readers != 0) && !SharedRead) ||
3441 ((ShareAccess->Writers != 0) && !SharedWrite) ||
3442 ((ShareAccess->Deleters != 0) && !SharedDelete))
3443 {
3444 /* Sharing violation, fail */
3446 }
3447
3448 /* Set them */
3449 FileObject->SharedRead = SharedRead;
3450 FileObject->SharedWrite = SharedWrite;
3451 FileObject->SharedDelete = SharedDelete;
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 */
3476VOID
3477NTAPI
3480{
3481 PAGED_CODE();
3482
3483 /* Check if the file has an 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 */
3515VOID
3516NTAPI
3521{
3524 BOOLEAN DeleteAccess;
3525 BOOLEAN SharedRead;
3526 BOOLEAN SharedWrite;
3527 BOOLEAN SharedDelete;
3529 PAGED_CODE();
3530
3533 DeleteAccess = (DesiredAccess & DELETE) != 0;
3534
3535 /* Check if the file has an 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 */
3595VOID
3596NTAPI
3599{
3600 PIRP Irp;
3601 KEVENT Event;
3602 KIRQL OldIrql;
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,
3612 (ULONG_PTR)DeviceObject, 0, 0);
3613
3614 /* Reset the events */
3616 KeClearEvent(&FileObject->Event);
3617
3618 /* Allocate the IRP we'll use */
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
3630 Stack->MajorFunction = IRP_MJ_CLEANUP;
3631 Stack->FileObject = FileObject;
3632
3633 /* Put on top of IRPs list of the thread */
3635
3636 /* Call the driver */
3638 if (Status == STATUS_PENDING)
3639 {
3642 }
3643
3644 /* Remove from IRPs list */
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 */
3656}
3657
3658/*
3659 * @implemented
3660 */
3662NTAPI
3665{
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 */
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 */
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 */
3722NTAPI
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 */
3757NTAPI
3762 PLARGE_INTEGER AllocateSize,
3769{
3770 /* Call the I/O Function */
3771 return IoCreateFile(FileHandle,
3775 AllocateSize,
3780 EaBuffer,
3781 EaLength,
3783 NULL,
3784 0);
3785}
3786
3788NTAPI
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 */
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,
3844 NULL,
3845 0,
3849 NULL,
3850 0,
3852 (PVOID)&Buffer,
3853 0);
3854}
3855
3857NTAPI
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 */
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,
3924 NULL,
3925 0,
3929 NULL,
3930 0,
3932 (PVOID)&Buffer,
3933 0);
3934}
3935
3937NTAPI
3939{
3940 PAGED_CODE();
3941
3942 /* Call the kernel */
3944 return STATUS_SUCCESS;
3945}
3946
3947/*
3948 * @implemented
3949 */
3951NTAPI
3958{
3959 /* Call the I/O Function */
3960 return IoCreateFile(FileHandle,
3964 NULL,
3965 0,
3967 FILE_OPEN,
3969 NULL,
3970 0,
3972 NULL,
3973 0);
3974}
3975
3977NTAPI
3980{
3981 /* Call the internal helper API */
3984 sizeof(FILE_BASIC_INFORMATION),
3986}
3987
3989NTAPI
3992{
3993 /* Call the internal helper API */
3998}
3999
4018NTAPI
4021{
4024 PIRP Irp;
4025 KIRQL OldIrql;
4026 BOOLEAN OurIrpsInList = FALSE;
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 */
4042 }
4044 {
4045 /* Return the exception code */
4047 }
4048 _SEH2_END;
4049 }
4050
4051 /* Reference the file object */
4053 0,
4056 (PVOID*)&FileObject,
4057 NULL);
4058 if (!NT_SUCCESS(Status)) return Status;
4059
4060 /* IRP cancellations are synchronized at APC_LEVEL. */
4062
4063 /* Get the current thread */
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 */
4080 OurIrpsInList = TRUE;
4081 }
4082
4083 /* Go to the next entry */
4084 NextEntry = NextEntry->Flink;
4085 }
4086
4087 /* Lower the IRQL */
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 */
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 */
4125 }
4126 }
4127
4128 /* Enter SEH for writing back the I/O Status */
4129 _SEH2_TRY
4130 {
4131 /* Write success */
4134 }
4136 {
4137 /* Ignore exception */
4138 }
4139 _SEH2_END;
4140
4141 /* Dereference the file object and return success */
4143 return STATUS_SUCCESS;
4144}
4145
4146/*
4147 * @implemented
4148 */
4150NTAPI
4152{
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);
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 */
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 */
#define PAGED_CODE()
@ ObjectNameInformation
Definition: DriverTester.h:55
unsigned char BOOLEAN
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
Type
Definition: Type.h:7
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)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1994
#define VOID
Definition: acefi.h:82
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_OPEN_FOR_FREE_SPACE_QUERY
Definition: constants.h:495
#define FILE_COMPLETE_IF_OPLOCKED
Definition: constants.h:493
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define DPRINT1
Definition: precomp.h:8
@ Update
Definition: registry.c:565
@ LocalDevice
Definition: bl.h:261
#define UNIMPLEMENTED
Definition: debug.h:118
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define DEVICE_TYPE
Definition: guid.c:10
#define FILE_SHARE_READ
Definition: compat.h:136
_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:4147
#define ULONG_PTR
Definition: config.h:101
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DO_EXCLUSIVE
Definition: env_spec_w32.h:395
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define NonPagedPool
Definition: env_spec_w32.h:307
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define DO_NEVER_LAST_DEVICE
Definition: env_spec_w32.h:402
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
@ Success
Definition: eventcreate.c:712
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define ExGetPreviousMode
Definition: ex.h:140
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1676
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:879
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:323
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
VOID NTAPI FsRtlPTeardownPerFileObjectContexts(IN PFILE_OBJECT FileObject)
Definition: filtrctx.c:28
_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:1236
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
@ FileNameInformation
Definition: from_kernel.h:70
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileBasicInformation
Definition: from_kernel.h:65
#define FILE_MAXIMUM_DISPOSITION
Definition: from_kernel.h:59
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_RESERVE_OPFILTER
Definition: from_kernel.h:45
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_opt_ PVOID FilterContext
Definition: fsrtlfuncs.h:746
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
VOID NTAPI KeFlushWriteBuffer(VOID)
Definition: misc.c:39
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
__in WDFOBJECT __in PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
Definition: handleapi.cpp:601
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1605
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _FILE_NAME_INFORMATION * PFILE_NAME_INFORMATION
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
static __inline NTSTATUS IopLockFileObject(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode)
Definition: io_x.h:12
static __inline BOOLEAN IopValidateOpenPacket(IN POPEN_PACKET OpenPacket)
Definition: io_x.h:154
FORCEINLINE VOID IopQueueIrpToThread(IN PIRP Irp)
Definition: io_x.h:49
static __inline VOID IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type)
Definition: io_x.h:82
static __inline VOID IopUnlockFileObject(IN PFILE_OBJECT FileObject)
Definition: io_x.h:36
FORCEINLINE VOID IopUnQueueIrpFromThread(IN PIRP Irp)
Definition: io_x.h:66
NTSTATUS NTAPI IoQueryFileInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength)
Definition: iofunc.c:1274
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: vista.c:17
DeviceType
Definition: mmdrv.h:42
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
ObjectType
Definition: metafile.c:81
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
DWORD * PSECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3228
_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:6017
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define KeGetPreviousMode()
Definition: ketypes.h:1115
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:453
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
#define FILE_PIPE_MESSAGE_TYPE
Definition: iotypes.h:76
#define FO_FILE_OBJECT_HAS_EXTENSION
Definition: iotypes.h:144
#define IO_ATTACH_DEVICE_API
Definition: iotypes.h:218
#define DOE_REMOVE_PROCESSED
Definition: iotypes.h:152
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define FILE_PIPE_COMPLETE_OPERATION
Definition: iotypes.h:80
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
#define FILE_PIPE_MESSAGE_MODE
Definition: iotypes.h:78
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
DWORD Interval
Definition: netstat.c:30
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define WRITE_DAC
Definition: nt_native.h:59
#define FILE_READ_DATA
Definition: nt_native.h:628
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_VALID_PIPE_OPTION_FLAGS
Definition: nt_native.h:760
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define WRITE_OWNER
Definition: nt_native.h:60
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_VALID_MAILSLOT_OPTION_FLAGS
Definition: nt_native.h:761
NTSTATUS NTAPI NtCreateFile(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 CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
@ SynchronizationEvent
@ FILE_OBJECT
Definition: ntobjenum.h:17
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
GENERIC_MAPPING IopFileMapping
Definition: iomgr.c:49
#define IOP_USE_TOP_LEVEL_DEVICE_HINT
Definition: io.h:96
struct _OPEN_PACKET * POPEN_PACKET
PVPB NTAPI IopCheckVpbMounted(IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING RemainingName, OUT PNTSTATUS Status)
Definition: volume.c:76
struct _FILE_OBJECT_EXTENSION FILE_OBJECT_EXTENSION
BOOLEAN NTAPI IopVerifyDeviceObjectOnStack(IN PDEVICE_OBJECT BaseDeviceObject, IN PDEVICE_OBJECT TopDeviceObjectHint)
Definition: device.c:695
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
@ IopOtherTransfer
Definition: io.h:263
PIRP NTAPI IopAllocateIrpMustSucceed(IN CCHAR StackSize)
Definition: irp.c:716
#define IO_API_DEBUG
Definition: io.h:21
#define IOP_CREATE_FILE_OBJECT_EXTENSION
Definition: io.h:97
#define IOP_MAX_REPARSE_TRAVERSAL
Definition: io.h:91
#define IO_FILE_DEBUG
Definition: io.h:20
#define IOTRACE(x, fmt,...)
Definition: io.h:47
struct _FILE_OBJECT_EXTENSION * PFILE_OBJECT_EXTENSION
NTSTATUS NTAPI IopGetFileInformation(IN PFILE_OBJECT FileObject, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInfoClass, OUT PVOID Buffer, OUT PULONG ReturnedLength)
Definition: iofunc.c:777
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:186
struct _OPEN_PACKET OPEN_PACKET
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:129
const LUID SeBackupPrivilege
Definition: priv.c:36
const LUID SeRestorePrivilege
Definition: priv.c:37
NTSTATUS NTAPI SeSetWorldSecurityDescriptor(_In_ SECURITY_INFORMATION SecurityInformation, _In_ PISECURITY_DESCRIPTOR SecurityDescriptor, _In_ PULONG BufferLength)
Sets a "World" security descriptor.
Definition: sd.c:155
BOOLEAN NTAPI SeFastTraverseCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PACCESS_STATE AccessState, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE AccessMode)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:2138
#define ExRaiseStatus
Definition: ntoskrnl.h:114
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1385
NTSTATUS NTAPI IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG FileInformationSize, OUT PVOID FileInformation)
Definition: file.c:2344
VOID NTAPI IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject)
Definition: file.c:3597
NTSTATUS NTAPI IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject, IN PVOID FilterContext, IN BOOLEAN Define)
Definition: file.c:2511
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3517
NTSTATUS NTAPI NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
Definition: file.c:3978
NTSTATUS NTAPI NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: file.c:4019
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
NTSTATUS NTAPI IoSetFileOrigin(IN PFILE_OBJECT FileObject, IN BOOLEAN Remote)
Definition: file.c:3723
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
ERESOURCE IopSecurityResource
Definition: iomgr.c:60
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
NTSTATUS NTAPI IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, IN ULONG QuotaLength, OUT PULONG ErrorOffset)
Definition: file.c:2997
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
NTSTATUS NTAPI IopAcquireFileObjectLock(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode, _In_ BOOLEAN Alertable, _Out_ PBOOLEAN LockFailed)
Definition: file.c:2450
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
PDEVICE_OBJECT NTAPI IopGetDevicePDO(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1499
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
NTSTATUS IopCheckTopDeviceHint(IN OUT PDEVICE_OBJECT *DeviceObject, IN POPEN_PACKET OpenPacket, BOOLEAN DirectOpen)
Definition: file.c:275
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
NTSTATUS NTAPI IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN BOOLEAN SetOperation)
Definition: file.c:2984
VOID NTAPI IopCheckBackupRestorePrivilege(IN PACCESS_STATE AccessState, IN OUT PULONG CreateOptions, IN KPROCESSOR_MODE PreviousMode, IN ULONG Disposition)
Definition: file.c:25
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:1319
NTSTATUS NTAPI IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
Definition: file.c:3663
VOID NTAPI IopDoNameTransmogrify(IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER DataBuffer)
Definition: file.c:170
PFILE_OBJECT NTAPI IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, OUT PHANDLE FileObjectHandle OPTIONAL)
Definition: file.c:3100
VOID NTAPI IopCloseFile(IN PEPROCESS Process OPTIONAL, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount, IN ULONG SystemHandleCount)
Definition: file.c:2178
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
NTSTATUS NTAPI NtFlushWriteBuffer(VOID)
Definition: file.c:3938
PVOID NTAPI IoGetFileObjectFilterContext(IN PFILE_OBJECT FileObject)
Definition: file.c:2496
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
NTSTATUS NTAPI NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
Definition: file.c:3990
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
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
NTSTATUS NTAPI NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: file.c:4151
NTSTATUS NTAPI IopCheckDeviceAndDriver(IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:135
PDEVICE_OBJECT NTAPI IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1486
PFILE_OBJECT NTAPI IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:3199
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3278
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
VOID NTAPI IopDeleteFile(IN PVOID ObjectBody)
Definition: file.c:1355
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3351
NTSTATUS NTAPI IopParseDevice(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: file.c:324
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
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
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
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
NTSTATUS NTAPI IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)
Definition: volume.c:1279
VOID NTAPI SeSetAccessStateGenericMapping(_In_ PACCESS_STATE AccessState, _In_ PGENERIC_MAPPING GenericMapping)
Sets a new generic mapping for an allocated access state.
Definition: access.c:193
VOID NTAPI SeOpenObjectAuditAlarm(_In_ PUNICODE_STRING ObjectTypeName, _In_opt_ PVOID Object, _In_opt_ PUNICODE_STRING AbsoluteObjectName, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PACCESS_STATE AccessState, _In_ BOOLEAN ObjectCreated, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE AccessMode, _Out_ PBOOLEAN GenerateOnClose)
Creates an audit with alarm notification of an object that is being opened.
Definition: audit.c:1213
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
VOID NTAPI SeFreePrivileges(_In_ PPRIVILEGE_SET Privileges)
Frees a set of privileges.
Definition: priv.c:669
NTSTATUS NTAPI SeAppendPrivileges(_Inout_ PACCESS_STATE AccessState, _In_ PPRIVILEGE_SET Privileges)
Appends additional privileges.
Definition: priv.c:588
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER
Definition: ntstatus.h:915
#define STATUS_MOUNT_POINT_NOT_RESOLVED
Definition: ntstatus.h:914
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:285
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define STATUS_IO_REPARSE_DATA_INVALID
Definition: ntstatus.h:756
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define L(x)
Definition: ntvdm.h:50
VOID NTAPI ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: oblife.c:603
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
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:2935
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:2532
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:1039
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
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:494
NTSTATUS NTAPI ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, IN ULONG RefBias)
Definition: obsdcach.c:364
VOID NTAPI ObDereferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count)
Definition: obsdcach.c:287
VOID NTAPI ObReferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count)
Definition: obsdcach.c:256
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_FILE_SYSTEM
Definition: winioctl.h:54
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_TAPE
Definition: winioctl.h:76
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:77
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:65
#define FILE_DEVICE_DFS_FILE_SYSTEM
Definition: winioctl.h:98
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:81
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForWriteIoStatusBlock(Ptr)
Definition: probe.h:52
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
OBJECT_HEADER ObjectHeader
Definition: io.h:358
ULONG Flags
Definition: pstypes.h:1436
LIST_ENTRY IrpList
Definition: pstypes.h:1145
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:102
PVOID FilterContext
Definition: io.h:103
PACCESS_STATE AccessState
Definition: iotypes.h:2867
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2866
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2868
struct _IO_STACK_LOCATION::@3974::@3992 QuerySecurity
struct _IO_STACK_LOCATION::@3974::@3976 CreatePipe
struct _IO_STACK_LOCATION::@3974::@3977 CreateMailslot
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@3974::@3993 SetSecurity
struct _IO_STACK_LOCATION::@3974::@3975 Create
union _IO_STACK_LOCATION::@1575 Parameters
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LONG_PTR PointerCount
Definition: obtypes.h:487
POBJECT_TYPE Type
Definition: obtypes.h:493
UNICODE_STRING Name
Definition: nt_native.h:1270
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
LARGE_INTEGER AllocationSize
Definition: io.h:376
BOOLEAN Override
Definition: io.h:388
BOOLEAN DeleteOnly
Definition: io.h:390
PFILE_BASIC_INFORMATION BasicInformation
Definition: io.h:384
USHORT FileAttributes
Definition: io.h:378
PVOID ExtraCreateParameters
Definition: io.h:387
PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
Definition: io.h:385
USHORT ShareAccess
Definition: io.h:379
BOOLEAN FullAttributes
Definition: io.h:391
NTSTATUS FinalStatus
Definition: io.h:371
CREATE_FILE_TYPE CreateFileType
Definition: io.h:386
PDUMMY_FILE_OBJECT LocalFileObject
Definition: io.h:392
CSHORT Type
Definition: io.h:368
ULONG_PTR Information
Definition: io.h:372
ULONG InternalFlags
Definition: io.h:394
ULONG Disposition
Definition: io.h:383
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:395
PFILE_OBJECT FileObject
Definition: io.h:370
ULONG Options
Definition: io.h:382
BOOLEAN TraversedMountPoint
Definition: io.h:393
PFILE_OBJECT RelatedFileObject
Definition: io.h:374
ULONG ParseCheck
Definition: io.h:373
CSHORT Size
Definition: io.h:369
ULONG CreateOptions
Definition: io.h:377
PVOID EaBuffer
Definition: io.h:380
ULONG EaLength
Definition: io.h:381
BOOLEAN QueryOnly
Definition: io.h:389
WCHAR PathBuffer[1]
Definition: shellext.h:176
USHORT ReparseDataLength
Definition: shellext.h:166
USHORT MaximumLength
Definition: env_spec_w32.h:370
PVPB Vpb
Definition: cdstruc.h:511
Definition: iotypes.h:189
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
#define TAG_EA
Definition: tag.h:82
#define TAG_IO
Definition: tag.h:80
#define TAG_IO_NAME
Definition: tag.h:83
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define NT_WARNING(Status)
Definition: umtypes.h:105
#define NT_ERROR(Status)
Definition: umtypes.h:106
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG _Out_opt_ PULONG CreateDisposition
Definition: wdfregistry.h:120
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:118
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
_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:191
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
_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:845
_In_opt_ PDEVICE_OBJECT _Out_opt_ PHANDLE FileObjectHandle
Definition: iofuncs.h:2175
_In_ ULONG DesiredShareAccess
Definition: iofuncs.h:781
_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:847
#define IRP_MN_UNLOCK_ALL
Definition: iotypes.h:4412
#define IO_REPARSE
Definition: iotypes.h:543
#define FO_FILE_OPEN_CANCELLED
Definition: iotypes.h:1797
#define FO_REMOTE_ORIGIN
Definition: iotypes.h:1799
#define IRP_DEALLOCATE_BUFFER
#define FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1780
#define IO_TYPE_DEVICE
#define IRP_CLOSE_OPERATION
#define FO_ALERTABLE_IO
Definition: iotypes.h:1777
#define IRP_SYNCHRONOUS_API
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:540
@ ReadAccess
Definition: iotypes.h:424
@ WriteAccess
Definition: iotypes.h:425
#define IRP_MJ_CREATE_NAMED_PIPE
#define IRP_MJ_CREATE_MAILSLOT
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_CHECK_CREATE_PARAMETERS
Definition: iotypes.h:4429
#define DO_BUS_ENUMERATED_DEVICE
#define FO_OPENED_CASE_SENSITIVE
Definition: iotypes.h:1793
#define FO_HANDLE_CREATED
Definition: iotypes.h:1794
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1796
#define IO_ATTACH_DEVICE
Definition: iotypes.h:4430
#define FO_VOLUME_OPEN
Definition: iotypes.h:1798
#define IO_TYPE_FILE
#define IRP_CREATE_OPERATION
#define IRP_MJ_QUERY_SECURITY
#define IRP_DEFER_IO_COMPLETION
#define FO_DIRECT_DEVICE_OPEN
Definition: iotypes.h:1787
* PFILE_OBJECT
Definition: iotypes.h:1998
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7213
#define FO_STREAM_FILE
Definition: iotypes.h:1783
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
@ CreateFileTypeNone
Definition: iotypes.h:535
@ CreateFileTypeNamedPipe
Definition: iotypes.h:536
@ CreateFileTypeMailslot
Definition: iotypes.h:537
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
enum _CREATE_FILE_TYPE CREATE_FILE_TYPE
#define IO_REMOUNT
Definition: iotypes.h:544
#define IO_TYPE_OPEN_PACKET
#define IRP_BUFFERED_IO
#define IRP_MJ_SET_SECURITY
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
#define IRP_MJ_CLEANUP
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ UserRequest
Definition: ketypes.h:421
@ Executive
Definition: ketypes.h:415
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
@ LockQueueIoDatabaseLock
Definition: ketypes.h:668
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
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)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE _In_ BOOLEAN _In_ BOOLEAN AccessGranted
Definition: sefuncs.h:419
NTKERNELAPI NTSTATUS NTAPI SeQuerySecurityDescriptorInfo(_In_ PSECURITY_INFORMATION SecurityInformation, _Out_writes_bytes_(*Length) PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PULONG Length, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor)
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13
_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:20
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1178
SECURITY_OPERATION_CODE
Definition: setypes.h:170
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1179
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1180
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1183
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1187
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180