diff --git a/reactos/ntoskrnl/io/file.c b/reactos/ntoskrnl/io/file.c index faa1d8275c4..430a4a5a52a 100644 --- a/reactos/ntoskrnl/io/file.c +++ b/reactos/ntoskrnl/io/file.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/io/file.c * PURPOSE: I/O File Object & NT File Handle Access/Managment of Files. - * + * * PROGRAMMERS: David Welch (welch@mcmail.com) */ @@ -23,8 +23,8 @@ extern GENERIC_MAPPING IopFileMapping; /* INTERNAL FUNCTIONS ********************************************************/ -static -NTSTATUS +static +NTSTATUS STDCALL IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, @@ -38,16 +38,16 @@ IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, /* * NAME INTERNAL * IopCreateFile - * + * * DESCRIPTION - * + * * ARGUMENTS - * + * * RETURN VALUE * * REVISIONS */ -NTSTATUS +NTSTATUS STDCALL IopCreateFile(PVOID ObjectBody, PVOID Parent, @@ -173,7 +173,7 @@ IopCreateFile(PVOID ObjectBody, return(STATUS_SUCCESS); } -VOID +VOID STDCALL IopDeleteFile(PVOID ObjectBody) { @@ -183,11 +183,11 @@ IopDeleteFile(PVOID ObjectBody) NTSTATUS Status; KEVENT Event; PDEVICE_OBJECT DeviceObject; - + DPRINT("IopDeleteFile()\n"); if (FileObject->DeviceObject) - { + { /* Check if this is a direct open or not */ if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) { @@ -197,46 +197,46 @@ IopDeleteFile(PVOID ObjectBody) { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Clear and set up Events */ KeClearEvent(&FileObject->Event); KeInitializeEvent(&Event, SynchronizationEvent, FALSE); - + /* Allocate an IRP */ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - + /* Set it up */ Irp->UserEvent = &Event; Irp->UserIosb = &Irp->IoStatus; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API; - + /* Set up Stack Pointer Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_CLOSE; StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; - + /* Call the FS Driver */ Status = IoCallDriver(DeviceObject, Irp); - + /* Wait for completion */ if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } IoFreeIrp(Irp); - + } - /* Clear the file name */ + /* Clear the file name */ if (FileObject->FileName.Buffer) { ExFreePool(FileObject->FileName.Buffer); FileObject->FileName.Buffer = NULL; } - + /* Free the completion context */ if (FileObject->CompletionContext) { @@ -245,7 +245,7 @@ IopDeleteFile(PVOID ObjectBody) } } -static +static NTSTATUS IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, @@ -489,7 +489,7 @@ IopQueryNameFile(PVOID ObjectBody, return Status; } -VOID +VOID STDCALL IopCloseFile(PVOID ObjectBody, ULONG HandleCount) @@ -500,9 +500,9 @@ IopCloseFile(PVOID ObjectBody, PIO_STACK_LOCATION StackPtr; NTSTATUS Status; PDEVICE_OBJECT DeviceObject; - + DPRINT("IopCloseFile()\n"); - + if (HandleCount > 1 || FileObject->DeviceObject == NULL) return; /* Check if this is a direct open or not */ @@ -514,29 +514,29 @@ IopCloseFile(PVOID ObjectBody, { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Clear and set up Events */ KeClearEvent(&FileObject->Event); KeInitializeEvent(&Event, SynchronizationEvent, FALSE); - + /* Allocate an IRP */ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - + /* Set it up */ Irp->UserEvent = &Event; Irp->UserIosb = &Irp->IoStatus; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API; - + /* Set up Stack Pointer Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_CLEANUP; StackPtr->FileObject = FileObject; - + /* Call the FS Driver */ Status = IoCallDriver(DeviceObject, Irp); - + /* Wait for completion */ if (Status == STATUS_PENDING) { @@ -576,60 +576,60 @@ IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, /* * NAME EXPORTED * IoCreateFile@56 - * + * * DESCRIPTION * Either causes a new file or directory to be created, or it * opens an existing file, device, directory or volume, giving * the caller a handle for the file object. This handle can be * used by subsequent calls to manipulate data within the file * or the file object's state of attributes. - * + * * ARGUMENTS * FileHandle (OUT) * Points to a variable which receives the file handle * on return; - * + * * DesiredAccess * Desired access to the file; - * + * * ObjectAttributes * Structure describing the file; - * + * * IoStatusBlock (OUT) * Receives information about the operation on return; - * + * * AllocationSize [OPTIONAL] * Initial size of the file in bytes; - * + * * FileAttributes * Attributes to create the file with; - * + * * ShareAccess * Type of shared access the caller would like to the * file; - * + * * CreateDisposition * Specifies what to do, depending on whether the * file already exists; - * + * * CreateOptions * Options for creating a new file; - * + * * EaBuffer [OPTIONAL] * Undocumented; - * + * * EaLength * Undocumented; - * + * * CreateFileType * Type of file (normal, named pipe, mailslot) to create; - * + * * ExtraCreateParameters [OPTIONAL] * Additional creation data for named pipe and mailsots; - * + * * Options * Undocumented. - * + * * RETURN VALUE * Status * @@ -637,12 +637,12 @@ IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer, * Prototype taken from Bo Branten's ntifs.h v15. * Description taken from old NtCreateFile's which is * now a wrapper of this call. - * + * * REVISIONS - * + * * @implemented */ -NTSTATUS +NTSTATUS STDCALL IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, @@ -670,12 +670,12 @@ IoCreateFile(OUT PHANDLE FileHandle, LARGE_INTEGER SafeAllocationSize; PVOID SystemEaBuffer = NULL; NTSTATUS Status = STATUS_SUCCESS; - + DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, " "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n", FileHandle,DesiredAccess,ObjectAttributes, ObjectAttributes->ObjectName->Buffer); - + ASSERT_IRQL(PASSIVE_LEVEL); if (IoStatusBlock == NULL || FileHandle == NULL) @@ -687,7 +687,7 @@ IoCreateFile(OUT PHANDLE FileHandle, AccessMode = KernelMode; else AccessMode = ExGetPreviousMode(); - + if(AccessMode != KernelMode) { _SEH_TRY @@ -733,7 +733,7 @@ IoCreateFile(OUT PHANDLE FileHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - + if(!NT_SUCCESS(Status)) { return Status; @@ -775,7 +775,7 @@ IoCreateFile(OUT PHANDLE FileHandle, AccessMode, (PVOID*)&DeviceObject, NULL); - ZwClose(LocalHandle); + ZwClose(LocalHandle); if (!NT_SUCCESS(Status)) { return Status; @@ -808,9 +808,9 @@ IoCreateFile(OUT PHANDLE FileHandle, return Status; } } - RtlMapGenericMask(&DesiredAccess, + RtlMapGenericMask(&DesiredAccess, BODY_TO_HEADER(FileObject)->ObjectType->Mapping); - + Status = ObInsertObject ((PVOID)FileObject, NULL, DesiredAccess, @@ -840,10 +840,10 @@ IoCreateFile(OUT PHANDLE FileHandle, SecurityContext.AccessState = NULL; /* ?? */ SecurityContext.DesiredAccess = DesiredAccess; SecurityContext.FullCreateOptions = 0; /* ?? */ - + KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE); KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE); - + DPRINT("FileObject %x\n", FileObject); DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject); /* @@ -867,7 +867,7 @@ IoCreateFile(OUT PHANDLE FileHandle, Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->UserEvent = &FileObject->Event; Irp->Overlay.AllocationSize = SafeAllocationSize; - + /* * Get the stack location for the new * IRP and prepare it. @@ -891,7 +891,7 @@ IoCreateFile(OUT PHANDLE FileHandle, StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess; StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0; break; - + case CreateFileTypeNamedPipe: StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE; StackLoc->Parameters.CreatePipe.SecurityContext = &SecurityContext; @@ -919,7 +919,7 @@ IoCreateFile(OUT PHANDLE FileHandle, */ Status = IofCallDriver(FileObject->DeviceObject, Irp ); DPRINT("Status :%x\n", Status); - + if (Status == STATUS_PENDING) { KeWaitForSingleObject(&FileObject->Event, @@ -992,25 +992,25 @@ IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle, /* * NAME EXPORTED * IoCreateStreamFileObject@8 - * + * * DESCRIPTION - * + * * ARGUMENTS * FileObject * ? - * + * * DeviceObject * ? - * + * * RETURN VALUE * * NOTE - * + * * REVISIONS - * + * * @implemented */ -PFILE_OBJECT +PFILE_OBJECT STDCALL IoCreateStreamFileObject(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) @@ -1046,14 +1046,14 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject, DPRINT("DeviceObject %x\n", DeviceObject); - if (DeviceObject->Vpb && + if (DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject) { CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject; } else { - CreatedFileObject->DeviceObject = DeviceObject; + CreatedFileObject->DeviceObject = DeviceObject; } CreatedFileObject->Vpb = DeviceObject->Vpb; CreatedFileObject->Type = IO_TYPE_FILE; @@ -1093,7 +1093,7 @@ IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, /* * @implemented */ -PGENERIC_MAPPING +PGENERIC_MAPPING STDCALL IoGetFileObjectGenericMapping(VOID) { @@ -1126,7 +1126,7 @@ IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject, /* * @implemented */ -NTSTATUS +NTSTATUS STDCALL IoQueryFileInformation(IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, @@ -1141,20 +1141,20 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject, BOOLEAN LocalEvent = FALSE; KEVENT Event; NTSTATUS Status; - + ASSERT(FileInformation != NULL); - + Status = ObReferenceObjectByPointer(FileObject, FILE_READ_ATTRIBUTES, IoFileObjectType, KernelMode); if (!NT_SUCCESS(Status)) return(Status); - + DPRINT("FileObject %x\n", FileObject); - + /* Get the Device Object */ DeviceObject = IoGetRelatedDeviceObject(FileObject); - + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -1167,10 +1167,10 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject, KeInitializeEvent(&Event, SynchronizationEvent, FALSE); LocalEvent = TRUE; } - + /* Allocate the IRP */ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - + /* Set the IRP */ Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->RequestorMode = KernelMode; @@ -1179,42 +1179,42 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject, Irp->UserEvent = (LocalEvent) ? &Event : NULL; Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - + /* Set the Stack Data */ StackPtr = IoGetNextIrpStackLocation(Irp); - StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION; + StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION; StackPtr->FileObject = FileObject; - + /* Set Parameters */ StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryFile.Length = Length; - + /* Call the Driver */ Status = IoCallDriver(FileObject->DeviceObject, Irp); - + if (Status == STATUS_PENDING) { if (LocalEvent) { - KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FileObject->Flags & FO_ALERTABLE_IO, + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = IoStatusBlock.Status; } else { KeWaitForSingleObject(&FileObject->Event, - Executive, - KernelMode, - FileObject->Flags & FO_ALERTABLE_IO, + Executive, + KernelMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = FileObject->FinalStatus; } } - - + + /* Return the Length and Status. ReturnedLength is NOT optional */ *ReturnedLength = IoStatusBlock.Information; return Status; @@ -1235,7 +1235,7 @@ IoSetFileOrigin(IN PFILE_OBJECT FileObject, /** * @name NtCancelIoFile * - * Cancel all pending I/O operations in the current thread for specified + * Cancel all pending I/O operations in the current thread for specified * file object. * * @param FileHandle @@ -1249,7 +1249,7 @@ IoSetFileOrigin(IN PFILE_OBJECT FileObject, * * @implemented */ -NTSTATUS +NTSTATUS STDCALL NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock) @@ -1293,7 +1293,7 @@ NtCancelIoFile(IN HANDLE FileHandle, /* Don't break here, we want to cancel all IRPs for the file object. */ OurIrpsInList = TRUE; } - } + } KfLowerIrql(OldIrql); @@ -1349,14 +1349,14 @@ NtCancelIoFile(IN HANDLE FileHandle, /* * NAME EXPORTED * NtCreateFile@44 - * + * * DESCRIPTION * Entry point to call IoCreateFile with * default parameters. * * ARGUMENTS * See IoCreateFile. - * + * * RETURN VALUE * See IoCreateFile. * @@ -1366,7 +1366,7 @@ NtCancelIoFile(IN HANDLE FileHandle, * * @implemented */ -NTSTATUS +NTSTATUS STDCALL NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, @@ -1409,14 +1409,14 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle, IN PLARGE_INTEGER TimeOut) { MAILSLOT_CREATE_PARAMETERS Buffer; - + DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, " "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n", FileHandle,DesiredAccess,ObjectAttributes, ObjectAttributes->ObjectName->Buffer); - + ASSERT_IRQL(PASSIVE_LEVEL); - + if (TimeOut != NULL) { Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart; @@ -1506,9 +1506,9 @@ NtCreateNamedPipeFile(PHANDLE FileHandle, /* * NAME EXPORTED * NtDeleteFile@4 - * + * * DESCRIPTION - * + * * ARGUMENTS * ObjectAttributes * ? @@ -1516,10 +1516,10 @@ NtCreateNamedPipeFile(PHANDLE FileHandle, * RETURN VALUE * * REVISIONS - * + * * @unimplemented */ -NTSTATUS +NTSTATUS STDCALL NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes) { @@ -1539,10 +1539,10 @@ NtFlushWriteBuffer(VOID) * FUNCTION: Flushes cached file data to disk * ARGUMENTS: * FileHandle = Points to the file - * IoStatusBlock = Caller must supply storage to receive the result of + * IoStatusBlock = Caller must supply storage to receive the result of * the flush buffers operation. The information field is * set to number of bytes flushed to disk. - * RETURNS: Status + * RETURNS: Status * REMARKS: This function maps to the win32 FlushFileBuffers */ NTSTATUS @@ -1577,7 +1577,7 @@ NtFlushBuffersFile(IN HANDLE FileHandle, { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -1597,7 +1597,7 @@ NtFlushBuffersFile(IN HANDLE FileHandle, ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } - + /* Set up the IRP */ Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0; Irp->RequestorMode = PreviousMode; @@ -1610,26 +1610,26 @@ NtFlushBuffersFile(IN HANDLE FileHandle, StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_FLUSH_BUFFERS; StackPtr->FileObject = FileObject; - + /* Call the Driver */ Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { if (LocalEvent) { - KeWaitForSingleObject(&Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + KeWaitForSingleObject(&Event, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = IoStatusBlock->Status; } else { KeWaitForSingleObject(&FileObject->Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = FileObject->FinalStatus; } @@ -1645,9 +1645,9 @@ NtFlushBuffersFile(IN HANDLE FileHandle, NTSTATUS STDCALL NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG BufferSize, @@ -1660,13 +1660,13 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, PIO_STACK_LOCATION IoStack; KPROCESSOR_MODE PreviousMode; NTSTATUS Status = STATUS_SUCCESS; - + DPRINT("NtNotifyChangeDirectoryFile()\n"); - + PAGED_CODE(); PreviousMode = ExGetPreviousMode(); - + if(PreviousMode != KernelMode) { _SEH_TRY @@ -1686,7 +1686,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - + if(!NT_SUCCESS(Status)) { return Status; @@ -1700,18 +1700,18 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, (PVOID *)&FileObject, NULL); if (Status != STATUS_SUCCESS) return(Status); - - + + DeviceObject = FileObject->DeviceObject; - - + + Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp==NULL) { ObDereferenceObject(FileObject); return STATUS_UNSUCCESSFUL; } - + if (Event == NULL) { Event = &FileObject->Event; @@ -1727,16 +1727,16 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, Irp->UserBuffer = Buffer; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; - + IoStack = IoGetNextIrpStackLocation(Irp); - + IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY; IoStack->Flags = 0; IoStack->Control = 0; IoStack->DeviceObject = DeviceObject; IoStack->FileObject = FileObject; - + if (WatchTree) { IoStack->Flags = SL_WATCH_TREE; @@ -1744,7 +1744,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter; IoStack->Parameters.NotifyDirectory.Length = BufferSize; - + Status = IoCallDriver(FileObject->DeviceObject,Irp); /* FIXME: Should we wait here or not for synchronously opened files? */ @@ -1915,39 +1915,39 @@ fail:; /* * NAME EXPORTED * NtOpenFile@24 - * + * * DESCRIPTION * Opens an existing file (simpler than NtCreateFile). * * ARGUMENTS * FileHandle (OUT) * Variable that receives the file handle on return; - * + * * DesiredAccess * Access desired by the caller to the file; - * + * * ObjectAttributes * Structue describing the file to be opened; - * + * * IoStatusBlock (OUT) * Receives details about the result of the * operation; - * + * * ShareAccess * Type of shared access the caller requires; - * + * * OpenOptions * Options for the file open. * * RETURN VALUE * Status. - * + * * NOTE * Undocumented. * * @implemented */ -NTSTATUS +NTSTATUS STDCALL NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, @@ -1973,7 +1973,7 @@ NtOpenFile(PHANDLE FileHandle, 0); } -NTSTATUS +NTSTATUS STDCALL NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation) @@ -2028,10 +2028,10 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION * * Length = Size of the storage supplied - * FileInformationClass = Indicates the type of information requested. - * ReturnSingleEntry = Specify true if caller only requests the first + * FileInformationClass = Indicates the type of information requested. + * ReturnSingleEntry = Specify true if caller only requests the first * directory found. - * FileName = Initial directory name to query, that may contain wild + * FileName = Initial directory name to query, that may contain wild * cards. * RestartScan = Number of times the action should be repeated * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES, @@ -2039,7 +2039,7 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ] */ NTSTATUS -STDCALL +STDCALL NtQueryDirectoryFile(IN HANDLE FileHandle, IN HANDLE PEvent OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, @@ -2060,10 +2060,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, NTSTATUS Status = STATUS_SUCCESS; BOOLEAN LocalEvent = FALSE; PKEVENT Event = NULL; - + DPRINT("NtQueryDirectoryFile()\n"); PAGED_CODE(); - + /* Validate User-Mode Buffers */ if(PreviousMode != KernelMode) { @@ -2093,7 +2093,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, (PVOID *)&FileObject, NULL); if (Status != STATUS_SUCCESS) return(Status); - + /* Get Event Object */ if (PEvent) { @@ -2116,7 +2116,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -2127,14 +2127,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, { LocalEvent = TRUE; } - + /* Allocate the IRP */ if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE))) { ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } - + /* Set up the IRP */ Irp->RequestorMode = PreviousMode; Irp->UserIosb = IoStatusBlock; @@ -2144,13 +2144,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, Irp->UserBuffer = FileInformation; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; - + /* Set up Stack Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; StackPtr->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; StackPtr->MinorFunction = IRP_MN_QUERY_DIRECTORY; - + /* Set Parameters */ StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryDirectory.FileName = FileName; @@ -2159,7 +2159,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, StackPtr->Flags = 0; if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN; if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY; - + /* Call the Driver */ Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) @@ -2167,9 +2167,9 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, if (!LocalEvent) { KeWaitForSingleObject(&FileObject->Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = FileObject->FinalStatus; } @@ -2197,7 +2197,7 @@ NtQueryEaFile(IN HANDLE FileHandle, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS +NTSTATUS STDCALL NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation) @@ -2302,7 +2302,7 @@ NtQueryInformationFile(HANDLE FileHandle, } DPRINT("FileObject %x\n", FileObject); - + /* Check if this is a direct open or not */ if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) { @@ -2312,7 +2312,7 @@ NtQueryInformationFile(HANDLE FileHandle, { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -2332,10 +2332,10 @@ NtQueryInformationFile(HANDLE FileHandle, ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } - + /* Allocate the System Buffer */ - if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, - Length, + if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, + Length, TAG_SYSB))) { IoFreeIrp(Irp); @@ -2352,7 +2352,7 @@ NtQueryInformationFile(HANDLE FileHandle, Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_INPUT_OPERATION; Irp->Flags |= (LocalEvent) ? IRP_SYNCHRONOUS_API : 0; - + /* Set up Stack Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION; @@ -2361,26 +2361,26 @@ NtQueryInformationFile(HANDLE FileHandle, /* Set the Parameters */ StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryFile.Length = Length; - + /* Call the Driver */ Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { if (LocalEvent) { - KeWaitForSingleObject(&Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + KeWaitForSingleObject(&Event, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = IoStatusBlock->Status; } else { KeWaitForSingleObject(&FileObject->Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = FileObject->FinalStatus; } @@ -2423,7 +2423,7 @@ NtQueryQuotaInformationFile(IN HANDLE FileHandle, * * @implemented */ -NTSTATUS +NTSTATUS STDCALL NtReadFile(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -2448,7 +2448,7 @@ NtReadFile(IN HANDLE FileHandle, "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, IoStatusBlock); PAGED_CODE(); - + /* Validate User-Mode Buffers */ if(PreviousMode != KernelMode) { @@ -2461,7 +2461,7 @@ NtReadFile(IN HANDLE FileHandle, ProbeForWrite(Buffer, Length, sizeof(ULONG)); - #endif + #endif } _SEH_HANDLE { @@ -2480,9 +2480,9 @@ NtReadFile(IN HANDLE FileHandle, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) return Status; - + /* Check the Byte Offset */ - if (!ByteOffset || + if (!ByteOffset || (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION && ByteOffset->u.HighPart == 0xffffffff)) { @@ -2525,7 +2525,7 @@ NtReadFile(IN HANDLE FileHandle, { DeviceObject = IoGetRelatedDeviceObject(FileObject); } - + /* Check if we should use Sync IO or not */ if (FileObject->Flags & FO_SYNCHRONOUS_IO) { @@ -2536,7 +2536,7 @@ NtReadFile(IN HANDLE FileHandle, { LocalEvent = TRUE; } - + /* Create the IRP */ _SEH_TRY { @@ -2573,7 +2573,7 @@ NtReadFile(IN HANDLE FileHandle, Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Flags |= IRP_READ_OPERATION; if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE; - + /* Setup Stack Data */ StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; @@ -2586,9 +2586,9 @@ NtReadFile(IN HANDLE FileHandle, if (!LocalEvent) { KeWaitForSingleObject(&FileObject->Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, NULL); Status = FileObject->FinalStatus; } @@ -2601,7 +2601,7 @@ NtReadFile(IN HANDLE FileHandle, /* * NAME EXPORTED * NtReadFileScatter - * + * * DESCRIPTION * * ARGUMENTS @@ -2629,7 +2629,7 @@ NtReadFileScatter(IN HANDLE FileHandle, /* * @unimplemented */ -NTSTATUS +NTSTATUS STDCALL NtSetEaFile(IN HANDLE FileHandle, IN PIO_STATUS_BLOCK IoStatusBlock, @@ -2820,7 +2820,7 @@ NtSetInformationFile(HANDLE FileHandle, /* * @unimplemented */ -NTSTATUS +NTSTATUS STDCALL NtSetQuotaInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, @@ -2945,7 +2945,7 @@ fail:; * * @implemented */ -NTSTATUS +NTSTATUS STDCALL NtWriteFile (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -2957,158 +2957,200 @@ NtWriteFile (IN HANDLE FileHandle, IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */ IN PULONG Key OPTIONAL) { - OBJECT_HANDLE_INFORMATION HandleInformation; - NTSTATUS Status; - PFILE_OBJECT FileObject; - PIRP Irp = NULL; - PIO_STACK_LOCATION StackPtr; - KPROCESSOR_MODE PreviousMode; - PKEVENT EventObject = NULL; - LARGE_INTEGER Offset; + OBJECT_HANDLE_INFORMATION HandleInformation; + NTSTATUS Status = STATUS_SUCCESS; + PFILE_OBJECT FileObject; + PIRP Irp = NULL; + PDEVICE_OBJECT DeviceObject; + PIO_STACK_LOCATION StackPtr; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + BOOLEAN LocalEvent = FALSE; + PKEVENT EventObject = NULL; - DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " - "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, - IoStatusBlock); - - if (IoStatusBlock == NULL) - return STATUS_ACCESS_VIOLATION; - - PreviousMode = ExGetPreviousMode(); - - Status = ObReferenceObjectByHandle(FileHandle, - 0, - IoFileObjectType, - PreviousMode, - (PVOID*)&FileObject, - &HandleInformation); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */ - if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA))) - { - DPRINT1("Invalid access rights\n"); - ObDereferenceObject(FileObject); - return STATUS_ACCESS_DENIED; - } - - if (HandleInformation.GrantedAccess & FILE_WRITE_DATA) - { - if (ByteOffset == NULL) - { - /* a valid ByteOffset is required if asynch. op. */ - if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) - { - DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n"); - ObDereferenceObject(FileObject); - return STATUS_INVALID_PARAMETER; - } - - ByteOffset = &FileObject->CurrentByteOffset; - } - } - else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA) - { - /* a valid ByteOffset is required if asynch. op. */ - if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) - { - DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n"); - ObDereferenceObject(FileObject); - return STATUS_INVALID_PARAMETER; - } - - Offset.u.LowPart = FILE_WRITE_TO_END_OF_FILE; - Offset.u.HighPart = 0xffffffff; - ByteOffset = &Offset; - } - - if (Event != NULL) - { - Status = ObReferenceObjectByHandle(Event, - SYNCHRONIZE, - ExEventObjectType, - PreviousMode, - (PVOID*)&EventObject, - NULL); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - return Status; - } - - KeClearEvent(EventObject); - } - - _SEH_TRY - { - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, - FileObject->DeviceObject, - Buffer, - Length, - ByteOffset, - EventObject, + DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " + "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, IoStatusBlock); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - if (!NT_SUCCESS(Status) || Irp == NULL) - { - if (Event) - { - ObDereferenceObject(&EventObject); - } - ObDereferenceObject(FileObject); - if (Irp) - { - IoFreeIrp(Irp); - } - return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status; - } - - KeClearEvent(&FileObject->Event); - - /* Trigger FileObject/Event dereferencing */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; - - Irp->RequestorMode = PreviousMode; - - Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; - Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; - - StackPtr = IoGetNextIrpStackLocation(Irp); - StackPtr->FileObject = FileObject; - StackPtr->Parameters.Write.Key = Key ? *Key : 0; - - Status = IoCallDriver(FileObject->DeviceObject, Irp); - if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) - { - Status = KeWaitForSingleObject(&FileObject->Event, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, - NULL); - if (Status != STATUS_WAIT_0) + /* Validate User-Mode Buffers */ + if(PreviousMode != KernelMode) { - /* Wait failed. */ - return Status; + _SEH_TRY + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + #if 0 + ProbeForRead(Buffer, + Length, + sizeof(ULONG)); + #endif + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) return Status; } - Status = IoStatusBlock->Status; - } + /* Get File Object */ + Status = ObReferenceObjectByHandle(FileHandle, + 0, + IoFileObjectType, + PreviousMode, + (PVOID*)&FileObject, + &HandleInformation); + if (!NT_SUCCESS(Status)) return Status; - return Status; + /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */ + if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA))) + { + DPRINT1("Invalid access rights\n"); + ObDereferenceObject(FileObject); + return STATUS_ACCESS_DENIED; + } + + /* Check if we got write Access */ + if (HandleInformation.GrantedAccess & FILE_WRITE_DATA) + { + /* Check the Byte Offset */ + if (!ByteOffset || + (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION && + ByteOffset->u.HighPart == 0xffffffff)) + { + /* a valid ByteOffset is required if asynch. op. */ + if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) + { + DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n"); + ObDereferenceObject(FileObject); + return STATUS_INVALID_PARAMETER; + } + + /* Use the Current Byte OFfset */ + ByteOffset = &FileObject->CurrentByteOffset; + } + } + else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA) + { + /* a valid ByteOffset is required if asynch. op. */ + if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) + { + DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n"); + ObDereferenceObject(FileObject); + return STATUS_INVALID_PARAMETER; + } + + /* Give the drivers somethign to understand */ + ByteOffset->u.LowPart = FILE_WRITE_TO_END_OF_FILE; + ByteOffset->u.HighPart = 0xffffffff; + } + + /* Check if we got an event */ + if (Event) + { + /* Reference it */ + Status = ObReferenceObjectByHandle(Event, + EVENT_MODIFY_STATE, + ExEventObjectType, + PreviousMode, + (PVOID*)&EventObject, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + return Status; + } + KeClearEvent(EventObject); + } + + /* Check if this is a direct open or not */ + if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) + { + DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject); + } + else + { + DeviceObject = IoGetRelatedDeviceObject(FileObject); + } + + /* Check if we should use Sync IO or not */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Use File Object event */ + KeClearEvent(&FileObject->Event); + } + else + { + LocalEvent = TRUE; + } + + /* Build the IRP */ + _SEH_TRY + { + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, + FileObject->DeviceObject, + Buffer, + Length, + ByteOffset, + EventObject, + IoStatusBlock); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + /* Cleanup on failure */ + if (!NT_SUCCESS(Status) || !Irp) + { + if (Event) + { + ObDereferenceObject(&EventObject); + } + ObDereferenceObject(FileObject); + if (Irp) IoFreeIrp(Irp); + return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status; + } + + /* Set up IRP Data */ + Irp->Tail.Overlay.OriginalFileObject = FileObject; + Irp->RequestorMode = PreviousMode; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; + Irp->Flags |= IRP_WRITE_OPERATION; + if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE; + + /* Setup Stack Data */ + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + StackPtr->Parameters.Write.Key = Key ? *Key : 0; + if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH; + + /* Call the Driver */ + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + if (!LocalEvent) + { + KeWaitForSingleObject(&FileObject->Event, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, + NULL); + Status = FileObject->FinalStatus; + } + } + + /* Return the Status */ + return Status; } /* * NAME EXPORTED * NtWriteFileGather - * + * * DESCRIPTION * * ARGUMENTS