dll: overwrite refactoring

This commit is contained in:
Bill Zissimopoulos 2016-01-12 16:43:24 -08:00
parent cbf15e47ad
commit 7e1883044b
5 changed files with 113 additions and 186 deletions

View File

@ -162,6 +162,7 @@ typedef struct
{ {
UINT64 UserContext; /* open file user context (unique file id) */ UINT64 UserContext; /* open file user context (unique file id) */
UINT64 UserContext2; /* kernel file object user context (stores as many bits as a pointer) */ UINT64 UserContext2; /* kernel file object user context (stores as many bits as a pointer) */
UINT32 FileAttributes; /* FILE_ATTRIBUTE_{NORMAL,DIRECTORY,etc.} */
UINT64 AllocationSize; /* file allocation size */ UINT64 AllocationSize; /* file allocation size */
UINT64 FileSize; /* file size */ UINT64 FileSize; /* file size */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */

View File

@ -27,23 +27,39 @@
typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM;
typedef VOID FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); 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 NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *);
typedef struct _FSP_FILE_NODE_INFO
{
PVOID FileNode;
DWORD FileAttributes;
UINT64 AllocationSize;
UINT64 FileSize;
} FSP_FILE_NODE_INFO;
typedef struct _FSP_FILE_SIZE_INFO
{
UINT64 AllocationSize;
UINT64 FileSize;
} FSP_FILE_SIZE_INFO;
typedef struct _FSP_FILE_SYSTEM_INTERFACE typedef struct _FSP_FILE_SYSTEM_INTERFACE
{ {
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);
#if 0
NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE **PFileNode); FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE_INFO *Info);
NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE **PFileNode); FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE_INFO *Info);
NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN ReplaceFileAttributes, FSP_FILE_NODE *FileNode); FSP_FSCTL_TRANSACT_REQ *Request,
PVOID FileNode, DWORD FileAttributes, BOOLEAN ReplaceFileAttributes,
FSP_FILE_SIZE_INFO *Info);
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode, BOOLEAN Delete); FSP_FSCTL_TRANSACT_REQ *Request,
PVOID FileNode, BOOLEAN Delete);
VOID (*Close)(FSP_FILE_SYSTEM *FileSystem, VOID (*Close)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode); FSP_FSCTL_TRANSACT_REQ *Request,
#endif PVOID FileNode);
} FSP_FILE_SYSTEM_INTERFACE; } FSP_FILE_SYSTEM_INTERFACE;
typedef struct _FSP_FILE_SYSTEM typedef struct _FSP_FILE_SYSTEM
{ {
@ -139,6 +155,16 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, UINT_PTR Information,
const FSP_FILE_NODE_INFO *NodeInfo, DWORD GrantedAccess);
FSP_API NTSTATUS FspFileSystemSendOverwriteResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
const FSP_FILE_SIZE_INFO *SizeInfo);
FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
/* /*
* Path Handling * Path Handling

View File

@ -9,35 +9,10 @@
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request)
{ {
return STATUS_INVALID_DEVICE_REQUEST; if (0 != FileSystem->Interface->Cleanup)
} FileSystem->Interface->Cleanup(FileSystem, Request,
(PVOID)Request->Req.Cleanup.UserContext,
#if 0 0 != Request->Req.Cleanup.Delete);
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (0 == FileSystem->Interface->Cleanup)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
FSP_FILE_NODE *FileNode = (PVOID)Request->Req.Close.UserContext;
BOOLEAN DeletePending;
LONG OpenCount;
FspFileNodeLock(FileNode);
FspShareAccessRemove(FileSystem, Request, FileNode);
/* propagate the DeleteOnClose flag to DeletePending */
if (FileNode->Flags.DeleteOnClose)
FileNode->Flags.DeletePending = TRUE;
DeletePending = FileNode->Flags.DeletePending;
/* all handles on the kernel FILE_OBJECT gone; decrement the FileNode's OpenCount */
OpenCount = FspFileNodeClose(FileNode);
FspFileNodeUnlock(FileNode);
FileSystem->Interface->Cleanup(FileSystem, Request, FileNode, 0 == OpenCount && DeletePending);
return FspFileSystemSendCleanupResponse(FileSystem, Request); return FspFileSystemSendCleanupResponse(FileSystem, Request);
} }
@ -55,4 +30,3 @@ FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
Response.IoStatus.Information = 0; Response.IoStatus.Information = 0;
return FspFileSystemSendResponse(FileSystem, &Response); return FspFileSystemSendResponse(FileSystem, &Response);
} }
#endif

