diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 6caa3177..143e1eca 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -21,6 +21,139 @@ #include +/* + * File System + */ +typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; +typedef VOID FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); +typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); +typedef struct _FSP_FILE_SYSTEM_INTERFACE +{ + NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, PDWORD PFileAttributes, + PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize); +#if 0 + NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE **PFileNode); + NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE **PFileNode); + NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN ReplaceFileAttributes, FSP_FILE_NODE *FileNode); + VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode, BOOLEAN Delete); + VOID (*Close)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode); +#endif +} FSP_FILE_SYSTEM_INTERFACE; +typedef struct _FSP_FILE_SYSTEM +{ + UINT16 Version; + WCHAR VolumePath[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)]; + HANDLE VolumeHandle; + PVOID UserContext; + NTSTATUS DispatcherResult; + FSP_FILE_SYSTEM_DISPATCHER *Dispatcher; + FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, *LeaveOperation; + FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; + const FSP_FILE_SYSTEM_INTERFACE *Interface; +} FSP_FILE_SYSTEM; + +FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, + const FSP_FILE_SYSTEM_INTERFACE *Interface, + FSP_FILE_SYSTEM **PFileSystem); +FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem); +FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem); + +FSP_API VOID FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); +FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); +static inline +VOID FspFileSystemSetDispatcher(FSP_FILE_SYSTEM *FileSystem, + FSP_FILE_SYSTEM_DISPATCHER *Dispatcher, + FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, + FSP_FILE_SYSTEM_DISPATCHER *LeaveOperation) +{ + FileSystem->Dispatcher = Dispatcher; + FileSystem->EnterOperation = EnterOperation; + FileSystem->LeaveOperation = LeaveOperation; +} +static inline +VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem, + ULONG Index, + FSP_FILE_SYSTEM_OPERATION *Operation) +{ + FileSystem->Operations[Index] = Operation; +} + +static inline +VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS *PDispatcherResult) +{ + /* 32-bit reads are atomic */ + *PDispatcherResult = FileSystem->DispatcherResult; + MemoryBarrier(); +} +static inline +VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS DispatcherResult) +{ + if (NT_SUCCESS(DispatcherResult)) + return; + InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0); +} + +static inline +VOID FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) +{ + if (0 != FileSystem->EnterOperation) + FileSystem->EnterOperation(FileSystem, Request); +} +static inline +VOID FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) +{ + if (0 != FileSystem->LeaveOperation) + FileSystem->LeaveOperation(FileSystem, Request); +} + +FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result); + +/* + * File System Operations + */ +FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID); +FSP_API NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck, + DWORD DesiredAccess, PDWORD PGrantedAccess); +FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); +FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); +FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); +FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request); + +/* + * Path Handling + */ +FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain); +FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix); +FSP_API VOID FspPathCombine(PWSTR Prefix, PWSTR Suffix); + +/* + * Utility + */ +FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error); +FSP_API VOID FspDebugLog(const char *format, ...); + +#if 0 /* * File Nodes */ @@ -218,18 +351,6 @@ FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request); FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request); - -/* - * Path Handling - */ -FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain); -FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix); -FSP_API VOID FspPathCombine(PWSTR Prefix, PWSTR Suffix); - -/* - * Utility - */ -FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error); -FSP_API VOID FspDebugLog(const char *format, ...); +#endif #endif diff --git a/src/dll/cleanup.c b/src/dll/cleanup.c index 93411bd8..b18893a4 100644 --- a/src/dll/cleanup.c +++ b/src/dll/cleanup.c @@ -6,24 +6,13 @@ #include -#if 0 -FSP_API VOID FspShareAccessRemove(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode) +FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) { - if (Request->Req.Cleanup.ReadAccess || - Request->Req.Cleanup.WriteAccess || - Request->Req.Cleanup.DeleteAccess) - { - FileNode->ShareAccess.OpenCount--; - FileNode->ShareAccess.Readers -= Request->Req.Cleanup.ReadAccess; - FileNode->ShareAccess.Writers -= Request->Req.Cleanup.WriteAccess; - FileNode->ShareAccess.Deleters -= Request->Req.Cleanup.DeleteAccess; - FileNode->ShareAccess.SharedRead -= Request->Req.Cleanup.SharedRead; - FileNode->ShareAccess.SharedWrite -= Request->Req.Cleanup.SharedWrite; - FileNode->ShareAccess.SharedDelete -= Request->Req.Cleanup.SharedDelete; - } + return STATUS_INVALID_DEVICE_REQUEST; } +#if 0 FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) { diff --git a/src/dll/close.c b/src/dll/close.c index 14250550..d85c9b18 100644 --- a/src/dll/close.c +++ b/src/dll/close.c @@ -6,6 +6,13 @@ #include +FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) +{ + return STATUS_INVALID_DEVICE_REQUEST; +} + +#if 0 FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) { @@ -32,3 +39,4 @@ FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem, Response.IoStatus.Information = 0; return FspFileSystemSendResponse(FileSystem, &Response); } +#endif diff --git a/src/dll/create.c b/src/dll/create.c index 2af7fd3a..13d2a9ea 100644 --- a/src/dll/create.c +++ b/src/dll/create.c @@ -166,60 +166,8 @@ exit: return Result; } -FSP_API NTSTATUS FspShareAccessCheck(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode) -{ - DWORD ShareAccess = Request->Req.Create.ShareAccess; - BOOLEAN ReadAccess, WriteAccess, DeleteAccess; - BOOLEAN SharedRead, SharedWrite, SharedDelete; - ULONG OpenCount; - - ReadAccess = 0 != (GrantedAccess & (FILE_READ_DATA | FILE_EXECUTE)); - WriteAccess = 0 != (GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)); - DeleteAccess = 0 != (GrantedAccess & DELETE); - - if (ReadAccess || WriteAccess || DeleteAccess) - { - SharedRead = 0 != (ShareAccess & FILE_SHARE_READ); - SharedWrite = 0 != (ShareAccess & FILE_SHARE_WRITE); - SharedDelete = 0 != (ShareAccess & FILE_SHARE_DELETE); - - OpenCount = FileNode->ShareAccess.OpenCount; - - /* - * IF ReadAccess AND there are already some exclusive readers - * OR WriteAccess AND there are already some exclusive writers - * OR DeleteAccess AND there are already some exclusive deleters - * OR exclusive read requested AND there are already some readers - * OR exclusive write requested AND there are already some writers - * OR exclusive delete requested AND there are already some deleters - */ - if (ReadAccess && (FileNode->ShareAccess.SharedRead < OpenCount)) - return STATUS_SHARING_VIOLATION; - if (WriteAccess && (FileNode->ShareAccess.SharedWrite < OpenCount)) - return STATUS_SHARING_VIOLATION; - if (DeleteAccess && (FileNode->ShareAccess.SharedDelete < OpenCount)) - return STATUS_SHARING_VIOLATION; - if (!SharedRead && 0 != FileNode->ShareAccess.Readers) - return STATUS_SHARING_VIOLATION; - if (!SharedWrite && 0 != FileNode->ShareAccess.Writers) - return STATUS_SHARING_VIOLATION; - if (!SharedDelete && 0 != FileNode->ShareAccess.Deleters) - return STATUS_SHARING_VIOLATION; - - FileNode->ShareAccess.OpenCount++; - FileNode->ShareAccess.Readers += ReadAccess; - FileNode->ShareAccess.Writers += WriteAccess; - FileNode->ShareAccess.Deleters += DeleteAccess; - FileNode->ShareAccess.SharedRead += SharedRead; - FileNode->ShareAccess.SharedWrite += SharedWrite; - FileNode->ShareAccess.SharedDelete += SharedDelete; - } - - return STATUS_SUCCESS; -} - -FSP_API NTSTATUS FspFileSystemPreCreateCheck(FSP_FILE_SYSTEM *FileSystem, +static inline +NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess) { NTSTATUS Result; @@ -235,57 +183,16 @@ FSP_API NTSTATUS FspFileSystemPreCreateCheck(FSP_FILE_SYSTEM *FileSystem, return Result; } -FSP_API VOID FspFileSystemPostCreateCheck(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode) -{ - FspFileNodeLock(FileNode); - - FspShareAccessCheck(FileSystem, Request, GrantedAccess, FileNode); - - if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) - FileNode->Flags.DeleteOnClose = TRUE; - - FspFileNodeOpen(FileNode); - - FspFileNodeUnlock(FileNode); -} - -FSP_API NTSTATUS FspFileSystemPreOpenCheck(FSP_FILE_SYSTEM *FileSystem, +static inline +NTSTATUS FspFileSystemPreOpenCheck(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess) { return FspAccessCheck(FileSystem, Request, FALSE, AllowTraverseCheck, Request->Req.Create.DesiredAccess, PGrantedAccess); } -FSP_API NTSTATUS FspFileSystemPostOpenCheck(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode) -{ - NTSTATUS Result; - - FspFileNodeLock(FileNode); - - if (FileNode->Flags.DeletePending) - { - Result = STATUS_DELETE_PENDING; - goto exit; - } - - Result = FspShareAccessCheck(FileSystem, Request, GrantedAccess, FileNode); - if (!NT_SUCCESS(Result)) - goto exit; - - if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) - FileNode->Flags.DeleteOnClose = TRUE; - - FspFileNodeOpen(FileNode); - -exit: - FspFileNodeUnlock(FileNode); - - return Result; -} - -FSP_API NTSTATUS FspFileSystemPreOverwriteCheck(FSP_FILE_SYSTEM *FileSystem, +static inline +NTSTATUS FspFileSystemOverwriteCheck(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess) { NTSTATUS Result; @@ -305,12 +212,19 @@ FSP_API NTSTATUS FspFileSystemPreOverwriteCheck(FSP_FILE_SYSTEM *FileSystem, return Result; } -FSP_API NTSTATUS FspFileSystemPostOverwriteCheck(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode) +FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) { - return FspFileSystemPostOpenCheck(FileSystem, Request, GrantedAccess, FileNode); + return STATUS_INVALID_DEVICE_REQUEST; } +FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request) +{ + return STATUS_INVALID_DEVICE_REQUEST; +} + +#if 0 static BOOLEAN FspIsRootDirectory(PWSTR FileName) { for (PWSTR Pointer = FileName; *Pointer; Pointer++) @@ -621,3 +535,4 @@ FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem, Response.Rsp.Create.Opened.GrantedAccess = GrantedAccess; return FspFileSystemSendResponse(FileSystem, &Response); } +#endif diff --git a/src/dll/loop.c b/src/dll/loop.c index 719d29a2..131dd80c 100644 --- a/src/dll/loop.c +++ b/src/dll/loop.c @@ -43,6 +43,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, FileSystem->Dispatcher = FspFileSystemDirectDispatcher; FileSystem->Operations[FspFsctlTransactCreateKind] = FspFileSystemOpCreate; + FileSystem->Operations[FspFsctlTransactOverwriteKind] = FspFileSystemOpOverwrite; FileSystem->Operations[FspFsctlTransactCleanupKind] = FspFileSystemOpCleanup; FileSystem->Operations[FspFsctlTransactCloseKind] = FspFileSystemOpClose; // !!!: ...