Some named pipe improvements (not usable yet!).

svn path=/trunk/; revision=1902
This commit is contained in:
Eric Kohl 2001-05-10 23:38:31 +00:00
parent 4c5a154f4d
commit 7d0f1e3433
9 changed files with 502 additions and 348 deletions

View file

@ -1,99 +1,100 @@
#include <windows.h>
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;
}
#include <windows.h>
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;
}

View file

@ -2,57 +2,86 @@
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <tchar.h>
#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);
}

View file

@ -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

View file

@ -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,
&current->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, &current->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 */

View file

@ -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 <welch@cwcom.net>
* Eric Kohl <ekohl@rz-online.de>
*/
/* 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 */

View file

@ -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 <debug.h>
/* 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 */

View file

@ -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, \

View file

@ -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
{

View file

@ -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 <ddk/ntddk.h>
#include <windows.h>
#include <wchar.h>
#include <string.h>
#include <ntdll/rtl.h>
#include <windows.h>
//#include <wchar.h>
//#include <string.h>
#include <kernel32/kernel32.h>
#include <kernel32/error.h>
/* 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 */