From d13046ca0ff117a919a7f82290136bce71bf5925 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 5 May 2001 15:21:05 +0000 Subject: [PATCH] Added mailslot fs driver svn path=/trunk/; revision=1884 --- reactos/Makefile | 6 +- reactos/apps/tests/mstest/Makefile | 44 ++++ reactos/apps/tests/mstest/msclient.c | 46 ++++ reactos/apps/tests/mstest/msserver.c | 40 ++++ reactos/drivers/fs/ms/.cvsignore | 2 + reactos/drivers/fs/ms/Makefile | 55 +++++ reactos/drivers/fs/ms/create.c | 319 +++++++++++++++++++++++++++ reactos/drivers/fs/ms/finfo.c | 193 ++++++++++++++++ reactos/drivers/fs/ms/fsctrl.c | 71 ++++++ reactos/drivers/fs/ms/msfs.c | 92 ++++++++ reactos/drivers/fs/ms/msfs.h | 60 +++++ reactos/drivers/fs/ms/msfs.rc | 39 ++++ reactos/drivers/fs/ms/rw.c | 182 +++++++++++++++ reactos/install.bat | 3 + reactos/lib/kernel32/file/mailslot.c | 8 +- reactos/ntoskrnl/ldr/loader.c | 28 ++- 16 files changed, 1178 insertions(+), 10 deletions(-) create mode 100644 reactos/apps/tests/mstest/Makefile create mode 100644 reactos/apps/tests/mstest/msclient.c create mode 100644 reactos/apps/tests/mstest/msserver.c create mode 100644 reactos/drivers/fs/ms/.cvsignore create mode 100644 reactos/drivers/fs/ms/Makefile create mode 100644 reactos/drivers/fs/ms/create.c create mode 100644 reactos/drivers/fs/ms/finfo.c create mode 100644 reactos/drivers/fs/ms/fsctrl.c create mode 100644 reactos/drivers/fs/ms/msfs.c create mode 100644 reactos/drivers/fs/ms/msfs.h create mode 100644 reactos/drivers/fs/ms/msfs.rc create mode 100644 reactos/drivers/fs/ms/rw.c diff --git a/reactos/Makefile b/reactos/Makefile index df310a1aa71..2c0828f5ac0 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -42,7 +42,7 @@ DEVICE_DRIVERS = vidport vga blue ide null floppy INPUT_DRIVERS = keyboard #FS_DRIVERS = vfat minix ext2 template -FS_DRIVERS = vfat +FS_DRIVERS = vfat ms #NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd NET_DRIVERS = ndis tcpip tditest wshtcpip afd @@ -57,9 +57,7 @@ NET_DEVICE_DRIVERS = ne2000 SYS_APPS = shell winlogon services APPS = args hello test cat bench apc shm lpc thread event file gditest \ - pteb consume dump_shared_data vmtest regtest alive - -# objdir + pteb consume dump_shared_data vmtest regtest alive mstest objdir #NET_APPS = ping roshttpd NET_APPS = ping diff --git a/reactos/apps/tests/mstest/Makefile b/reactos/apps/tests/mstest/Makefile new file mode 100644 index 00000000000..0dbea99c7ff --- /dev/null +++ b/reactos/apps/tests/mstest/Makefile @@ -0,0 +1,44 @@ +# +# +# +PATH_TO_TOP = ../.. + +SRV_OBJECTS = ../common/crt0.o msserver.o +CLT_OBJECTS = ../common/crt0.o msclient.o + +PROGS = msserver.exe msclient.exe + +BASE_CFLAGS = -I../../include +LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a + +all: $(PROGS) + +.phony: all + +clean: + - $(RM) *.o + - $(RM) *.exe + - $(RM) *.sym + +.phony: clean + +install: $(PROGS:%=$(FLOPPY_DIR)/apps/%) + +$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % + $(CP) $* $(FLOPPY_DIR)/apps/$* + +dist: $(PROGS:%=../../$(DIST_DIR)/apps/%) + +$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: % + $(CP) $* ../../$(DIST_DIR)/apps/$* + +msserver.exe: $(SRV_OBJECTS) $(LIBS) + $(LD) $(SRV_OBJECTS) $(LIBS) -o msserver.exe + $(NM) --numeric-sort msserver.exe > msserver.sym + +msclient.exe: $(CLT_OBJECTS) $(LIBS) + $(LD) $(CLT_OBJECTS) $(LIBS) -o msclient.exe + $(NM) --numeric-sort msclient.exe > msclient.sym + + +include ../../rules.mak diff --git a/reactos/apps/tests/mstest/msclient.c b/reactos/apps/tests/mstest/msclient.c new file mode 100644 index 00000000000..d503caadc67 --- /dev/null +++ b/reactos/apps/tests/mstest/msclient.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +#define BUFSIZE 1024 +#define MAILSLOT_TIMEOUT 1000 + + +int main(int argc, char *argv[]) +{ + HANDLE hMailslot; + LPSTR lpszMailslotName = "\\\\.\\MAILSLOT\\mymailslot"; + LPSTR lpszTestMessage = "Mailslot test message!"; + DWORD cbLength, cbWritten; + + hMailslot = CreateFile(lpszMailslotName, + GENERIC_WRITE, + FILE_SHARE_READ, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + (HANDLE)NULL); + printf("hMailslot %x\n", (DWORD)hMailslot); + if (hMailslot == INVALID_HANDLE_VALUE) + { + printf("CreateFile() failed\n"); + return 0; + } + + cbLength = (ULONG)strlen(lpszTestMessage); + + WriteFile(hMailslot, + lpszTestMessage, + cbLength, + &cbWritten, + NULL); + + CloseHandle(hMailslot); + + return 0; +} + +/* EOF */ + diff --git a/reactos/apps/tests/mstest/msserver.c b/reactos/apps/tests/mstest/msserver.c new file mode 100644 index 00000000000..939c0aa93e9 --- /dev/null +++ b/reactos/apps/tests/mstest/msserver.c @@ -0,0 +1,40 @@ + + +#include + + +int main(int argc, char *argv[]) +{ + HANDLE hMailslot; + CHAR chBuf[512]; + BOOL fResult; + DWORD cbRead; + LPTSTR lpszMailslotName = "\\\\.\\mailslot\\mymailslot"; + + hMailslot = CreateMailslot(lpszMailslotName, + 512, + MAILSLOT_WAIT_FOREVER, + NULL); +for (;;) +{ + fResult = ReadFile(hMailslot, + chBuf, + 512, + &cbRead, + NULL); + if (fResult == FALSE) + { + printf("ReadFile() failed!\n"); + CloseHandle(hMailslot); + return 0; + } + + printf("Data read: %s\n", chBuf); +} + + CloseHandle(hMailslot); + + return 0; +} + +/* EOF */ diff --git a/reactos/drivers/fs/ms/.cvsignore b/reactos/drivers/fs/ms/.cvsignore new file mode 100644 index 00000000000..4742e3ba8b3 --- /dev/null +++ b/reactos/drivers/fs/ms/.cvsignore @@ -0,0 +1,2 @@ +msfs.coff +msfs.sys.unstripped \ No newline at end of file diff --git a/reactos/drivers/fs/ms/Makefile b/reactos/drivers/fs/ms/Makefile new file mode 100644 index 00000000000..e06698fd8b2 --- /dev/null +++ b/reactos/drivers/fs/ms/Makefile @@ -0,0 +1,55 @@ +# $Id: Makefile,v 1.1 2001/05/05 15:11:57 ekohl Exp $ +# +# Mailslot File System +# +PATH_TO_TOP = ../../.. + +TARGETNAME=msfs + +OBJECTS = create.o finfo.o fsctrl.o msfs.o rw.o msfs.coff + +LIBS = ../../../ntoskrnl/ntoskrnl.a + +all: $(TARGETNAME).sys + +.phony: all + +clean: + - $(RM) *.o + - $(RM) $(TARGETNAME).sym + - $(RM) $(TARGETNAME).sys + +.phony: clean + +$(TARGETNAME).sys: $(OBJECTS) $(LIBS) + $(CC) \ + -specs=../../svc_specs \ + -mdll \ + -o junk.tmp \ + -Wl,--defsym,_end=end \ + -Wl,--defsym,_edata=__data_end__ \ + -Wl,--defsym,_etext=etext \ + -Wl,--base-file,base.tmp \ + $(OBJECTS) $(LIBS) + $(RM) junk.tmp + $(DLLTOOL) \ + --dllname $(TARGETNAME).sys \ + --base-file base.tmp \ + --output-exp temp.exp \ + --kill-at + $(RM) base.tmp + $(CC) \ + --verbose \ + -Wl,--image-base,0x10000 \ + -Wl,-e,_DriverEntry@8 \ + -specs=../../svc_specs \ + -mdll \ + -o $(TARGETNAME).sys \ + $(OBJECTS) $(LIBS) \ + -Wl,temp.exp + $(RM) temp.exp + $(NM) --numeric-sort msfs.sys > msfs.sym + +msfs.coff: ../../../include/reactos/buildno.h msfs.rc + +include ../../../rules.mak diff --git a/reactos/drivers/fs/ms/create.c b/reactos/drivers/fs/ms/create.c new file mode 100644 index 00000000000..1a0b54e0cb0 --- /dev/null +++ b/reactos/drivers/fs/ms/create.c @@ -0,0 +1,319 @@ +/* $Id: create.c,v 1.1 2001/05/05 15:11:57 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ms/create.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include "msfs.h" + +//#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS STDCALL +MsfsCreate(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_DEVICE_EXTENSION DeviceExtension; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + PMSFS_MAILSLOT current; + PLIST_ENTRY current_entry; + KIRQL oldIrql; + + DPRINT1("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = DeviceObject->DeviceExtension; + FileObject = IoStack->FileObject; + + DPRINT1("Mailslot name: %wZ\n", &FileObject->FileName); + + Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB)); + if (Fcb == NULL) + { + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_NO_MEMORY); + } + + KeLockMutex(&DeviceExtension->MailslotListLock); + current_entry = DeviceExtension->MailslotListHead.Flink; + while (current_entry != &DeviceExtension->MailslotListHead) + { + current = CONTAINING_RECORD(current_entry, + MSFS_MAILSLOT, + MailslotListEntry); + + if (!RtlCompareUnicodeString(&FileObject->FileName, ¤t->Name, TRUE)) + { + break; + } + + current_entry = current_entry->Flink; + } + + if (current_entry == &DeviceExtension->MailslotListHead) + { + ExFreePool(Fcb); + KeUnlockMutex(&DeviceExtension->MailslotListLock); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_UNSUCCESSFUL); + } + + Mailslot = current; + + KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql); + InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry); + KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql); + + Mailslot->ReferenceCount++; + + Fcb->Mailslot = Mailslot; + + KeUnlockMutex(&DeviceExtension->MailslotListLock); + + FileObject->FsContext = Fcb; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_DEVICE_EXTENSION DeviceExtension; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + KIRQL oldIrql; + PLIST_ENTRY current_entry; + PMSFS_MAILSLOT current; + PIO_MAILSLOT_CREATE_BUFFER Buffer; + + DPRINT1("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = DeviceObject->DeviceExtension; + FileObject = IoStack->FileObject; + Buffer = (PIO_MAILSLOT_CREATE_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer; + + DPRINT1("Mailslot name: %wZ\n", &FileObject->FileName); + + Mailslot = ExAllocatePool(NonPagedPool, sizeof(MSFS_MAILSLOT)); + if (Mailslot == NULL) + { + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_NO_MEMORY); + } + + if (!RtlCreateUnicodeString(&Mailslot->Name, FileObject->FileName.Buffer)) + { + ExFreePool(Mailslot); + ExFreePool(Fcb); + + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_NO_MEMORY); + } + + Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB)); + if (Fcb == NULL) + { + ExFreePool(Mailslot); + + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_NO_MEMORY); + } + + Mailslot->ReferenceCount = 0; + InitializeListHead(&Mailslot->FcbListHead); + KeInitializeSpinLock(&Mailslot->FcbListLock); + + Mailslot->MaxMessageSize = Buffer->MaxMessageSize; + Mailslot->MessageCount = 0; + Mailslot->TimeOut = Buffer->TimeOut; + KeInitializeEvent(&Mailslot->MessageEvent, + NotificationEvent, + FALSE); + + InitializeListHead(&Mailslot->MessageListHead); + KeInitializeSpinLock(&Mailslot->MessageListLock); + + KeLockMutex(&DeviceExtension->MailslotListLock); + current_entry = DeviceExtension->MailslotListHead.Flink; + while (current_entry != &DeviceExtension->MailslotListHead) + { + current = CONTAINING_RECORD(current_entry, + MSFS_MAILSLOT, + MailslotListEntry); + + if (!RtlCompareUnicodeString(&Mailslot->Name, ¤t->Name, TRUE)) + { + break; + } + + current_entry = current_entry->Flink; + } + + if (current_entry != &DeviceExtension->MailslotListHead) + { + RtlFreeUnicodeString(&Mailslot->Name); + ExFreePool(Mailslot); + + Mailslot = current; + } + else + { + InsertTailList(&DeviceExtension->MailslotListHead, + &Mailslot->MailslotListEntry); + } + + KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql); + InsertTailList(&Mailslot->FcbListHead, &Fcb->FcbListEntry); + KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql); + + Mailslot->ReferenceCount++; + Mailslot->ServerFcb = Fcb; + Fcb->Mailslot = Mailslot; + + KeUnlockMutex(&DeviceExtension->MailslotListLock); + + FileObject->FsContext = Fcb; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +MsfsClose(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_DEVICE_EXTENSION DeviceExtension; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + PMSFS_MESSAGE Message; + KIRQL oldIrql; + + DPRINT1("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = DeviceObject->DeviceExtension; + FileObject = IoStack->FileObject; + + KeLockMutex(&DeviceExtension->MailslotListLock); + + if (DeviceExtension->MailslotListHead.Flink == &DeviceExtension->MailslotListHead) + { + KeUnlockMutex(&DeviceExtension->MailslotListLock); +CHECKPOINT1; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +CHECKPOINT1; + + return(STATUS_SUCCESS); + } + + Fcb = FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT1("Mailslot name: %wZ\n", &Mailslot->Name); + + Mailslot->ReferenceCount--; +CHECKPOINT1; + if (Mailslot->ServerFcb == Fcb) + { +CHECKPOINT1; + /* delete all messages from message-list */ + KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql); + + while (Mailslot->MessageListHead.Flink != &Mailslot->MessageListHead) + { + Message = CONTAINING_RECORD(Mailslot->MessageListHead.Flink, + MSFS_MESSAGE, + MessageListEntry); + RemoveEntryList(Mailslot->MessageListHead.Flink); + ExFreePool(Message); + } + Mailslot->MessageCount = 0; + + KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql); + Mailslot->ServerFcb = NULL; + } +CHECKPOINT1; + + KeAcquireSpinLock(&Mailslot->FcbListLock, &oldIrql); + RemoveEntryList(&Fcb->FcbListEntry); + KeReleaseSpinLock(&Mailslot->FcbListLock, oldIrql); + ExFreePool(Fcb); + FileObject->FsContext = NULL; +CHECKPOINT1; + + if (Mailslot->ReferenceCount == 0) + { + DPRINT1("ReferenceCount == 0: Deleting mailslot data\n"); + RtlFreeUnicodeString(&Mailslot->Name); + RemoveEntryList(&Mailslot->MailslotListEntry); + ExFreePool(Mailslot); + } +CHECKPOINT1; + + KeUnlockMutex(&DeviceExtension->MailslotListLock); +CHECKPOINT1; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +CHECKPOINT1; + + return(STATUS_SUCCESS); +} + +/* EOF */ diff --git a/reactos/drivers/fs/ms/finfo.c b/reactos/drivers/fs/ms/finfo.c new file mode 100644 index 00000000000..776221e352c --- /dev/null +++ b/reactos/drivers/fs/ms/finfo.c @@ -0,0 +1,193 @@ +/* $Id: finfo.c,v 1.1 2001/05/05 15:11:57 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ms/finfo.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include "msfs.h" + +//#define NDEBUG +#include + + + +static NTSTATUS +MsfsQueryMailslotInformation(PMSFS_FCB Fcb, + PFILE_MAILSLOT_QUERY_INFORMATION Buffer); + +static NTSTATUS +MsfsSetMailslotInformation(PMSFS_FCB Fcb, + PFILE_MAILSLOT_SET_INFORMATION Buffer); + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS STDCALL +MsfsQueryInformation(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + FILE_INFORMATION_CLASS FileInformationClass; + PFILE_OBJECT FileObject; + PMSFS_DEVICE_EXTENSION DeviceExtension; + PMSFS_FCB Fcb; + PMSFS_MAILSLOT Mailslot; + NTSTATUS Status; + PVOID Buffer; + + DPRINT1("MsfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation (Irp); + FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass; + DeviceExtension = DeviceObject->DeviceExtension; + FileObject = IoStack->FileObject; + Fcb = (PMSFS_FCB)FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT1("Mailslot name: %wZ\n", &Mailslot->Name); + + /* querying information is not permitted on client side */ + if (Fcb->Mailslot->ServerFcb != Fcb) + { + Status = STATUS_ACCESS_DENIED; + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(Status); + } + + // FIXME : determine Buffer for result : + if (Irp->MdlAddress) + Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + else + Buffer = Irp->UserBuffer; + + switch (FileInformationClass) + { + case FileMailslotQueryInformation: + Status = MsfsQueryMailslotInformation(Fcb, + (PFILE_MAILSLOT_QUERY_INFORMATION)Buffer); + break; + default: + Status = STATUS_NOT_IMPLEMENTED; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + return(Status); +} + + +static NTSTATUS +MsfsQueryMailslotInformation(PMSFS_FCB Fcb, + PFILE_MAILSLOT_QUERY_INFORMATION Buffer) +{ + PMSFS_MAILSLOT Mailslot; + KIRQL oldIrql; + + Mailslot = Fcb->Mailslot; + + Buffer->MaxMessageSize = Mailslot->MaxMessageSize; + Buffer->Timeout = Mailslot->TimeOut; + + KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql); + Buffer->MessageCount = Mailslot->MessageCount; + if (Mailslot->MessageCount == 0) + { + Buffer->NextSize = 0; + } + else + { + /* FIXME: read size of first message (head) */ + Buffer->NextSize = 0; + } + KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql); + + return(STATUS_SUCCESS); +} + + + +NTSTATUS STDCALL +MsfsSetInformation(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + FILE_INFORMATION_CLASS FileInformationClass; + PFILE_OBJECT FileObject; + PMSFS_FCB Fcb; + PMSFS_MAILSLOT Mailslot; + PVOID Buffer; + NTSTATUS Status; + + DPRINT1("MsfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation (Irp); + FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass; + FileObject = IoStack->FileObject; + Fcb = (PMSFS_FCB)FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT1("Mailslot name: %wZ\n", &Mailslot->Name); + + /* setting information is not permitted on client side */ + if (Fcb->Mailslot->ServerFcb != Fcb) + { + Status = STATUS_ACCESS_DENIED; + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(Status); + } + + // FIXME : determine Buffer for result : + if (Irp->MdlAddress) + Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + else + Buffer = Irp->UserBuffer; + + DPRINT("FileInformationClass %d\n", FileInformationClass); + DPRINT("Buffer %x\n", Buffer); + + switch (FileInformationClass) + { + case FileMailslotSetInformation: + Status = MsfsSetMailslotInformation(Fcb, + (PFILE_MAILSLOT_SET_INFORMATION)Buffer); + break; + default: + Status = STATUS_NOT_IMPLEMENTED; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(Status); +} + + +static NTSTATUS +MsfsSetMailslotInformation(PMSFS_FCB Fcb, + PFILE_MAILSLOT_SET_INFORMATION Buffer) +{ + Fcb->Mailslot->TimeOut = Buffer->Timeout; + + return(STATUS_SUCCESS); +} + + +/* EOF */ diff --git a/reactos/drivers/fs/ms/fsctrl.c b/reactos/drivers/fs/ms/fsctrl.c new file mode 100644 index 00000000000..5281350186a --- /dev/null +++ b/reactos/drivers/fs/ms/fsctrl.c @@ -0,0 +1,71 @@ +/* $Id: fsctrl.c,v 1.1 2001/05/05 15:11:57 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ms/fsctrl.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include "msfs.h" + +//#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS STDCALL +MsfsFileSystemControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + NTSTATUS Status; + + DPRINT1("MsfsFileSystemControl(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + FileObject = IoStack->FileObject; + Fcb = FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT1("Mailslot name: %wZ\n", &Mailslot->Name); + + switch (IoStack->Parameters.FileSystemControl.IoControlCode) + { +#if 0 + case FSCTL_WAIT_PIPE: + break; + + case FSCTL_LISTEN: + break; + + case FSCTL_SET_STATE: + break; + + case FSCTL_GET_STATE: + { + + + break; + } + +#endif + default: + Status = STATUS_NOT_IMPLEMENTED; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + return(Status); +} + +/* EOF */ diff --git a/reactos/drivers/fs/ms/msfs.c b/reactos/drivers/fs/ms/msfs.c new file mode 100644 index 00000000000..a11c025603f --- /dev/null +++ b/reactos/drivers/fs/ms/msfs.c @@ -0,0 +1,92 @@ +/* $Id: msfs.c,v 1.1 2001/05/05 15:11:57 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ms/msfs.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include "msfs.h" + +#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS STDCALL +DriverEntry(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) +{ + PMSFS_DEVICE_EXTENSION DeviceExtension; + PDEVICE_OBJECT DeviceObject; + UNICODE_STRING DeviceName; + UNICODE_STRING LinkName; + NTSTATUS Status; + + DbgPrint("Mailslot FSD 0.0.1\n"); + + RtlInitUnicodeString(&DeviceName, + L"\\Device\\MailSlot"); + Status = IoCreateDevice(DriverObject, + sizeof(MSFS_DEVICE_EXTENSION), + &DeviceName, + FILE_DEVICE_MAILSLOT, + 0, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + DeviceObject->Flags = 0; + DriverObject->MajorFunction[IRP_MJ_CREATE] = MsfsCreate; + DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = + MsfsCreateMailslot; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = MsfsClose; + DriverObject->MajorFunction[IRP_MJ_READ] = MsfsRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = MsfsWrite; + DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = + MsfsQueryInformation; + DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = + MsfsSetInformation; +// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = +// MsfsDirectoryControl; +// DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = MsfsFlushBuffers; +// DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = MsfsShutdown; +// DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = +// MsfsQuerySecurity; +// DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = +// MsfsSetSecurity; + DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = + MsfsFileSystemControl; + + DriverObject->DriverUnload = NULL; + +//#if 0 + RtlInitUnicodeString(&LinkName, + L"\\??\\MAILSLOT"); + Status = IoCreateSymbolicLink(&LinkName, + &DeviceName); + if (!NT_SUCCESS(Status)) + { +// IoDeleteDevice(); + return(Status); + } +//#endif + + /* initialize device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + InitializeListHead(&DeviceExtension->MailslotListHead); + KeInitializeMutex(&DeviceExtension->MailslotListLock, + 0); + + return(STATUS_SUCCESS); +} + +/* EOF */ diff --git a/reactos/drivers/fs/ms/msfs.h b/reactos/drivers/fs/ms/msfs.h new file mode 100644 index 00000000000..4f7da5439f7 --- /dev/null +++ b/reactos/drivers/fs/ms/msfs.h @@ -0,0 +1,60 @@ +#ifndef __SERVICES_FS_MS_MSFS_H +#define __SERVICES_FS_MS_MSFS_H + +typedef struct _MSFS_DEVICE_EXTENSION +{ + LIST_ENTRY MailslotListHead; + KMUTEX MailslotListLock; +} MSFS_DEVICE_EXTENSION, *PMSFS_DEVICE_EXTENSION; + +typedef struct _MSFS_MAILSLOT +{ + UNICODE_STRING Name; + LIST_ENTRY MailslotListEntry; + KSPIN_LOCK FcbListLock; + LIST_ENTRY FcbListHead; + struct _MSFS_FCB *ServerFcb; + ULONG ReferenceCount; + LARGE_INTEGER TimeOut; + KEVENT MessageEvent; + ULONG MaxMessageSize; + ULONG MessageCount; + KSPIN_LOCK MessageListLock; + LIST_ENTRY MessageListHead; +} MSFS_MAILSLOT, *PMSFS_MAILSLOT; + +typedef struct _MSFS_FCB +{ + LIST_ENTRY FcbListEntry; + PMSFS_MAILSLOT Mailslot; +} MSFS_FCB, *PMSFS_FCB; + +typedef struct _MSFS_MESSAGE +{ + LIST_ENTRY MessageListEntry; + ULONG Size; + UCHAR Buffer[1]; +} MSFS_MESSAGE, *PMSFS_MESSAGE; + + +#define KeLockMutex(x) KeWaitForSingleObject(x, \ + UserRequest, \ + KernelMode, \ + FALSE, \ + NULL); + +#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE); + +NTSTATUS STDCALL MsfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS STDCALL MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS STDCALL MsfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +NTSTATUS STDCALL MsfsQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS STDCALL MsfsSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +NTSTATUS STDCALL MsfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS STDCALL MsfsWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +NTSTATUS STDCALL MsfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +#endif /* __SERVICES_FS_NP_NPFS_H */ diff --git a/reactos/drivers/fs/ms/msfs.rc b/reactos/drivers/fs/ms/msfs.rc new file mode 100644 index 00000000000..a3a164d5428 --- /dev/null +++ b/reactos/drivers/fs/ms/msfs.rc @@ -0,0 +1,39 @@ + +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "Mailslot IFS Driver\0" + VALUE "FileVersion", "0.0.1\0" + VALUE "InternalName", "msfs\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "msfs.sys\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/reactos/drivers/fs/ms/rw.c b/reactos/drivers/fs/ms/rw.c new file mode 100644 index 00000000000..9a6c248d5c2 --- /dev/null +++ b/reactos/drivers/fs/ms/rw.c @@ -0,0 +1,182 @@ +/* $Id: rw.c,v 1.1 2001/05/05 15:11:57 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ms/rw.c + * PURPOSE: Mailslot filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#include "msfs.h" + +//#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS STDCALL +MsfsRead(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + PMSFS_MESSAGE Message; + KIRQL oldIrql; + ULONG Length; + ULONG LengthRead = 0; + PVOID Buffer; + NTSTATUS Status; + + DPRINT("MsfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation (Irp); + FileObject = IoStack->FileObject; + Fcb = (PMSFS_FCB)FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT("MailslotName: %wZ\n", &Mailslot->Name); + + /* reading is not permitted on client side */ + if (Fcb->Mailslot->ServerFcb != Fcb) + { + Irp->IoStatus.Status = STATUS_ACCESS_DENIED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_ACCESS_DENIED); + } + + Length = IoStack->Parameters.Read.Length; + if (Irp->MdlAddress) + Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + else + Buffer = Irp->UserBuffer; + + Status = KeWaitForSingleObject(&Mailslot->MessageEvent, + UserRequest, + KernelMode, + FALSE, + NULL); /* FIXME: handle timeout */ +CHECKPOINT1; + if ((NT_SUCCESS(Status)) && (Mailslot->MessageCount > 0)) + { + /* copy current message into buffer */ + Message = CONTAINING_RECORD(Mailslot->MessageListHead.Flink, + MSFS_MESSAGE, + MessageListEntry); + memcpy(Buffer, &Message->Buffer, min(Message->Size,Length)); + LengthRead = Message->Size; +CHECKPOINT1; + KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql); +CHECKPOINT1; + RemoveHeadList(&Mailslot->MessageListHead); +CHECKPOINT1; + KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql); +CHECKPOINT1; + ExFreePool(Message); +CHECKPOINT1; + Mailslot->MessageCount--; +CHECKPOINT1; + if (Mailslot->MessageCount == 0) + { +CHECKPOINT1; + KeClearEvent(&Mailslot->MessageEvent); + } + } +CHECKPOINT1; + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = LengthRead; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(Status); +} + + +NTSTATUS STDCALL +MsfsWrite(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PMSFS_MAILSLOT Mailslot; + PMSFS_FCB Fcb; + PMSFS_MESSAGE Message; + KIRQL oldIrql; + ULONG Length; + PVOID Buffer; + + DPRINT1("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + IoStack = IoGetCurrentIrpStackLocation (Irp); + FileObject = IoStack->FileObject; + Fcb = (PMSFS_FCB)FileObject->FsContext; + Mailslot = Fcb->Mailslot; + + DPRINT1("MailslotName: %wZ\n", &Mailslot->Name); + + /* writing is not permitted on server side */ + if (Fcb->Mailslot->ServerFcb == Fcb) + { + Irp->IoStatus.Status = STATUS_ACCESS_DENIED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_ACCESS_DENIED); + } + + Length = IoStack->Parameters.Write.Length; + if (Irp->MdlAddress) + Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + else + Buffer = Irp->UserBuffer; + + DPRINT("Length: %lu Message: %s\n", Length, (PUCHAR)Buffer); + + /* Allocate new message */ + Message = ExAllocatePool(NonPagedPool, + sizeof(MSFS_MESSAGE) + Length); + if (Message == NULL) + { + Irp->IoStatus.Status = STATUS_NO_MEMORY; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_NO_MEMORY); + } + + Message->Size = Length; + memcpy(&Message->Buffer, Buffer, Length); + + KeAcquireSpinLock(&Mailslot->MessageListLock, &oldIrql); + InsertTailList(&Mailslot->MessageListHead, &Message->MessageListEntry); + KeReleaseSpinLock(&Mailslot->MessageListLock, oldIrql); + + Mailslot->MessageCount++; + if (Mailslot->MessageCount == 1) + { + KeSetEvent(&Mailslot->MessageEvent, + 0, + FALSE); + } + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = Length; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_SUCCESS); +} + +/* EOF */ diff --git a/reactos/install.bat b/reactos/install.bat index 2bc3171236b..8c2676ea2b1 100644 --- a/reactos/install.bat +++ b/reactos/install.bat @@ -10,6 +10,7 @@ copy boot.bat c:\reactos copy loaders\dos\loadros.com c:\reactos copy ntoskrnl\ntoskrnl.exe c:\reactos copy services\fs\vfat\vfatfs.sys c:\reactos +copy services\fs\ms\msfs.sys c:\reactos\system32\drivers copy services\bus\acpi\acpi.sys c:\reactos copy services\bus\isapnp\isapnp.sys c:\reactos copy services\dd\ide\ide.sys c:\reactos @@ -50,5 +51,7 @@ copy apps\pteb\pteb.exe c:\reactos\bin copy apps\consume\consume.exe c:\reactos\bin copy apps\vmtest\vmtest.exe c:\reactos\bin copy apps\gditest\gditest.exe c:\reactos\bin +copy apps\mstest\msserver.exe c:\reactos\bin +copy apps\mstest\msclient.exe c:\reactos\bin copy media\fonts\helb____.ttf c:\reactos\media\fonts copy media\fonts\timr____.ttf c:\reactos\media\fonts diff --git a/reactos/lib/kernel32/file/mailslot.c b/reactos/lib/kernel32/file/mailslot.c index b93678fc5dd..141baba4641 100644 --- a/reactos/lib/kernel32/file/mailslot.c +++ b/reactos/lib/kernel32/file/mailslot.c @@ -1,4 +1,4 @@ -/* $Id: mailslot.c,v 1.3 2001/05/03 06:10:29 ekohl Exp $ +/* $Id: mailslot.c,v 1.4 2001/05/05 15:21:05 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -71,7 +71,7 @@ CreateMailslotW(LPCWSTR lpName, InitializeObjectAttributes(&ObjectAttributes, &MailslotName, - 0, + OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -136,7 +136,7 @@ GetMailslotInfo(HANDLE hMailslot, } if (lpReadTimeout != NULL) { - *lpReadTimeout = (DWORD)(Buffer.Timeout.QuadPart / 10000); + *lpReadTimeout = (DWORD)(Buffer.Timeout.QuadPart / -10000); } return(TRUE); @@ -151,7 +151,7 @@ SetMailslotInfo(HANDLE hMailslot, IO_STATUS_BLOCK Iosb; NTSTATUS Status; - Buffer.Timeout.QuadPart = lReadTimeout * 10000; + Buffer.Timeout.QuadPart = lReadTimeout * -10000; Status = NtSetInformationFile(hMailslot, &Iosb, diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 711be345195..841660b8a36 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.77 2001/05/01 23:08:20 chorns Exp $ +/* $Id: loader.c,v 1.78 2001/05/05 15:19:14 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -42,6 +42,7 @@ /* MACROS ********************************************************************/ #define MODULE_ROOT_NAME L"\\Modules\\" +#define FILESYSTEM_ROOT_NAME L"\\FileSystem\\" /* GLOBALS *******************************************************************/ @@ -175,6 +176,19 @@ VOID LdrInitModuleManagement(VOID) Status = NtCreateDirectoryObject(&DirHandle, 0, &ObjectAttributes); assert(NT_SUCCESS(Status)); + /* Create FileSystem object directory */ + wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME); + *(wcsrchr(NameBuffer, L'\\')) = 0; + RtlInitUnicodeString (&ModuleName, NameBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &ModuleName, + 0, + NULL, + NULL); + DPRINT("Create dir: %wZ\n", &ModuleName); + Status = NtCreateDirectoryObject(&DirHandle, 0, &ObjectAttributes); + assert(NT_SUCCESS(Status)); + /* Add module entry for NTOSKRNL */ wcscpy(NameBuffer, MODULE_ROOT_NAME); wcscat(NameBuffer, L"ntoskrnl.exe"); @@ -654,7 +668,17 @@ VOID LdrLoadAutoConfigDrivers (VOID) * Minix filesystem driver */ LdrLoadAutoConfigDriver(L"minixfs.sys"); - + + /* + * Mailslot filesystem driver + */ + LdrLoadAutoConfigDriver(L"msfs.sys"); + + /* + * Named pipe filesystem driver + */ +// LdrLoadAutoConfigDriver(L"npfs.sys"); + /* * Networking */