mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
dll: create.c: refactoring
This commit is contained in:
parent
5eaa6b03ae
commit
d2eabf4e05
@ -24,7 +24,6 @@
|
|||||||
<ClInclude Include="..\..\src\dll\library.h" />
|
<ClInclude Include="..\..\src\dll\library.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\src\dll\access.c" />
|
|
||||||
<ClCompile Include="..\..\src\dll\cleanup.c" />
|
<ClCompile Include="..\..\src\dll\cleanup.c" />
|
||||||
<ClCompile Include="..\..\src\dll\close.c" />
|
<ClCompile Include="..\..\src\dll\close.c" />
|
||||||
<ClCompile Include="..\..\src\dll\create.c" />
|
<ClCompile Include="..\..\src\dll\create.c" />
|
||||||
|
@ -43,9 +43,6 @@
|
|||||||
<ClCompile Include="..\..\src\dll\create.c">
|
<ClCompile Include="..\..\src\dll\create.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\dll\access.c">
|
|
||||||
<Filter>Source</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\dll\path.c">
|
<ClCompile Include="..\..\src\dll\path.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -50,9 +50,6 @@ typedef VOID FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_RE
|
|||||||
typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(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
|
typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||||
{
|
{
|
||||||
NTSTATUS (*AccessCheck)(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
|
|
||||||
DWORD DesiredAccess, PDWORD PGrantedAccess);
|
|
||||||
NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PWSTR FileName, PDWORD PFileAttributes,
|
PWSTR FileName, PDWORD PFileAttributes,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize);
|
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize);
|
||||||
@ -149,6 +146,24 @@ FSP_API NTSTATUS FspFileSystemSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem
|
|||||||
/*
|
/*
|
||||||
* File System Operations
|
* 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 FspShareCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode);
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess);
|
||||||
|
FSP_API VOID FspFileSystemPostCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode);
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreOpenCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess);
|
||||||
|
FSP_API NTSTATUS FspFileSystemPostOpenCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode);
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess);
|
||||||
|
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_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request);
|
FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -163,16 +178,6 @@ FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request);
|
FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
|
|
||||||
/*
|
|
||||||
* Access Checks
|
|
||||||
*/
|
|
||||||
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 FspShareCheck(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
DWORD GrantedAccess, DWORD ShareAccess, FSP_FILE_NODE *FileNode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Path Handling
|
* Path Handling
|
||||||
*/
|
*/
|
||||||
|
213
src/dll/access.c
213
src/dll/access.c
@ -1,213 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file dll/access.c
|
|
||||||
*
|
|
||||||
* @copyright 2015 Bill Zissimopoulos
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dll/library.h>
|
|
||||||
|
|
||||||
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 FspGetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
PWSTR FileName, PDWORD PFileAttributes,
|
|
||||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
NTSTATUS Result = FileSystem->Interface->GetSecurity(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 FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
|
|
||||||
DWORD DesiredAccess, PDWORD PGrantedAccess)
|
|
||||||
{
|
|
||||||
if (0 != FileSystem->Interface->AccessCheck)
|
|
||||||
return FileSystem->Interface->AccessCheck(FileSystem,
|
|
||||||
Request, CheckParentDirectory, AllowTraverseCheck, DesiredAccess, PGrantedAccess);
|
|
||||||
|
|
||||||
if (0 == FileSystem->Interface->GetSecurity)
|
|
||||||
{
|
|
||||||
*PGrantedAccess = DesiredAccess;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
PWSTR Parent, Suffix;
|
|
||||||
DWORD FileAttributes;
|
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
|
||||||
SIZE_T SecurityDescriptorSize;
|
|
||||||
DWORD PrivilegeSetLength;
|
|
||||||
BOOL AccessStatus;
|
|
||||||
|
|
||||||
*PGrantedAccess = 0;
|
|
||||||
|
|
||||||
if (CheckParentDirectory)
|
|
||||||
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix);
|
|
||||||
|
|
||||||
SecurityDescriptorSize = 1024;
|
|
||||||
SecurityDescriptor = MemAlloc(SecurityDescriptorSize);
|
|
||||||
if (0 == SecurityDescriptor)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege)
|
|
||||||
{
|
|
||||||
PWSTR Path = (PWSTR)Request->Buffer, Prefix;
|
|
||||||
DWORD TraverseAccess;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FspPathPrefix(Path, &Prefix, &Path);
|
|
||||||
if (L'\0' == Path[0])
|
|
||||||
{
|
|
||||||
FspPathCombine((PWSTR)Request->Buffer, Path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Prefix = L'\0' == Prefix[0] ? L"\\" : (PWSTR)Request->Buffer;
|
|
||||||
Result = FspGetSecurity(FileSystem, Prefix, 0,
|
|
||||||
&SecurityDescriptor, &SecurityDescriptorSize);
|
|
||||||
|
|
||||||
FspPathCombine((PWSTR)Request->Buffer, Path);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
|
|
||||||
Result = STATUS_OBJECT_PATH_NOT_FOUND;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE,
|
|
||||||
&FspFileGenericMapping, 0, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
|
|
||||||
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
|
||||||
else
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = FspGetSecurity(FileSystem, (PWSTR)Request->Buffer, &FileAttributes,
|
|
||||||
&SecurityDescriptor, &SecurityDescriptorSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (CheckParentDirectory)
|
|
||||||
{
|
|
||||||
if (0 == (FileAttributes && FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
return STATUS_NOT_A_DIRECTORY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) &&
|
|
||||||
0 == (FileAttributes && FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
return STATUS_NOT_A_DIRECTORY;
|
|
||||||
if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) &&
|
|
||||||
0 != (FileAttributes && FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
return STATUS_NOT_A_DIRECTORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
|
|
||||||
&FspFileGenericMapping, 0, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
|
|
||||||
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
|
||||||
else
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
|
|
||||||
exit:
|
|
||||||
MemFree(SecurityDescriptor);
|
|
||||||
|
|
||||||
if (CheckParentDirectory)
|
|
||||||
FspPathCombine((PWSTR)Request->Buffer, Suffix);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSP_API NTSTATUS FspShareCheck(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
DWORD GrantedAccess, DWORD ShareAccess, FSP_FILE_NODE *FileNode)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
411
src/dll/create.c
411
src/dll/create.c
@ -6,19 +6,221 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
|
||||||
static inline
|
static GENERIC_MAPPING FspFileGenericMapping =
|
||||||
BOOLEAN FspIsRootDirectory(PWSTR FileName)
|
|
||||||
{
|
{
|
||||||
for (PWSTR Pointer = FileName; *Pointer; Pointer++)
|
.GenericRead = FILE_GENERIC_READ,
|
||||||
if (L'\\' != *Pointer)
|
.GenericWrite = FILE_GENERIC_WRITE,
|
||||||
return FALSE;
|
.GenericExecute = FILE_GENERIC_EXECUTE,
|
||||||
return TRUE;
|
.GenericAll = FILE_ALL_ACCESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID)
|
||||||
|
{
|
||||||
|
return &FspFileGenericMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static NTSTATUS FspGetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||||
NTSTATUS FspCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
PWSTR FileName, PDWORD PFileAttributes,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck,
|
PSECURITY_DESCRIPTOR *PSecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
|
||||||
PDWORD PGrantedAccess)
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
NTSTATUS Result = FileSystem->Interface->GetSecurity(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 FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN CheckParentDirectory, BOOLEAN AllowTraverseCheck,
|
||||||
|
DWORD DesiredAccess, PDWORD PGrantedAccess)
|
||||||
|
{
|
||||||
|
if (0 == FileSystem->Interface->GetSecurity)
|
||||||
|
{
|
||||||
|
*PGrantedAccess = DesiredAccess;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWSTR Parent, Suffix, Prefix, Remain;
|
||||||
|
DWORD FileAttributes;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
SIZE_T SecurityDescriptorSize;
|
||||||
|
DWORD PrivilegeSetLength;
|
||||||
|
DWORD TraverseAccess;
|
||||||
|
BOOL AccessStatus;
|
||||||
|
|
||||||
|
*PGrantedAccess = 0;
|
||||||
|
|
||||||
|
if (CheckParentDirectory)
|
||||||
|
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix);
|
||||||
|
|
||||||
|
SecurityDescriptorSize = 1024;
|
||||||
|
SecurityDescriptor = MemAlloc(SecurityDescriptorSize);
|
||||||
|
if (0 == SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege)
|
||||||
|
{
|
||||||
|
Remain = (PWSTR)Request->Buffer;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
FspPathPrefix(Remain, &Prefix, &Remain);
|
||||||
|
if (L'\0' == Remain[0])
|
||||||
|
{
|
||||||
|
FspPathCombine((PWSTR)Request->Buffer, Remain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Prefix = L'\0' == Prefix[0] ? L"\\" : (PWSTR)Request->Buffer;
|
||||||
|
Result = FspGetSecurity(FileSystem, Prefix, 0,
|
||||||
|
&SecurityDescriptor, &SecurityDescriptorSize);
|
||||||
|
|
||||||
|
FspPathCombine((PWSTR)Request->Buffer, Remain);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
|
||||||
|
Result = STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE,
|
||||||
|
&FspFileGenericMapping, 0, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
|
||||||
|
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
|
else
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspGetSecurity(FileSystem, (PWSTR)Request->Buffer, &FileAttributes,
|
||||||
|
&SecurityDescriptor, &SecurityDescriptorSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
|
||||||
|
&FspFileGenericMapping, 0, &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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(SecurityDescriptor);
|
||||||
|
|
||||||
|
if (CheckParentDirectory)
|
||||||
|
FspPathCombine((PWSTR)Request->Buffer, Suffix);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspShareCheck(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,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
@ -33,17 +235,73 @@ NTSTATUS FspCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspFileSystemPostCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
memset(&FileNode->Flags, 0, sizeof FileNode->Flags);
|
||||||
|
memset(&FileNode->ShareAccess, 0, sizeof FileNode->ShareAccess);
|
||||||
|
|
||||||
|
FspShareCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API 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)
|
||||||
|
{
|
||||||
|
return FspShareCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||||
|
|
||||||
|
Result = FspAccessCheck(FileSystem, Request, FALSE, AllowTraverseCheck,
|
||||||
|
Request->Req.Create.DesiredAccess | (Supersede ? DELETE : FILE_WRITE_DATA),
|
||||||
|
PGrantedAccess);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
||||||
|
*PGrantedAccess &= Supersede ?
|
||||||
|
(~DELETE | (Request->Req.Create.DesiredAccess & DELETE)) :
|
||||||
|
(~FILE_WRITE_DATA | (Request->Req.Create.DesiredAccess & FILE_WRITE_DATA));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemPostOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, DWORD GrantedAccess, FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
return FspShareCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN FspIsRootDirectory(PWSTR FileName)
|
||||||
|
{
|
||||||
|
for (PWSTR Pointer = FileName; *Pointer; Pointer++)
|
||||||
|
if (L'\\' != *Pointer)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request)
|
FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
{
|
{
|
||||||
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
DWORD GrantedAccess;
|
DWORD GrantedAccess;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
|
|
||||||
Result = FspCreateCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
Result = FspFileSystemPreCreateCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
@ -51,10 +309,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
memset(&FileNode->Flags, 0, sizeof FileNode->Flags);
|
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
memset(&FileNode->ShareAccess, 0, sizeof FileNode->ShareAccess);
|
|
||||||
|
|
||||||
FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
|
||||||
|
|
||||||
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
||||||
FILE_CREATED, FileNode, GrantedAccess);
|
FILE_CREATED, FileNode, GrantedAccess);
|
||||||
@ -67,8 +322,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
DWORD GrantedAccess;
|
DWORD GrantedAccess;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
|
|
||||||
Result = FspAccessCheck(FileSystem, Request, FALSE, TRUE,
|
Result = FspFileSystemPreOpenCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
||||||
Request->Req.Create.DesiredAccess, &GrantedAccess);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
@ -76,7 +330,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
Result = FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
Result = FspFileSystemPostOpenCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (0 != FileSystem->Interface->Close)
|
if (0 != FileSystem->Interface->Close)
|
||||||
@ -96,8 +350,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
BOOLEAN Create = FALSE;
|
BOOLEAN Create = FALSE;
|
||||||
|
|
||||||
Result = FspAccessCheck(FileSystem, Request, FALSE, TRUE,
|
Result = FspFileSystemPreOpenCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
||||||
Request->Req.Create.DesiredAccess, &GrantedAccess);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||||
@ -114,6 +367,16 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
Create = TRUE;
|
Create = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = FspFileSystemPostOpenCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 != FileSystem->Interface->Close)
|
||||||
|
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
||||||
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Create)
|
if (Create)
|
||||||
@ -121,7 +384,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
Result = FspCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
|
Result = FspFileSystemPreCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
@ -129,16 +392,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
memset(&FileNode->Flags, 0, sizeof FileNode->Flags);
|
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
memset(&FileNode->ShareAccess, 0, sizeof FileNode->ShareAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (0 != FileSystem->Interface->Close)
|
|
||||||
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
||||||
@ -146,31 +400,25 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN Supersede)
|
FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
{
|
{
|
||||||
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
DWORD GrantedAccess;
|
DWORD GrantedAccess;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
|
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||||
|
|
||||||
Result = FspAccessCheck(FileSystem, Request, FALSE, TRUE,
|
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
||||||
Request->Req.Create.DesiredAccess | (Supersede ? DELETE : FILE_WRITE_DATA),
|
return STATUS_ACCESS_DENIED;
|
||||||
&GrantedAccess);
|
|
||||||
|
Result = FspFileSystemPreOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
|
||||||
GrantedAccess &= Supersede ?
|
|
||||||
(~DELETE | (Request->Req.Create.DesiredAccess & DELETE)) :
|
|
||||||
(~FILE_WRITE_DATA | (Request->Req.Create.DesiredAccess & FILE_WRITE_DATA));
|
|
||||||
|
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode);
|
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
Result = FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
Result = FspFileSystemPostOverwriteCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (0 != FileSystem->Interface->Close)
|
if (0 != FileSystem->Interface->Close)
|
||||||
@ -193,28 +441,21 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request)
|
FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
{
|
{
|
||||||
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
DWORD GrantedAccess;
|
DWORD GrantedAccess;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
BOOLEAN Create = FALSE;
|
BOOLEAN Create = FALSE;
|
||||||
|
|
||||||
Result = FspAccessCheck(FileSystem, Request, FALSE, TRUE,
|
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
||||||
Request->Req.Create.DesiredAccess | FILE_WRITE_DATA,
|
return STATUS_ACCESS_DENIED;
|
||||||
&GrantedAccess);
|
|
||||||
|
Result = FspFileSystemPreOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
Create = TRUE;
|
Create = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
|
||||||
GrantedAccess &= ~FILE_WRITE_DATA | (Request->Req.Create.DesiredAccess & FILE_WRITE_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Create)
|
if (!Create)
|
||||||
{
|
{
|
||||||
@ -225,11 +466,29 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
Create = TRUE;
|
Create = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = FspFileSystemPostOverwriteCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 != FileSystem->Interface->Close)
|
||||||
|
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
||||||
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FileSystem->Interface->Overwrite(FileSystem, Request, FALSE, FileNode);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 != FileSystem->Interface->Close)
|
||||||
|
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
||||||
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Create)
|
if (Create)
|
||||||
{
|
{
|
||||||
Result = FspCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
|
Result = FspFileSystemPreCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
@ -237,27 +496,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
memset(&FileNode->Flags, 0, sizeof FileNode->Flags);
|
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
memset(&FileNode->ShareAccess, 0, sizeof FileNode->ShareAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (0 != FileSystem->Interface->Close)
|
|
||||||
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Create)
|
|
||||||
{
|
|
||||||
Result = FileSystem->Interface->Overwrite(FileSystem, Request, FALSE, FileNode);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (0 != FileSystem->Interface->Close)
|
|
||||||
FileSystem->Interface->Close(FileSystem, Request, FileNode);
|
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
return FspFileSystemSendCreateResponse(FileSystem, Request,
|
||||||
@ -267,15 +506,15 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request)
|
FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
{
|
{
|
||||||
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
PWSTR Parent, Suffix;
|
PWSTR Parent, Suffix;
|
||||||
DWORD GrantedAccess;
|
DWORD GrantedAccess;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
UINT_PTR Information;
|
UINT_PTR Information;
|
||||||
|
|
||||||
|
if (FspIsRootDirectory((PWSTR)Request->Buffer))
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
Result = FspAccessCheck(FileSystem, Request, TRUE, TRUE,
|
Result = FspAccessCheck(FileSystem, Request, TRUE, TRUE,
|
||||||
Request->Req.Create.DesiredAccess, &GrantedAccess);
|
Request->Req.Create.DesiredAccess, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -287,7 +526,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
|
||||||
|
|
||||||
Result = FspShareCheck(FileSystem, GrantedAccess, Request->Req.Create.ShareAccess, FileNode);
|
Result = FspFileSystemPostOpenCheck(FileSystem, Request, GrantedAccess, FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (0 != FileSystem->Interface->Close)
|
if (0 != FileSystem->Interface->Close)
|
||||||
@ -326,9 +565,9 @@ FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
case FILE_OPEN_IF:
|
case FILE_OPEN_IF:
|
||||||
return FspFileSystemOpCreate_FileOpenIf(FileSystem, Request);
|
return FspFileSystemOpCreate_FileOpenIf(FileSystem, Request);
|
||||||
case FILE_OVERWRITE:
|
case FILE_OVERWRITE:
|
||||||
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, FALSE);
|
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request);
|
||||||
case FILE_SUPERSEDE:
|
case FILE_SUPERSEDE:
|
||||||
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, TRUE);
|
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request);
|
||||||
case FILE_OVERWRITE_IF:
|
case FILE_OVERWRITE_IF:
|
||||||
return FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request);
|
return FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request);
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user