View File

@ -9,19 +9,9 @@
FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request)
{ {
return STATUS_INVALID_DEVICE_REQUEST; if (0 != FileSystem->Interface->Close)
} FileSystem->Interface->Close(FileSystem, Request,
(PVOID)Request->Req.Close.UserContext);
#if 0
FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (0 == FileSystem->Interface->Close)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
FSP_FILE_NODE *FileNode = (PVOID)Request->Req.Close.UserContext;
FileSystem->Interface->Close(FileSystem, Request, FileNode);
return FspFileSystemSendCloseResponse(FileSystem, Request); return FspFileSystemSendCloseResponse(FileSystem, Request);
} }
@ -39,4 +29,3 @@ FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem,
Response.IoStatus.Information = 0; Response.IoStatus.Information = 0;
return FspFileSystemSendResponse(FileSystem, &Response); return FspFileSystemSendResponse(FileSystem, &Response);
} }
#endif

View File

@ -184,7 +184,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
} }
static inline static inline
NTSTATUS FspFileSystemPreOpenCheck(FSP_FILE_SYSTEM *FileSystem, NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess) FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN AllowTraverseCheck, PDWORD PGrantedAccess)
{ {
return FspAccessCheck(FileSystem, Request, FALSE, AllowTraverseCheck, return FspAccessCheck(FileSystem, Request, FALSE, AllowTraverseCheck,
@ -212,49 +212,23 @@ NTSTATUS FspFileSystemOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
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++)
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)
{ {
NTSTATUS Result; NTSTATUS Result;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
if (FspIsRootDirectory((PWSTR)Request->Buffer)) Result = FspFileSystemCreateCheck(FileSystem, Request, TRUE, &GrantedAccess);
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);
Result = FileSystem->Interface->Create(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Create(FileSystem, Request, &NodeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
return FspFileSystemSendCreateResponse(FileSystem, Request, return FspFileSystemSendCreateResponse(FileSystem, Request,
FILE_CREATED, FileNode, GrantedAccess); FILE_CREATED, &NodeInfo, GrantedAccess);
} }
static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
@ -262,26 +236,18 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
{ {
NTSTATUS Result; NTSTATUS Result;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
Result = FspFileSystemPreOpenCheck(FileSystem, Request, TRUE, &GrantedAccess); Result = FspFileSystemOpenCheck(FileSystem, Request, TRUE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Open(FileSystem, Request, &NodeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
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);
}
return FspFileSystemSendCreateResponse(FileSystem, Request, return FspFileSystemSendCreateResponse(FileSystem, Request,
FILE_OPENED, FileNode, GrantedAccess); FILE_OPENED, &NodeInfo, GrantedAccess);
} }
static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
@ -289,10 +255,10 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
{ {
NTSTATUS Result; NTSTATUS Result;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
BOOLEAN Create = FALSE; BOOLEAN Create = FALSE;
Result = FspFileSystemPreOpenCheck(FileSystem, Request, TRUE, &GrantedAccess); Result = FspFileSystemOpenCheck(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)
@ -302,43 +268,28 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
if (!Create) if (!Create)
{ {
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Open(FileSystem, Request, &NodeInfo);
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
{
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)
{ {
if (FspIsRootDirectory((PWSTR)Request->Buffer)) Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
return STATUS_ACCESS_DENIED;
Result = FspFileSystemPreCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
Result = FileSystem->Interface->Create(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Create(FileSystem, Request, &NodeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, return FspFileSystemSendCreateResponse(FileSystem, Request,
Create ? FILE_CREATED : FILE_OPENED, FileNode, GrantedAccess); Create ? FILE_CREATED : FILE_OPENED, &NodeInfo, GrantedAccess);
} }
static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
@ -346,38 +297,19 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
{ {
NTSTATUS Result; NTSTATUS Result;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff); BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
if (FspIsRootDirectory((PWSTR)Request->Buffer)) Result = FspFileSystemOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
return STATUS_ACCESS_DENIED;
Result = FspFileSystemPreOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Open(FileSystem, Request, &NodeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
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, Supersede, 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,
Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN, FileNode, GrantedAccess); Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN, &NodeInfo, GrantedAccess);
} }
static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem,
@ -385,13 +317,10 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
{ {
NTSTATUS Result; NTSTATUS Result;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
BOOLEAN Create = FALSE; BOOLEAN Create = FALSE;
if (FspIsRootDirectory((PWSTR)Request->Buffer)) Result = FspFileSystemOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
return STATUS_ACCESS_DENIED;
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)
@ -401,48 +330,28 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
if (!Create) if (!Create)
{ {
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Open(FileSystem, Request, &NodeInfo);
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
{
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 = FspFileSystemPreCreateCheck(FileSystem, Request, FALSE, &GrantedAccess); Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
Result = FileSystem->Interface->Create(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Create(FileSystem, Request, &NodeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
FspFileSystemPostCreateCheck(FileSystem, Request, GrantedAccess, FileNode);
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, return FspFileSystemSendCreateResponse(FileSystem, Request,
Create ? FILE_CREATED : FILE_OVERWRITTEN, FileNode, GrantedAccess); Create ? FILE_CREATED : FILE_OVERWRITTEN, &NodeInfo, GrantedAccess);
} }
static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem,
@ -451,31 +360,20 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
NTSTATUS Result; NTSTATUS Result;
PWSTR Parent, Suffix; PWSTR Parent, Suffix;
DWORD GrantedAccess; DWORD GrantedAccess;
FSP_FILE_NODE *FileNode; FSP_FILE_NODE_INFO NodeInfo;
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))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix); FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix);
Result = FileSystem->Interface->Open(FileSystem, Request, &FileNode); Result = FileSystem->Interface->Open(FileSystem, Request, &NodeInfo);
FspPathCombine((PWSTR)Request->Buffer, Suffix); FspPathCombine((PWSTR)Request->Buffer, Suffix);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
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);
}
Information = FILE_OPENED; Information = FILE_OPENED;
if (0 != FileSystem->Interface->GetSecurity) if (0 != FileSystem->Interface->GetSecurity)
{ {
@ -484,7 +382,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, return FspFileSystemSendCreateResponse(FileSystem, Request,
Information, FileNode, GrantedAccess); Information, &NodeInfo, GrantedAccess);
} }
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
@ -517,9 +415,31 @@ FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
} }
} }
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
NTSTATUS Result;
FSP_FILE_SIZE_INFO SizeInfo;
Result = FileSystem->Interface->Overwrite(FileSystem, Request,
(PVOID)Request->Req.Overwrite.UserContext,
Request->Req.Overwrite.FileAttributes,
Request->Req.Overwrite.Supersede,
&SizeInfo);
if (!NT_SUCCESS(Result))
{
if (0 != FileSystem->Interface->Close)
FileSystem->Interface->Close(FileSystem, Request,
(PVOID)Request->Req.Overwrite.UserContext);
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
}
return FspFileSystemSendOverwriteResponse(FileSystem, Request, &SizeInfo);
}
FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, UINT_PTR Information, FSP_FSCTL_TRANSACT_REQ *Request, UINT_PTR Information,
FSP_FILE_NODE *FileNode, DWORD GrantedAccess) const FSP_FILE_NODE_INFO *NodeInfo, DWORD GrantedAccess)
{ {
FSP_FSCTL_TRANSACT_RSP Response; FSP_FSCTL_TRANSACT_RSP Response;
@ -529,10 +449,27 @@ FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem,
Response.Hint = Request->Hint; Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS; Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = Information; Response.IoStatus.Information = Information;
Response.Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode; Response.Rsp.Create.Opened.UserContext = (UINT_PTR)NodeInfo->FileNode;
Response.Rsp.Create.Opened.AllocationSize = FileNode->AllocationSize; Response.Rsp.Create.Opened.FileAttributes = NodeInfo->FileAttributes;
Response.Rsp.Create.Opened.FileSize = FileNode->FileSize; Response.Rsp.Create.Opened.AllocationSize = NodeInfo->AllocationSize;
Response.Rsp.Create.Opened.FileSize = NodeInfo->FileSize;
Response.Rsp.Create.Opened.GrantedAccess = GrantedAccess; Response.Rsp.Create.Opened.GrantedAccess = GrantedAccess;
return FspFileSystemSendResponse(FileSystem, &Response); return FspFileSystemSendResponse(FileSystem, &Response);
} }
#endif
FSP_API NTSTATUS FspFileSystemSendOverwriteResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
const FSP_FILE_SIZE_INFO *SizeInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = Request->Kind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
Response.Rsp.Overwrite.AllocationSize = SizeInfo->AllocationSize;
Response.Rsp.Overwrite.FileSize = SizeInfo->FileSize;
return FspFileSystemSendResponse(FileSystem, &Response);
}