Author: mjmartin
Date: Sat Jan 17 09:21:15 2009
New Revision: 38818
URL:
http://svn.reactos.org/svn/reactos?rev=38818&view=rev
Log:
- rw.c: Better implementation of read/write for pipes.
The ReadPtr is there so use it. Duuhh.
Only move memory to make room for more data when the buffer is full vice moving memory
on every read.
Call KeSetEvent at the correct time, when reading is done.
- fsctrl.c: Correct data returned from NpfsPeekPipe when read mode is byte stream.
Modified:
trunk/reactos/drivers/filesystems/npfs/fsctrl.c
trunk/reactos/drivers/filesystems/npfs/rw.c
Modified: trunk/reactos/drivers/filesystems/npfs/fsctrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] Sat Jan 17 09:21:15 2009
@@ -398,7 +398,7 @@
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
ExAcquireFastMutex(&Ccb->DataListLock);
- BufferPtr = Ccb->Data;
+ BufferPtr = Ccb->ReadPtr;
DPRINT("BufferPtr = %x\n", BufferPtr);
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
{
@@ -420,9 +420,8 @@
if (ReadDataAvailable > 0)
{
- memcpy(&Reply->MessageLength,Ccb->Data,sizeof(ULONG));
-
- /* NOTE: Modifying the structure in header file to keep track of
NumberOfMessage would be better */
+ memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
+
while ((ReadDataAvailable > 0) && (BufferPtr <
Ccb->WritePtr))
{
memcpy(&MessageLength, BufferPtr,
sizeof(MessageLength));
@@ -430,20 +429,34 @@
ASSERT(MessageLength > 0);
DPRINT("MessageLength = %lu\n",MessageLength);
+ ReadDataAvailable -= MessageLength;
MessageCount++;
- ReadDataAvailable -= MessageLength;
-
- /* If its the first message, copy the Message if the size
of buffer is large enough */
- if (MessageCount==1)
+
+ if (Ccb->Fcb->ReadMode ==
FILE_PIPE_BYTE_STREAM_MODE)
{
-
if ((Reply->Data[0])
- && (OutputBufferLength >=
(MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
+ && (OutputBufferLength >=
(MessageLength + ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
{
- ReturnLength = MessageLength;
- memcpy(&Reply->Data[0],
(PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
+
memcpy((PVOID)((ULONG_PTR)&Reply->Data[0] + ReturnLength),
+ (PVOID)((ULONG)BufferPtr +
sizeof(MessageLength)),
+ MessageLength);
+ ReturnLength += MessageLength;
}
}
+ else
+ {
+ /* If its the first message, copy the Message if
the size of buffer is large enough */
+ if (MessageCount==1)
+ {
+ if ((Reply->Data[0])
+ && (OutputBufferLength
>= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
+ {
+ memcpy(&Reply->Data[0],
(PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
+ ReturnLength = MessageLength;
+ }
+ }
+ }
+
BufferPtr =(PVOID)((ULONG)BufferPtr + MessageLength +
sizeof(MessageLength));
DPRINT("BufferPtr = %x\n", BufferPtr);
DPRINT("ReadDataAvailable: %lu\n",
ReadDataAvailable);
Modified: trunk/reactos/drivers/filesystems/npfs/rw.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/r…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/rw.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/rw.c [iso-8859-1] Sat Jan 17 09:21:15 2009
@@ -320,6 +320,15 @@
Ccb = FileObject->FsContext2;
Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+ if ((Ccb->OtherSide) && (Ccb->OtherSide->PipeState ==
FILE_PIPE_DISCONNECTED_STATE) && (Ccb->PipeState ==
FILE_PIPE_DISCONNECTED_STATE))
+ {
+ DPRINT("Both Client and Server are disconnected!\n");
+ Status = STATUS_PIPE_DISCONNECTED;
+ Irp->IoStatus.Information = 0;
+ goto done;
+
+ }
+
if ((Ccb->OtherSide == NULL) && (Ccb->ReadDataAvailable == 0))
{
/* Its ok if the other side has been Disconnect, but if we have data still
in the buffer
@@ -523,123 +532,104 @@
}
else if (Ccb->Fcb->PipeType == FILE_PIPE_MESSAGE_TYPE)
{
- ULONG ThisCopyLength = 0;
- ULONG TotalLengthNeeded = min(Length,
Ccb->ReadDataAvailable);
-
DPRINT("Message mode: Ccb>Data %x\n",
Ccb->Data);
- do
- {
- Buffer = (PVOID)((ULONG_PTR)Buffer +
ThisCopyLength);
-
- /* For Message mode, the Message length will be
stored in the buffer preceeding the Message. */
- if (Ccb->ReadDataAvailable)
- {
- ULONG NextMessageLength = 0;
-
- /*First get the size of the message */
- memcpy(&NextMessageLength,
Ccb->Data, sizeof(NextMessageLength));
-
- if ((NextMessageLength == 0) ||
(NextMessageLength > Ccb->ReadDataAvailable))
+ /* Check if buffer is full and the read pointer is not at
the start of the buffer */
+ if ((Ccb->WriteQuotaAvailable == 0) &&
(Ccb->ReadPtr > Ccb->Data))
+ {
+ memcpy(Ccb->Data, Ccb->ReadPtr,
(ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->ReadPtr);
+ Ccb->WritePtr =
(PVOID)((ULONG_PTR)Ccb->WritePtr - ((ULONG_PTR)Ccb->WritePtr -
(ULONG_PTR)Ccb->ReadPtr));
+ Ccb->ReadPtr = Ccb->Data;
+ Ccb->WriteQuotaAvailable +=
(ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->ReadPtr;
+ }
+
+ /* For Message mode, the Message length is stored in the
buffer preceeding the Message. */
+ if (Ccb->ReadDataAvailable)
+ {
+ ULONG NextMessageLength = 0;
+
+ /*First get the size of the message */
+ memcpy(&NextMessageLength, Ccb->ReadPtr,
sizeof(NextMessageLength));
+
+ if ((NextMessageLength == 0) || (NextMessageLength
> Ccb->ReadDataAvailable))
+ {
+ DPRINT1("Possible memory
corruption.\n");
+ HexDump(Ccb->Data,
(ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->Data);
+ ASSERT(FALSE);
+ }
+
+ /* Use the smaller value */
+ CopyLength = min(NextMessageLength, Length);
+
+ /* retrieve the message from the buffer */
+ memcpy(Buffer, (PVOID)((ULONG_PTR)Ccb->ReadPtr
+ 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);
- }
-
- /* Use the smaller value */
- ThisCopyLength = min(NextMessageLength,
Length);
-
- /* retrieve the message from the buffer */
- memcpy(Buffer,
(PVOID)((ULONG_PTR)Ccb->Data + sizeof(NextMessageLength)), ThisCopyLength);
-
- if (Ccb->ReadDataAvailable >
ThisCopyLength)
- {
- if (ThisCopyLength <
NextMessageLength)
- {
- /* Client only requested
part of the message */
-
- /* Calculate the remaining
message new size */
- ULONG NewMessageSize =
NextMessageLength-ThisCopyLength;
-
- /* Write a new Message
size to buffer for the part of the message still there */
- memcpy(Ccb->Data,
&NewMessageSize, sizeof(NewMessageSize));
-
- /* 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));
- }
+ /* Calculate the remaining message
new size */
+ ULONG NewMessageSize =
NextMessageLength-CopyLength;
+ /* Update ReadPtr to point to new
Message size location */
+ Ccb->ReadPtr =
(PVOID)((ULONG_PTR)Ccb->ReadPtr + CopyLength);
+
+ /* Write a new Message size to
buffer for the part of the message still there */
+ memcpy(Ccb->ReadPtr,
&NewMessageSize, sizeof(NewMessageSize));
}
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));
-
- /* 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 +=
(ThisCopyLength + sizeof(ULONG));
-
-
KeResetEvent(&Ccb->ReadEvent);
- if (Ccb->PipeState ==
FILE_PIPE_CONNECTED_STATE)
- {
-
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
- }
+ /* Update ReadPtr to point to next
message size */
+ Ccb->ReadPtr =
(PVOID)((ULONG_PTR)Ccb->ReadPtr + CopyLength + sizeof(CopyLength));
}
+ }
+ else
+ {
+ /* This was the last Message, so just zero
this messages for safety sake */
+ memset(Ccb->Data, 0, NextMessageLength
+ sizeof(NextMessageLength));
+
+ /* reset read and write pointer to
beginning of buffer */
+ Ccb->WritePtr = Ccb->Data;
+ Ccb->ReadPtr = Ccb->Data;
+
+ /* Add both the message length and the
header to the WriteQuotaAvailable
+ as they both were removed */
+ Ccb->WriteQuotaAvailable += (CopyLength
+ sizeof(CopyLength));
+ }
#ifndef NDEBUG
- DPRINT("Length %d Buffer
%x\n",ThisCopyLength,Buffer);
- HexDump((PUCHAR)Buffer, ThisCopyLength);
+ DPRINT("Length %d Buffer
%x\n",CopyLength,Buffer);
+ HexDump((PUCHAR)Buffer, CopyLength);
#endif
- Information += ThisCopyLength;
-
- 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));
-
+ Information += CopyLength;
+
+ Ccb->ReadDataAvailable -= CopyLength;
+
+ if ((ULONG)Ccb->WriteQuotaAvailable >
(ULONG)Ccb->MaxDataLength) ASSERT(FALSE);
+ }
if (Information > 0)
{
- break;
+ if ((Ccb->Fcb->ReadMode ==
FILE_PIPE_BYTE_STREAM_MODE) && (Ccb->ReadDataAvailable) && (Length >
CopyLength))
+ {
+ Buffer = (PVOID)((ULONG_PTR)Buffer +
CopyLength);
+ Length -= CopyLength;
+ }
+ else
+ {
+ KeResetEvent(&Ccb->ReadEvent);
+ if (Ccb->PipeState ==
FILE_PIPE_CONNECTED_STATE)
+ {
+
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+ }
+ break;
+ }
}
}
else
{
- DPRINT1("Unhandled Pipe Mode with Read
Mode!\n");
+ DPRINT1("Unhandled Pipe Mode!\n");
ASSERT(FALSE);
}
}