ReactOS 0.4.16-dev-2610-ge2c92c0
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 ((DeviceObject->Flags & DO_DEVICE_INITIALIZING) ||
140 (IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
143 {
144 /* It's initializing or unloading, so fail */
145 DPRINT1("\nYou are seeing this because the following ROS driver: %wZ\n"
146 "sucks. Please fix its AddDevice routine.\n",
147 &DeviceObject->DriverObject->DriverName);
149 }
150 else if ((DeviceObject->Flags & DO_EXCLUSIVE) &&
151 (DeviceObject->ReferenceCount) &&
152 !(OpenPacket->RelatedFileObject) &&
153 !(OpenPacket->Options & IO_ATTACH_DEVICE))
154 {
156 }
157 else
158 {
159 /* Increase reference count */
160 InterlockedIncrement(&DeviceObject->ReferenceCount);
161 return STATUS_SUCCESS;
162 }
163}
164
165VOID
166NTAPI
169 IN PREPARSE_DATA_BUFFER DataBuffer)
170{
174 PWSTR NewBuffer;
175
176 PAGED_CODE();
177
178 ASSERT(Irp->IoStatus.Status == STATUS_REPARSE);
179 ASSERT(Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT);
180 ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
181 ASSERT(DataBuffer != NULL);
182 ASSERT(DataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT);
183 ASSERT(DataBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
184 ASSERT(DataBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
185
186 /* First of all, validate data */
187 if (DataBuffer->ReparseDataLength < REPARSE_DATA_BUFFER_HEADER_SIZE ||
188 (DataBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
189 DataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength +
191 {
192 Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
193 }
194
195 /* Everything went right */
196 if (NT_SUCCESS(Irp->IoStatus.Status))
197 {
198 /* Compute buffer & length */
199 Buffer = (PWSTR)((ULONG_PTR)DataBuffer->MountPointReparseBuffer.PathBuffer +
200 DataBuffer->MountPointReparseBuffer.SubstituteNameOffset);
201 Length = DataBuffer->MountPointReparseBuffer.SubstituteNameLength;
202
203 /* Check we don't overflow */
204 if (((ULONG)MAXUSHORT - DataBuffer->Reserved) <= (Length + sizeof(UNICODE_NULL)))
205 {
206 Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
207 }
208 else
209 {
210 /* Compute how much memory we'll need */
211 RequiredLength = DataBuffer->Reserved + Length + sizeof(UNICODE_NULL);
212
213 /* Check if FileObject can already hold what we need */
214 if (FileObject->FileName.MaximumLength >= RequiredLength)
215 {
216 NewBuffer = FileObject->FileName.Buffer;
217 }
218 else
219 {
220 /* Allocate otherwise */
222 if (NewBuffer == NULL)
223 {
224 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
225 }
226 }
227 }
228 }
229
230 /* Everything went right */
231 if (NT_SUCCESS(Irp->IoStatus.Status))
232 {
233 /* Copy the reserved data */
234 if (DataBuffer->Reserved)
235 {
236 RtlMoveMemory((PWSTR)((ULONG_PTR)NewBuffer + Length),
237 (PWSTR)((ULONG_PTR)FileObject->FileName.Buffer + FileObject->FileName.Length - DataBuffer->Reserved),
238 DataBuffer->Reserved);
239 }
240
241 /* Then the buffer */
242 if (Length)
243 {
244 RtlCopyMemory(NewBuffer, Buffer, Length);
245 }
246
247 /* And finally replace buffer if new one was allocated */
248 FileObject->FileName.Length = RequiredLength - sizeof(UNICODE_NULL);
249 if (NewBuffer != FileObject->FileName.Buffer)
250 {
251 if (FileObject->FileName.Buffer)
252 {
253 /*
254 * Don't use TAG_IO_NAME since the FileObject's FileName
255 * may have been re-allocated using a different tag
256 * by a filesystem.
257 */
258 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
259 }
260
261 FileObject->FileName.Buffer = NewBuffer;
262 FileObject->FileName.MaximumLength = RequiredLength;
263 FileObject->FileName.Buffer[RequiredLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
264 }
265 }
266
267 /* We don't need them anymore - it was allocated by the driver */
268 ExFreePool(DataBuffer);
269}
270
273 IN POPEN_PACKET OpenPacket,
274 BOOLEAN DirectOpen)
275{
276 PDEVICE_OBJECT LocalDevice;
278
279 LocalDevice = *DeviceObject;
280
281 /* Direct open is not allowed */
282 if (DirectOpen)
283 {
285 }
286
287 /* Validate we have a file system device */
288 DeviceType = LocalDevice->DeviceType;
294 {
296 }
297
298 /* Verify the hint and if it's OK, return it */
299 if (IopVerifyDeviceObjectOnStack(LocalDevice, OpenPacket->TopDeviceObjectHint))
300 {
301 *DeviceObject = OpenPacket->TopDeviceObjectHint;
302 return STATUS_SUCCESS;
303 }
304
305 /* Failure case here */
306 /* If we thought was had come through a mount point,
307 * actually update we didn't and return the error
308 */
309 if (OpenPacket->TraversedMountPoint)
310 {
311 OpenPacket->TraversedMountPoint = FALSE;
313 }
314
315 /* Otherwise, just return the fact the hint is invalid */
317}
318
320NTAPI
326 IN OUT PUNICODE_STRING CompleteName,
331{
332 POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
333 PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject;
334 PDEVICE_OBJECT DeviceObject, OwnerDevice;
337 PVPB Vpb = NULL;
338 PIRP Irp;
339 PIO_STACK_LOCATION StackLoc;
340 IO_SECURITY_CONTEXT SecurityContext;
342 BOOLEAN DirectOpen = FALSE, OpenCancelled, UseDummyFile;
345 PDUMMY_FILE_OBJECT LocalFileObject;
348 KPROCESSOR_MODE CheckMode;
349 BOOLEAN VolumeOpen = FALSE;
351 BOOLEAN AccessGranted, LockHeld = FALSE;
353 UNICODE_STRING FileString;
354 USHORT Attempt;
355 IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n",
356 ParseObject, RemainingName);
357
358 for (Attempt = 0; Attempt < IOP_MAX_REPARSE_TRAVERSAL; ++Attempt)
359 {
360 /* Assume failure */
361 *Object = NULL;
362
363 /* Validate the open packet */
364 if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
365
366 /* Valide reparse point in case we traversed a mountpoint */
367 if (OpenPacket->TraversedMountPoint)
368 {
369 /* This is a reparse point we understand */
371
372 /* Make sure we're dealing with correct DO */
373 if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK &&
374 OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM &&
375 OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
376 OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE)
377 {
380 }
381 }
382
383 /* Check if we have a related file object */
384 if (OpenPacket->RelatedFileObject)
385 {
386 /* Use the related file object's device object */
387 OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
388 }
389
390 /* Validate device status */
391 Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject);
392 if (!NT_SUCCESS(Status))
393 {
394 /* We failed, return status */
395 OpenPacket->FinalStatus = Status;
396 return Status;
397 }
398
399 /* Map the generic mask and set the new mapping in the access state */
400 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
402 RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
406 DesiredAccess = AccessState->RemainingDesiredAccess;
407
408 /* Check what kind of access checks to do */
409 if ((AccessMode != KernelMode) ||
410 (OpenPacket->Options & IO_FORCE_ACCESS_CHECK))
411 {
412 /* Call is from user-mode or kernel is forcing checks */
413 CheckMode = UserMode;
414 }
415 else
416 {
417 /* Call is from the kernel */
418 CheckMode = KernelMode;
419 }
420
421 /* Check privilege for backup or restore operation */
423 &OpenPacket->CreateOptions,
424 CheckMode,
425 OpenPacket->Disposition);
426
427 /* Check if we are re-parsing */
428 if (((OpenPacket->Override) && !(RemainingName->Length)) ||
430 {
431 /* Get granted access from the last call */
432 DesiredAccess |= AccessState->PreviouslyGrantedAccess;
433 }
434
435 /* Check if this is a volume open */
436 if ((OpenPacket->RelatedFileObject) &&
437 (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
438 !(RemainingName->Length))
439 {
440 /* It is */
441 VolumeOpen = TRUE;
442 }
443
444 /* Now check if we need access checks */
445 if (((AccessMode != KernelMode) ||
446 (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) &&
447 (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) &&
448 !(OpenPacket->Override))
449 {
452
453 /* Check if a device object is being parsed */
454 if (!RemainingName->Length)
455 {
456 /* Lock the subject context */
457 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
458 LockHeld = TRUE;
459
460 /* Do access check */
461 AccessGranted = SeAccessCheck(OriginalDeviceObject->
463 &AccessState->SubjectSecurityContext,
464 LockHeld,
466 0,
467 &Privileges,
469 TypeInfo.GenericMapping,
470 UserMode,
472 &Status);
473 if (Privileges)
474 {
475 /* Append and free the privileges */
478 }
479
480 /* Check if we got access */
481 if (AccessGranted)
482 {
483 /* Update access state */
484 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
485 AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
487 OpenPacket->Override= TRUE;
488 }
489
490 FileString.Length = 8;
491 FileString.MaximumLength = 8;
492 FileString.Buffer = L"File";
493
494 /* Do Audit/Alarm for open operation */
495 SeOpenObjectAuditAlarm(&FileString,
496 OriginalDeviceObject,
497 CompleteName,
498 OriginalDeviceObject->SecurityDescriptor,
500 FALSE,
502 UserMode,
503 &AccessState->GenerateOnClose);
504 }
505 else
506 {
507 /* Check if we need to do traverse validation */
509 ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
510 (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM)))
511 {
512 /* Check if this is a restricted token */
513 if (!(AccessState->Flags & TOKEN_IS_RESTRICTED))
514 {
515 /* Do the FAST traverse check */
516 AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor,
519 UserMode);
520 }
521 else
522 {
523 /* Fail */
525 }
526
527 /* Check if we failed to get access */
528 if (!AccessGranted)
529 {
530 /* Lock the subject context */
531 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
532 LockHeld = TRUE;
533
534 /* Do access check */
535 AccessGranted = SeAccessCheck(OriginalDeviceObject->
537 &AccessState->SubjectSecurityContext,
538 LockHeld,
540 0,
541 &Privileges,
543 TypeInfo.GenericMapping,
544 UserMode,
546 &Status);
547 if (Privileges)
548 {
549 /* Append and free the privileges */
552 }
553 }
554
555 /* FIXME: Do Audit/Alarm for traverse check */
556 }
557 else
558 {
559 /* Access automatically granted */
561 }
562 }
563
566
567 /* Check if we hold the lock */
568 if (LockHeld)
569 {
570 /* Release it */
571 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
572 }
573
574 /* Check if access failed */
575 if (!AccessGranted)
576 {
577 /* Dereference the device and fail */
578 DPRINT1("Traverse access failed!\n");
579 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
581 }
582 }
583
584 /* Check if we can simply use a dummy file */
585 UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
586
587 /* Check if this is a direct open */
588 if (!(RemainingName->Length) &&
589 !(OpenPacket->RelatedFileObject) &&
595 WRITE_DAC)) == 0) &&
596 !(UseDummyFile))
597 {
598 /* Remember this for later */
599 DirectOpen = TRUE;
600 }
601
602 /* Check if we have a related FO that wasn't a direct open */
603 if ((OpenPacket->RelatedFileObject) &&
604 !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
605 {
606 /* The device object is the one we were given */
607 DeviceObject = ParseObject;
608
609 /* Check if the related FO had a VPB */
610 if (OpenPacket->RelatedFileObject->Vpb)
611 {
612 /* Yes, remember it */
613 Vpb = OpenPacket->RelatedFileObject->Vpb;
614
615 /* Reference it */
616 InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
617
618 /* Check if we were given a specific top level device to use */
620 {
621 DeviceObject = Vpb->DeviceObject;
622 }
623 }
624 }
625 else
626 {
627 /* Check if it has a VPB */
628 if ((OriginalDeviceObject->Vpb) && !(DirectOpen))
629 {
630 /* Check if the VPB is mounted, and mount it */
631 Vpb = IopCheckVpbMounted(OpenPacket,
632 OriginalDeviceObject,
634 &Status);
635 if (!Vpb) return Status;
636
637 /* Get the VPB's device object */
638 DeviceObject = Vpb->DeviceObject;
639 }
640 else
641 {
642 /* The device object is the one we were given */
643 DeviceObject = OriginalDeviceObject;
644 }
645
646 /* If we weren't given a specific top level device, look for an attached device */
647 if (!(OpenPacket->InternalFlags & IOP_USE_TOP_LEVEL_DEVICE_HINT) &&
648 DeviceObject->AttachedDevice)
649 {
650 /* Get the attached device */
652 }
653 }
654
655 /* If we have a top level device hint, verify it */
657 {
658 Status = IopCheckTopDeviceHint(&DeviceObject, OpenPacket, DirectOpen);
659 if (!NT_SUCCESS(Status))
660 {
661 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
663 return Status;
664 }
665 }
666
667 /* If we traversed a mount point, reset the information */
668 if (OpenPacket->TraversedMountPoint)
669 {
670 OpenPacket->TraversedMountPoint = FALSE;
671 }
672
673 /* Check if this is a secure FSD */
674 if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
675 ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) &&
676 (!VolumeOpen))
677 {
679 GrantedAccess = 0;
680
683
684 /* Lock the subject context */
685 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
686
687 /* Do access check */
688 AccessGranted = SeAccessCheck(OriginalDeviceObject->SecurityDescriptor,
689 &AccessState->SubjectSecurityContext,
690 TRUE,
692 0,
693 &Privileges,
695 UserMode,
697 &Status);
698 if (Privileges != NULL)
699 {
700 /* Append and free the privileges */
703 }
704
705 /* Check if we got access */
706 if (GrantedAccess)
707 {
708 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
709 AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED);
710 }
711
712 FileString.Length = 8;
713 FileString.MaximumLength = 8;
714 FileString.Buffer = L"File";
715
716 /* Do Audit/Alarm for open operation
717 * NOTA: we audit target device object
718 */
719 SeOpenObjectAuditAlarm(&FileString,
721 CompleteName,
722 OriginalDeviceObject->SecurityDescriptor,
724 FALSE,
726 UserMode,
727 &AccessState->GenerateOnClose);
728
729 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
730
733
734 /* Check if access failed */
735 if (!AccessGranted)
736 {
737 /* Dereference the device and fail */
738 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
741 }
742 }
743
744 /* Allocate the IRP */
745 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
746 if (!Irp)
747 {
748 /* Dereference the device and VPB, then fail */
749 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
752 }
753
754 /* Now set the IRP data */
755 Irp->RequestorMode = AccessMode;
757 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
758 Irp->UserIosb = &IoStatusBlock;
759 Irp->MdlAddress = NULL;
760 Irp->PendingReturned = FALSE;
761 Irp->UserEvent = NULL;
762 Irp->Cancel = FALSE;
763 Irp->CancelRoutine = NULL;
764 Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
765
766 /* Setup the security context */
767 SecurityContext.SecurityQos = SecurityQos;
768 SecurityContext.AccessState = AccessState;
769 SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
770 SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
771
772 /* Get the I/O Stack location */
773 StackLoc = IoGetNextIrpStackLocation(Irp);
774 StackLoc->Control = 0;
775
776 /* Check what kind of file this is */
777 switch (OpenPacket->CreateFileType)
778 {
779 /* Normal file */
781
782 /* Set the major function and EA Length */
783 StackLoc->MajorFunction = IRP_MJ_CREATE;
784 StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
785
786 /* Set the flags */
787 StackLoc->Flags = (UCHAR)OpenPacket->Options;
789 break;
790
791 /* Named pipe */
793
794 /* Set the named pipe MJ and set the parameters */
796 StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters;
797 break;
798
799 /* Mailslot */
801
802 /* Set the mailslot MJ and set the parameters */
804 StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters;
805 break;
806 }
807
808 /* Set the common data */
809 Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
810 Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer;
811 StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
812 (OpenPacket->CreateOptions &
813 0xFFFFFF);
814 StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
815 StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
816 StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
817
818 /* Check if we really need to create an object */
819 if (!UseDummyFile)
820 {
821 ULONG ObjectSize = sizeof(FILE_OBJECT);
822
823 /* Tag on space for a file object extension */
825 ObjectSize += sizeof(FILE_OBJECT_EXTENSION);
826
827 /* Create the actual file object */
829 NULL,
831 NULL,
832 NULL);
837 NULL,
838 ObjectSize,
839 0,
840 0,
841 (PVOID*)&FileObject);
842 if (!NT_SUCCESS(Status))
843 {
844 /* Create failed, free the IRP */
845 IoFreeIrp(Irp);
846
847 /* Dereference the device and VPB */
848 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
850
851 /* We failed, return status */
852 OpenPacket->FinalStatus = Status;
853 return Status;
854 }
855
856 /* Clear the file object */
857 RtlZeroMemory(FileObject, ObjectSize);
858
859 /* Check if this is Synch I/O */
860 if (OpenPacket->CreateOptions &
862 {
863 /* Set the synch flag */
865
866 /* Check if it's also alertable */
868 {
869 /* It is, set the alertable flag */
870 FileObject->Flags |= FO_ALERTABLE_IO;
871 }
872 }
873
874 /* Check if this is synch I/O */
875 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
876 {
877 /* Initialize the event */
879 }
880
881 /* Check if the caller requested no intermediate buffering */
883 {
884 /* Set the correct flag for the FSD to read */
886 }
887
888 /* Check if the caller requested write through support */
889 if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH)
890 {
891 /* Set the correct flag for the FSD to read */
893 }
894
895 /* Check if the caller says the file will be only read sequentially */
896 if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
897 {
898 /* Set the correct flag for the FSD to read */
900 }
901
902 /* Check if the caller believes the file will be only read randomly */
903 if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
904 {
905 /* Set the correct flag for the FSD to read */
907 }
908
909 /* Check if we were asked to setup a file object extension */
911 {
912 PFILE_OBJECT_EXTENSION FileObjectExtension;
913
914 /* Make sure the file object knows it has an extension */
916
917 /* Initialize file object extension */
918 FileObjectExtension = (PFILE_OBJECT_EXTENSION)(FileObject + 1);
919 FileObject->FileObjectExtension = FileObjectExtension;
920
921 /* Add the top level device which we'll send the request to */
923 {
924 FileObjectExtension->TopDeviceObjectHint = DeviceObject;
925 }
926 }
927 }
928 else
929 {
930 /* Use the dummy object instead */
931 LocalFileObject = OpenPacket->LocalFileObject;
932 RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT));
933
934 /* Set it up */
935 FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body;
936 LocalFileObject->ObjectHeader.Type = IoFileObjectType;
937 LocalFileObject->ObjectHeader.PointerCount = 1;
938 }
939
940 /* Setup the file header */
941 FileObject->Type = IO_TYPE_FILE;
942 FileObject->Size = sizeof(FILE_OBJECT);
943 FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
944 FileObject->DeviceObject = OriginalDeviceObject;
945
946 /* Check if this is a direct device open */
947 if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
948
949 /* Check if the caller wants case sensitivity */
951 {
952 /* Tell the driver about it */
954 }
955
956 /* Now set the file object */
957 Irp->Tail.Overlay.OriginalFileObject = FileObject;
958 StackLoc->FileObject = FileObject;
959
960 /* Check if the file object has a name */
961 if (RemainingName->Length)
962 {
963 /* Setup the unicode string */
964 FileObject->FileName.MaximumLength = RemainingName->Length + sizeof(WCHAR);
965 FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool,
966 FileObject->FileName.MaximumLength,
968 if (!FileObject->FileName.Buffer)
969 {
970 /* Failed to allocate the name, free the IRP */
971 IoFreeIrp(Irp);
972
973 /* Dereference the device object and VPB */
974 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
976
977 /* Clear the FO and dereference it */
978 FileObject->DeviceObject = NULL;
979 if (!UseDummyFile) ObDereferenceObject(FileObject);
980
981 /* Fail */
983 }
984 }
985
986 /* Copy the name */
988
989 /* Initialize the File Object event and set the FO */
991 OpenPacket->FileObject = FileObject;
992
993 /* Queue the IRP and call the driver */
996 if (Status == STATUS_PENDING)
997 {
998 /* Wait for the driver to complete the create */
1000 Executive,
1001 KernelMode,
1002 FALSE,
1003 NULL);
1004
1005 /* Get the new status */
1007 }
1008 else
1009 {
1010 /* We'll have to complete it ourselves */
1011 ASSERT(!Irp->PendingReturned);
1012 ASSERT(!Irp->MdlAddress);
1013
1014 /* Handle name change if required */
1015 if (Status == STATUS_REPARSE)
1016 {
1017 /* Check this is a mount point */
1018 if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1019 {
1020 PREPARSE_DATA_BUFFER ReparseData;
1021
1022 /* Reparse point attributes were passed by the driver in the auxiliary buffer */
1023 ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1024 ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1025
1029
1030 IopDoNameTransmogrify(Irp, FileObject, ReparseData);
1031 }
1032 }
1033
1034 /* Completion happens at APC_LEVEL */
1036
1037 /* Get the new I/O Status block ourselves */
1038 IoStatusBlock = Irp->IoStatus;
1040
1041 /* Manually signal the even, we can't have any waiters */
1042 FileObject->Event.Header.SignalState = 1;
1043
1044 /* Now that we've signaled the events, de-associate the IRP */
1046
1047 /* Check if the IRP had an input buffer */
1048 if ((Irp->Flags & IRP_BUFFERED_IO) &&
1049 (Irp->Flags & IRP_DEALLOCATE_BUFFER))
1050 {
1051 /* Free it. A driver might've tacked one on */
1052 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1053 }
1054
1055 /* Free the IRP and bring the IRQL back down */
1056 IoFreeIrp(Irp);
1058 }
1059
1060 /* Copy the I/O Status */
1062
1063 /* The driver failed to create the file */
1064 if (!NT_SUCCESS(Status))
1065 {
1066 /* Check if we have a name and if so, free it */
1067 if (FileObject->FileName.Length)
1068 {
1069 /*
1070 * Don't use TAG_IO_NAME since the FileObject's FileName
1071 * may have been re-allocated using a different tag
1072 * by a filesystem.
1073 */
1074 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1075 FileObject->FileName.Buffer = NULL;
1076 FileObject->FileName.Length = 0;
1077 }
1078
1079 /* Clear its device object */
1080 FileObject->DeviceObject = NULL;
1081
1082 /* Save this now because the FO might go away */
1083 OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ?
1084 TRUE : FALSE;
1085
1086 /* Clear the file object in the open packet */
1087 OpenPacket->FileObject = NULL;
1088
1089 /* Dereference the file object */
1090 if (!UseDummyFile) ObDereferenceObject(FileObject);
1091
1092 /* Dereference the device object */
1093 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1094
1095 /* Unless the driver cancelled the open, dereference the VPB */
1096 if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb);
1097
1098 /* Set the status and return */
1099 OpenPacket->FinalStatus = Status;
1100 return Status;
1101 }
1102 else if (Status == STATUS_REPARSE)
1103 {
1104 if (OpenPacket->Information == IO_REPARSE ||
1106 {
1107 /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */
1108 if (CompleteName->MaximumLength < FileObject->FileName.Length)
1109 {
1110 PWSTR NewCompleteName;
1111
1112 /* Allocate a new buffer for the string */
1113 NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME);
1114 if (NewCompleteName == NULL)
1115 {
1118 }
1119
1120 /* Release the old one */
1121 if (CompleteName->Buffer != NULL)
1122 {
1123 /*
1124 * Don't use TAG_IO_NAME since the FileObject's FileName
1125 * may have been re-allocated using a different tag
1126 * by a filesystem.
1127 */
1128 ExFreePoolWithTag(CompleteName->Buffer, 0);
1129 }
1130
1131 /* And setup the new one */
1132 CompleteName->Buffer = NewCompleteName;
1133 CompleteName->MaximumLength = FileObject->FileName.Length;
1134 }
1135
1136 /* Copy our new complete name */
1137 RtlCopyUnicodeString(CompleteName, &FileObject->FileName);
1138
1139 if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1140 {
1141 OpenPacket->RelatedFileObject = NULL;
1142 }
1143 }
1144
1145 /* Check if we have a name and if so, free it */
1146 if (FileObject->FileName.Length)
1147 {
1148 /*
1149 * Don't use TAG_IO_NAME since the FileObject's FileName
1150 * may have been re-allocated using a different tag
1151 * by a filesystem.
1152 */
1153 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1154 FileObject->FileName.Buffer = NULL;
1155 FileObject->FileName.Length = 0;
1156 }
1157
1158 /* Clear its device object */
1159 FileObject->DeviceObject = NULL;
1160
1161 /* Clear the file object in the open packet */
1162 OpenPacket->FileObject = NULL;
1163
1164 /* Dereference the file object */
1165 if (!UseDummyFile) ObDereferenceObject(FileObject);
1166
1167 /* Dereference the device object */
1168 IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
1169
1170 /* Unless the driver cancelled the open, dereference the VPB */
1172
1173 if (OpenPacket->Information != IO_REMOUNT)
1174 {
1175 OpenPacket->RelatedFileObject = NULL;
1176
1177 /* Inform we traversed a mount point for later attempt */
1178 if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT)
1179 {
1180 OpenPacket->TraversedMountPoint = 1;
1181 }
1182
1183 /* In case we override checks, but got this on volume open, fail hard */
1184 if (OpenPacket->Override)
1185 {
1186 KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN,
1187 (ULONG_PTR)OriginalDeviceObject,
1189 (ULONG_PTR)CompleteName,
1190 OpenPacket->Information);
1191 }
1192
1193 /* Return to IO/OB so that information can be upgraded */
1194 return STATUS_REPARSE;
1195 }
1196
1197 /* Loop again and reattempt an opening */
1198 continue;
1199 }
1200
1201 break;
1202 }
1203
1204 if (Attempt == IOP_MAX_REPARSE_TRAVERSAL)
1205 return STATUS_UNSUCCESSFUL;
1206
1207 /* Get the owner of the File Object */
1208 OwnerDevice = IoGetRelatedDeviceObject(FileObject);
1209
1210 /*
1211 * It's possible that the device to whom we sent the IRP to
1212 * isn't actually the device that ended opening the file object
1213 * internally.
1214 */
1215 if (OwnerDevice != DeviceObject)
1216 {
1217 /* We have to de-reference the VPB we had associated */
1219
1220 /* And re-associate with the actual one */
1221 Vpb = FileObject->Vpb;
1222 if (Vpb) InterlockedIncrement((PLONG)&Vpb->ReferenceCount);
1223 }
1224
1225 /* Make sure we are not using a dummy */
1226 if (!UseDummyFile)
1227 {
1228 /* Check if this was a volume open */
1229 if ((!(FileObject->RelatedFileObject) ||
1230 (FileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN)) &&
1231 !(FileObject->FileName.Length))
1232 {
1233 /* All signs point to it, but make sure it was actually an FSD */
1234 if ((OwnerDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) ||
1235 (OwnerDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) ||
1236 (OwnerDevice->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) ||
1237 (OwnerDevice->DeviceType == FILE_DEVICE_FILE_SYSTEM))
1238 {
1239 /* The owner device is an FSD, so this is a volume open for real */
1240 FileObject->Flags |= FO_VOLUME_OPEN;
1241 }
1242 }
1243
1244 /* Reference the object and set the parse check */
1246 *Object = FileObject;
1247 OpenPacket->FinalStatus = IoStatusBlock.Status;
1248 OpenPacket->ParseCheck = TRUE;
1249 return OpenPacket->FinalStatus;
1250 }
1251 else
1252 {
1253 /* Check if this was a query */
1254 if (OpenPacket->QueryOnly)
1255 {
1256 /* Check if the caller wants basic info only */
1257 if (!OpenPacket->FullAttributes)
1258 {
1259 /* Allocate the buffer */
1261 sizeof(*FileBasicInfo),
1262 TAG_IO);
1263 if (FileBasicInfo)
1264 {
1265 /* Do the query */
1268 sizeof(*FileBasicInfo),
1270 &ReturnLength);
1271 if (NT_SUCCESS(Status))
1272 {
1273 /* Copy the data */
1274 RtlCopyMemory(OpenPacket->BasicInformation,
1276 ReturnLength);
1277 }
1278
1279 /* Free our buffer */
1281 }
1282 else
1283 {
1284 /* Fail */
1286 }
1287 }
1288 else
1289 {
1290 /* This is a full query */
1292 FileObject,
1295 OpenPacket->NetworkInformation,
1296 &ReturnLength);
1298 }
1299 }
1300
1301 /* Delete the file object */
1303
1304 /* Clear out the file */
1305 OpenPacket->FileObject = NULL;
1306
1307 /* Set and return status */
1308 OpenPacket->FinalStatus = Status;
1309 OpenPacket->ParseCheck = TRUE;
1310 return Status;
1311 }
1312}
1313
1315NTAPI
1321 IN OUT PUNICODE_STRING CompleteName,
1325 OUT PVOID *Object)
1326{
1328 POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
1329
1330 /* Validate the open packet */
1331 if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
1332
1333 /* Get the device object */
1335 OpenPacket->RelatedFileObject = ParseObject;
1336
1337 /* Call the main routine */
1339 ObjectType,
1341 AccessMode,
1342 Attributes,
1343 CompleteName,
1345 OpenPacket,
1346 SecurityQos,
1347 Object);
1348}
1349
1350VOID
1351NTAPI
1353{
1354 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1355 PIRP Irp;
1356 PIO_STACK_LOCATION StackPtr;
1358 KEVENT Event;
1360 BOOLEAN DereferenceDone = FALSE;
1361 PVPB Vpb;
1362 KIRQL OldIrql;
1363 IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1364
1365 /* Check if the file has a device object */
1366 if (FileObject->DeviceObject)
1367 {
1368 /* Check if this is a direct open or not */
1369 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1370 {
1371 /* Get the attached device */
1373 }
1374 else
1375 {
1376 /* Use the file object's device object */
1378 }
1379
1380 /* Sanity check */
1381 ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
1383
1384 /* Check if the handle wasn't created yet */
1385 if (!(FileObject->Flags & FO_HANDLE_CREATED))
1386 {
1387 /* Send the cleanup IRP */
1388 IopCloseFile(NULL, ObjectBody, 0, 1, 1);
1389 }
1390
1391 /* Clear and set up Events */
1392 KeClearEvent(&FileObject->Event);
1394
1395 /* Allocate an IRP */
1397
1398 /* Set it up */
1399 Irp->UserEvent = &Event;
1400 Irp->UserIosb = &Irp->IoStatus;
1401 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1402 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1404
1405 /* Set up Stack Pointer Data */
1406 StackPtr = IoGetNextIrpStackLocation(Irp);
1407 StackPtr->MajorFunction = IRP_MJ_CLOSE;
1408 StackPtr->FileObject = FileObject;
1409
1410 /* Queue the IRP */
1412
1413 /* Get the VPB and check if this isn't a direct open */
1414 Vpb = FileObject->Vpb;
1415 if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
1416 {
1417 /* Dereference the VPB before the close */
1418 InterlockedDecrement((PLONG)&Vpb->ReferenceCount);
1419 }
1420
1421 /* Check if the FS will never disappear by itself */
1422 if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
1423 {
1424 /* Dereference it */
1425 InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
1426 DereferenceDone = TRUE;
1427 }
1428
1429 /* Call the FS Driver */
1431 if (Status == STATUS_PENDING)
1432 {
1433 /* Wait for completion */
1435 }
1436
1437 /* De-queue the IRP */
1441
1442 /* Free the IRP */
1443 IoFreeIrp(Irp);
1444
1445 /* Clear the file name */
1446 if (FileObject->FileName.Buffer)
1447 {
1448 /*
1449 * Don't use TAG_IO_NAME since the FileObject's FileName
1450 * may have been re-allocated using a different tag
1451 * by a filesystem.
1452 */
1453 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
1454 FileObject->FileName.Buffer = NULL;
1455 }
1456
1457 /* Check if the FO had a completion port */
1458 if (FileObject->CompletionContext)
1459 {
1460 /* Free it */
1461 ObDereferenceObject(FileObject->CompletionContext->Port);
1462 ExFreePool(FileObject->CompletionContext);
1463 }
1464
1465 /* Check if the FO had extension */
1467 {
1468 /* Release filter context structure if any */
1470 }
1471
1472 /* Check if dereference has been done yet */
1473 if (!DereferenceDone)
1474 {
1475 /* Dereference device object */
1477 }
1478 }
1479}
1480
1482NTAPI
1484{
1486
1487 /* Go down the stack to attempt to get the PDO */
1488 while (IoGetDevObjExtension(PDO)->AttachedTo != NULL)
1489 PDO = IoGetDevObjExtension(PDO)->AttachedTo;
1490
1491 return PDO;
1492}
1493
1495NTAPI
1497{
1498 KIRQL OldIrql;
1499 PDEVICE_OBJECT PDO;
1500
1502
1504 /* Get the base DO */
1506 /* Check whether that's really a PDO and if so, keep it */
1508 {
1509 PDO = NULL;
1510 }
1511 else
1512 {
1513 ObReferenceObject(PDO);
1514 }
1516
1517 return PDO;
1518}
1519
1521NTAPI
1527{
1529 PSECURITY_DESCRIPTOR OldSecurityDescriptor, CachedSecurityDescriptor, NewSecurityDescriptor;
1530
1531 PAGED_CODE();
1532
1533 /* Keep attempting till we find our old SD or fail */
1534 while (TRUE)
1535 {
1538
1539 /* Get our old SD and reference it */
1540 OldSecurityDescriptor = DeviceObject->SecurityDescriptor;
1541 if (OldSecurityDescriptor != NULL)
1542 {
1543 ObReferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1544 }
1545
1548
1549 /* Set the SD information */
1550 NewSecurityDescriptor = OldSecurityDescriptor;
1552 SecurityDescriptor, &NewSecurityDescriptor,
1554
1555 if (!NT_SUCCESS(Status))
1556 {
1557 if (OldSecurityDescriptor != NULL)
1558 {
1559 ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1560 }
1561
1562 break;
1563 }
1564
1565 /* Add the new DS to the internal cache */
1566 Status = ObLogSecurityDescriptor(NewSecurityDescriptor,
1567 &CachedSecurityDescriptor, 1);
1568 ExFreePool(NewSecurityDescriptor);
1569 if (!NT_SUCCESS(Status))
1570 {
1571 ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1572 break;
1573 }
1574
1577 /* Check if someone changed it in our back */
1578 if (DeviceObject->SecurityDescriptor == OldSecurityDescriptor)
1579 {
1580 /* We're clear, do the swap */
1581 DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1584
1585 /* And dereference old SD (twice - us + not in use) */
1586 ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 2);
1587
1588 break;
1589 }
1592
1593 /* If so, try again */
1594 ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
1595 ObDereferenceSecurityDescriptor(CachedSecurityDescriptor, 1);
1596 }
1597
1598 return Status;
1599}
1600
1602NTAPI
1609{
1610 PDEVICE_OBJECT CurrentDO = PhysicalDeviceObject, NextDevice;
1611 NTSTATUS Status = STATUS_SUCCESS, TmpStatus;
1612
1613 PAGED_CODE();
1614
1616
1617 /* We always reference the DO we're working on */
1618 ObReferenceObject(CurrentDO);
1619
1620 /* Go up from PDO to latest DO */
1621 do
1622 {
1623 /* Attempt to set the new SD on it */
1627 /* Was our last one? Remember that status then */
1628 if (CurrentDO == UpperDeviceObject)
1629 {
1630 Status = TmpStatus;
1631 }
1632
1633 /* Try to move to the next DO (and thus, reference it) */
1634 NextDevice = CurrentDO->AttachedDevice;
1635 if (NextDevice)
1636 {
1637 ObReferenceObject(NextDevice);
1638 }
1639
1640 /* Dereference current DO and move to the next one */
1641 ObDereferenceObject(CurrentDO);
1642 CurrentDO = NextDevice;
1643 }
1644 while (CurrentDO != NULL);
1645
1646 return Status;
1647}
1648
1650NTAPI
1652 IN SECURITY_OPERATION_CODE OperationCode,
1656 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1659{
1661 PIO_STACK_LOCATION StackPtr;
1664 PIRP Irp;
1665 BOOLEAN LocalEvent = FALSE;
1666 KEVENT Event;
1668 PAGED_CODE();
1669 IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1670
1671 /* Check if this is a device or file */
1672 if (((PFILE_OBJECT)ObjectBody)->Type == IO_TYPE_DEVICE)
1673 {
1674 /* It's a device */
1675 DeviceObject = (PDEVICE_OBJECT)ObjectBody;
1676 FileObject = NULL;
1677 }
1678 else
1679 {
1680 /* It's a file */
1681 FileObject = (PFILE_OBJECT)ObjectBody;
1682
1683 /* Check if this is a direct open */
1684 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
1685 {
1686 /* Get the Device Object */
1688 }
1689 else
1690 {
1691 /* Otherwise, use the direct device*/
1692 DeviceObject = FileObject->DeviceObject;
1693 }
1694 }
1695
1696 /* Check if the request was for a device object */
1697 if (!(FileObject) ||
1698 (!(FileObject->FileName.Length) && !(FileObject->RelatedFileObject)) ||
1700 {
1701 /* Check what kind of request this was */
1702 if (OperationCode == QuerySecurityDescriptor)
1703 {
1707 &DeviceObject->SecurityDescriptor);
1708 }
1709 else if (OperationCode == DeleteSecurityDescriptor)
1710 {
1711 /* Simply return success */
1712 return STATUS_SUCCESS;
1713 }
1714 else if (OperationCode == AssignSecurityDescriptor)
1715 {
1717
1718 /* Make absolutely sure this is a device object */
1719 if (!(FileObject) || !(FileObject->Flags & FO_STREAM_FILE))
1720 {
1721 PSECURITY_DESCRIPTOR CachedSecurityDescriptor;
1722
1723 /* Add the security descriptor in cache */
1724 Status = ObLogSecurityDescriptor(SecurityDescriptor, &CachedSecurityDescriptor, 1);
1725 if (NT_SUCCESS(Status))
1726 {
1729
1730 /* Assign the Security Descriptor */
1731 DeviceObject->SecurityDescriptor = CachedSecurityDescriptor;
1732
1735 }
1736 }
1737
1738 /* Return status */
1739 return Status;
1740 }
1741 else if (OperationCode == SetSecurityDescriptor)
1742 {
1743 /* Get the Physical Device Object if any */
1745
1746 if (PDO != NULL)
1747 {
1748 /* Apply the new SD to any DO in the path from PDO to current DO */
1754 }
1755 else
1756 {
1757 /* Otherwise, just set for ourselves */
1762 }
1763
1764 return STATUS_SUCCESS;
1765 }
1766
1767 /* Shouldn't happen */
1768 return STATUS_SUCCESS;
1769 }
1770 else if (OperationCode == DeleteSecurityDescriptor)
1771 {
1772 /* Same as for devices, do nothing */
1773 return STATUS_SUCCESS;
1774 }
1775
1776 /* At this point, we know we're a file. Reference it */
1778
1779 /* Check if we should use Sync IO or not */
1780 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1781 {
1782 /* Lock the file object */
1784 if (Status != STATUS_SUCCESS)
1785 {
1787 return Status;
1788 }
1789 }
1790 else
1791 {
1792 /* Use local event */
1794 LocalEvent = TRUE;
1795 }
1796
1797 /* Clear the File Object event */
1798 KeClearEvent(&FileObject->Event);
1799
1800 /* Get the device object */
1802
1803 /* Allocate the IRP */
1804 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1805 if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);
1806
1807 /* Set the IRP */
1808 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1809 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1810 Irp->RequestorMode = ExGetPreviousMode();
1811 Irp->UserIosb = &IoStatusBlock;
1812 Irp->UserEvent = (LocalEvent) ? &Event : NULL;
1813 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
1814 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
1815
1816 /* Set Stack Parameters */
1817 StackPtr = IoGetNextIrpStackLocation(Irp);
1818 StackPtr->FileObject = FileObject;
1819
1820 /* Check if this is a query or set */
1821 if (OperationCode == QuerySecurityDescriptor)
1822 {
1823 /* Set the major function and parameters */
1825 StackPtr->Parameters.QuerySecurity.SecurityInformation =
1827 StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
1828 Irp->UserBuffer = SecurityDescriptor;
1829 }
1830 else
1831 {
1832 /* Set the major function and parameters for a set */
1834 StackPtr->Parameters.SetSecurity.SecurityInformation =
1836 StackPtr->Parameters.SetSecurity.SecurityDescriptor =
1838 }
1839
1840 /* Queue the IRP */
1842
1843 /* Update operation counts */
1845
1846 /* Call the Driver */
1848
1849 /* Check if this was async I/O */
1850 if (LocalEvent)
1851 {
1852 /* Check if the IRP is pending completion */
1853 if (Status == STATUS_PENDING)
1854 {
1855 /* Wait on the local event */
1857 Executive,
1858 KernelMode,
1859 FALSE,
1860 NULL);
1862 }
1863 }
1864 else
1865 {
1866 /* Check if the IRP is pending completion */
1867 if (Status == STATUS_PENDING)
1868 {
1869 /* Wait on the file object */
1871 Executive,
1872 KernelMode,
1873 FALSE,
1874 NULL);
1875 Status = FileObject->FinalStatus;
1876 }
1877
1878 /* Release the lock */
1880 }
1881
1882 /* This Driver doesn't implement Security, so try to give it a default */
1884 {
1885 /* Was this a query? */
1886 if (OperationCode == QuerySecurityDescriptor)
1887 {
1888 /* Set a World Security Descriptor */
1891 BufferLength);
1892 }
1893 else
1894 {
1895 /* It wasn't a query, so just fake success */
1897 }
1898 }
1899 else if (OperationCode == QuerySecurityDescriptor)
1900 {
1901 /* Callers usually expect the normalized form */
1903
1904 _SEH2_TRY
1905 {
1906 /* Return length */
1908 }
1910 {
1911 /* Get the exception code */
1913 }
1914 _SEH2_END;
1915 }
1916
1917 /* Return Status */
1918 return Status;
1919}
1920
1922NTAPI
1924 IN BOOLEAN HasName,
1925 OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1926 IN ULONG Length,
1929{
1930 return IopQueryNameInternal(ObjectBody,
1931 HasName,
1932 FALSE,
1933 ObjectNameInfo,
1934 Length,
1936 PreviousMode);
1937}
1938
1940NTAPI
1942 IN BOOLEAN HasName,
1943 IN BOOLEAN QueryDosName,
1944 OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1945 IN ULONG Length,
1948{
1949 POBJECT_NAME_INFORMATION LocalInfo;
1950 PFILE_NAME_INFORMATION LocalFileInfo;
1951 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
1952 ULONG LocalReturnLength, FileLength;
1953 BOOLEAN LengthMismatch = FALSE;
1955 PWCHAR p;
1957 BOOLEAN NoObCall;
1958
1959 IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
1960
1961 /* Validate length */
1962 if (Length < sizeof(OBJECT_NAME_INFORMATION))
1963 {
1964 /* Wrong length, fail */
1967 }
1968
1969 /* Allocate Buffer */
1971 if (!LocalInfo) return STATUS_INSUFFICIENT_RESOURCES;
1972
1973 /* Query DOS name if the caller asked to */
1974 NoObCall = FALSE;
1975 if (QueryDosName)
1976 {
1977 DeviceObject = FileObject->DeviceObject;
1978
1979 /* In case of a network file system, don't call mountmgr */
1981 {
1982 /* We'll store separator and terminator */
1983 LocalReturnLength = sizeof(OBJECT_NAME_INFORMATION) + 2 * sizeof(WCHAR);
1984 if (Length < LocalReturnLength)
1985 {
1987 }
1988 else
1989 {
1990 LocalInfo->Name.Length = sizeof(WCHAR);
1991 LocalInfo->Name.MaximumLength = sizeof(WCHAR);
1992 LocalInfo->Name.Buffer = (PVOID)((ULONG_PTR)LocalInfo + sizeof(OBJECT_NAME_INFORMATION));
1993 LocalInfo->Name.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
1995 }
1996 }
1997 /* Otherwise, call mountmgr to get DOS name */
1998 else
1999 {
2001 LocalReturnLength = LocalInfo->Name.Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
2002 }
2003 }
2004
2005 /* Fall back if querying DOS name failed or if caller never wanted it ;-) */
2006 if (!QueryDosName || !NT_SUCCESS(Status))
2007 {
2008 /* Query the name */
2009 Status = ObQueryNameString(FileObject->DeviceObject,
2010 LocalInfo,
2011 Length,
2012 &LocalReturnLength);
2013 }
2014 else
2015 {
2016 NoObCall = TRUE;
2017 }
2018
2020 {
2021 /* Free the buffer and fail */
2022 ExFreePoolWithTag(LocalInfo, TAG_IO);
2023 return Status;
2024 }
2025
2026 /* Get buffer pointer */
2027 p = (PWCHAR)(ObjectNameInfo + 1);
2028
2029 _SEH2_TRY
2030 {
2031 /* Copy the information */
2032 if (QueryDosName && NoObCall)
2033 {
2035
2036 /* Copy structure first */
2037 RtlCopyMemory(ObjectNameInfo,
2038 LocalInfo,
2039 (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length));
2040 /* Name then */
2041 RtlCopyMemory(p, LocalInfo->Name.Buffer,
2042 (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION)));
2043
2044 if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
2045 {
2046 ExFreePool(LocalInfo->Name.Buffer);
2047 }
2048 }
2049 else
2050 {
2051 RtlCopyMemory(ObjectNameInfo,
2052 LocalInfo,
2053 (LocalReturnLength > Length) ?
2054 Length : LocalReturnLength);
2055 }
2056
2057 /* Set buffer pointer */
2058 ObjectNameInfo->Name.Buffer = p;
2059
2060 /* Advance in buffer */
2061 p += (LocalInfo->Name.Length / sizeof(WCHAR));
2062
2063 /* Check if this already filled our buffer */
2064 if (LocalReturnLength > Length)
2065 {
2066 /* Set the length mismatch to true, so that we can return
2067 * the proper buffer size to the caller later
2068 */
2069 LengthMismatch = TRUE;
2070
2071 /* Save the initial buffer length value */
2072 *ReturnLength = LocalReturnLength;
2073 }
2074
2075 /* Now get the file name buffer and check the length needed */
2076 LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
2077 FileLength = Length -
2078 LocalReturnLength +
2080
2081 /* Query the File name */
2082 if (PreviousMode == KernelMode &&
2084 {
2086 LengthMismatch ? Length : FileLength,
2088 LocalFileInfo,
2089 &LocalReturnLength);
2090 }
2091 else
2092 {
2095 LengthMismatch ? Length : FileLength,
2096 LocalFileInfo,
2097 &LocalReturnLength);
2098 }
2099 if (NT_ERROR(Status))
2100 {
2101 /* Allow status that would mean it's not implemented in the storage stack */
2104 {
2106 }
2107
2108 /* In such case, zero the output and reset the status */
2109 LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2110 LocalFileInfo->FileNameLength = 0;
2111 LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
2113 }
2114 else
2115 {
2116 /* We'll at least return the name length */
2117 if (LocalReturnLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
2118 {
2119 LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
2120 }
2121 }
2122
2123 /* If the provided buffer is too small, return the required size */
2124 if (LengthMismatch)
2125 {
2126 /* Add the required length */
2127 *ReturnLength += LocalFileInfo->FileNameLength;
2128
2129 /* Free the allocated buffer and return failure */
2132 }
2133
2134 /* Now calculate the new lengths left */
2135 FileLength = LocalReturnLength -
2137 LocalReturnLength = (ULONG)((ULONG_PTR)p -
2138 (ULONG_PTR)ObjectNameInfo +
2139 LocalFileInfo->FileNameLength);
2140
2141 /* Don't copy the name if it's not valid */
2142 if (LocalFileInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR)
2143 {
2144 /* Free the allocated buffer and return failure */
2147 }
2148
2149 /* Write the Name and null-terminate it */
2150 RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
2151 p += (FileLength / sizeof(WCHAR));
2152 *p = UNICODE_NULL;
2153 LocalReturnLength += sizeof(UNICODE_NULL);
2154
2155 /* Return the length needed */
2156 *ReturnLength = LocalReturnLength;
2157
2158 /* Setup the length and maximum length */
2159 FileLength = (ULONG)((ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo);
2160 ObjectNameInfo->Name.Length = (USHORT)FileLength -
2162 ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
2163 sizeof(UNICODE_NULL);
2164 }
2166 {
2167 /* Free buffer and return */
2168 ExFreePoolWithTag(LocalInfo, TAG_IO);
2169 } _SEH2_END;
2170
2171 return Status;
2172}
2173
2174VOID
2175NTAPI
2177 IN PVOID ObjectBody,
2180 IN ULONG SystemHandleCount)
2181{
2182 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
2183 KEVENT Event;
2184 PIRP Irp;
2185 PIO_STACK_LOCATION StackPtr;
2188 KIRQL OldIrql;
2190 IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
2191
2192 /* If this isn't the last handle for the current process, quit */
2193 if (HandleCount != 1) return;
2194
2195 /* Check if the file is locked and has more then one handle opened */
2196 if ((FileObject->LockOperation) && (SystemHandleCount != 1))
2197 {
2198 /* Check if this is a direct open or not */
2200 {
2201 /* Get the attached device */
2203 }
2204 else
2205 {
2206 /* Get the FO's device */
2208 }
2209
2210 /* Check if this is a sync FO and lock it */
2212 {
2214 }
2215
2216 /* Go the FastIO path if possible, otherwise fall back to IRP */
2217 if (DeviceObject->DriverObject->FastIoDispatch == NULL ||
2218 DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll == NULL ||
2219 !DeviceObject->DriverObject->FastIoDispatch->FastIoUnlockAll(FileObject, PsGetCurrentProcess(), &IoStatusBlock, DeviceObject))
2220 {
2221 /* Clear and set up Events */
2222 KeClearEvent(&FileObject->Event);
2224
2225 /* Allocate an IRP */
2227
2228 /* Set it up */
2229 Irp->UserEvent = &Event;
2230 Irp->UserIosb = &Irp->IoStatus;
2231 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2232 Irp->Tail.Overlay.OriginalFileObject = FileObject;
2233 Irp->RequestorMode = KernelMode;
2234 Irp->Flags = IRP_SYNCHRONOUS_API;
2235 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2237
2238 /* Set up Stack Pointer Data */
2239 StackPtr = IoGetNextIrpStackLocation(Irp);
2241 StackPtr->MinorFunction = IRP_MN_UNLOCK_ALL;
2242 StackPtr->FileObject = FileObject;
2243
2244 /* Queue the IRP */
2246
2247 /* Call the FS Driver */
2249 if (Status == STATUS_PENDING)
2250 {
2251 /* Wait for completion */
2253 }
2254
2255 /* IO will unqueue & free for us */
2256 }
2257
2258 /* Release the lock if we were holding it */
2260 {
2262 }
2263 }
2264
2265 /* Make sure this is the last handle */
2266 if (SystemHandleCount != 1) return;
2267
2268 /* Check if this is a direct open or not */
2269 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
2270 {
2271 /* Get the attached device */
2273 }
2274 else
2275 {
2276 /* Get the FO's device */
2278 }
2279
2280 /* Set the handle created flag */
2281 FileObject->Flags |= FO_HANDLE_CREATED;
2282
2283 /* Check if this is a sync FO and lock it */
2284 if (Process != NULL &&
2286 {
2288 }
2289
2290 /* Clear and set up Events */
2291 KeClearEvent(&FileObject->Event);
2293
2294 /* Allocate an IRP */
2296
2297 /* Set it up */
2298 Irp->UserEvent = &Event;
2299 Irp->UserIosb = &Irp->IoStatus;
2300 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2301 Irp->Tail.Overlay.OriginalFileObject = FileObject;
2302 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2304
2305 /* Set up Stack Pointer Data */
2306 StackPtr = IoGetNextIrpStackLocation(Irp);
2307 StackPtr->MajorFunction = IRP_MJ_CLEANUP;
2308 StackPtr->FileObject = FileObject;
2309
2310 /* Queue the IRP */
2312
2313 /* Update operation counts */
2315
2316 /* Call the FS Driver */
2318 if (Status == STATUS_PENDING)
2319 {
2320 /* Wait for completion */
2322 }
2323
2324 /* Unqueue the IRP */
2328
2329 /* Free the IRP */
2330 IoFreeIrp(Irp);
2331
2332 /* Release the lock if we were holding it */
2333 if (Process != NULL &&
2335 {
2337 }
2338}
2339
2341NTAPI
2344 IN ULONG FileInformationSize,
2346{
2349 DUMMY_FILE_OBJECT LocalFileObject;
2350 FILE_NETWORK_OPEN_INFORMATION NetworkOpenInfo;
2351 HANDLE Handle;
2352 OPEN_PACKET OpenPacket;
2353 BOOLEAN IsBasic;
2354 PAGED_CODE();
2355 IOTRACE(IO_FILE_DEBUG, "Class: %lx\n", FileInformationClass);
2356
2357 /* Check if the caller was user mode */
2358 if (AccessMode != KernelMode)
2359 {
2360 /* Protect probe in SEH */
2361 _SEH2_TRY
2362 {
2363 /* Probe the buffer */
2364 ProbeForWrite(FileInformation, FileInformationSize, sizeof(ULONG));
2365 }
2367 {
2368 /* Return the exception code */
2370 }
2371 _SEH2_END;
2372 }
2373
2374 /* Check if this is a basic or full request */
2375 IsBasic = (FileInformationSize == sizeof(FILE_BASIC_INFORMATION));
2376
2377 /* Setup the Open Packet */
2378 RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
2379 OpenPacket.Type = IO_TYPE_OPEN_PACKET;
2380 OpenPacket.Size = sizeof(OPEN_PACKET);
2383 OpenPacket.Disposition = FILE_OPEN;
2384 OpenPacket.BasicInformation = IsBasic ? FileInformation : NULL;
2385 OpenPacket.NetworkInformation = IsBasic ? &NetworkOpenInfo :
2386 (AccessMode != KernelMode) ?
2387 &NetworkOpenInfo : FileInformation;
2388 OpenPacket.QueryOnly = TRUE;
2389 OpenPacket.FullAttributes = IsBasic ? FALSE : TRUE;
2390 OpenPacket.LocalFileObject = &LocalFileObject;
2391
2392 /* Update the operation count */
2394
2395 /*
2396 * Attempt opening the file. This will call the I/O Parse Routine for
2397 * the File Object (IopParseDevice) which will use the dummy file obejct
2398 * send the IRP to its device object. Note that we have two statuses
2399 * to worry about: the Object Manager's status (in Status) and the I/O
2400 * status, which is in the Open Packet's Final Status, and determined
2401 * by the Parse Check member.
2402 */
2404 NULL,
2405 AccessMode,
2406 NULL,
2408 &OpenPacket,
2409 &Handle);
2410 if (OpenPacket.ParseCheck == FALSE)
2411 {
2412 /* Parse failed */
2413 DPRINT("IopQueryAttributesFile failed for '%wZ' with 0x%lx\n",
2414 ObjectAttributes->ObjectName, Status);
2415 return Status;
2416 }
2417 else
2418 {
2419 /* Use the Io status */
2420 Status = OpenPacket.FinalStatus;
2421 }
2422
2423 /* Check if we were succesful and this was user mode and a full query */
2424 if ((NT_SUCCESS(Status)) && (AccessMode != KernelMode) && !(IsBasic))
2425 {
2426 /* Enter SEH for copy */
2427 _SEH2_TRY
2428 {
2429 /* Copy the buffer back */
2431 &NetworkOpenInfo,
2432 FileInformationSize);
2433 }
2435 {
2436 /* Get exception code */
2438 }
2439 _SEH2_END;
2440 }
2441
2442 /* Return status */
2443 return Status;
2444}
2445
2447NTAPI
2450 _In_ KPROCESSOR_MODE WaitMode,
2452 _Out_ PBOOLEAN LockFailed)
2453{
2455
2456 PAGED_CODE();
2457
2459
2461 do
2462 {
2464 {
2465 break;
2466 }
2468 Executive,
2469 WaitMode,
2470 Alertable,
2471 NULL);
2472 } while (Status == STATUS_SUCCESS);
2473
2475 if (Status == STATUS_SUCCESS)
2476 {
2478 *LockFailed = FALSE;
2479 }
2480 else
2481 {
2482 if (!FileObject->Busy && FileObject->Waiters)
2483 {
2485 }
2486 *LockFailed = TRUE;
2487 }
2488
2489 return Status;
2490}
2491
2492PVOID
2493NTAPI
2495{
2497 {
2498 PFILE_OBJECT_EXTENSION FileObjectExtension;
2499
2500 FileObjectExtension = FileObject->FileObjectExtension;
2501 return FileObjectExtension->FilterContext;
2502 }
2503
2504 return NULL;
2505}
2506
2508NTAPI
2511 IN BOOLEAN Define)
2512{
2514 PFILE_OBJECT_EXTENSION FileObjectExtension;
2515
2517 {
2519 }
2520
2521 FileObjectExtension = FileObject->FileObjectExtension;
2522 if (Define)
2523 {
2524 /* If define, just set the new value if not value is set
2525 * Success will only contain old value. It is valid if it is NULL
2526 */
2528 }
2529 else
2530 {
2531 /* If not define, we want to reset filter context.
2532 * We will remove value (provided by the caller) and set NULL instead.
2533 * This will only success if caller provides correct previous value.
2534 * To catch whether it worked, we substract previous value to expect value:
2535 * If it matches (and thus, we reset), Success will contain 0
2536 * Otherwise, it will contain a non-zero value.
2537 */
2539 }
2540
2541 /* If success isn't 0, it means we failed somewhere (set or unset) */
2542 if (Success != 0)
2543 {
2545 }
2546
2547 return STATUS_SUCCESS;
2548}
2549
2551NTAPI
2564 IN PVOID ExtraCreateParameters OPTIONAL,
2566 IN ULONG Flags,
2568{
2570 HANDLE LocalHandle = 0;
2571 LARGE_INTEGER SafeAllocationSize;
2573 PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters;
2574 POPEN_PACKET OpenPacket;
2575 ULONG EaErrorOffset;
2576 PAGED_CODE();
2577
2578 IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
2579
2580
2581 /* Check if we have no parameter checking to do */
2583 {
2584 /* Then force kernel-mode access to avoid checks */
2586 }
2587 else
2588 {
2589 /* Otherwise, use the actual mode */
2591 }
2592
2593 /* Check if we need to do parameter checking */
2595 {
2596 /* Validate parameters */
2598 {
2599 DPRINT1("File Create 'FileAttributes' Parameter contains invalid flags!\n");
2601 }
2602
2604 {
2605 DPRINT1("File Create 'ShareAccess' Parameter contains invalid flags!\n");
2607 }
2608
2610 {
2611 DPRINT1("File Create 'Disposition' Parameter is out of range!\n");
2613 }
2614
2616 {
2617 DPRINT1("File Create 'CreateOptions' parameter contains invalid flags!\n");
2619 }
2620
2623 {
2624 DPRINT1("File Create 'CreateOptions' parameter FILE_SYNCHRONOUS_IO_* requested, but 'DesiredAccess' does not have SYNCHRONIZE!\n");
2626 }
2627
2629 {
2630 DPRINT1("File Create 'CreateOptions' parameter FILE_DELETE_ON_CLOSE requested, but 'DesiredAccess' does not have DELETE!\n");
2632 }
2633
2636 {
2637 DPRINT1("File Create 'FileAttributes' parameter both FILE_SYNCHRONOUS_IO_NONALERT and FILE_SYNCHRONOUS_IO_ALERT specified!\n");
2639 }
2640
2653 {
2654 DPRINT1("File Create 'CreateOptions' Parameter has flags incompatible with FILE_DIRECTORY_FILE!\n");
2656 }
2657
2660 {
2661 DPRINT1("File Create 'CreateOptions' Parameter FILE_DIRECTORY_FILE requested, but 'Disposition' is not FILE_CREATE/FILE_OPEN/FILE_OPEN_IF!\n");
2663 }
2664
2666 {
2667 DPRINT1("File Create 'CreateOptions' Parameter both FILE_COMPLETE_IF_OPLOCKED and FILE_RESERVE_OPFILTER specified!\n");
2669 }
2670
2672 {
2673 DPRINT1("File Create 'CreateOptions' parameter FILE_NO_INTERMEDIATE_BUFFERING requested, but 'DesiredAccess' FILE_APPEND_DATA requires it!\n");
2675 }
2676
2677 /* Now check if this is a named pipe */
2679 {
2680 /* Make sure we have extra parameters */
2681 if (!ExtraCreateParameters)
2682 {
2683 DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2685 }
2686
2687 /* Get the parameters and validate them */
2688 NamedPipeCreateParameters = ExtraCreateParameters;
2689 if ((NamedPipeCreateParameters->NamedPipeType > FILE_PIPE_MESSAGE_TYPE) ||
2690 (NamedPipeCreateParameters->ReadMode > FILE_PIPE_MESSAGE_MODE) ||
2691 (NamedPipeCreateParameters->CompletionMode > FILE_PIPE_COMPLETE_OPERATION) ||
2695 {
2696 /* Invalid named pipe create */
2697 DPRINT1("Invalid named pipe create\n");
2699 }
2700 }
2702 {
2703 /* Make sure we have extra parameters */
2704 if (!ExtraCreateParameters)
2705 {
2706 DPRINT1("Invalid parameter: ExtraCreateParameters == 0!\n");
2708 }
2709
2710 /* Get the parameters and validate them */
2713 (Disposition != FILE_CREATE) ||
2715 {
2716 /* Invalid mailslot create */
2717 DPRINT1("Invalid mailslot create\n");
2719 }
2720 }
2721 }
2722
2723 /* Allocate the open packet */
2724 OpenPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*OpenPacket), 'pOoI');
2725 if (!OpenPacket) return STATUS_INSUFFICIENT_RESOURCES;
2726 RtlZeroMemory(OpenPacket, sizeof(*OpenPacket));
2727
2728 /* Check if the call came from user mode */
2729 if (AccessMode != KernelMode)
2730 {
2731 _SEH2_TRY
2732 {
2733 /* Probe the output parameters */
2736
2737 /* Probe the allocation size if one was passed in */
2738 if (AllocationSize)
2739 {
2740 SafeAllocationSize = ProbeForReadLargeInteger(AllocationSize);
2741 }
2742 else
2743 {
2744 SafeAllocationSize.QuadPart = 0;
2745 }
2746
2747 /* Make sure it's valid */
2748 if (SafeAllocationSize.QuadPart < 0)
2749 {
2751 }
2752
2753 /* Check if EA was passed in */
2754 if ((EaBuffer) && (EaLength))
2755 {
2756 /* Probe it */
2758
2759 /* And marshall it */
2761 EaLength,
2762 TAG_EA);
2763 OpenPacket->EaLength = EaLength;
2764 RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2765
2766 /* Validate the buffer */
2768 EaLength,
2769 &EaErrorOffset);
2770 if (!NT_SUCCESS(Status))
2771 {
2772 /* Undo everything if it's invalid */
2773 DPRINT1("Invalid EA buffer\n");
2775 IoStatusBlock->Information = EaErrorOffset;
2777 }
2778 }
2779 }
2781 {
2782 /* Return the exception code */
2783 if (OpenPacket->EaBuffer != NULL) ExFreePool(OpenPacket->EaBuffer);
2784 ExFreePool(OpenPacket);
2786 }
2787 _SEH2_END;
2788 }
2789 else
2790 {
2791 /* Check if this is a device attach */
2793 {
2794 /* Set the flag properly */
2796 CreateOptions &= ~IO_ATTACH_DEVICE_API;
2797 }
2798
2799 /* Check if we have allocation size */
2800 if (AllocationSize)
2801 {
2802 /* Capture it */
2803 SafeAllocationSize = *AllocationSize;
2804 }
2805 else
2806 {
2807 /* Otherwise, no size */
2808 SafeAllocationSize.QuadPart = 0;
2809 }
2810
2811 /* Check if we have an EA packet */
2812 if ((EaBuffer) && (EaLength))
2813 {
2814 /* Allocate the kernel copy */
2816 EaLength,
2817 TAG_EA);
2818 if (!OpenPacket->EaBuffer)
2819 {
2820 ExFreePool(OpenPacket);
2821 DPRINT1("Failed to allocate open packet EA buffer\n");
2823 }
2824
2825 /* Copy the data */
2826 OpenPacket->EaLength = EaLength;
2827 RtlCopyMemory(OpenPacket->EaBuffer, EaBuffer, EaLength);
2828
2829 /* Validate the buffer */
2831 EaLength,
2832 &EaErrorOffset);
2833 if (!NT_SUCCESS(Status))
2834 {
2835 /* Undo everything if it's invalid */
2836 DPRINT1("Invalid EA buffer\n");
2837 ExFreePool(OpenPacket->EaBuffer);
2839 IoStatusBlock->Information = EaErrorOffset;
2840 ExFreePool(OpenPacket);
2841 return Status;
2842 }
2843 }
2844 }
2845
2846 /* Setup the Open Packet */
2847 OpenPacket->Type = IO_TYPE_OPEN_PACKET;
2848 OpenPacket->Size = sizeof(*OpenPacket);
2849 OpenPacket->AllocationSize = SafeAllocationSize;
2850 OpenPacket->CreateOptions = CreateOptions;
2851 OpenPacket->FileAttributes = (USHORT)FileAttributes;
2852 OpenPacket->ShareAccess = (USHORT)ShareAccess;
2853 OpenPacket->Options = Options;
2854 OpenPacket->Disposition = Disposition;
2855 OpenPacket->CreateFileType = CreateFileType;
2856 OpenPacket->ExtraCreateParameters = ExtraCreateParameters;
2857 OpenPacket->InternalFlags = Flags;
2858 OpenPacket->TopDeviceObjectHint = DeviceObject;
2859
2860 /* Update the operation count */
2862
2863 /*
2864 * Attempt opening the file. This will call the I/O Parse Routine for
2865 * the File Object (IopParseDevice) which will create the object and
2866 * send the IRP to its device object. Note that we have two statuses
2867 * to worry about: the Object Manager's status (in Status) and the I/O
2868 * status, which is in the Open Packet's Final Status, and determined
2869 * by the Parse Check member.
2870 */
2872 NULL,
2873 AccessMode,
2874 NULL,
2876 OpenPacket,
2877 &LocalHandle);
2878
2879 /* Free the EA Buffer */
2880 if (OpenPacket->EaBuffer) ExFreePool(OpenPacket->EaBuffer);
2881
2882 /* Now check for Ob or Io failure */
2883 if (!(NT_SUCCESS(Status)) || (OpenPacket->ParseCheck == FALSE))
2884 {
2885 /* Check if Ob thinks well went well */
2886 if (NT_SUCCESS(Status))
2887 {
2888 /*
2889 * Tell it otherwise. Because we didn't use an ObjectType,
2890 * it incorrectly returned us a handle to God knows what.
2891 */
2894 }
2895
2896 /* Now check the Io status */
2897 if (!NT_SUCCESS(OpenPacket->FinalStatus))
2898 {
2899 /* Use this status instead of Ob's */
2900 Status = OpenPacket->FinalStatus;
2901
2902 /* Check if it was only a warning */
2903 if (NT_WARNING(Status))
2904 {
2905 /* Protect write with SEH */
2906 _SEH2_TRY
2907 {
2908 /* In this case, we copy the I/O Status back */
2909 IoStatusBlock->Information = OpenPacket->Information;
2910 IoStatusBlock->Status = OpenPacket->FinalStatus;
2911 }
2913 {
2914 /* Get exception code */
2916 }
2917 _SEH2_END;
2918 }
2919 }
2920 else if ((OpenPacket->FileObject) && (OpenPacket->ParseCheck == FALSE))
2921 {
2922 /*
2923 * This can happen in the very bizarre case where the parse routine
2924 * actually executed more then once (due to a reparse) and ended
2925 * up failing after already having created the File Object.
2926 */
2927 if (OpenPacket->FileObject->FileName.Length)
2928 {
2929 /* It had a name, free it */
2930 ExFreePoolWithTag(OpenPacket->FileObject->FileName.Buffer, TAG_IO_NAME);
2931 }
2932
2933 /* Clear the device object to invalidate the FO, and dereference */
2934 OpenPacket->FileObject->DeviceObject = NULL;
2935 ObDereferenceObject(OpenPacket->FileObject);
2936 }
2937 }
2938 else
2939 {
2940 /* We reached success and have a valid file handle */
2941 OpenPacket->FileObject->Flags |= FO_HANDLE_CREATED;
2942 ASSERT(OpenPacket->FileObject->Type == IO_TYPE_FILE);
2943
2944 /* Enter SEH for write back */
2945 _SEH2_TRY
2946 {
2947 /* Write back the handle and I/O Status */
2949 IoStatusBlock->Information = OpenPacket->Information;
2950 IoStatusBlock->Status = OpenPacket->FinalStatus;
2951
2952 /* Get the Io status */
2953 Status = OpenPacket->FinalStatus;
2954 }
2956 {
2957 /* Get the exception status */
2959 }
2960 _SEH2_END;
2961 }
2962
2963 /* Check if we were 100% successful */
2964 if ((OpenPacket->ParseCheck != FALSE) && (OpenPacket->FileObject))
2965 {
2966 /* Dereference the File Object */
2967 ObDereferenceObject(OpenPacket->FileObject);
2968 }
2969
2970 /* Return status */
2971 ExFreePool(OpenPacket);
2972 return Status;
2973}
2974
2975/* FUNCTIONS *****************************************************************/
2976
2977/*
2978 * @unimplemented
2979 */
2981NTAPI
2983 IN ULONG Length,
2984 IN BOOLEAN SetOperation)
2985{
2988}
2989
2990/*
2991 * @unimplemented
2992 */
2994NTAPI
2996 IN ULONG QuotaLength,
2997 OUT PULONG ErrorOffset)
2998{
3001}
3002
3003/*
3004 * @implemented
3005 */
3007NTAPI
3020 IN PVOID ExtraCreateParameters OPTIONAL,
3022{
3023 PAGED_CODE();
3024
3034 EaBuffer,
3035 EaLength,
3037 ExtraCreateParameters,
3038 Options,
3039 0,
3040 NULL);
3041}
3042
3043/*
3044 * @unimplemented
3045 */
3047NTAPI
3060 IN PVOID ExtraCreateParameters OPTIONAL,
3063{
3064 ULONG Flags = 0;
3065
3066 PAGED_CODE();
3067
3068 /* Check if we were passed a device to send the create request to*/
3069 if (DeviceObject)
3070 {
3071 /* We'll tag this request into a file object extension */
3073 }
3074
3084 EaBuffer,
3085 EaLength,
3087 ExtraCreateParameters,
3089 Flags,
3090 DeviceObject);
3091}
3092
3093/*
3094 * @implemented
3095 */
3097NTAPI
3101{
3102 PFILE_OBJECT CreatedFileObject;
3106 PAGED_CODE();
3107 IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3108
3109 /* Choose Device Object */
3110 if (FileObject) DeviceObject = FileObject->DeviceObject;
3111
3112 /* Reference the device object and initialize attributes */
3113 InterlockedIncrement(&DeviceObject->ReferenceCount);
3115
3116 /* Create the File Object */
3120 KernelMode,
3121 NULL,
3122 sizeof(FILE_OBJECT),
3123 sizeof(FILE_OBJECT),
3124 0,
3125 (PVOID*)&CreatedFileObject);
3126 if (!NT_SUCCESS(Status))
3127 {
3128 /* Fail */
3131 }
3132
3133 /* Set File Object Data */
3134 RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3135 CreatedFileObject->DeviceObject = DeviceObject;
3136 CreatedFileObject->Type = IO_TYPE_FILE;
3137 CreatedFileObject->Size = sizeof(FILE_OBJECT);
3138 CreatedFileObject->Flags = FO_STREAM_FILE;
3139
3140 /* Initialize the wait event */
3141 KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3142
3143 /* Insert it to create a handle for it */
3144 Status = ObInsertObject(CreatedFileObject,
3145 NULL,
3147 1,
3148 (PVOID*)&CreatedFileObject,
3149 &FileHandle);
3151
3152 /* Set the handle created flag */
3153 CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3154 ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3155
3156 /* Check if we have a VPB */
3157 if (DeviceObject->Vpb)
3158 {
3159 /* Reference it */
3160 InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3161 }
3162
3163 /* Check if the caller wants the handle */
3164 if (FileObjectHandle)
3165 {
3166 /* Return it */
3168 ObDereferenceObject(CreatedFileObject);
3169 }
3170 else
3171 {
3172 /* Otherwise, close it */
3174 }
3175
3176 /* Return the file object */
3177 return CreatedFileObject;
3178}
3179
3180/*
3181 * @implemented
3182 */
3184NTAPI
3187{
3188 /* Call the newer function */
3190}
3191
3192/*
3193 * @implemented
3194 */
3196NTAPI
3199{
3200 PFILE_OBJECT CreatedFileObject;
3203 PAGED_CODE();
3204 IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
3205
3206 /* Choose Device Object */
3207 if (FileObject) DeviceObject = FileObject->DeviceObject;
3208
3209 /* Reference the device object and initialize attributes */
3210 InterlockedIncrement(&DeviceObject->ReferenceCount);
3212
3213 /* Create the File Object */
3217 KernelMode,
3218 NULL,
3219 sizeof(FILE_OBJECT),
3220 sizeof(FILE_OBJECT),
3221 0,
3222 (PVOID*)&CreatedFileObject);
3223 if (!NT_SUCCESS(Status))
3224 {
3225 /* Fail */
3228 }
3229
3230 /* Set File Object Data */
3231 RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
3232 CreatedFileObject->DeviceObject = DeviceObject;
3233 CreatedFileObject->Type = IO_TYPE_FILE;
3234 CreatedFileObject->Size = sizeof(FILE_OBJECT);
3235 CreatedFileObject->Flags = FO_STREAM_FILE;
3236
3237 /* Initialize the wait event */
3238 KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
3239
3240 /* Destroy create information */
3242 ObjectCreateInfo);
3243 OBJECT_TO_OBJECT_HEADER(CreatedFileObject)->ObjectCreateInfo = NULL;
3244
3245 /* Set the handle created flag */
3246 CreatedFileObject->Flags |= FO_HANDLE_CREATED;
3247 ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
3248
3249 /* Check if we have a VPB */
3250 if (DeviceObject->Vpb)
3251 {
3252 /* Reference it */
3253 InterlockedIncrement((PLONG)&DeviceObject->Vpb->ReferenceCount);
3254 }
3255
3256 /* Return the file object */
3257 return CreatedFileObject;
3258}
3259
3260/*
3261 * @implemented
3262 */
3264NTAPI
3266{
3267 /* Return the mapping */
3268 return &IopFileMapping;
3269}
3270
3271/*
3272 * @implemented
3273 */
3274BOOLEAN
3275NTAPI
3277{
3278 /* Return the flag status */
3279 return FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3280}
3281
3282/*
3283 * @implemented
3284 */
3285BOOLEAN
3286NTAPI
3292{
3294 DUMMY_FILE_OBJECT LocalFileObject;
3295 HANDLE Handle;
3296 OPEN_PACKET OpenPacket;
3297 PAGED_CODE();
3298 IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
3299
3300 /* Setup the Open Packet */
3301 RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
3302 OpenPacket.Type = IO_TYPE_OPEN_PACKET;
3303 OpenPacket.Size = sizeof(OPEN_PACKET);
3306 OpenPacket.Options = IO_FORCE_ACCESS_CHECK;
3307 OpenPacket.Disposition = FILE_OPEN;
3308 OpenPacket.NetworkInformation = Buffer;
3309 OpenPacket.QueryOnly = TRUE;
3310 OpenPacket.FullAttributes = TRUE;
3311 OpenPacket.LocalFileObject = &LocalFileObject;
3312
3313 /*
3314 * Attempt opening the file. This will call the I/O Parse Routine for
3315 * the File Object (IopParseDevice) which will use the dummy file obejct
3316 * send the IRP to its device object. Note that we have two statuses
3317 * to worry about: the Object Manager's status (in Status) and the I/O
3318 * status, which is in the Open Packet's Final Status, and determined
3319 * by the Parse Check member.
3320 */
3322 NULL,
3323 KernelMode,
3324 NULL,
3326 &OpenPacket,
3327 &Handle);
3328 if (OpenPacket.ParseCheck == FALSE)
3329 {
3330 /* Parse failed */
3331 IoStatus->Status = Status;
3332 }
3333 else
3334 {
3335 /* Use the Io status */
3336 IoStatus->Status = OpenPacket.FinalStatus;
3337 IoStatus->Information = OpenPacket.Information;
3338 }
3339
3340 /* Return success */
3341 return TRUE;
3342}
3343
3344/*
3345 * @implemented
3346 */
3347VOID
3348NTAPI
3351{
3352 PAGED_CODE();
3353
3354 /* Check if the file has an extension */
3356 {
3357 /* Check if caller specified to ignore access checks */
3358 //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3359 {
3360 /* Don't update share access */
3361 return;
3362 }
3363 }
3364
3365 /* Otherwise, check if there's any access present */
3366 if ((FileObject->ReadAccess) ||
3367 (FileObject->WriteAccess) ||
3368 (FileObject->DeleteAccess))
3369 {
3370 /* Increase the open count */
3371 ShareAccess->OpenCount++;
3372
3373 /* Add new share access */
3374 ShareAccess->Readers += FileObject->ReadAccess;
3375 ShareAccess->Writers += FileObject->WriteAccess;
3376 ShareAccess->Deleters += FileObject->DeleteAccess;
3377 ShareAccess->SharedRead += FileObject->SharedRead;
3378 ShareAccess->SharedWrite += FileObject->SharedWrite;
3379 ShareAccess->SharedDelete += FileObject->SharedDelete;
3380 }
3381}
3382
3383/*
3384 * @implemented
3385 */
3387NTAPI
3393{
3396 BOOLEAN DeleteAccess;
3397 BOOLEAN SharedRead;
3398 BOOLEAN SharedWrite;
3399 BOOLEAN SharedDelete;
3400 PAGED_CODE();
3401
3402 /* Get access masks */
3405 DeleteAccess = (DesiredAccess & DELETE) != 0;
3406
3407 /* Set them in the file object */
3408 FileObject->ReadAccess = ReadAccess;
3409 FileObject->WriteAccess = WriteAccess;
3410 FileObject->DeleteAccess = DeleteAccess;
3411
3412 /* Check if the file has an extension */
3414 {
3415 /* Check if caller specified to ignore access checks */
3416 //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3417 {
3418 /* Don't check share access */
3419 return STATUS_SUCCESS;
3420 }
3421 }
3422
3423 /* Check if we have any access */
3424 if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
3425 {
3426 /* Get shared access masks */
3427 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3428 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3429 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3430
3431 /* Check if the shared access is violated */
3432 if ((ReadAccess &&
3433 (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
3434 (WriteAccess &&
3435 (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
3436 (DeleteAccess &&
3437 (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
3438 ((ShareAccess->Readers != 0) && !SharedRead) ||
3439 ((ShareAccess->Writers != 0) && !SharedWrite) ||
3440 ((ShareAccess->Deleters != 0) && !SharedDelete))
3441 {
3442 /* Sharing violation, fail */
3444 }
3445
3446 /* Set them */
3447 FileObject->SharedRead = SharedRead;
3448 FileObject->SharedWrite = SharedWrite;
3449 FileObject->SharedDelete = SharedDelete;
3450
3451 /* It's not, check if caller wants us to update it */
3452 if (Update)
3453 {
3454 /* Increase open count */
3455 ShareAccess->OpenCount++;
3456
3457 /* Update shared access */
3458 ShareAccess->Readers += ReadAccess;
3459 ShareAccess->Writers += WriteAccess;
3460 ShareAccess->Deleters += DeleteAccess;
3461 ShareAccess->SharedRead += SharedRead;
3462 ShareAccess->SharedWrite += SharedWrite;
3463 ShareAccess->SharedDelete += SharedDelete;
3464 }
3465 }
3466
3467 /* Validation successful */
3468 return STATUS_SUCCESS;
3469}
3470
3471/*
3472 * @implemented
3473 */
3474VOID
3475NTAPI
3478{
3479 PAGED_CODE();
3480
3481 /* Check if the file has an extension */
3483 {
3484 /* Check if caller specified to ignore access checks */
3485 //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3486 {
3487 /* Don't update share access */
3488 return;
3489 }
3490 }
3491
3492 /* Otherwise, check if there's any access present */
3493 if ((FileObject->ReadAccess) ||
3494 (FileObject->WriteAccess) ||
3495 (FileObject->DeleteAccess))
3496 {
3497 /* Decrement the open count */
3498 ShareAccess->OpenCount--;
3499
3500 /* Remove share access */
3501 ShareAccess->Readers -= FileObject->ReadAccess;
3502 ShareAccess->Writers -= FileObject->WriteAccess;
3503 ShareAccess->Deleters -= FileObject->DeleteAccess;
3504 ShareAccess->SharedRead -= FileObject->SharedRead;
3505 ShareAccess->SharedWrite -= FileObject->SharedWrite;
3506 ShareAccess->SharedDelete -= FileObject->SharedDelete;
3507 }
3508}
3509
3510/*
3511 * @implemented
3512 */
3513VOID
3514NTAPI
3519{
3522 BOOLEAN DeleteAccess;
3523 BOOLEAN SharedRead;
3524 BOOLEAN SharedWrite;
3525 BOOLEAN SharedDelete;
3527 PAGED_CODE();
3528
3531 DeleteAccess = (DesiredAccess & DELETE) != 0;
3532
3533 /* Check if the file has an extension */
3535 {
3536 /* Check if caller specified to ignore access checks */
3537 //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
3538 {
3539 /* Don't update share access */
3540 Update = FALSE;
3541 }
3542 }
3543
3544 /* Update basic access */
3545 FileObject->ReadAccess = ReadAccess;
3546 FileObject->WriteAccess = WriteAccess;
3547 FileObject->DeleteAccess = DeleteAccess;
3548
3549 /* Check if we have no access as all */
3550 if (!(ReadAccess) && !(WriteAccess) && !(DeleteAccess))
3551 {
3552 /* Check if we need to update the structure */
3553 if (!Update) return;
3554
3555 /* Otherwise, clear data */
3556 ShareAccess->OpenCount = 0;
3557 ShareAccess->Readers = 0;
3558 ShareAccess->Writers = 0;
3559 ShareAccess->Deleters = 0;
3560 ShareAccess->SharedRead = 0;
3561 ShareAccess->SharedWrite = 0;
3562 ShareAccess->SharedDelete = 0;
3563 }
3564 else
3565 {
3566 /* Calculate shared access */
3567 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
3568 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
3569 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
3570
3571 /* Set it in the FO */
3572 FileObject->SharedRead = SharedRead;
3573 FileObject->SharedWrite = SharedWrite;
3574 FileObject->SharedDelete = SharedDelete;
3575
3576 /* Check if we need to update the structure */
3577 if (!Update) return;
3578
3579 /* Otherwise, set data */
3580 ShareAccess->OpenCount = 1;
3581 ShareAccess->Readers = ReadAccess;
3582 ShareAccess->Writers = WriteAccess;
3583 ShareAccess->Deleters = DeleteAccess;
3584 ShareAccess->SharedRead = SharedRead;
3585 ShareAccess->SharedWrite = SharedWrite;
3586 ShareAccess->SharedDelete = SharedDelete;
3587 }
3588}
3589
3590/*
3591 * @implemented
3592 */
3593VOID
3594NTAPI
3597{
3598 PIRP Irp;
3599 KEVENT Event;
3600 KIRQL OldIrql;
3603
3604 /* Check if handles were already created for the
3605 * open file. If so, that's over.
3606 */
3607 if (FileObject->Flags & FO_HANDLE_CREATED)
3608 KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN,
3610 (ULONG_PTR)DeviceObject, 0, 0);
3611
3612 /* Reset the events */
3614 KeClearEvent(&FileObject->Event);
3615
3616 /* Allocate the IRP we'll use */
3618 /* Properly set it */
3619 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
3620 Irp->UserEvent = &Event;
3621 Irp->UserIosb = &Irp->IoStatus;
3622 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
3623 Irp->Tail.Overlay.OriginalFileObject = FileObject;
3624 Irp->RequestorMode = KernelMode;
3626
3628 Stack->MajorFunction = IRP_MJ_CLEANUP;
3629 Stack->FileObject = FileObject;
3630
3631 /* Put on top of IRPs list of the thread */
3633
3634 /* Call the driver */
3636 if (Status == STATUS_PENDING)
3637 {
3640 }
3641
3642 /* Remove from IRPs list */
3646
3647 /* Free the IRP */
3648 IoFreeIrp(Irp);
3649
3650 /* Clear the event */
3651 KeClearEvent(&FileObject->Event);
3652 /* And finally, mark the open operation as canceled */
3654}
3655
3656/*
3657 * @implemented
3658 */
3660NTAPI
3663{
3666 POBJECT_NAME_INFORMATION LocalInfo;
3667
3668 /* Start with a buffer length of 200 */
3669 ReturnLength = 200;
3670 /*
3671 * We'll loop until query works.
3672 * We will use returned length for next loop
3673 * iteration, trying to have a big enough buffer.
3674 */
3675 for (Length = 200; ; Length = ReturnLength)
3676 {
3677 /* Allocate our work buffer */
3678 LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, 'nDoI');
3679 if (LocalInfo == NULL)
3680 {
3682 }
3683
3684 /* Query the DOS name */
3686 TRUE,
3687 TRUE,
3688 LocalInfo,
3689 Length,
3690 &ReturnLength,
3691 KernelMode);
3692 /* If it succeed, nothing more to do */
3693 if (Status == STATUS_SUCCESS)
3694 {
3695 break;
3696 }
3697
3698 /* Otherwise, prepare for re-allocation */
3699 ExFreePoolWithTag(LocalInfo, 'nDoI');
3700
3701 /*
3702 * If we failed because of something else
3703 * than memory, simply stop and fail here
3704 */
3706 {
3707 return Status;
3708 }
3709 }
3710
3711 /* Success case here: return our buffer */
3712 *ObjectNameInformation = LocalInfo;
3713 return STATUS_SUCCESS;
3714}
3715
3716/*
3717 * @implemented
3718 */
3720NTAPI
3722 IN BOOLEAN Remote)
3723{
3725 BOOLEAN FlagSet;
3726
3727 /* Get the flag status */
3728 FlagSet = FileObject->Flags & FO_REMOTE_ORIGIN ? TRUE : FALSE;
3729
3730 /* Don't set the flag if it was set already, and don't remove it if it wasn't set */
3731 if (Remote && !FlagSet)
3732 {
3733 /* Set the flag */
3734 FileObject->Flags |= FO_REMOTE_ORIGIN;
3735 }
3736 else if (!Remote && FlagSet)
3737 {
3738 /* Remove the flag */
3739 FileObject->Flags &= ~FO_REMOTE_ORIGIN;
3740 }
3741 else
3742 {
3743 /* Fail */
3745 }
3746
3747 /* Return status */
3748 return Status;
3749}
3750
3751/*
3752 * @implemented
3753 */
3755NTAPI
3760 PLARGE_INTEGER AllocateSize,
3767{
3768 /* Call the I/O Function */
3769 return IoCreateFile(FileHandle,
3773 AllocateSize,
3778 EaBuffer,
3779 EaLength,
3781 NULL,
3782 0);
3783}
3784
3786NTAPI
3792 IN ULONG MailslotQuota,
3793 IN ULONG MaxMessageSize,
3794 IN PLARGE_INTEGER TimeOut)
3795{
3797 PAGED_CODE();
3798
3799 /* Check for Timeout */
3800 if (TimeOut)
3801 {
3802 /* check if the call came from user mode */
3804 {
3805 /* Enter SEH for Probe */
3806 _SEH2_TRY
3807 {
3808 /* Probe the timeout */
3809 Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
3810 }
3812 {
3813 /* Return the exception code */
3815 }
3816 _SEH2_END;
3817 }
3818 else
3819 {
3820 /* Otherwise, capture directly */
3821 Buffer.ReadTimeout = *TimeOut;
3822 }
3823
3824 /* Set the correct setting */
3825 Buffer.TimeoutSpecified = TRUE;
3826 }
3827 else
3828 {
3829 /* Tell the FSD we don't have a timeout */
3830 Buffer.TimeoutSpecified = FALSE;
3831 }
3832
3833 /* Set Settings */
3834 Buffer.MailslotQuota = MailslotQuota;
3835 Buffer.MaximumMessageSize = MaxMessageSize;
3836
3837 /* Call I/O */
3838 return IoCreateFile(FileHandle,
3842 NULL,
3843 0,
3847 NULL,
3848 0,
3850 (PVOID)&Buffer,
3851 0);
3852}
3853
3855NTAPI
3863 IN ULONG NamedPipeType,
3864 IN ULONG ReadMode,
3865 IN ULONG CompletionMode,
3866 IN ULONG MaximumInstances,
3867 IN ULONG InboundQuota,
3868 IN ULONG OutboundQuota,
3869 IN PLARGE_INTEGER DefaultTimeout)
3870{
3872 PAGED_CODE();
3873
3874 /* Check for Timeout */
3875 if (DefaultTimeout)
3876 {
3877 /* check if the call came from user mode */
3879 {
3880 /* Enter SEH for Probe */
3881 _SEH2_TRY
3882 {
3883 /* Probe the timeout */
3884 Buffer.DefaultTimeout =
3885 ProbeForReadLargeInteger(DefaultTimeout);
3886 }
3888 {
3889 /* Return the exception code */
3891 }
3892 _SEH2_END;
3893 }
3894 else
3895 {
3896 /* Otherwise, capture directly */
3897 Buffer.DefaultTimeout = *DefaultTimeout;
3898 }
3899
3900 /* Set the correct setting */
3901 Buffer.TimeoutSpecified = TRUE;
3902 }
3903 else
3904 {
3905 /* Tell the FSD we don't have a timeout */
3906 Buffer.TimeoutSpecified = FALSE;
3907 }
3908
3909 /* Set Settings */
3910 Buffer.NamedPipeType = NamedPipeType;
3911 Buffer.ReadMode = ReadMode;
3912 Buffer.CompletionMode = CompletionMode;
3913 Buffer.MaximumInstances = MaximumInstances;
3914 Buffer.InboundQuota = InboundQuota;
3915 Buffer.OutboundQuota = OutboundQuota;
3916
3917 /* Call I/O */
3918 return IoCreateFile(FileHandle,
3922 NULL,
3923 0,
3927 NULL,
3928 0,
3930 (PVOID)&Buffer,
3931 0);
3932}
3933
3935NTAPI
3937{
3938 PAGED_CODE();
3939
3940 /* Call the kernel */
3942 return STATUS_SUCCESS;
3943}
3944
3945/*
3946 * @implemented
3947 */
3949NTAPI
3956{
3957 /* Call the I/O Function */
3958 return IoCreateFile(FileHandle,
3962 NULL,
3963 0,
3965 FILE_OPEN,
3967 NULL,
3968 0,
3970 NULL,
3971 0);
3972}
3973
3975NTAPI
3978{
3979 /* Call the internal helper API */
3982 sizeof(FILE_BASIC_INFORMATION),
3984}
3985
3987NTAPI
3990{
3991 /* Call the internal helper API */
3996}
3997
4016NTAPI
4019{
4022 PIRP Irp;
4023 KIRQL OldIrql;
4024 BOOLEAN OurIrpsInList = FALSE;
4028 PLIST_ENTRY ListHead, NextEntry;
4029 PAGED_CODE();
4030 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
4031
4032 /* Check the previous mode */
4033 if (PreviousMode != KernelMode)
4034 {
4035 /* Enter SEH for probing */
4036 _SEH2_TRY
4037 {
4038 /* Probe the I/O Status Block */
4040 }
4042 {
4043 /* Return the exception code */
4045 }
4046 _SEH2_END;
4047 }
4048
4049 /* Reference the file object */
4051 0,
4054 (PVOID*)&FileObject,
4055 NULL);
4056 if (!NT_SUCCESS(Status)) return Status;
4057
4058 /* IRP cancellations are synchronized at APC_LEVEL. */
4060
4061 /* Get the current thread */
4063
4064 /* Update the operation counts */
4066
4067 /* Loop the list */
4068 ListHead = &Thread->IrpList;
4069 NextEntry = ListHead->Flink;
4070 while (ListHead != NextEntry)
4071 {
4072 /* Get the IRP and check if the File Object matches */
4073 Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4074 if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4075 {
4076 /* Cancel this IRP and keep looping */
4078 OurIrpsInList = TRUE;
4079 }
4080
4081 /* Go to the next entry */
4082 NextEntry = NextEntry->Flink;
4083 }
4084
4085 /* Lower the IRQL */
4087
4088 /* Check if we had found an IRP */
4089 if (OurIrpsInList)
4090 {
4091 /* Setup a 10ms wait */
4092 Interval.QuadPart = -100000;
4093
4094 /* Start looping */
4095 while (OurIrpsInList)
4096 {
4097 /* Do the wait */
4099 OurIrpsInList = FALSE;
4100
4101 /* Raise IRQL */
4103
4104 /* Now loop the list again */
4105 NextEntry = ListHead->Flink;
4106 while (NextEntry != ListHead)
4107 {
4108 /* Get the IRP and check if the File Object matches */
4109 Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
4110 if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
4111 {
4112 /* Keep looping */
4113 OurIrpsInList = TRUE;
4114 break;
4115 }
4116
4117 /* Go to the next entry */
4118 NextEntry = NextEntry->Flink;
4119 }
4120
4121 /* Lower the IRQL */
4123 }
4124 }
4125
4126 /* Enter SEH for writing back the I/O Status */
4127 _SEH2_TRY
4128 {
4129 /* Write success */
4132 }
4134 {
4135 /* Ignore exception */
4136 }
4137 _SEH2_END;
4138
4139 /* Dereference the file object and return success */
4141 return STATUS_SUCCESS;
4142}
4143
4144/*
4145 * @implemented
4146 */
4148NTAPI
4150{
4152 DUMMY_FILE_OBJECT LocalFileObject;
4153 HANDLE Handle;
4155 OPEN_PACKET OpenPacket;
4156 PAGED_CODE();
4157 IOTRACE(IO_API_DEBUG, "FileMame: %wZ\n", ObjectAttributes->ObjectName);
4158
4159 /* Setup the Open Packet */
4160 RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
4161 OpenPacket.Type = IO_TYPE_OPEN_PACKET;
4162 OpenPacket.Size = sizeof(OPEN_PACKET);
4164 OpenPacket.ShareAccess = FILE_SHARE_READ |
4167 OpenPacket.Disposition = FILE_OPEN;
4168 OpenPacket.DeleteOnly = TRUE;
4169 OpenPacket.LocalFileObject = &LocalFileObject;
4170
4171 /* Update the operation counts */
4173
4174 /*
4175 * Attempt opening the file. This will call the I/O Parse Routine for
4176 * the File Object (IopParseDevice) which will use the dummy file obejct
4177 * send the IRP to its device object. Note that we have two statuses
4178 * to worry about: the Object Manager's status (in Status) and the I/O
4179 * status, which is in the Open Packet's Final Status, and determined
4180 * by the Parse Check member.
4181 */
4183 NULL,
4184 AccessMode,
4185 NULL,
4186 DELETE,
4187 &OpenPacket,
4188 &Handle);
4189 if (OpenPacket.ParseCheck == FALSE) return Status;
4190
4191 /* Retrn the Io status */
4192 return OpenPacket.FinalStatus;
4193}
4194
4195/* EOF */
#define PAGED_CODE()
@ ObjectNameInformation
Definition: DriverTester.h:55
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
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
unsigned char BOOLEAN
Definition: actypes.h:127
#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
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
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_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
#define L(x)
Definition: resources.c:13
_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:4148
#define ULONG_PTR
Definition: config.h:101
#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:143
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
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:90
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
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
@ FileBasicInfo
Definition: minwinbase.h:304
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 UCHAR
Definition: file.c:60
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
DWORD * PSECURITY_INFORMATION
Definition: ms-dtyp.idl:311
__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 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
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
#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:219
#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:28
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3950
#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
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
@ FILE_OBJECT
Definition: ntobjenum.h:17
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
GENERIC_MAPPING IopFileMapping
Definition: iomgr.c:50
#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:696
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:463
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
@ IopOtherTransfer
Definition: io.h:262
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:128
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:1549
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1386
NTSTATUS NTAPI IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG FileInformationSize, OUT PVOID FileInformation)
Definition: file.c:2342
VOID NTAPI IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject)
Definition: file.c:3595
NTSTATUS NTAPI IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject, IN PVOID FilterContext, IN BOOLEAN Define)
Definition: file.c:2509
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3515
NTSTATUS NTAPI NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
Definition: file.c:3976
NTSTATUS NTAPI NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: file.c:4017
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:1522
NTSTATUS NTAPI IoSetFileOrigin(IN PFILE_OBJECT FileObject, IN BOOLEAN Remote)
Definition: file.c:3721
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:3008
ERESOURCE IopSecurityResource
Definition: iomgr.c:61
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:3287
NTSTATUS NTAPI IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, IN ULONG QuotaLength, OUT PULONG ErrorOffset)
Definition: file.c:2995
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3388
NTSTATUS NTAPI IopAcquireFileObjectLock(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode, _In_ BOOLEAN Alertable, _Out_ PBOOLEAN LockFailed)
Definition: file.c:2448
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:1941
PDEVICE_OBJECT NTAPI IopGetDevicePDO(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1496
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3476
NTSTATUS IopCheckTopDeviceHint(IN OUT PDEVICE_OBJECT *DeviceObject, IN POPEN_PACKET OpenPacket, BOOLEAN DirectOpen)
Definition: file.c:272
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:1651
NTSTATUS NTAPI IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN BOOLEAN SetOperation)
Definition: file.c:2982
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:1316
NTSTATUS NTAPI IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
Definition: file.c:3661
VOID NTAPI IopDoNameTransmogrify(IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER DataBuffer)
Definition: file.c:167
PFILE_OBJECT NTAPI IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, OUT PHANDLE FileObjectHandle OPTIONAL)
Definition: file.c:3098
VOID NTAPI IopCloseFile(IN PEPROCESS Process OPTIONAL, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount, IN ULONG SystemHandleCount)
Definition: file.c:2176
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:3787
NTSTATUS NTAPI NtFlushWriteBuffer(VOID)
Definition: file.c:3936
PVOID NTAPI IoGetFileObjectFilterContext(IN PFILE_OBJECT FileObject)
Definition: file.c:2494
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:1923
NTSTATUS NTAPI NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
Definition: file.c:3988
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:2552
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3265
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3185
NTSTATUS NTAPI NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: file.c:4149
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:1483
PFILE_OBJECT NTAPI IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:3197
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3276
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:3856
VOID NTAPI IopDeleteFile(IN PVOID ObjectBody)
Definition: file.c:1352
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3349
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:321
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:1603
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:3048
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_ _When_(return==0, _At_(DosName->Buffer, __drv_allocatesMem(Mem))) 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:1043
#define STATUS_MOUNT_POINT_NOT_RESOLVED
Definition: ntstatus.h:1042
#define STATUS_REPARSE
Definition: ntstatus.h:136
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:378
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:363
#define STATUS_IO_REPARSE_DATA_INVALID
Definition: ntstatus.h:878
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:387
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
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
short WCHAR
Definition: pedump.c:58
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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define _SEH2_LEAVE
Definition: pseh2_64.h:206
#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
#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
_In_ PVOID Context
Definition: storport.h:2269
OBJECT_HEADER ObjectHeader
Definition: io.h:357
ULONG Flags
Definition: pstypes.h:1529
LIST_ENTRY IrpList
Definition: pstypes.h:1233
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:102
PVOID FilterContext
Definition: io.h:103
PACCESS_STATE AccessState
Definition: iotypes.h:2869
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2868
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2870
struct _IO_STACK_LOCATION::@4315::@4333 QuerySecurity
union _IO_STACK_LOCATION::@1670 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3171
struct _IO_STACK_LOCATION::@4315::@4317 CreatePipe
struct _IO_STACK_LOCATION::@4315::@4334 SetSecurity
struct _IO_STACK_LOCATION::@4315::@4316 Create
struct _IO_STACK_LOCATION::@4315::@4318 CreateMailslot
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:1273
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
LARGE_INTEGER AllocationSize
Definition: io.h:375
BOOLEAN Override
Definition: io.h:387
BOOLEAN DeleteOnly
Definition: io.h:389
PFILE_BASIC_INFORMATION BasicInformation
Definition: io.h:383
USHORT FileAttributes
Definition: io.h:377
PVOID ExtraCreateParameters
Definition: io.h:386
PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
Definition: io.h:384
USHORT ShareAccess
Definition: io.h:378
BOOLEAN FullAttributes
Definition: io.h:390
NTSTATUS FinalStatus
Definition: io.h:370
CREATE_FILE_TYPE CreateFileType
Definition: io.h:385
PDUMMY_FILE_OBJECT LocalFileObject
Definition: io.h:391
CSHORT Type
Definition: io.h:367
ULONG_PTR Information
Definition: io.h:371
ULONG InternalFlags
Definition: io.h:393
ULONG Disposition
Definition: io.h:382
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:394
PFILE_OBJECT FileObject
Definition: io.h:369
ULONG Options
Definition: io.h:381
BOOLEAN TraversedMountPoint
Definition: io.h:392
PFILE_OBJECT RelatedFileObject
Definition: io.h:373
ULONG ParseCheck
Definition: io.h:372
CSHORT Size
Definition: io.h:368
ULONG CreateOptions
Definition: io.h:376
PVOID EaBuffer
Definition: io.h:379
ULONG EaLength
Definition: io.h:380
BOOLEAN QueryOnly
Definition: io.h:388
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:81
#define TAG_IO
Definition: tag.h:79
#define TAG_IO_NAME
Definition: tag.h:82
#define STATUS_PENDING
Definition: telnetd.h:14
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
static ULONG HandleCount
Definition: uefidisk.c:68
#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:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3821
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_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
struct _FILE_NAME_INFORMATION * PFILE_NAME_INFORMATION
_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:4415
#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:4432
#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:4433
#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:7216
#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:7234
#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:473
@ Executive
Definition: ketypes.h:467
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
@ LockQueueIoDatabaseLock
Definition: ketypes.h:720
_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_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:1190
SECURITY_OPERATION_CODE
Definition: setypes.h:170
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1191
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1192
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1195
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1199