mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Reply 38790, with fix for npfsPeekPipe which was breaking rosautotests.
svn path=/trunk/; revision=38797
This commit is contained in:
parent
1ae5ee225a
commit
9ae3084028
4 changed files with 178 additions and 117 deletions
|
@ -373,9 +373,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
||||||
return STATUS_INSTANCE_NOT_AVAILABLE;
|
return STATUS_INSTANCE_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Check pipe modes also! */
|
|
||||||
if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
|
if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
|
||||||
Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart)
|
Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart ||
|
||||||
|
Fcb->PipeType != Buffer->NamedPipeType)
|
||||||
{
|
{
|
||||||
DPRINT("Asked for invalid pipe mode.\n");
|
DPRINT("Asked for invalid pipe mode.\n");
|
||||||
ExFreePool(Ccb);
|
ExFreePool(Ccb);
|
||||||
|
@ -420,8 +420,11 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
||||||
KeInitializeMutex(&Fcb->CcbListLock, 0);
|
KeInitializeMutex(&Fcb->CcbListLock, 0);
|
||||||
|
|
||||||
Fcb->PipeType = Buffer->NamedPipeType;
|
Fcb->PipeType = Buffer->NamedPipeType;
|
||||||
Fcb->WriteMode = Buffer->ReadMode;
|
/* FIXME: Verify which is correct */
|
||||||
Fcb->ReadMode = Buffer->ReadMode;
|
Fcb->WriteMode = Buffer->ReadMode;//Buffer->NamedPipeType;
|
||||||
|
/* MSDN documentation reads that clients always start off in byte mode */
|
||||||
|
Fcb->ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
|
||||||
|
|
||||||
Fcb->CompletionMode = Buffer->CompletionMode;
|
Fcb->CompletionMode = Buffer->CompletionMode;
|
||||||
switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
|
switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
|
||||||
{
|
{
|
||||||
|
@ -737,6 +740,10 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
|
||||||
DPRINT("Client\n");
|
DPRINT("Client\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disconnect the pipes */
|
||||||
|
if (Ccb->OtherSide) Ccb->OtherSide->OtherSide = NULL;
|
||||||
|
if (Ccb) Ccb->OtherSide = NULL;
|
||||||
|
|
||||||
ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);
|
ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);
|
||||||
|
|
||||||
FileObject->FsContext2 = NULL;
|
FileObject->FsContext2 = NULL;
|
||||||
|
|
|
@ -30,6 +30,12 @@ NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
Fcb = Ccb->Fcb;
|
Fcb = Ccb->Fcb;
|
||||||
Request = (PFILE_PIPE_INFORMATION)Info;
|
Request = (PFILE_PIPE_INFORMATION)Info;
|
||||||
|
|
||||||
|
if ((Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Request->ReadMode == FILE_PIPE_MESSAGE_MODE))
|
||||||
|
{
|
||||||
|
DPRINT("Cannot change readmode to message type on a byte type pipe!\n");
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set Pipe Data */
|
/* Set Pipe Data */
|
||||||
Fcb->ReadMode = Request->ReadMode;
|
Fcb->ReadMode = Request->ReadMode;
|
||||||
Fcb->CompletionMode = Request->CompletionMode;
|
Fcb->CompletionMode = Request->CompletionMode;
|
||||||
|
|
|
@ -202,7 +202,7 @@ NpfsDisconnectPipe(PNPFS_CCB Ccb)
|
||||||
{
|
{
|
||||||
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
|
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
|
||||||
OtherSide = Ccb->OtherSide;
|
OtherSide = Ccb->OtherSide;
|
||||||
Ccb->OtherSide = NULL;
|
//Ccb->OtherSide = NULL;
|
||||||
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||||
/* Lock the server first */
|
/* Lock the server first */
|
||||||
if (Server)
|
if (Server)
|
||||||
|
@ -216,7 +216,7 @@ NpfsDisconnectPipe(PNPFS_CCB Ccb)
|
||||||
ExAcquireFastMutex(&Ccb->DataListLock);
|
ExAcquireFastMutex(&Ccb->DataListLock);
|
||||||
}
|
}
|
||||||
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||||
OtherSide->OtherSide = NULL;
|
//OtherSide->OtherSide = NULL;
|
||||||
/*
|
/*
|
||||||
* Signaling the write event. If is possible that an other
|
* Signaling the write event. If is possible that an other
|
||||||
* thread waits for an empty buffer.
|
* thread waits for an empty buffer.
|
||||||
|
@ -365,6 +365,7 @@ NpfsPeekPipe(PIRP Irp,
|
||||||
PIO_STACK_LOCATION IoStack)
|
PIO_STACK_LOCATION IoStack)
|
||||||
{
|
{
|
||||||
ULONG OutputBufferLength;
|
ULONG OutputBufferLength;
|
||||||
|
ULONG ReturnLength = 0;
|
||||||
PFILE_PIPE_PEEK_BUFFER Reply;
|
PFILE_PIPE_PEEK_BUFFER Reply;
|
||||||
PNPFS_FCB Fcb;
|
PNPFS_FCB Fcb;
|
||||||
PNPFS_CCB Ccb;
|
PNPFS_CCB Ccb;
|
||||||
|
@ -396,11 +397,21 @@ NpfsPeekPipe(PIRP Irp,
|
||||||
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
|
Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
|
||||||
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
|
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
|
||||||
|
|
||||||
if (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
ExAcquireFastMutex(&Ccb->DataListLock);
|
||||||
|
BufferPtr = Ccb->Data;
|
||||||
|
DPRINT("BufferPtr = %x\n", BufferPtr);
|
||||||
|
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT("Byte Stream Mode\n");
|
DPRINT("Byte Stream Mode\n");
|
||||||
Reply->MessageLength = Ccb->ReadDataAvailable;
|
Reply->MessageLength = Ccb->ReadDataAvailable;
|
||||||
DPRINT("Reply->MessageLength %d\n",Reply->MessageLength );
|
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength );
|
||||||
|
MessageCount = 1;
|
||||||
|
|
||||||
|
if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
|
||||||
|
{
|
||||||
|
ReturnLength = Ccb->ReadDataAvailable;
|
||||||
|
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -410,7 +421,7 @@ NpfsPeekPipe(PIRP Irp,
|
||||||
if (ReadDataAvailable > 0)
|
if (ReadDataAvailable > 0)
|
||||||
{
|
{
|
||||||
memcpy(&Reply->MessageLength,Ccb->Data,sizeof(ULONG));
|
memcpy(&Reply->MessageLength,Ccb->Data,sizeof(ULONG));
|
||||||
BufferPtr = Ccb->Data;
|
|
||||||
/* NOTE: Modifying the structure in header file to keep track of NumberOfMessage would be better */
|
/* NOTE: Modifying the structure in header file to keep track of NumberOfMessage would be better */
|
||||||
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
|
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
|
||||||
{
|
{
|
||||||
|
@ -418,34 +429,38 @@ NpfsPeekPipe(PIRP Irp,
|
||||||
|
|
||||||
ASSERT(MessageLength > 0);
|
ASSERT(MessageLength > 0);
|
||||||
|
|
||||||
DPRINT("MessageLength = %d\n",MessageLength);
|
DPRINT("MessageLength = %lu\n",MessageLength);
|
||||||
MessageCount++;
|
MessageCount++;
|
||||||
ReadDataAvailable -= MessageLength;
|
ReadDataAvailable -= MessageLength;
|
||||||
|
|
||||||
/* If its the first message, copy the Message if the size of buffer is large enough */
|
/* If its the first message, copy the Message if the size of buffer is large enough */
|
||||||
if ((MessageCount==1) && (Reply->Data[0])
|
if (MessageCount==1)
|
||||||
&& (OutputBufferLength >= (sizeof(FILE_PIPE_PEEK_BUFFER) + MessageLength)))
|
|
||||||
{
|
{
|
||||||
memcpy(&Reply->Data[0], (PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
|
|
||||||
|
if ((Reply->Data[0])
|
||||||
|
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
|
||||||
|
{
|
||||||
|
ReturnLength = MessageLength;
|
||||||
|
memcpy(&Reply->Data[0], (PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BufferPtr =(PVOID)((ULONG)BufferPtr + MessageLength + sizeof(MessageLength));
|
BufferPtr =(PVOID)((ULONG)BufferPtr + MessageLength + sizeof(MessageLength));
|
||||||
DPRINT("Message %d\n",MessageCount);
|
DPRINT("BufferPtr = %x\n", BufferPtr);
|
||||||
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
|
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadDataAvailable != 0)
|
if (ReadDataAvailable != 0)
|
||||||
{
|
{
|
||||||
DPRINT1("This should never happen! Possible memory corruption.\n");
|
DPRINT1("Possible memory corruption.\n");
|
||||||
return STATUS_UNSUCCESSFUL;
|
ASSERT(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExReleaseFastMutex(&Ccb->DataListLock);
|
||||||
|
|
||||||
Reply->NumberOfMessages = MessageCount;
|
Reply->NumberOfMessages = MessageCount;
|
||||||
if (MessageCount > 0)
|
|
||||||
Reply->Data[0] = 0;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = OutputBufferLength;
|
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
VOID HexDump(PUCHAR Buffer, ULONG Length)
|
VOID HexDump(PUCHAR Buffer, ULONG Length)
|
||||||
{
|
{
|
||||||
CHAR Line[65];
|
CHAR Line[65];
|
||||||
|
@ -42,7 +41,6 @@ VOID HexDump(PUCHAR Buffer, ULONG Length)
|
||||||
}
|
}
|
||||||
DbgPrint("---------------\n");
|
DbgPrint("---------------\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static DRIVER_CANCEL NpfsReadWriteCancelRoutine;
|
static DRIVER_CANCEL NpfsReadWriteCancelRoutine;
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
|
@ -360,7 +358,6 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Irp->RequestorMode,
|
Irp->RequestorMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
||||||
{
|
{
|
||||||
Status = STATUS_CANCELLED;
|
Status = STATUS_CANCELLED;
|
||||||
|
@ -449,7 +446,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Irp->RequestorMode,
|
Irp->RequestorMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
DPRINT("Finished waiting (%wZ)! Status: %x\n", &Ccb->Fcb->PipeName, Status);
|
DPRINT("Finished waiting (%wZ)! Status: %x\n", &Ccb->Fcb->PipeName, Status);
|
||||||
|
|
||||||
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
||||||
{
|
{
|
||||||
|
@ -480,9 +477,11 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
|
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
|
||||||
if (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
|
||||||
|
/* If the pipe type and read mode are both byte stream */
|
||||||
|
if ((Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE))
|
||||||
{
|
{
|
||||||
DPRINT("Byte stream mode\n");
|
DPRINT("Byte stream mode: Ccb->Data %x\n", Ccb->Data);
|
||||||
/* Byte stream mode */
|
/* Byte stream mode */
|
||||||
while (Length > 0 && Ccb->ReadDataAvailable > 0)
|
while (Length > 0 && Ccb->ReadDataAvailable > 0)
|
||||||
{
|
{
|
||||||
|
@ -522,116 +521,136 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Ccb->Fcb->PipeType == FILE_PIPE_MESSAGE_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT("Message mode\n");
|
ULONG ThisCopyLength = 0;
|
||||||
|
ULONG TotalLengthNeeded = min(Length, Ccb->ReadDataAvailable);
|
||||||
|
|
||||||
/* For Message mode, the Message length will be stored in the buffer preceeding the Message. */
|
DPRINT("Message mode: Ccb>Data %x\n", Ccb->Data);
|
||||||
if (Ccb->ReadDataAvailable)
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
ULONG NextMessageLength=0;
|
Buffer = (PVOID)((ULONG_PTR)Buffer + ThisCopyLength);
|
||||||
//HexDump(Ccb->Data, (ULONG)Ccb->WritePtr - (ULONG)Ccb->Data);
|
|
||||||
/*First get the size of the message */
|
/* For Message mode, the Message length will be stored in the buffer preceeding the Message. */
|
||||||
memcpy(&NextMessageLength, Ccb->Data, sizeof(NextMessageLength));
|
if (Ccb->ReadDataAvailable)
|
||||||
if ((NextMessageLength == 0) || (NextMessageLength > Ccb->ReadDataAvailable))
|
|
||||||
{
|
{
|
||||||
DPRINT1("This should never happen! Possible memory corruption.\n");
|
ULONG NextMessageLength = 0;
|
||||||
#ifndef NDEBUG
|
|
||||||
HexDump(Ccb->Data, (ULONG)Ccb->WritePtr - (ULONG)Ccb->Data);
|
|
||||||
#endif
|
|
||||||
ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use the smaller value */
|
/*First get the size of the message */
|
||||||
|
memcpy(&NextMessageLength, Ccb->Data, sizeof(NextMessageLength));
|
||||||
|
|
||||||
CopyLength = min(NextMessageLength, Length);
|
if ((NextMessageLength == 0) || (NextMessageLength > Ccb->ReadDataAvailable))
|
||||||
|
|
||||||
/* retrieve the message from the buffer */
|
|
||||||
memcpy(Buffer, (PVOID)((ULONG)Ccb->Data + sizeof(NextMessageLength)), CopyLength);
|
|
||||||
|
|
||||||
|
|
||||||
if (Ccb->ReadDataAvailable > CopyLength)
|
|
||||||
{
|
|
||||||
if (CopyLength < NextMessageLength)
|
|
||||||
{
|
{
|
||||||
/* Client only requested part of the message */
|
DPRINT("Possible memory corruption.\n");
|
||||||
|
HexDump(Ccb->Data, (ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->Data);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate the remaining message new size */
|
/* Use the smaller value */
|
||||||
ULONG NewMessageSize = NextMessageLength-CopyLength;
|
ThisCopyLength = min(NextMessageLength, Length);
|
||||||
|
|
||||||
/* Write a new Message size to buffer for the part of the message still there */
|
/* retrieve the message from the buffer */
|
||||||
memcpy(Ccb->Data, &NewMessageSize, sizeof(NewMessageSize));
|
memcpy(Buffer, (PVOID)((ULONG_PTR)Ccb->Data + sizeof(NextMessageLength)), ThisCopyLength);
|
||||||
|
|
||||||
/* Move the memory starting from end of partial Message just retrieved */
|
if (Ccb->ReadDataAvailable > ThisCopyLength)
|
||||||
memmove((PVOID)((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)),
|
{
|
||||||
(PVOID)((ULONG_PTR) Ccb->Data + CopyLength + sizeof(NewMessageSize)),
|
if (ThisCopyLength < NextMessageLength)
|
||||||
(ULONG)Ccb->WritePtr - ((ULONG)Ccb->Data + sizeof(NewMessageSize)) - CopyLength);
|
{
|
||||||
|
/* Client only requested part of the message */
|
||||||
|
|
||||||
/* Update the write pointer */
|
/* Calculate the remaining message new size */
|
||||||
Ccb->WritePtr = (PVOID)((ULONG)Ccb->WritePtr - CopyLength);
|
ULONG NewMessageSize = NextMessageLength-ThisCopyLength;
|
||||||
|
|
||||||
/* Add CopyLength only to WriteQuotaAvailable as the
|
/* Write a new Message size to buffer for the part of the message still there */
|
||||||
Message Size was replaced in the buffer */
|
memcpy(Ccb->Data, &NewMessageSize, sizeof(NewMessageSize));
|
||||||
Ccb->WriteQuotaAvailable += CopyLength;
|
|
||||||
|
/* Move the memory starting from end of partial Message just retrieved */
|
||||||
|
memmove((PVOID)((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)),
|
||||||
|
(PVOID)((ULONG_PTR)Ccb->Data + ThisCopyLength + sizeof(NewMessageSize)),
|
||||||
|
(ULONG_PTR)Ccb->WritePtr - ((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)) -
|
||||||
|
ThisCopyLength);
|
||||||
|
|
||||||
|
/* Update the write pointer */
|
||||||
|
Ccb->WritePtr = (PVOID)((ULONG_PTR)Ccb->WritePtr - ThisCopyLength);
|
||||||
|
|
||||||
|
/* Add ThisCopyLength only to WriteQuotaAvailable as the
|
||||||
|
Message Size was replaced in the buffer */
|
||||||
|
Ccb->WriteQuotaAvailable += ThisCopyLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Client wanted the entire message */
|
||||||
|
|
||||||
|
/* Move the memory starting from the next Message just retrieved */
|
||||||
|
memmove(Ccb->Data,
|
||||||
|
(PVOID)((ULONG_PTR) Ccb->Data + NextMessageLength + sizeof(NextMessageLength)),
|
||||||
|
(ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->Data - NextMessageLength -
|
||||||
|
sizeof(NextMessageLength));
|
||||||
|
|
||||||
|
/* Update the write pointer */
|
||||||
|
Ccb->WritePtr = (PVOID)((ULONG_PTR)Ccb->WritePtr - ThisCopyLength -
|
||||||
|
sizeof(NextMessageLength));
|
||||||
|
|
||||||
|
/* Add both the message length and the header to the WriteQuotaAvailable
|
||||||
|
as they both were removed */
|
||||||
|
Ccb->WriteQuotaAvailable += (ThisCopyLength + sizeof(NextMessageLength));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Client wanted the entire message */
|
/* This was the last Message, so just zero this messages for safety sake */
|
||||||
|
memset(Ccb->Data, 0, NextMessageLength + sizeof(NextMessageLength));
|
||||||
|
|
||||||
/* Move the memory starting from the next Message just retrieved */
|
/* reset the write pointer to beginning of buffer */
|
||||||
memmove(Ccb->Data,
|
Ccb->WritePtr = Ccb->Data;
|
||||||
(PVOID)((ULONG_PTR) Ccb->Data + NextMessageLength + sizeof(NextMessageLength)),
|
|
||||||
(ULONG)Ccb->WritePtr - (ULONG)Ccb->Data - NextMessageLength - sizeof(NextMessageLength));
|
|
||||||
|
|
||||||
/* Update the write pointer */
|
|
||||||
Ccb->WritePtr = (PVOID)((ULONG)Ccb->WritePtr - NextMessageLength);
|
|
||||||
|
|
||||||
/* Add both the message length and the header to the WriteQuotaAvailable
|
/* Add both the message length and the header to the WriteQuotaAvailable
|
||||||
as they both were removed */
|
as they both were removed */
|
||||||
Ccb->WriteQuotaAvailable += (CopyLength + sizeof(NextMessageLength));
|
Ccb->WriteQuotaAvailable += (ThisCopyLength + sizeof(ULONG));
|
||||||
|
|
||||||
|
KeResetEvent(&Ccb->ReadEvent);
|
||||||
|
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||||
|
{
|
||||||
|
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This was the last Message, so just zero this messages for safety sake */
|
|
||||||
memset(Ccb->Data,0,NextMessageLength + sizeof(NextMessageLength));
|
|
||||||
|
|
||||||
/* reset the write pointer to beginning of buffer */
|
|
||||||
Ccb->WritePtr = Ccb->Data;
|
|
||||||
|
|
||||||
/* Add both the message length and the header to the WriteQuotaAvailable
|
|
||||||
as they both were removed */
|
|
||||||
Ccb->WriteQuotaAvailable += (CopyLength + sizeof(ULONG));
|
|
||||||
|
|
||||||
KeResetEvent(&Ccb->ReadEvent);
|
|
||||||
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
|
||||||
{
|
|
||||||
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
|
DPRINT("Length %d Buffer %x\n",ThisCopyLength,Buffer);
|
||||||
HexDump((PUCHAR)Buffer, CopyLength);
|
HexDump((PUCHAR)Buffer, ThisCopyLength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Information += CopyLength;
|
Information += ThisCopyLength;
|
||||||
|
|
||||||
Ccb->ReadDataAvailable -= CopyLength;
|
Ccb->ReadDataAvailable -= ThisCopyLength;
|
||||||
|
|
||||||
|
if ((ULONG)Ccb->WriteQuotaAvailable > (ULONG)Ccb->MaxDataLength) ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}while ((ThisCopyLength < TotalLengthNeeded)
|
||||||
|
&& (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
|
||||||
|
&& (Ccb->ReadDataAvailable));
|
||||||
|
|
||||||
if ((ULONG)Ccb->WriteQuotaAvailable > (ULONG)Ccb->MaxDataLength) ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Information > 0)
|
if (Information > 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Unhandled Pipe Mode with Read Mode!\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Information = Information;
|
Irp->IoStatus.Information = Information;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
|
||||||
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
|
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
|
||||||
|
|
||||||
|
if (Status == STATUS_CANCELLED)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (IoIsOperationSynchronous(Irp))
|
if (IoIsOperationSynchronous(Irp))
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Context->ListEntry);
|
RemoveEntryList(&Context->ListEntry);
|
||||||
|
@ -718,15 +737,15 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (Irp->MdlAddress == NULL)
|
if (Irp->MdlAddress == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Irp->MdlAddress == NULL\n");
|
DPRINT("Irp->MdlAddress == NULL\n");
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
Length = 0;
|
Length = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReaderCcb == NULL)
|
if ((ReaderCcb == NULL) || (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE))
|
||||||
{
|
{
|
||||||
DPRINT1("Pipe is NOT connected!\n");
|
DPRINT("Pipe is NOT connected!\n");
|
||||||
if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
|
if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||||
Status = STATUS_PIPE_LISTENING;
|
Status = STATUS_PIPE_LISTENING;
|
||||||
else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
|
else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
|
||||||
|
@ -739,7 +758,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (ReaderCcb->Data == NULL)
|
if (ReaderCcb->Data == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Pipe is NOT writable!\n");
|
DPRINT("Pipe is NOT writable!\n");
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
Length = 0;
|
Length = 0;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -749,6 +768,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
|
|
||||||
ExAcquireFastMutex(&ReaderCcb->DataListLock);
|
ExAcquireFastMutex(&ReaderCcb->DataListLock);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
|
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
|
||||||
HexDump(Buffer, Length);
|
HexDump(Buffer, Length);
|
||||||
|
@ -774,7 +794,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
DPRINT("Write Finished waiting (%S)! Status: %x\n", Fcb->PipeName.Buffer, Status);
|
DPRINT("Write Finished waiting (%S)! Status: %x\n", Fcb->PipeName.Buffer, Status);
|
||||||
ExAcquireFastMutex(&ReaderCcb->DataListLock);
|
|
||||||
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
|
||||||
{
|
{
|
||||||
Status = STATUS_CANCELLED;
|
Status = STATUS_CANCELLED;
|
||||||
|
@ -792,14 +812,14 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
DPRINT("PipeState: %x\n", Ccb->PipeState);
|
DPRINT("PipeState: %x\n", Ccb->PipeState);
|
||||||
Status = STATUS_PIPE_BROKEN;
|
Status = STATUS_PIPE_BROKEN;
|
||||||
// ExReleaseFastMutex(&ReaderCcb->DataListLock);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
ExAcquireFastMutex(&ReaderCcb->DataListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Fcb->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
|
if ((Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE) && (Ccb->Fcb->WriteMode == FILE_PIPE_BYTE_STREAM_MODE))
|
||||||
{
|
{
|
||||||
DPRINT("Byte stream mode\n");
|
DPRINT("Byte stream mode: Ccb->Data %x, Ccb->WritePtr %x\n", ReaderCcb->Data, ReaderCcb->WritePtr);
|
||||||
|
|
||||||
while (Length > 0 && ReaderCcb->WriteQuotaAvailable > 0)
|
while (Length > 0 && ReaderCcb->WriteQuotaAvailable > 0)
|
||||||
{
|
{
|
||||||
|
@ -816,7 +836,10 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TempLength = (ULONG)((ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength - (ULONG_PTR)ReaderCcb->WritePtr);
|
|
||||||
|
TempLength = (ULONG)((ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength -
|
||||||
|
(ULONG_PTR)ReaderCcb->WritePtr);
|
||||||
|
|
||||||
memcpy(ReaderCcb->WritePtr, Buffer, TempLength);
|
memcpy(ReaderCcb->WritePtr, Buffer, TempLength);
|
||||||
memcpy(ReaderCcb->Data, Buffer + TempLength, CopyLength - TempLength);
|
memcpy(ReaderCcb->Data, Buffer + TempLength, CopyLength - TempLength);
|
||||||
ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->Data + CopyLength - TempLength);
|
ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->Data + CopyLength - TempLength);
|
||||||
|
@ -837,33 +860,38 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if ((Ccb->Fcb->PipeType == FILE_PIPE_MESSAGE_TYPE) && (Ccb->Fcb->WriteMode == FILE_PIPE_MESSAGE_MODE))
|
||||||
{
|
{
|
||||||
/* For Message Type Pipe, the Pipes memory will be used to store the size of each message */
|
/* For Message Type Pipe, the Pipes memory will be used to store the size of each message */
|
||||||
/* FIXME: Check and verify ReadMode ByteStream */
|
DPRINT("Message mode: Ccb->Data %x, Ccb->WritePtr %x\n",ReaderCcb->Data, ReaderCcb->WritePtr);
|
||||||
|
|
||||||
if (Length > 0)
|
if (Length > 0)
|
||||||
{
|
{
|
||||||
/* Verify the WritePtr is still inside the buffer */
|
/* Verify the WritePtr is still inside the buffer */
|
||||||
if (((ULONG)ReaderCcb->WritePtr > ((ULONG)ReaderCcb->Data + (ULONG)ReaderCcb->MaxDataLength)) ||
|
if (((ULONG_PTR)ReaderCcb->WritePtr > ((ULONG_PTR)ReaderCcb->Data + (ULONG_PTR)ReaderCcb->MaxDataLength)) ||
|
||||||
((ULONG)ReaderCcb->WritePtr < (ULONG)ReaderCcb->Data))
|
((ULONG_PTR)ReaderCcb->WritePtr < (ULONG_PTR)ReaderCcb->Data))
|
||||||
{
|
{
|
||||||
DPRINT1("NPFS is writing out of its buffer. Report to developer!\n");
|
DPRINT1("NPFS is writing out of its buffer. Report to developer!\n");
|
||||||
DPRINT1("ReaderCcb->WritePtr %x, ReaderCcb->Data %x, ReaderCcb->MaxDataLength%d\n",
|
DPRINT1("ReaderCcb->WritePtr %x, ReaderCcb->Data %x, ReaderCcb->MaxDataLength %lu\n",
|
||||||
ReaderCcb->WritePtr,ReaderCcb->Data,ReaderCcb->MaxDataLength);
|
ReaderCcb->WritePtr, ReaderCcb->Data, ReaderCcb->MaxDataLength);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable - sizeof(ULONG));
|
CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable - sizeof(ULONG));
|
||||||
|
if (CopyLength > ReaderCcb->WriteQuotaAvailable)
|
||||||
|
{
|
||||||
|
DPRINT1("Writing %lu byte to pipe would overflow as only %lu bytes are available\n",
|
||||||
|
CopyLength, ReaderCcb->ReadDataAvailable);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* First Copy the Length of the message into the pipes buffer */
|
/* First Copy the Length of the message into the pipes buffer */
|
||||||
memcpy(ReaderCcb->WritePtr, &CopyLength, sizeof(CopyLength));
|
memcpy(ReaderCcb->WritePtr, &CopyLength, sizeof(CopyLength));
|
||||||
|
|
||||||
/* Now the user buffer itself */
|
/* Now the user buffer itself */
|
||||||
memcpy((PVOID)((ULONG)ReaderCcb->WritePtr+ sizeof(CopyLength)), Buffer, CopyLength);
|
memcpy((PVOID)((ULONG_PTR)ReaderCcb->WritePtr + sizeof(CopyLength)), Buffer, CopyLength);
|
||||||
|
|
||||||
/* Update the write pointer */
|
/* Update the write pointer */
|
||||||
ReaderCcb->WritePtr = (PVOID)((ULONG)ReaderCcb->WritePtr + sizeof(CopyLength) + CopyLength);
|
ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->WritePtr + sizeof(CopyLength) + CopyLength);
|
||||||
|
|
||||||
Information += CopyLength;
|
Information += CopyLength;
|
||||||
|
|
||||||
|
@ -871,7 +899,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
ReaderCcb->WriteQuotaAvailable -= (CopyLength + sizeof(ULONG));
|
ReaderCcb->WriteQuotaAvailable -= (CopyLength + sizeof(ULONG));
|
||||||
|
|
||||||
if ((ULONG)ReaderCcb->WriteQuotaAvailable > (ULONG)ReaderCcb->MaxDataLength)
|
if ((ULONG_PTR)ReaderCcb->WriteQuotaAvailable > (ULONG)ReaderCcb->MaxDataLength)
|
||||||
{
|
{
|
||||||
DPRINT1("QuotaAvailable is greater than buffer size!\n");
|
DPRINT1("QuotaAvailable is greater than buffer size!\n");
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
|
@ -885,6 +913,11 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Unhandled Pipe Type Mode and Read Write Mode!\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseFastMutex(&ReaderCcb->DataListLock);
|
ExReleaseFastMutex(&ReaderCcb->DataListLock);
|
||||||
|
|
Loading…
Reference in a new issue