diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj
index 1111e220..b82dad36 100644
--- a/build/VStudio/winfsp_dll.vcxproj
+++ b/build/VStudio/winfsp_dll.vcxproj
@@ -24,18 +24,14 @@
-
-
-
+
-
+
-
-
diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters
index 2c9fd85c..1cc5a36a 100644
--- a/build/VStudio/winfsp_dll.vcxproj.filters
+++ b/build/VStudio/winfsp_dll.vcxproj.filters
@@ -37,28 +37,16 @@
Source
-
- Source
-
Source
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
Source
-
+
+ Source
+
+
Source
diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h
index 7dfe852f..9920e37a 100644
--- a/inc/winfsp/winfsp.h
+++ b/inc/winfsp/winfsp.h
@@ -166,18 +166,6 @@ VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
/*
* File System Operations
*/
-FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID);
-FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request,
- BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
- UINT32 DesiredAccess, PUINT32 PGrantedAccess,
- PSECURITY_DESCRIPTOR *PSecurityDescriptor);
-FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request,
- PSECURITY_DESCRIPTOR ParentDescriptor,
- PSECURITY_DESCRIPTOR *PSecurityDescriptor);
-FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
@@ -198,6 +186,22 @@ FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
+
+/*
+ * Access
+ */
+FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID);
+FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request,
+ BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
+ UINT32 DesiredAccess, PUINT32 PGrantedAccess,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor);
+FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request,
+ PSECURITY_DESCRIPTOR ParentDescriptor,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor);
+FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ NTSTATUS (*CreateFunc)());
static inline
NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
diff --git a/src/dll/access.c b/src/dll/access.c
new file mode 100644
index 00000000..a2b73537
--- /dev/null
+++ b/src/dll/access.c
@@ -0,0 +1,234 @@
+/**
+ * @file dll/access.c
+ *
+ * @copyright 2015 Bill Zissimopoulos
+ */
+
+#include
+
+static GENERIC_MAPPING FspFileGenericMapping =
+{
+ .GenericRead = FILE_GENERIC_READ,
+ .GenericWrite = FILE_GENERIC_WRITE,
+ .GenericExecute = FILE_GENERIC_EXECUTE,
+ .GenericAll = FILE_ALL_ACCESS,
+};
+
+FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID)
+{
+ return &FspFileGenericMapping;
+}
+
+static NTSTATUS FspGetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
+ PWSTR FileName, PUINT32 PFileAttributes,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
+{
+ for (;;)
+ {
+ NTSTATUS Result = FileSystem->Interface->GetSecurityByName(FileSystem,
+ FileName, PFileAttributes, *PSecurityDescriptor, PSecurityDescriptorSize);
+ if (STATUS_BUFFER_OVERFLOW != Result)
+ return Result;
+
+ MemFree(*PSecurityDescriptor);
+ *PSecurityDescriptor = MemAlloc(*PSecurityDescriptorSize);
+ if (0 == *PSecurityDescriptor)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+}
+
+FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request,
+ BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
+ UINT32 DesiredAccess, PUINT32 PGrantedAccess,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor)
+{
+ *PGrantedAccess = 0;
+ if (0 != PSecurityDescriptor)
+ *PSecurityDescriptor = 0;
+
+ if (0 == FileSystem->Interface->GetSecurityByName ||
+ (!Request->Req.Create.UserMode && 0 == PSecurityDescriptor))
+ {
+ *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
+ FspFileGenericMapping.GenericAll : DesiredAccess;
+ return STATUS_SUCCESS;
+ }
+
+ NTSTATUS Result;
+ WCHAR Root[2] = L"\\", TraverseCheckRoot[2] = L"\\";
+ PWSTR FileName, Suffix, Prefix, Remain;
+ UINT32 FileAttributes;
+ PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
+ SIZE_T SecurityDescriptorSize;
+ UINT8 PrivilegeSetBuf[sizeof(PRIVILEGE_SET) + 15 * sizeof(LUID_AND_ATTRIBUTES)];
+ PPRIVILEGE_SET PrivilegeSet = (PVOID)PrivilegeSetBuf;
+ DWORD PrivilegeSetLength = sizeof PrivilegeSetBuf;
+ UINT32 TraverseAccess;
+ BOOL AccessStatus;
+
+ if (CheckParentDirectory)
+ FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root);
+ else
+ FileName = (PWSTR)Request->Buffer;
+
+ SecurityDescriptorSize = 1024;
+ SecurityDescriptor = MemAlloc(SecurityDescriptorSize);
+ if (0 == SecurityDescriptor)
+ {
+ Result = STATUS_INSUFFICIENT_RESOURCES;
+ goto exit;
+ }
+
+ if (Request->Req.Create.UserMode &&
+ AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege)
+ {
+ Remain = (PWSTR)FileName;
+ for (;;)
+ {
+ FspPathPrefix(Remain, &Prefix, &Remain, TraverseCheckRoot);
+ if (L'\0' == Remain[0])
+ {
+ FspPathCombine(FileName, Remain);
+ break;
+ }
+
+ Result = FspGetSecurityByName(FileSystem, Prefix, 0,
+ &SecurityDescriptor, &SecurityDescriptorSize);
+
+ FspPathCombine(FileName, Remain);
+
+ if (!NT_SUCCESS(Result))
+ {
+ if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
+ Result = STATUS_OBJECT_PATH_NOT_FOUND;
+ goto exit;
+ }
+
+ if (0 < SecurityDescriptorSize)
+ {
+ if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE,
+ &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
+ Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
+ else
+ Result = FspNtStatusFromWin32(GetLastError());
+ if (!NT_SUCCESS(Result))
+ goto exit;
+ }
+ }
+ }
+
+ Result = FspGetSecurityByName(FileSystem, FileName, &FileAttributes,
+ &SecurityDescriptor, &SecurityDescriptorSize);
+ if (!NT_SUCCESS(Result))
+ goto exit;
+
+ if (Request->Req.Create.UserMode)
+ {
+ if (0 < SecurityDescriptorSize)
+ {
+ if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
+ &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
+ Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
+ else
+ Result = FspNtStatusFromWin32(GetLastError());
+ if (!NT_SUCCESS(Result))
+ goto exit;
+ }
+
+ if (CheckParentDirectory)
+ {
+ if (0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ Result = STATUS_NOT_A_DIRECTORY;
+ goto exit;
+ }
+ }
+ else
+ {
+ if ((Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) &&
+ 0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ Result = STATUS_NOT_A_DIRECTORY;
+ goto exit;
+ }
+ if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) &&
+ 0 != (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ Result = STATUS_FILE_IS_A_DIRECTORY;
+ goto exit;
+ }
+ }
+
+ if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY))
+ {
+ if (DesiredAccess &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD))
+ {
+ Result = STATUS_ACCESS_DENIED;
+ goto exit;
+ }
+ if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE)
+ {
+ Result = STATUS_CANNOT_DELETE;
+ goto exit;
+ }
+ }
+
+ if (0 == SecurityDescriptorSize)
+ *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
+ FspFileGenericMapping.GenericAll : DesiredAccess;
+ }
+ else
+ *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
+ FspFileGenericMapping.GenericAll : DesiredAccess;
+
+ Result = STATUS_SUCCESS;
+
+exit:
+ if (0 != PSecurityDescriptor && 0 < SecurityDescriptorSize && NT_SUCCESS(Result))
+ *PSecurityDescriptor = SecurityDescriptor;
+ else
+ MemFree(SecurityDescriptor);
+
+ if (CheckParentDirectory)
+ {
+ FspPathCombine((PWSTR)Request->Buffer, Suffix);
+
+ if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
+ Result = STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+
+ return Result;
+}
+
+FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request,
+ PSECURITY_DESCRIPTOR ParentDescriptor,
+ PSECURITY_DESCRIPTOR *PSecurityDescriptor)
+{
+ *PSecurityDescriptor = 0;
+
+ if (!CreatePrivateObjectSecurity(
+ ParentDescriptor,
+ 0 != Request->Req.Create.SecurityDescriptor.Offset ?
+ (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0,
+ PSecurityDescriptor,
+ 0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE),
+ (HANDLE)Request->Req.Create.AccessToken,
+ &FspFileGenericMapping))
+ return FspNtStatusFromWin32(GetLastError());
+
+ //DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor);
+
+ return STATUS_SUCCESS;
+}
+
+FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ NTSTATUS(*CreateFunc)())
+{
+ if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc)
+ MemFree(SecurityDescriptor);
+ else if ((NTSTATUS (*)())FspAssignSecurity == CreateFunc)
+ DestroyPrivateObjectSecurity(&SecurityDescriptor);
+}
diff --git a/src/dll/cleanup.c b/src/dll/cleanup.c
deleted file mode 100644
index c6d1a942..00000000
--- a/src/dll/cleanup.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * @file dll/cleanup.c
- *
- * @copyright 2015 Bill Zissimopoulos
- */
-
-#include
-
-FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- if (0 != FileSystem->Interface->Cleanup)
- FileSystem->Interface->Cleanup(FileSystem, Request,
- (PVOID)Request->Req.Cleanup.UserContext,
- 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
- 0 != Request->Req.Cleanup.Delete);
-
- return STATUS_SUCCESS;
-}
diff --git a/src/dll/close.c b/src/dll/close.c
deleted file mode 100644
index 6a4cb243..00000000
--- a/src/dll/close.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @file dll/close.c
- *
- * @copyright 2015 Bill Zissimopoulos
- */
-
-#include
-
-FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- if (0 != FileSystem->Interface->Close)
- FileSystem->Interface->Close(FileSystem, Request,
- (PVOID)Request->Req.Close.UserContext);
-
- return STATUS_SUCCESS;
-}
diff --git a/src/dll/fileinfo.c b/src/dll/fileinfo.c
deleted file mode 100644
index 16c7c298..00000000
--- a/src/dll/fileinfo.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @file dll/fileinfo.c
- *
- * @copyright 2015 Bill Zissimopoulos
- */
-
-#include
-
-FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
- FSP_FSCTL_FILE_INFO FileInfo;
-
- if (0 == FileSystem->Interface->GetFileInfo)
- return STATUS_INVALID_DEVICE_REQUEST;
-
- memset(&FileInfo, 0, sizeof FileInfo);
- Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
- (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo);
- if (!NT_SUCCESS(Result))
- return Result;
-
- memcpy(&Response->Rsp.QueryInformation.FileInfo, &FileInfo, sizeof FileInfo);
- return STATUS_SUCCESS;
-}
-
-FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
- FSP_FSCTL_FILE_INFO FileInfo;
-
- Result = STATUS_INVALID_DEVICE_REQUEST;
- memset(&FileInfo, 0, sizeof FileInfo);
- switch (Request->Req.SetInformation.FileInformationClass)
- {
- case 4/*FileBasicInformation*/:
- if (0 != FileSystem->Interface->SetBasicInfo)
- Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- Request->Req.SetInformation.Info.Basic.FileAttributes,
- Request->Req.SetInformation.Info.Basic.CreationTime,
- Request->Req.SetInformation.Info.Basic.LastAccessTime,
- Request->Req.SetInformation.Info.Basic.LastWriteTime,
- &FileInfo);
- break;
- case 19/*FileAllocationInformation*/:
- if (0 != FileSystem->Interface->SetAllocationSize)
- Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- Request->Req.SetInformation.Info.Allocation.AllocationSize,
- &FileInfo);
- else
- if (0 != FileSystem->Interface->GetFileInfo &&
- 0 != FileSystem->Interface->SetFileSize)
- {
- Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext, &FileInfo);
- if (NT_SUCCESS(Result) &&
- Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize)
- {
- Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- Request->Req.SetInformation.Info.Allocation.AllocationSize,
- FALSE,
- &FileInfo);
- }
- }
- break;
- case 20/*FileEndOfFileInformation*/:
- if (0 != FileSystem->Interface->SetFileSize)
- Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- Request->Req.SetInformation.Info.EndOfFile.FileSize,
- Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly,
- &FileInfo);
- break;
- case 13/*FileDispositionInformation*/:
- if (0 != FileSystem->Interface->CanDelete)
- if (Request->Req.SetInformation.Info.Disposition.Delete)
- Result = FileSystem->Interface->CanDelete(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- (PWSTR)Request->Buffer);
- else
- Result = STATUS_SUCCESS;
- break;
- case 10/*FileRenameInformation*/:
- if (0 != FileSystem->Interface->Rename)
- Result = FileSystem->Interface->Rename(FileSystem, Request,
- (PVOID)Request->Req.SetInformation.UserContext,
- (PWSTR)Request->Buffer,
- (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
- Request->Req.SetInformation.Info.Rename.ReplaceIfExists);
- break;
- }
-
- if (!NT_SUCCESS(Result))
- return Result;
-
- memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo);
- return STATUS_SUCCESS;
-}
diff --git a/src/dll/create.c b/src/dll/fsop.c
similarity index 65%
rename from src/dll/create.c
rename to src/dll/fsop.c
index d1e4f0c4..303e29e2 100644
--- a/src/dll/create.c
+++ b/src/dll/fsop.c
@@ -1,238 +1,11 @@
/**
- * @file dll/create.c
+ * @file dll/fsop.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include
-static GENERIC_MAPPING FspFileGenericMapping =
-{
- .GenericRead = FILE_GENERIC_READ,
- .GenericWrite = FILE_GENERIC_WRITE,
- .GenericExecute = FILE_GENERIC_EXECUTE,
- .GenericAll = FILE_ALL_ACCESS,
-};
-
-FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID)
-{
- return &FspFileGenericMapping;
-}
-
-static NTSTATUS FspGetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
- PWSTR FileName, PUINT32 PFileAttributes,
- PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
-{
- for (;;)
- {
- NTSTATUS Result = FileSystem->Interface->GetSecurityByName(FileSystem,
- FileName, PFileAttributes, *PSecurityDescriptor, PSecurityDescriptorSize);
- if (STATUS_BUFFER_OVERFLOW != Result)
- return Result;
-
- MemFree(*PSecurityDescriptor);
- *PSecurityDescriptor = MemAlloc(*PSecurityDescriptorSize);
- if (0 == *PSecurityDescriptor)
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-}
-
-FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request,
- BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
- UINT32 DesiredAccess, PUINT32 PGrantedAccess,
- PSECURITY_DESCRIPTOR *PSecurityDescriptor)
-{
- *PGrantedAccess = 0;
- if (0 != PSecurityDescriptor)
- *PSecurityDescriptor = 0;
-
- if (0 == FileSystem->Interface->GetSecurityByName ||
- (!Request->Req.Create.UserMode && 0 == PSecurityDescriptor))
- {
- *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
- FspFileGenericMapping.GenericAll : DesiredAccess;
- return STATUS_SUCCESS;
- }
-
- NTSTATUS Result;
- WCHAR Root[2] = L"\\", TraverseCheckRoot[2] = L"\\";
- PWSTR FileName, Suffix, Prefix, Remain;
- UINT32 FileAttributes;
- PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
- SIZE_T SecurityDescriptorSize;
- UINT8 PrivilegeSetBuf[sizeof(PRIVILEGE_SET) + 15 * sizeof(LUID_AND_ATTRIBUTES)];
- PPRIVILEGE_SET PrivilegeSet = (PVOID)PrivilegeSetBuf;
- DWORD PrivilegeSetLength = sizeof PrivilegeSetBuf;
- UINT32 TraverseAccess;
- BOOL AccessStatus;
-
- if (CheckParentDirectory)
- FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root);
- else
- FileName = (PWSTR)Request->Buffer;
-
- SecurityDescriptorSize = 1024;
- SecurityDescriptor = MemAlloc(SecurityDescriptorSize);
- if (0 == SecurityDescriptor)
- {
- Result = STATUS_INSUFFICIENT_RESOURCES;
- goto exit;
- }
-
- if (Request->Req.Create.UserMode &&
- AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege)
- {
- Remain = (PWSTR)FileName;
- for (;;)
- {
- FspPathPrefix(Remain, &Prefix, &Remain, TraverseCheckRoot);
- if (L'\0' == Remain[0])
- {
- FspPathCombine(FileName, Remain);
- break;
- }
-
- Result = FspGetSecurityByName(FileSystem, Prefix, 0,
- &SecurityDescriptor, &SecurityDescriptorSize);
-
- FspPathCombine(FileName, Remain);
-
- if (!NT_SUCCESS(Result))
- {
- if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
- Result = STATUS_OBJECT_PATH_NOT_FOUND;
- goto exit;
- }
-
- if (0 < SecurityDescriptorSize)
- {
- if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE,
- &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
- Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
- else
- Result = FspNtStatusFromWin32(GetLastError());
- if (!NT_SUCCESS(Result))
- goto exit;
- }
- }
- }
-
- Result = FspGetSecurityByName(FileSystem, FileName, &FileAttributes,
- &SecurityDescriptor, &SecurityDescriptorSize);
- if (!NT_SUCCESS(Result))
- goto exit;
-
- if (Request->Req.Create.UserMode)
- {
- if (0 < SecurityDescriptorSize)
- {
- if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
- &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
- Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
- else
- Result = FspNtStatusFromWin32(GetLastError());
- if (!NT_SUCCESS(Result))
- goto exit;
- }
-
- if (CheckParentDirectory)
- {
- if (0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- Result = STATUS_NOT_A_DIRECTORY;
- goto exit;
- }
- }
- else
- {
- if ((Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) &&
- 0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- Result = STATUS_NOT_A_DIRECTORY;
- goto exit;
- }
- if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) &&
- 0 != (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- Result = STATUS_FILE_IS_A_DIRECTORY;
- goto exit;
- }
- }
-
- if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY))
- {
- if (DesiredAccess &
- (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD))
- {
- Result = STATUS_ACCESS_DENIED;
- goto exit;
- }
- if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE)
- {
- Result = STATUS_CANNOT_DELETE;
- goto exit;
- }
- }
-
- if (0 == SecurityDescriptorSize)
- *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
- FspFileGenericMapping.GenericAll : DesiredAccess;
- }
- else
- *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
- FspFileGenericMapping.GenericAll : DesiredAccess;
-
- Result = STATUS_SUCCESS;
-
-exit:
- if (0 != PSecurityDescriptor && 0 < SecurityDescriptorSize && NT_SUCCESS(Result))
- *PSecurityDescriptor = SecurityDescriptor;
- else
- MemFree(SecurityDescriptor);
-
- if (CheckParentDirectory)
- {
- FspPathCombine((PWSTR)Request->Buffer, Suffix);
-
- if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
- Result = STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- return Result;
-}
-
-FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request,
- PSECURITY_DESCRIPTOR ParentDescriptor,
- PSECURITY_DESCRIPTOR *PSecurityDescriptor)
-{
- *PSecurityDescriptor = 0;
-
- if (!CreatePrivateObjectSecurity(
- ParentDescriptor,
- 0 != Request->Req.Create.SecurityDescriptor.Offset ?
- (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0,
- PSecurityDescriptor,
- 0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE),
- (HANDLE)Request->Req.Create.AccessToken,
- &FspFileGenericMapping))
- return FspNtStatusFromWin32(GetLastError());
-
- //DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor);
-
- return STATUS_SUCCESS;
-}
-
-FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- NTSTATUS(*CreateFunc)())
-{
- if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc)
- MemFree(SecurityDescriptor);
- else if ((NTSTATUS (*)())FspAssignSecurity == CreateFunc)
- DestroyPrivateObjectSecurity(&SecurityDescriptor);
-}
-
static inline
NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
@@ -248,7 +21,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
if (NT_SUCCESS(Result))
{
*PGrantedAccess = (MAXIMUM_ALLOWED & Request->Req.Create.DesiredAccess) ?
- FspFileGenericMapping.GenericAll : Request->Req.Create.DesiredAccess;
+ FspGetFileGenericMapping()->GenericAll : Request->Req.Create.DesiredAccess;
}
return Result;
@@ -606,3 +379,187 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
memcpy(&Response->Rsp.Overwrite.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
}
+
+FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ if (0 != FileSystem->Interface->Cleanup)
+ FileSystem->Interface->Cleanup(FileSystem, Request,
+ (PVOID)Request->Req.Cleanup.UserContext,
+ 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
+ 0 != Request->Req.Cleanup.Delete);
+
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ if (0 != FileSystem->Interface->Close)
+ FileSystem->Interface->Close(FileSystem, Request,
+ (PVOID)Request->Req.Close.UserContext);
+
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+ FSP_FSCTL_FILE_INFO FileInfo;
+
+ if (0 == FileSystem->Interface->GetFileInfo)
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ memset(&FileInfo, 0, sizeof FileInfo);
+ Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
+ (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo);
+ if (!NT_SUCCESS(Result))
+ return Result;
+
+ memcpy(&Response->Rsp.QueryInformation.FileInfo, &FileInfo, sizeof FileInfo);
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+ FSP_FSCTL_FILE_INFO FileInfo;
+
+ Result = STATUS_INVALID_DEVICE_REQUEST;
+ memset(&FileInfo, 0, sizeof FileInfo);
+ switch (Request->Req.SetInformation.FileInformationClass)
+ {
+ case 4/*FileBasicInformation*/:
+ if (0 != FileSystem->Interface->SetBasicInfo)
+ Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ Request->Req.SetInformation.Info.Basic.FileAttributes,
+ Request->Req.SetInformation.Info.Basic.CreationTime,
+ Request->Req.SetInformation.Info.Basic.LastAccessTime,
+ Request->Req.SetInformation.Info.Basic.LastWriteTime,
+ &FileInfo);
+ break;
+ case 19/*FileAllocationInformation*/:
+ if (0 != FileSystem->Interface->SetAllocationSize)
+ Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ Request->Req.SetInformation.Info.Allocation.AllocationSize,
+ &FileInfo);
+ else
+ if (0 != FileSystem->Interface->GetFileInfo &&
+ 0 != FileSystem->Interface->SetFileSize)
+ {
+ Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext, &FileInfo);
+ if (NT_SUCCESS(Result) &&
+ Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize)
+ {
+ Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ Request->Req.SetInformation.Info.Allocation.AllocationSize,
+ FALSE,
+ &FileInfo);
+ }
+ }
+ break;
+ case 20/*FileEndOfFileInformation*/:
+ if (0 != FileSystem->Interface->SetFileSize)
+ Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ Request->Req.SetInformation.Info.EndOfFile.FileSize,
+ Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly,
+ &FileInfo);
+ break;
+ case 13/*FileDispositionInformation*/:
+ if (0 != FileSystem->Interface->CanDelete)
+ if (Request->Req.SetInformation.Info.Disposition.Delete)
+ Result = FileSystem->Interface->CanDelete(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ (PWSTR)Request->Buffer);
+ else
+ Result = STATUS_SUCCESS;
+ break;
+ case 10/*FileRenameInformation*/:
+ if (0 != FileSystem->Interface->Rename)
+ Result = FileSystem->Interface->Rename(FileSystem, Request,
+ (PVOID)Request->Req.SetInformation.UserContext,
+ (PWSTR)Request->Buffer,
+ (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
+ Request->Req.SetInformation.Info.Rename.ReplaceIfExists);
+ break;
+ }
+
+ if (!NT_SUCCESS(Result))
+ return Result;
+
+ memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo);
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+ FSP_FSCTL_VOLUME_INFO VolumeInfo;
+
+ if (0 == FileSystem->Interface->GetVolumeInfo)
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ memset(&VolumeInfo, 0, sizeof VolumeInfo);
+ Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo);
+ if (!NT_SUCCESS(Result))
+ return Result;
+
+ memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+ FSP_FSCTL_VOLUME_INFO VolumeInfo;
+
+ Result = STATUS_INVALID_DEVICE_REQUEST;
+ memset(&VolumeInfo, 0, sizeof VolumeInfo);
+ switch (Request->Req.SetVolumeInformation.FsInformationClass)
+ {
+ case 2/*FileFsLabelInformation*/:
+ if (0 != FileSystem->Interface->SetVolumeLabel)
+ Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request,
+ (PWSTR)Request->Buffer,
+ &VolumeInfo);
+ }
+
+ if (!NT_SUCCESS(Result))
+ return Result;
+
+ memcpy(&Response->Rsp.SetVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
+ return STATUS_SUCCESS;
+}
+
+FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+
+ if (0 == FileSystem->Interface->GetSecurity)
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ (VOID)Result;
+ return STATUS_INVALID_DEVICE_REQUEST;
+}
+
+FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
+ FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
+{
+ NTSTATUS Result;
+
+ if (0 == FileSystem->Interface->SetSecurity)
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ (VOID)Result;
+ return STATUS_INVALID_DEVICE_REQUEST;
+}
diff --git a/src/dll/security.c b/src/dll/security.c
deleted file mode 100644
index 7d2288ec..00000000
--- a/src/dll/security.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file dll/security.c
- *
- * @copyright 2015 Bill Zissimopoulos
- */
-
-#include
-
-FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
-
- if (0 == FileSystem->Interface->GetSecurity)
- return STATUS_INVALID_DEVICE_REQUEST;
-
- (VOID)Result;
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
-
- if (0 == FileSystem->Interface->SetSecurity)
- return STATUS_INVALID_DEVICE_REQUEST;
-
- (VOID)Result;
- return STATUS_INVALID_DEVICE_REQUEST;
-}
diff --git a/src/dll/volinfo.c b/src/dll/volinfo.c
deleted file mode 100644
index 12b2ccc8..00000000
--- a/src/dll/volinfo.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file dll/volinfo.c
- *
- * @copyright 2015 Bill Zissimopoulos
- */
-
-#include
-
-FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
- FSP_FSCTL_VOLUME_INFO VolumeInfo;
-
- if (0 == FileSystem->Interface->GetVolumeInfo)
- return STATUS_INVALID_DEVICE_REQUEST;
-
- memset(&VolumeInfo, 0, sizeof VolumeInfo);
- Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo);
- if (!NT_SUCCESS(Result))
- return Result;
-
- memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
- return STATUS_SUCCESS;
-}
-
-FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
- FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
-{
- NTSTATUS Result;
- FSP_FSCTL_VOLUME_INFO VolumeInfo;
-
- Result = STATUS_INVALID_DEVICE_REQUEST;
- memset(&VolumeInfo, 0, sizeof VolumeInfo);
- switch (Request->Req.SetVolumeInformation.FsInformationClass)
- {
- case 2/*FileFsLabelInformation*/:
- if (0 != FileSystem->Interface->SetVolumeLabel)
- Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request,
- (PWSTR)Request->Buffer,
- &VolumeInfo);
- }
-
- if (!NT_SUCCESS(Result))
- return Result;
-
- memcpy(&Response->Rsp.SetVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
- return STATUS_SUCCESS;
-}