mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
NtWriteFile must append to file if it was opened with the FILE_APPEND_DATA access.
FILE_WRITE_DATA take precedence over FILE_APPEND_DATA. svn path=/trunk/; revision=11101
This commit is contained in:
parent
3d82d976d3
commit
d394870def
1 changed files with 74 additions and 48 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: rw.c,v 1.54 2004/08/15 16:39:03 chorns Exp $
|
/* $Id: rw.c,v 1.55 2004/09/28 10:51:05 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -66,10 +66,10 @@ NtReadFile (IN HANDLE FileHandle,
|
||||||
(PVOID*)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ByteOffset == NULL)
|
if (ByteOffset == NULL)
|
||||||
{
|
{
|
||||||
/* a valid ByteOffset is required if asynch. op. */
|
/* a valid ByteOffset is required if asynch. op. */
|
||||||
|
@ -85,17 +85,18 @@ NtReadFile (IN HANDLE FileHandle,
|
||||||
|
|
||||||
if (Event != NULL)
|
if (Event != NULL)
|
||||||
{
|
{
|
||||||
Status = ObReferenceObjectByHandle(Event,
|
Status = ObReferenceObjectByHandle(Event,
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
ExEventObjectType,
|
ExEventObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&EventObject,
|
(PVOID*)&EventObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeClearEvent(EventObject);
|
KeClearEvent(EventObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,16 +125,15 @@ NtReadFile (IN HANDLE FileHandle,
|
||||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||||
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
{
|
{
|
||||||
Status = KeWaitForSingleObject (&FileObject->Event,
|
Status = KeWaitForSingleObject(&FileObject->Event,
|
||||||
Executive,
|
Executive,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
FileObject->Flags & FO_ALERTABLE_IO,
|
FileObject->Flags & FO_ALERTABLE_IO,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (Status != STATUS_WAIT_0)
|
if (Status != STATUS_WAIT_0)
|
||||||
{
|
{
|
||||||
/* Wait failed. */
|
/* Wait failed. */
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IoStatusBlock->Status;
|
Status = IoStatusBlock->Status;
|
||||||
|
@ -168,12 +168,14 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
|
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
|
||||||
IN PULONG Key OPTIONAL)
|
IN PULONG Key OPTIONAL)
|
||||||
{
|
{
|
||||||
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
PKEVENT EventObject = NULL;
|
PKEVENT EventObject = NULL;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
|
||||||
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
|
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
|
||||||
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
|
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
|
||||||
|
@ -185,17 +187,40 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
PreviousMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_WRITE_DATA,
|
0,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
&HandleInformation);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ByteOffset == NULL)
|
/* 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. */
|
/* a valid ByteOffset is required if asynch. op. */
|
||||||
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
|
@ -205,27 +230,28 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteOffset = &FileObject->CurrentByteOffset;
|
Offset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
|
||||||
|
Offset.u.HighPart = 0xffffffff;
|
||||||
|
ByteOffset = &Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Event != NULL)
|
if (Event != NULL)
|
||||||
{
|
{
|
||||||
Status = ObReferenceObjectByHandle(Event,
|
Status = ObReferenceObjectByHandle(Event,
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
ExEventObjectType,
|
ExEventObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&EventObject,
|
(PVOID*)&EventObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeClearEvent(EventObject);
|
KeClearEvent(EventObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeClearEvent(&FileObject->Event);
|
KeClearEvent(&FileObject->Event);
|
||||||
|
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
||||||
|
@ -250,21 +276,21 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
|
|
||||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||||
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
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)
|
||||||
{
|
{
|
||||||
Status = KeWaitForSingleObject (&FileObject->Event,
|
/* Wait failed. */
|
||||||
Executive,
|
return Status;
|
||||||
PreviousMode,
|
|
||||||
FileObject->Flags & FO_ALERTABLE_IO,
|
|
||||||
NULL);
|
|
||||||
if (Status != STATUS_WAIT_0)
|
|
||||||
{
|
|
||||||
/* Wait failed. */
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoStatusBlock->Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = IoStatusBlock->Status;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue