Fixed incorrect SetNamedPipeHandleState implementation to use the actual APIs/Structures it should and added one of the missing ones to NTIFS.

svn path=/trunk/; revision=16129
This commit is contained in:
Alex Ionescu 2005-06-20 01:52:47 +00:00
parent aaad0af903
commit f5e002e1c9
6 changed files with 207 additions and 264 deletions

View file

@ -17,26 +17,100 @@
/* FUNCTIONS *****************************************************************/
static NTSTATUS
NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB Fcb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
static
NTSTATUS
NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB Fcb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_PIPE Pipe;
PNPFS_PIPE Pipe;
PFILE_PIPE_INFORMATION Request;
DPRINT("NpfsSetPipeInformation()\n");
DPRINT("NpfsQueryPipeInformation()\n");
/* Get the Pipe and data */
Pipe = Fcb->Pipe;
Request = (PFILE_PIPE_INFORMATION)Info;
/* Set Pipe Data */
Pipe->ReadMode = Request->ReadMode;
Pipe->CompletionMode = Request->CompletionMode;
Pipe = Fcb->Pipe;
/* Return Success */
return STATUS_SUCCESS;
}
RtlZeroMemory(Info,
sizeof(FILE_PIPE_INFORMATION));
static
NTSTATUS
NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB Fcb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_PIPE Pipe;
PFILE_PIPE_REMOTE_INFORMATION Request;
DPRINT("NpfsSetPipeRemoteInformation()\n");
// Info->PipeMode =
// Info->CompletionMode =
/* Get the Pipe and data */
Pipe = Fcb->Pipe;
Request = (PFILE_PIPE_REMOTE_INFORMATION)Info;
/* Set the Settings */
Pipe->TimeOut = Request->CollectDataTime;
Pipe->InboundQuota = Request->MaximumCollectionCount;
/* Return Success */
return STATUS_SUCCESS;
}
static
NTSTATUS
NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB Fcb,
PFILE_PIPE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_PIPE Pipe;
DPRINT("NpfsQueryPipeInformation()\n");
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
return STATUS_SUCCESS;
/* Get the Pipe */
Pipe = Fcb->Pipe;
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_INFORMATION));
/* Return Info */
Info->CompletionMode = Pipe->CompletionMode;
Info->ReadMode = Pipe->ReadMode;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_INFORMATION);
return STATUS_SUCCESS;
}
static
NTSTATUS
NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject,
PNPFS_FCB Fcb,
PFILE_PIPE_REMOTE_INFORMATION Info,
PULONG BufferLength)
{
PNPFS_PIPE Pipe;
DPRINT("NpfsQueryPipeRemoteInformation()\n");
/* Get the Pipe */
Pipe = Fcb->Pipe;
/* Clear Info */
RtlZeroMemory(Info, sizeof(FILE_PIPE_REMOTE_INFORMATION));
/* Return Info */
Info->MaximumCollectionCount = Pipe->InboundQuota;
Info->CollectDataTime = Pipe->TimeOut;
/* Return success */
*BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION);
return STATUS_SUCCESS;
}
@ -128,7 +202,10 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
break;
case FilePipeRemoteInformation:
Status = STATUS_NOT_IMPLEMENTED;
Status = NpfsQueryPipeRemoteInformation(DeviceObject,
Fcb,
SystemBuffer,
&BufferLength);
break;
default:
@ -176,27 +253,35 @@ NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("BufferLength %lu\n", BufferLength);
switch (FileInformationClass)
switch (FileInformationClass)
{
case FilePipeInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeLocalInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeRemoteInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
Status = STATUS_NOT_SUPPORTED;
case FilePipeInformation:
/* Call the handler */
Status = NpfsSetPipeInformation(DeviceObject,
Fcb,
SystemBuffer,
&BufferLength);
break;
case FilePipeLocalInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FilePipeRemoteInformation:
/* Call the handler */
Status = NpfsSetPipeRemoteInformation(DeviceObject,
Fcb,
SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return Status;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
/* EOF */

View file

@ -272,12 +272,12 @@ NpfsWaitPipe(PIRP Irp,
PNPFS_PIPE Pipe;
PLIST_ENTRY current_entry;
PNPFS_FCB ServerFcb;
PNPFS_WAIT_PIPE WaitPipe;
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
NTSTATUS Status;
DPRINT("NpfsWaitPipe\n");
WaitPipe = (PNPFS_WAIT_PIPE)Irp->AssociatedIrp.SystemBuffer;
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
Pipe = Fcb->Pipe;
if (Fcb->PipeState != 0)
@ -326,82 +326,6 @@ NpfsWaitPipe(PIRP Irp,
* RETURNS:
* Status of operation
*/
static NTSTATUS
NpfsGetState(PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PNPFS_GET_STATE Reply;
PNPFS_PIPE Pipe;
PNPFS_FCB Fcb;
/* Validate parameters */
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(NPFS_GET_STATE))
{
DPRINT("Status (0x%X).\n", STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
Fcb = IrpSp->FileObject->FsContext;
Reply = (PNPFS_GET_STATE)Irp->AssociatedIrp.SystemBuffer;
Pipe = Fcb->Pipe;
Reply->WriteModeMessage = (Pipe->WriteMode == FILE_PIPE_MESSAGE_MODE);
Reply->ReadModeMessage = (Pipe->ReadMode == FILE_PIPE_MESSAGE_MODE);
Reply->NonBlocking = (Pipe->CompletionMode == FILE_PIPE_QUEUE_OPERATION);
Reply->InBufferSize = Pipe->InboundQuota;
Reply->OutBufferSize = Pipe->OutboundQuota;
Reply->Timeout = Pipe->TimeOut;
Irp->IoStatus.Information = sizeof(NPFS_GET_STATE);
DPRINT("Status (0x%X).\n", STATUS_SUCCESS);
return STATUS_SUCCESS;
}
/*
* FUNCTION: Set state of a pipe
* ARGUMENTS:
* Irp = Pointer to I/O request packet
* IrpSp = Pointer to current stack location of Irp
* RETURNS:
* Status of operation
*/
static NTSTATUS
NpfsSetState(PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PNPFS_SET_STATE Request;
PNPFS_PIPE Pipe;
PNPFS_FCB Fcb;
/* Validate parameters */
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(NPFS_SET_STATE))
{
DPRINT("Status (0x%X).\n", STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
Fcb = IrpSp->FileObject->FsContext;
Request = (PNPFS_SET_STATE)Irp->AssociatedIrp.SystemBuffer;
Pipe = Fcb->Pipe;
Pipe->WriteMode =
Request->WriteModeMessage ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE;
Pipe->ReadMode =
Request->WriteModeMessage ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE;
Pipe->CompletionMode =
Request->NonBlocking ? FILE_PIPE_QUEUE_OPERATION : FILE_PIPE_COMPLETE_OPERATION;
Pipe->InboundQuota = Request->InBufferSize;
Pipe->OutboundQuota = Request->OutBufferSize;
Pipe->TimeOut = Request->Timeout;
DPRINT("Status (0x%X).\n", STATUS_SUCCESS);
return STATUS_SUCCESS;
}
/*
* FUNCTION: Peek at a pipe (get information about messages)
@ -520,16 +444,6 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
Status = STATUS_NOT_IMPLEMENTED;
break;
case FSCTL_PIPE_GET_STATE:
DPRINT("Get state\n");
Status = NpfsGetState(Irp, (PIO_STACK_LOCATION)IoStack);
break;
case FSCTL_PIPE_SET_STATE:
DPRINT("Set state\n");
Status = NpfsSetState(Irp, (PIO_STACK_LOCATION)IoStack);
break;
case FSCTL_PIPE_INTERNAL_READ:
DPRINT("Internal read\n");
Status = STATUS_NOT_IMPLEMENTED;

View file

@ -35,12 +35,6 @@
#define FSCTL_PIPE_QUERY_CLIENT_PROCESS \
CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_GET_STATE \
CTL_CODE(FILE_DEVICE_NAMED_PIPE, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_SET_STATE \
CTL_CODE(FILE_DEVICE_NAMED_PIPE, 11, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_INTERNAL_READ \
CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA)
@ -54,46 +48,6 @@
CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2048, METHOD_BUFFERED, FILE_READ_DATA)
typedef struct _NPFS_WAIT_PIPE
{
LARGE_INTEGER Timeout;
} NPFS_WAIT_PIPE, *PNPFS_WAIT_PIPE;
#ifdef __GNUC__ /* robd */
typedef struct _NPFS_LISTEN
{
} NPFS_LISTEN, *PNPFS_LISTEN;
#endif
typedef struct _NPFS_SET_STATE
{
BOOLEAN WriteModeMessage;
BOOLEAN ReadModeMessage;
BOOLEAN NonBlocking;
ULONG InBufferSize;
ULONG OutBufferSize;
LARGE_INTEGER Timeout;
} NPFS_SET_STATE, *PNPFS_SET_STATE;
typedef struct _NPFS_GET_STATE
{
BOOLEAN WriteModeMessage;
BOOLEAN ReadModeMessage;
BOOLEAN NonBlocking;
ULONG InBufferSize;
ULONG OutBufferSize;
LARGE_INTEGER Timeout;
} NPFS_GET_STATE, *PNPFS_GET_STATE;
typedef struct _FILE_PIPE_PEEK_BUFFER
{
ULONG NamedPipeState;
ULONG ReadDataAvailable;
ULONG NumberOfMessages;
ULONG MessageLength;
CHAR Data[1];
} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;
#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000
#define FILE_PIPE_MESSAGE_TYPE 0x00000001

View file

@ -28,7 +28,7 @@
typedef struct _KERNEL32_FIND_FILE_DATA
{
HANDLE DirectoryHandle;
PFILE_BOTH_DIRECTORY_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pFileInfo;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;

View file

@ -243,7 +243,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
BOOL r;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
NPFS_WAIT_PIPE WaitPipe;
FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
HANDLE FileHandle;
IO_STATUS_BLOCK Iosb;
@ -371,112 +371,93 @@ ConnectNamedPipe(IN HANDLE hNamedPipe,
/*
* @implemented
*/
BOOL STDCALL
BOOL
STDCALL
SetNamedPipeHandleState(HANDLE hNamedPipe,
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout)
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout)
{
NPFS_GET_STATE GetState;
NPFS_SET_STATE SetState;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_PIPE_GET_STATE,
NULL,
0,
&GetState,
sizeof(NPFS_GET_STATE));
if (Status == STATUS_PENDING)
{
Status = NtWaitForSingleObject(hNamedPipe,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* Check if the Mode is being changed */
if (lpMode)
{
FILE_PIPE_INFORMATION Settings;
if (lpMode != NULL)
{
if ((*lpMode) & PIPE_READMODE_MESSAGE)
{
SetState.ReadModeMessage = TRUE;
}
else
{
SetState.ReadModeMessage = FALSE;
}
if ((*lpMode) & PIPE_NOWAIT)
{
SetState.NonBlocking = TRUE;
}
else
{
SetState.NonBlocking = FALSE;
}
SetState.WriteModeMessage = GetState.WriteModeMessage;
}
else
{
SetState.ReadModeMessage = GetState.ReadModeMessage;
SetState.WriteModeMessage = GetState.WriteModeMessage;
SetState.NonBlocking = SetState.NonBlocking;
}
/* Set the Completion Mode */
Settings.CompletionMode = (*lpMode & PIPE_NOWAIT) ?
FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
if (lpMaxCollectionCount != NULL)
{
SetState.InBufferSize = *lpMaxCollectionCount;
}
else
{
SetState.InBufferSize = GetState.InBufferSize;
}
/* Set the Read Mode */
Settings.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ?
FILE_PIPE_MESSAGE_MODE: FILE_PIPE_BYTE_STREAM_MODE;
SetState.OutBufferSize = GetState.OutBufferSize;
/* Send the changes to the Driver */
Status = NtSetInformationFile(hNamedPipe,
&Iosb,
&Settings,
sizeof(FILE_PIPE_INFORMATION),
FilePipeInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* Check if the Collection count or Timeout are being changed */
if (lpMaxCollectionCount || lpCollectDataTimeout)
{
FILE_PIPE_REMOTE_INFORMATION RemoteSettings;
if (lpCollectDataTimeout != NULL)
{
SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * -10000LL;
}
else
{
SetState.Timeout = GetState.Timeout;
}
/* Setting one without the other would delete it, so we read old one */
if (!lpMaxCollectionCount || !lpCollectDataTimeout)
{
Status = NtQueryInformationFile(hNamedPipe,
&Iosb,
&RemoteSettings,
sizeof(FILE_PIPE_REMOTE_INFORMATION),
FilePipeRemoteInformation);
Status = NtFsControlFile(hNamedPipe,
NULL,
NULL,
NULL,
&Iosb,
FSCTL_PIPE_SET_STATE,
&SetState,
sizeof(NPFS_SET_STATE),
NULL,
0);
if (Status == STATUS_PENDING)
{
Status = NtWaitForSingleObject(hNamedPipe,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
return(TRUE);
/* Now set the new settings */
RemoteSettings.MaximumCollectionCount = (lpMaxCollectionCount) ?
*lpMaxCollectionCount :
RemoteSettings.MaximumCollectionCount;
if (lpCollectDataTimeout)
{
/* Convert it to Quad */
RemoteSettings.CollectDataTime.QuadPart = -(LONGLONG)
UInt32x32To64(10000,
*lpCollectDataTimeout);
}
/* Tell the driver to change them */
Status = NtSetInformationFile(hNamedPipe,
&Iosb,
&RemoteSettings,
sizeof(FILE_PIPE_REMOTE_INFORMATION),
FilePipeRemoteInformation);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
}
/* All done */
return TRUE;
}
/*
* @implemented
*/

View file

@ -1124,6 +1124,15 @@ typedef struct _FILE_PIPE_EVENT_BUFFER {
ULONG NumberRequests;
} FILE_PIPE_EVENT_BUFFER, *PFILE_PIPE_EVENT_BUFFER;
typedef struct _FILE_PIPE_PEEK_BUFFER
{
ULONG NamedPipeState;
ULONG ReadDataAvailable;
ULONG NumberOfMessages;
ULONG MessageLength;
CHAR Data[1];
} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;
typedef struct _FILE_PIPE_INFORMATION {
ULONG ReadMode;
ULONG CompletionMode;