From 7d0f1e34336765df29b00ca423ef7460c43f40de Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 10 May 2001 23:38:31 +0000 Subject: [PATCH] Some named pipe improvements (not usable yet!). svn path=/trunk/; revision=1902 --- reactos/apps/tests/nptest/npclient.c | 199 +++++++++++------------ reactos/apps/tests/nptest/npserver.c | 136 ++++++++++------ reactos/drivers/fs/np/Makefile | 21 ++- reactos/drivers/fs/np/create.c | 94 ++++++----- reactos/drivers/fs/np/fsctrl.c | 55 ++++++- reactos/drivers/fs/np/mount.c | 59 +++---- reactos/drivers/fs/np/npfs.h | 7 +- reactos/include/napi/npipe.h | 46 +++++- reactos/lib/kernel32/file/npipe.c | 233 ++++++++++++++++----------- 9 files changed, 502 insertions(+), 348 deletions(-) diff --git a/reactos/apps/tests/nptest/npclient.c b/reactos/apps/tests/nptest/npclient.c index 99f7f3655bd..6d93f3a1acd 100644 --- a/reactos/apps/tests/nptest/npclient.c +++ b/reactos/apps/tests/nptest/npclient.c @@ -1,99 +1,100 @@ -#include - -VOID MyErrExit(LPTSTR Message) -{ - MessageBox(NULL, Message, NULL, MB_OK); - ExitProcess(0); -} - -DWORD main(int argc, char *argv[]) -{ - HANDLE hPipe; - LPVOID lpvMessage; - CHAR chBuf[512]; - BOOL fSuccess; - DWORD cbRead, cbWritten, dwMode; - LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; - -// Try to open a named pipe; wait for it, if necessary. - - while (1) - { - hPipe = CreateFile( - lpszPipename, // pipe name - GENERIC_READ | // read and write access - GENERIC_WRITE, - 0, // no sharing - NULL, // no security attributes - OPEN_EXISTING, // opens existing pipe - 0, // default attributes - NULL); // no template file - - // Break if the pipe handle is valid. - - if (hPipe != INVALID_HANDLE_VALUE) - break; - - // Exit if an error other than ERROR_PIPE_BUSY occurs. - - if (GetLastError() != ERROR_PIPE_BUSY) - MyErrExit("Could not open pipe"); - - // All pipe instances are busy, so wait for 20 seconds. - - if (! WaitNamedPipe(lpszPipename, 20000) ) - MyErrExit("Could not open pipe"); - } - -// The pipe connected; change to message-read mode. - - dwMode = PIPE_READMODE_MESSAGE; - fSuccess = SetNamedPipeHandleState( - hPipe, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - if (!fSuccess) - MyErrExit("SetNamedPipeHandleState"); - -// Send a message to the pipe server. - - lpvMessage = (argc > 1) ? argv[1] : "default message"; - - fSuccess = WriteFile( - hPipe, // pipe handle - lpvMessage, // message - strlen(lpvMessage) + 1, // message length - &cbWritten, // bytes written - NULL); // not overlapped - if (! fSuccess) - MyErrExit("WriteFile"); - - do - { - // Read from the pipe. - - fSuccess = ReadFile( - hPipe, // pipe handle - chBuf, // buffer to receive reply - 512, // size of buffer - &cbRead, // number of bytes read - NULL); // not overlapped - - if (! fSuccess && GetLastError() != ERROR_MORE_DATA) - break; - - // Reply from the pipe is written to STDOUT. - - if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), - chBuf, cbRead, &cbWritten, NULL)) - { - break; - } - - } while (! fSuccess); // repeat loop if ERROR_MORE_DATA - - CloseHandle(hPipe); - - return 0; -} \ No newline at end of file +#include + +VOID MyErrExit(LPTSTR Message) +{ +// MessageBox(NULL, Message, NULL, MB_OK); + puts(Message); + ExitProcess(0); +} + +int main(int argc, char *argv[]) +{ + HANDLE hPipe; + LPVOID lpvMessage; + CHAR chBuf[512]; + BOOL fSuccess; + DWORD cbRead, cbWritten, dwMode; + LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; + +// Try to open a named pipe; wait for it, if necessary. + + while (1) + { + hPipe = CreateFile( + lpszPipename, // pipe name + GENERIC_READ | // read and write access + GENERIC_WRITE, + 0, // no sharing + NULL, // no security attributes + OPEN_EXISTING, // opens existing pipe + 0, // default attributes + NULL); // no template file + + // Break if the pipe handle is valid. + + if (hPipe != INVALID_HANDLE_VALUE) + break; + + // Exit if an error other than ERROR_PIPE_BUSY occurs. + + if (GetLastError() != ERROR_PIPE_BUSY) + MyErrExit("Could not open pipe"); + + // All pipe instances are busy, so wait for 20 seconds. + + if (! WaitNamedPipe(lpszPipename, 20000) ) + MyErrExit("Could not open pipe"); + } + +// The pipe connected; change to message-read mode. + + dwMode = PIPE_READMODE_MESSAGE; + fSuccess = SetNamedPipeHandleState( + hPipe, // pipe handle + &dwMode, // new pipe mode + NULL, // don't set maximum bytes + NULL); // don't set maximum time + if (!fSuccess) + MyErrExit("SetNamedPipeHandleState"); + +// Send a message to the pipe server. + + lpvMessage = (argc > 1) ? argv[1] : "default message"; + + fSuccess = WriteFile( + hPipe, // pipe handle + lpvMessage, // message + strlen(lpvMessage) + 1, // message length + &cbWritten, // bytes written + NULL); // not overlapped + if (! fSuccess) + MyErrExit("WriteFile"); + + do + { + // Read from the pipe. + + fSuccess = ReadFile( + hPipe, // pipe handle + chBuf, // buffer to receive reply + 512, // size of buffer + &cbRead, // number of bytes read + NULL); // not overlapped + + if (! fSuccess && GetLastError() != ERROR_MORE_DATA) + break; + + // Reply from the pipe is written to STDOUT. + + if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + chBuf, cbRead, &cbWritten, NULL)) + { + break; + } + + } while (! fSuccess); // repeat loop if ERROR_MORE_DATA + + CloseHandle(hPipe); + + return 0; +} diff --git a/reactos/apps/tests/nptest/npserver.c b/reactos/apps/tests/nptest/npserver.c index 8b059e44145..0969b4228a2 100644 --- a/reactos/apps/tests/nptest/npserver.c +++ b/reactos/apps/tests/nptest/npserver.c @@ -2,57 +2,86 @@ #include #include #include +#include + +#define BUFSIZE 1024 +#define PIPE_TIMEOUT 1000 VOID InstanceThread (LPVOID); -VOID GetAnswerToRequest (LPTSTR, LPTSTR, LPDWORD) +VOID +GetAnswerToRequest(LPTSTR lpRequest, + LPTSTR lpReply, + LPDWORD lpcbReplyBytes) { } +VOID MyErrExit(LPTSTR Message) +{ +// MessageBox(NULL, Message, NULL, MB_OK); + puts(Message); + ExitProcess(0); +} + + + + int xx = 0; -DWORD main (VOID) +int main(int argc, char *argv[]) { BOOL fConnected; DWORD dwThreadId; HANDLE hPipe, hThread; - LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; + LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); - for (;;) - { - hPipe = CreateNamedPipe (lpszPipename, - PIPE_ACCESS_DUPLEX, - PIPE_TYPE_MESSAGE | - PIPE_READMODE_MESSAGE | - PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - BUFSIZE, - BUFSIZE, - PIPE_TIMEOUT, - NULL); +// for (;;) +// { + hPipe = CreateNamedPipe(lpszPipename, + PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | + PIPE_READMODE_MESSAGE | + PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + PIPE_TIMEOUT, + NULL); if (hPipe == INVALID_HANDLE_VALUE) - MyErrExit ("CreatePipe"); - - fConnected = ConnectNamedPipe (hPipe, - NULL) ? TRUE : (GetLastError () == + { + printf("CreateNamedPipe() failed\n"); + return 0; + } + + fConnected = ConnectNamedPipe(hPipe, + NULL) ? TRUE : (GetLastError () == ERROR_PIPE_CONNECTED); if (fConnected) - { - hThread = CreateThread (NULL, - 0, - (LPTHREAD_START_ROUTINE) InstanceThread, - (LPVOID) hPipe, - 0, - &dwThreadId); - if (hThread == NULL) - MyErrExit ("CreateThread"); - } - else { - CloseHandle (hPipe); + printf("Pipe connected!\n"); + + DisconnectNamedPipe(hPipe); + +#if 0 + hThread = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE) InstanceThread, + (LPVOID) hPipe, + 0, + &dwThreadId); + if (hThread == NULL) + MyErrExit("CreateThread"); +#endif } - } - return 1; + else + { +// CloseHandle(hPipe); + } +// } + + CloseHandle(hPipe); + + return 0; } VOID InstanceThread (LPVOID lpvParam) @@ -63,28 +92,29 @@ VOID InstanceThread (LPVOID lpvParam) BOOL fSuccess; HANDLE hPipe; - hPipe = (HANDLE) lpvParam; - while (1) - { - fSuccess = ReadFile (hPipe, - chRequest, - BUFSIZE, - &cbBytesRead, - NULL); + hPipe = (HANDLE)lpvParam; + while (1) + { + fSuccess = ReadFile(hPipe, + chRequest, + BUFSIZE, + &cbBytesRead, + NULL); if (!fSuccess || cbBytesRead == 0) break; - GetAnswerToRequest (chRequest, chReply, &cbReplyBytes); - - fSuccess = WriteFile (hPipe, - chReply, - cbReplyBytes, - &cbWritten, - NULL); - if (!fSuccess || cbReplyBytes != cbWritten) - break; + + GetAnswerToRequest(chRequest, chReply, &cbReplyBytes); + + fSuccess = WriteFile(hPipe, + chReply, + cbReplyBytes, + &cbWritten, + NULL); + if (!fSuccess || cbReplyBytes != cbWritten) + break; } - FlushFileBuffers(hPipe); - DisconnectNamedPipe (hPipe); - CloseHandle (hPipe); + FlushFileBuffers(hPipe); + DisconnectNamedPipe(hPipe); + CloseHandle(hPipe); } diff --git a/reactos/drivers/fs/np/Makefile b/reactos/drivers/fs/np/Makefile index e1b2507e3b3..805a1fef360 100644 --- a/reactos/drivers/fs/np/Makefile +++ b/reactos/drivers/fs/np/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 2001/05/07 22:03:27 chorns Exp $ +# $Id: Makefile,v 1.6 2001/05/10 23:38:31 ekohl Exp $ # # Named Pipes File System # @@ -8,21 +8,25 @@ TARGETNAME=npfs #BASE_CFLAGS = -I../../../include -OBJECTS = create.o fsctrl.o mount.o rw.o npfs.coff \ - ../../../ntoskrnl/ntoskrnl.a +OBJECTS = create.o fsctrl.o mount.o rw.o npfs.coff + +LIBS = ../../../ntoskrnl/ntoskrnl.a all: $(TARGETNAME).sys .phony: all clean: - - $(RM) create.o - - $(RM) mount.o + - $(RM) *.o + - $(RM) npfs.coff + - $(RM) junk.tmp + - $(RM) base.tmp + - $(RM) temp.exp - $(RM) $(TARGETNAME).sys .phony: clean -$(TARGETNAME).sys: $(OBJECTS) +$(TARGETNAME).sys: $(OBJECTS) $(LIBS) $(CC) \ -specs=../../svc_specs \ -mdll \ @@ -31,7 +35,7 @@ $(TARGETNAME).sys: $(OBJECTS) -Wl,--defsym,_edata=__data_end__ \ -Wl,--defsym,_etext=etext \ -Wl,--base-file,base.tmp \ - $(OBJECTS) + $(OBJECTS) $(LIBS) $(RM) junk.tmp $(DLLTOOL) \ --dllname $(TARGETNAME).sys \ @@ -46,9 +50,10 @@ $(TARGETNAME).sys: $(OBJECTS) -specs=../../svc_specs \ -mdll \ -o $(TARGETNAME).sys \ - $(OBJECTS) \ + $(OBJECTS) $(LIBS) \ -Wl,temp.exp $(RM) temp.exp + $(NM) --numeric-sort npfs.sys > npfs.sym npfs.coff: ../../../include/reactos/buildno.h npfs.rc diff --git a/reactos/drivers/fs/np/create.c b/reactos/drivers/fs/np/create.c index ddd8f849c1a..f7b1d61ef9e 100644 --- a/reactos/drivers/fs/np/create.c +++ b/reactos/drivers/fs/np/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.5 2001/05/01 11:09:01 ekohl Exp $ +/* $Id: create.c,v 1.6 2001/05/10 23:38:31 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,17 +19,9 @@ /* GLOBALS *******************************************************************/ -static LIST_ENTRY PipeListHead; -static KMUTEX PipeListLock; /* FUNCTIONS *****************************************************************/ -VOID NpfsInitPipeList(VOID) -{ - InitializeListHead(&PipeListHead); - KeInitializeMutex(&PipeListLock, 0); -} - NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) @@ -39,7 +31,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, NTSTATUS Status; PNPFS_PIPE Pipe; PNPFS_FCB Fcb; - PWSTR PipeName; PNPFS_PIPE current; PLIST_ENTRY current_entry; PNPFS_DEVICE_EXTENSION DeviceExt; @@ -51,8 +42,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, IoStack = IoGetCurrentIrpStackLocation(Irp); FileObject = IoStack->FileObject; - PipeName = FileObject->FileName.Buffer; - Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB)); if (Fcb == NULL) { @@ -64,15 +53,17 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, return(STATUS_NO_MEMORY); } - KeLockMutex(&PipeListLock); - current_entry = PipeListHead.Flink; - while (current_entry != &PipeListHead) + KeLockMutex(&DeviceExt->PipeListLock); + current_entry = DeviceExt->PipeListHead.Flink; + while (current_entry != &DeviceExt->PipeListHead) { current = CONTAINING_RECORD(current_entry, NPFS_PIPE, PipeListEntry); - if (wcscmp(Pipe->Name, current->Name) == 0) + if (RtlCompareUnicodeString(&Pipe->PipeName, + ¤t->PipeName, + TRUE) == 0) { break; } @@ -80,10 +71,10 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, current_entry = current_entry->Flink; } - if (current_entry == &PipeListHead) + if (current_entry == &DeviceExt->PipeListHead) { ExFreePool(Fcb); - KeUnlockMutex(&PipeListLock); + KeUnlockMutex(&DeviceExt->PipeListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; @@ -109,7 +100,10 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, Pipe->ReferenceCount++; - KeUnlockMutex(&PipeListLock); + /* search for unconnected server fcb */ + + + KeUnlockMutex(&DeviceExt->PipeListLock); FileObject->FsContext = Fcb; @@ -121,6 +115,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, return(Status); } + NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp) @@ -129,7 +124,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject; NTSTATUS Status = STATUS_SUCCESS; PNPFS_DEVICE_EXTENSION DeviceExt; - PWSTR PipeName; PNPFS_PIPE Pipe; PNPFS_FCB Fcb; KIRQL oldIrql; @@ -143,8 +137,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, IoStack = IoGetCurrentIrpStackLocation(Irp); FileObject = IoStack->FileObject; - PipeName = FileObject->FileName.Buffer; - Buffer = (PIO_PIPE_CREATE_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer; Pipe = ExAllocatePool(NonPagedPool, sizeof(NPFS_PIPE)); @@ -171,9 +163,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, return(STATUS_NO_MEMORY); } - Pipe->Name = ExAllocatePool(NonPagedPool, - (wcslen(PipeName) + 1) * sizeof(WCHAR)); - if (Pipe->Name == NULL) + if (RtlCreateUnicodeString(&Pipe->PipeName, FileObject->FileName.Buffer) == 0) { ExFreePool(Pipe); ExFreePool(Fcb); @@ -186,7 +176,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, return(STATUS_NO_MEMORY); } - wcscpy(Pipe->Name, PipeName); Pipe->ReferenceCount = 0; InitializeListHead(&Pipe->FcbListHead); KeInitializeSpinLock(&Pipe->FcbListLock); @@ -194,15 +183,15 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, Pipe->MaxInstances = Buffer->MaxInstances; Pipe->TimeOut = Buffer->TimeOut; - KeLockMutex(&PipeListLock); - current_entry = PipeListHead.Flink; - while (current_entry != &PipeListHead) + KeLockMutex(&DeviceExt->PipeListLock); + current_entry = DeviceExt->PipeListHead.Flink; + while (current_entry != &DeviceExt->PipeListHead) { current = CONTAINING_RECORD(current_entry, NPFS_PIPE, PipeListEntry); - if (wcscmp(Pipe->Name, current->Name) == 0) + if (RtlCompareUnicodeString(&Pipe->PipeName, ¤t->PipeName, TRUE) == 0) { break; } @@ -210,16 +199,16 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, current_entry = current_entry->Flink; } - if (current_entry != &PipeListHead) + if (current_entry != &DeviceExt->PipeListHead) { - ExFreePool(Pipe->Name); + RtlFreeUnicodeString(&Pipe->PipeName); ExFreePool(Pipe); Pipe = current; } else { - InsertTailList(&PipeListHead, &Pipe->PipeListEntry); + InsertTailList(&DeviceExt->PipeListHead, &Pipe->PipeListEntry); } Pipe->ReferenceCount++; @@ -237,7 +226,11 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, Fcb->IsServer = TRUE; Fcb->OtherSide = NULL; - KeUnlockMutex(&PipeListLock); + KeInitializeEvent(&Fcb->ConnectEvent, + SynchronizationEvent, + FALSE); + + KeUnlockMutex(&DeviceExt->PipeListLock); FileObject->FsContext = Fcb; @@ -254,27 +247,48 @@ NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { + PNPFS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PNPFS_FCB Fcb; - NTSTATUS Status; + PNPFS_PIPE Pipe; + KIRQL oldIrql; - DPRINT1("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; Fcb = FileObject->FsContext; + Pipe = Fcb->Pipe; - DPRINT1("Closing pipe %S\n", Fcb->Pipe->Name); + DPRINT("Closing pipe %wZ\n", &Pipe->PipeName); - Status = STATUS_SUCCESS; + KeLockMutex(&DeviceExt->PipeListLock); - Irp->IoStatus.Status = Status; + Pipe->ReferenceCount--; + + KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql); + RemoveEntryList(&Fcb->FcbListEntry); + KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql); + ExFreePool(Fcb); + FileObject->FsContext = NULL; + + if (Pipe->ReferenceCount == 0) + { + RtlFreeUnicodeString(&Pipe->PipeName); + RemoveEntryList(&Pipe->PipeListEntry); + ExFreePool(Pipe); + } + + KeUnlockMutex(&DeviceExt->PipeListLock); + + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return(Status); + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/drivers/fs/np/fsctrl.c b/reactos/drivers/fs/np/fsctrl.c index e8ec1965475..ec0e01a9e65 100644 --- a/reactos/drivers/fs/np/fsctrl.c +++ b/reactos/drivers/fs/np/fsctrl.c @@ -1,10 +1,11 @@ -/* $Id: fsctrl.c,v 1.2 2001/05/01 11:09:01 ekohl Exp $ +/* $Id: fsctrl.c,v 1.3 2001/05/10 23:38:31 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: services/fs/np/fsctrl.c * PURPOSE: Named pipe filesystem * PROGRAMMER: David Welch + * Eric Kohl */ /* INCLUDES ******************************************************************/ @@ -18,6 +19,31 @@ /* FUNCTIONS *****************************************************************/ +static NTSTATUS +NpfsConnectPipe(PNPFS_FCB Fcb) +{ + NTSTATUS Status; + + Status = KeWaitForSingleObject(&Fcb->ConnectEvent, + UserRequest, + KernelMode, + FALSE, + NULL); + + DPRINT("Finished waiting! Status: %x\n", Status); + + + return STATUS_SUCCESS; +} + + +static NTSTATUS +NpfsDisconnectPipe(PNPFS_FCB Fcb) +{ + + return STATUS_SUCCESS; +} + NTSTATUS STDCALL NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) @@ -29,6 +55,8 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PNPFS_PIPE Pipe; PNPFS_FCB Fcb; + DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); FileObject = IoStack->FileObject; @@ -37,10 +65,18 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, switch (IoStack->Parameters.FileSystemControl.IoControlCode) { - case FSCTL_WAIT_PIPE: + case FSCTL_PIPE_LISTEN: + DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName); + Status = NpfsConnectPipe(Fcb); break; - - case FSCTL_LISTEN: + + case FSCTL_PIPE_DISCONNECT: + DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName); + Status = NpfsDisconnectPipe(Fcb); + break; + +#if 0 + case FSCTL_WAIT_PIPE: break; case FSCTL_SET_STATE: @@ -53,9 +89,18 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, break; } +#endif default: + DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode) + Status = STATUS_UNSUCCESSFUL; } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(Status); } - /* EOF */ diff --git a/reactos/drivers/fs/np/mount.c b/reactos/drivers/fs/np/mount.c index 41f9707ea9b..abab8c48e7f 100644 --- a/reactos/drivers/fs/np/mount.c +++ b/reactos/drivers/fs/np/mount.c @@ -1,4 +1,4 @@ -/* $Id: mount.c,v 1.6 2001/05/07 22:03:27 chorns Exp $ +/* $Id: mount.c,v 1.7 2001/05/10 23:38:31 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -16,42 +16,19 @@ #include -/* GLOBALS *******************************************************************/ - -//static PDRIVER_OBJECT DriverObject; - /* FUNCTIONS *****************************************************************/ -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) +NTSTATUS STDCALL +DriverEntry(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) { + PNPFS_DEVICE_EXTENSION DeviceExtension; PDEVICE_OBJECT DeviceObject; - NTSTATUS Status; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; + NTSTATUS Status; - DbgPrint("Named Pipe Filesystem\n"); - -// DriverObject = _DriverObject; - -#if 0 - RtlInitUnicodeString(&DeviceName, L"\\Device\\Npfs"); - Status = IoCreateDevice(DriverObject, - 0, - &DeviceName, - FILE_DEVICE_NAMED_PIPE, - 0, - FALSE, - &DeviceObject); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - RtlInitUnicodeString(&LinkName, L"\\??\\Pipe"); - Status = IoCreateSymbolicLink(&LinkName, - &DeviceName); -#endif + DbgPrint("Named Pipe FSD 0.0.2\n"); DeviceObject->Flags = 0; DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate; @@ -68,7 +45,6 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, // NpfsSetInformation; // DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers; // DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NpfsShutdown; -// DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup; // DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = // NpfsQuerySecurity; // DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = @@ -78,9 +54,9 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->DriverUnload = NULL; - RtlInitUnicodeString(&DeviceName, L"\\Device\\Npfs"); + RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe"); Status = IoCreateDevice(DriverObject, - 0, + sizeof(NPFS_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_NAMED_PIPE, 0, @@ -88,25 +64,30 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, &DeviceObject); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create named pipe device! (Status %x)\n", Status); + DPRINT("Failed to create named pipe device! (Status %x)\n", Status); return(Status); } - RtlInitUnicodeString(&LinkName, L"\\??\\Pipe"); +#if 0 + /* FIXME: this should really be done by SMSS!! */ + RtlInitUnicodeString(&LinkName, L"\\??\\PIPE"); Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create named pipe symbolic link! (Status %x)\n", Status); - + DPRINT("Failed to create named pipe symbolic link! (Status %x)\n", Status); // IoDeleteDevice(); return(Status); } +#endif - NpfsInitPipeList(); + /* initialize the device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + InitializeListHead(&DeviceExtension->PipeListHead); + KeInitializeMutex(&DeviceExtension->PipeListLock, + 0); return(STATUS_SUCCESS); } - /* EOF */ diff --git a/reactos/drivers/fs/np/npfs.h b/reactos/drivers/fs/np/npfs.h index a34bbff9a02..87b8790d999 100644 --- a/reactos/drivers/fs/np/npfs.h +++ b/reactos/drivers/fs/np/npfs.h @@ -3,12 +3,13 @@ typedef struct { - PDEVICE_OBJECT StorageDevice; + LIST_ENTRY PipeListHead; + KMUTEX PipeListLock; } NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION; typedef struct { - PWCHAR Name; + UNICODE_STRING PipeName; LIST_ENTRY PipeListEntry; KSPIN_LOCK FcbListLock; LIST_ENTRY FcbListHead; @@ -28,9 +29,9 @@ typedef struct _NPFS_FCB PNPFS_PIPE Pipe; struct _NPFS_FCB* OtherSide; BOOLEAN IsServer; + KEVENT ConnectEvent; } NPFS_FCB, *PNPFS_FCB; -VOID NpfsPipeList(VOID); #define KeLockMutex(x) KeWaitForSingleObject(x, \ UserRequest, \ diff --git a/reactos/include/napi/npipe.h b/reactos/include/napi/npipe.h index 3eda0f98bbf..4400c2cf86f 100644 --- a/reactos/include/napi/npipe.h +++ b/reactos/include/napi/npipe.h @@ -81,18 +81,48 @@ NTSTATUS STDCALL ZwCreateNamedPipeFile(OUT PHANDLE NamedPipeFileHandle, IN ULONG OutBufferSize, IN PLARGE_INTEGER DefaultTimeOut); +#define FSCTL_PIPE_ASSIGN_EVENT \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_WAIT_PIPE \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 1, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_DISCONNECT \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_LISTEN \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_LISTEN \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_SET_STATE \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 3, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_PEEK \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 3, METHOD_BUFFERED, FILE_READ_DATA) + +#define FSCTL_PIPE_QUERY_EVENT \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 4, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_TRANSCEIVE \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 5, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) + +#define FSCTL_PIPE_WAIT \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_IMPERSONATE \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_SET_CLIENT_PROCESS \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_QUERY_CLIENT_PROCESS \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_INTERNAL_READ \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA) + +#define FSCTL_PIPE_INTERNAL_WRITE \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2046, METHOD_BUFFERED, FILE_WRITE_DATA) + +#define FSCTL_PIPE_INTERNAL_TRANSCEIVE \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2047, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) + +#define FSCTL_PIPE_INTERNAL_READ_OVFLOW \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2048, METHOD_BUFFERED, FILE_READ_DATA) -#define FSCTL_GET_STATE \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 4, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct _NPFS_WAIT_PIPE { diff --git a/reactos/lib/kernel32/file/npipe.c b/reactos/lib/kernel32/file/npipe.c index 4b57380ba77..b52b3b332f6 100644 --- a/reactos/lib/kernel32/file/npipe.c +++ b/reactos/lib/kernel32/file/npipe.c @@ -1,4 +1,4 @@ -/* $Id: npipe.c,v 1.4 2001/03/31 01:17:29 dwelch Exp $ +/* $Id: npipe.c,v 1.5 2001/05/10 23:37:06 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -11,24 +11,25 @@ /* INCLUDES *****************************************************************/ #include -#include -#include -#include #include +#include +//#include +//#include #include #include /* FUNCTIONS ****************************************************************/ -HANDLE STDCALL CreateNamedPipeA(LPCSTR lpName, - DWORD dwOpenMode, - DWORD dwPipeMode, - DWORD nMaxInstances, - DWORD nOutBufferSize, - DWORD nInBufferSize, - DWORD nDefaultTimeOut, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) +HANDLE STDCALL +CreateNamedPipeA(LPCSTR lpName, + DWORD dwOpenMode, + DWORD dwPipeMode, + DWORD nMaxInstances, + DWORD nOutBufferSize, + DWORD nInBufferSize, + DWORD nDefaultTimeOut, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) { HANDLE NamedPipeHandle; UNICODE_STRING NameU; @@ -51,14 +52,15 @@ HANDLE STDCALL CreateNamedPipeA(LPCSTR lpName, return(NamedPipeHandle); } -HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName, - DWORD dwOpenMode, - DWORD dwPipeMode, - DWORD nMaxInstances, - DWORD nOutBufferSize, - DWORD nInBufferSize, - DWORD nDefaultTimeOut, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) +HANDLE STDCALL +CreateNamedPipeW(LPCWSTR lpName, + DWORD dwOpenMode, + DWORD dwPipeMode, + DWORD nMaxInstances, + DWORD nOutBufferSize, + DWORD nInBufferSize, + DWORD nDefaultTimeOut, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) { UNICODE_STRING NamedPipeName; BOOL Result; @@ -79,15 +81,17 @@ HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName, &NamedPipeName, NULL, NULL); - if (!Result) { + SetLastError(ERROR_PATH_NOT_FOUND); return(INVALID_HANDLE_VALUE); } + DPRINT("Pipe name: %wZ\n", &NamedPipeName); + InitializeObjectAttributes(&ObjectAttributes, &NamedPipeName, - 0, + OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -97,10 +101,10 @@ HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName, CreateDisposition = FILE_OPEN_IF; - CreateOptions = 0; + CreateOptions = 0; if (dwOpenMode & FILE_FLAG_WRITE_THROUGH) { - CreateOptions = CreateOptions | FILE_FLAG_WRITE_THROUGH; + CreateOptions = CreateOptions | FILE_WRITE_THROUGH; } if (dwOpenMode & FILE_FLAG_OVERLAPPED) { @@ -146,8 +150,8 @@ HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName, NonBlocking = FALSE; } - DefaultTimeOut.QuadPart = nDefaultTimeOut * 1000 * 1000; - + DefaultTimeOut.QuadPart = nDefaultTimeOut * 10000; + Status = NtCreateNamedPipeFile(&PipeHandle, DesiredAccess, &ObjectAttributes, @@ -162,22 +166,28 @@ HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName, nInBufferSize, nOutBufferSize, &DefaultTimeOut); + + RtlFreeUnicodeString(&NamedPipeName); + if (!NT_SUCCESS(Status)) { + DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status); SetLastErrorByStatus (Status); return(INVALID_HANDLE_VALUE); } + return(PipeHandle); } -BOOL STDCALL WaitNamedPipeA(LPCSTR lpNamedPipeName, - DWORD nTimeOut) +BOOL STDCALL +WaitNamedPipeA(LPCSTR lpNamedPipeName, + DWORD nTimeOut) { BOOL r; UNICODE_STRING NameU; ANSI_STRING NameA; - RtlInitAnsiString(&NameA, lpNamedPipeName); + RtlInitAnsiString(&NameA, (LPSTR)lpNamedPipeName); RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE); r = WaitNamedPipeW(NameU.Buffer, nTimeOut); @@ -187,8 +197,9 @@ BOOL STDCALL WaitNamedPipeA(LPCSTR lpNamedPipeName, return(r); } -BOOL STDCALL WaitNamedPipeW(LPCWSTR lpNamedPipeName, - DWORD nTimeOut) +BOOL STDCALL +WaitNamedPipeW(LPCWSTR lpNamedPipeName, + DWORD nTimeOut) { UNICODE_STRING NamedPipeName; BOOL r; @@ -198,7 +209,7 @@ BOOL STDCALL WaitNamedPipeW(LPCWSTR lpNamedPipeName, HANDLE FileHandle; IO_STATUS_BLOCK Iosb; - r = RtlDosPathNameToNtPathName_U(lpNamedPipeName, + r = RtlDosPathNameToNtPathName_U((LPWSTR)lpNamedPipeName, &NamedPipeName, NULL, NULL); @@ -225,8 +236,9 @@ BOOL STDCALL WaitNamedPipeW(LPCWSTR lpNamedPipeName, return(FALSE); } - WaitPipe.Timeout.QuadPart = nTimeOut * 1000 * 1000; + WaitPipe.Timeout.QuadPart = nTimeOut * 10000; +#if 0 Status = NtFsControlFile(FileHandle, NULL, NULL, @@ -242,27 +254,28 @@ BOOL STDCALL WaitNamedPipeW(LPCWSTR lpNamedPipeName, SetLastErrorByStatus (Status); return(FALSE); } +#endif NtClose(FileHandle); return(TRUE); } -BOOL STDCALL ConnectNamedPipe(HANDLE hNamedPipe, - LPOVERLAPPED lpOverLapped) +BOOL STDCALL +ConnectNamedPipe(HANDLE hNamedPipe, + LPOVERLAPPED lpOverlapped) { - NPFS_LISTEN ListenPipe; IO_STATUS_BLOCK Iosb; HANDLE hEvent; PIO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; - if (lpOverLapped != NULL) + if (lpOverlapped != NULL) { - lpOverLapped->Internal = STATUS_PENDING; - hEvent = lpOverLapped->hEvent; - IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped; + lpOverlapped->Internal = STATUS_PENDING; + hEvent = lpOverlapped->hEvent; + IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped; } - else + else { IoStatusBlock = &Iosb; hEvent = NULL; @@ -273,12 +286,24 @@ BOOL STDCALL ConnectNamedPipe(HANDLE hNamedPipe, NULL, NULL, IoStatusBlock, - FSCTL_LISTEN, - &ListenPipe, - sizeof(ListenPipe), + FSCTL_PIPE_LISTEN, + NULL, + 0, NULL, 0); - if (!NT_SUCCESS(Status)) + if ((lpOverlapped == NULL) && (Status == STATUS_PENDING)) + { + Status = NtWaitForSingleObject(hNamedPipe, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + Status = Iosb.Status; + } + if (!NT_SUCCESS(Status) || (Status == STATUS_PENDING)) { SetLastErrorByStatus (Status); return(FALSE); @@ -286,16 +311,18 @@ BOOL STDCALL ConnectNamedPipe(HANDLE hNamedPipe, return(TRUE); } -BOOL STDCALL SetNamedPipeHandleState(HANDLE hNamedPipe, - LPDWORD lpMode, - LPDWORD lpMaxCollectionCount, - LPDWORD lpCollectDataTimeout) +BOOL STDCALL +SetNamedPipeHandleState(HANDLE hNamedPipe, + LPDWORD lpMode, + LPDWORD lpMaxCollectionCount, + LPDWORD lpCollectDataTimeout) { NPFS_GET_STATE GetState; NPFS_SET_STATE SetState; IO_STATUS_BLOCK Iosb; NTSTATUS Status; +#if 0 Status = NtFsControlFile(hNamedPipe, NULL, NULL, @@ -311,6 +338,7 @@ BOOL STDCALL SetNamedPipeHandleState(HANDLE hNamedPipe, SetLastErrorByStatus (Status); return(FALSE); } +#endif if (lpMode != NULL) { @@ -359,6 +387,7 @@ BOOL STDCALL SetNamedPipeHandleState(HANDLE hNamedPipe, SetState.Timeout = GetState.Timeout; } +#if 0 Status = NtFsControlFile(hNamedPipe, NULL, NULL, @@ -374,6 +403,7 @@ BOOL STDCALL SetNamedPipeHandleState(HANDLE hNamedPipe, SetLastErrorByStatus (Status); return(FALSE); } +#endif return(TRUE); } @@ -394,8 +424,7 @@ CallNamedPipeA ( } -WINBOOL -STDCALL +WINBOOL STDCALL CallNamedPipeW ( LPCWSTR lpNamedPipeName, LPVOID lpInBuffer, @@ -410,18 +439,45 @@ CallNamedPipeW ( return FALSE; } -WINBOOL -STDCALL -DisconnectNamedPipe ( - HANDLE hNamedPipe - ) + +WINBOOL STDCALL +DisconnectNamedPipe(HANDLE hNamedPipe) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + + Status = NtFsControlFile(hNamedPipe, + NULL, + NULL, + NULL, + &Iosb, + FSCTL_PIPE_DISCONNECT, + NULL, + 0, + 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); } -WINBOOL -STDCALL + +WINBOOL STDCALL GetNamedPipeHandleStateW ( HANDLE hNamedPipe, LPDWORD lpState, @@ -437,8 +493,7 @@ GetNamedPipeHandleStateW ( } -WINBOOL -STDCALL +WINBOOL STDCALL GetNamedPipeHandleStateA ( HANDLE hNamedPipe, LPDWORD lpState, @@ -454,50 +509,42 @@ GetNamedPipeHandleStateA ( } -WINBOOL -STDCALL -GetNamedPipeInfo ( - HANDLE hNamedPipe, - LPDWORD lpFlags, - LPDWORD lpOutBufferSize, - LPDWORD lpInBufferSize, - LPDWORD lpMaxInstances - ) +WINBOOL STDCALL +GetNamedPipeInfo(HANDLE hNamedPipe, + LPDWORD lpFlags, + LPDWORD lpOutBufferSize, + LPDWORD lpInBufferSize, + LPDWORD lpMaxInstances) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } -WINBOOL -STDCALL -PeekNamedPipe ( - HANDLE hNamedPipe, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesRead, - LPDWORD lpTotalBytesAvail, - LPDWORD lpBytesLeftThisMessage - ) + +WINBOOL STDCALL +PeekNamedPipe(HANDLE hNamedPipe, + LPVOID lpBuffer, + DWORD nBufferSize, + LPDWORD lpBytesRead, + LPDWORD lpTotalBytesAvail, + LPDWORD lpBytesLeftThisMessage) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } -WINBOOL -STDCALL -TransactNamedPipe ( - HANDLE hNamedPipe, - LPVOID lpInBuffer, - DWORD nInBufferSize, - LPVOID lpOutBuffer, - DWORD nOutBufferSize, - LPDWORD lpBytesRead, - LPOVERLAPPED lpOverlapped - ) + +WINBOOL STDCALL +TransactNamedPipe(HANDLE hNamedPipe, + LPVOID lpInBuffer, + DWORD nInBufferSize, + LPVOID lpOutBuffer, + DWORD nOutBufferSize, + LPDWORD lpBytesRead, + LPOVERLAPPED lpOverlapped) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } - /* EOF */