mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-15 08:12:45 -05:00
sys: rename FsContext to FileNode
This commit is contained in:
@ -156,7 +156,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\driver.c" />
|
<ClCompile Include="..\..\src\sys\driver.c" />
|
||||||
<ClCompile Include="..\..\src\sys\ea.c" />
|
<ClCompile Include="..\..\src\sys\ea.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fastio.c" />
|
<ClCompile Include="..\..\src\sys\fastio.c" />
|
||||||
<ClCompile Include="..\..\src\sys\filectx.c" />
|
<ClCompile Include="..\..\src\sys\node.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fileinfo.c" />
|
<ClCompile Include="..\..\src\sys\fileinfo.c" />
|
||||||
<ClCompile Include="..\..\src\sys\flush.c" />
|
<ClCompile Include="..\..\src\sys\flush.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\volume.c">
|
<ClCompile Include="..\..\src\sys\volume.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\sys\filectx.c">
|
<ClCompile Include="..\..\src\sys\node.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -50,22 +50,22 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* is this a valid FileObject? */
|
/* is this a valid FileObject? */
|
||||||
if (!FspFileContextIsValid(IrpSp->FileObject->FsContext))
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired;
|
BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_CONTEXT *FsContext = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
UINT64 UserContext = FsContext->UserContext;
|
UINT64 UserContext = FileNode->UserContext;
|
||||||
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
BOOLEAN DeletePending;
|
BOOLEAN DeletePending;
|
||||||
|
|
||||||
FspFileContextClose(FsContext, FileObject, &DeletePending);
|
FspFileNodeClose(FileNode, FileObject, &DeletePending);
|
||||||
|
|
||||||
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */
|
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */
|
||||||
FspIopCreateRequestMustSucceed(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
|
FspIopCreateRequestMustSucceed(Irp, FileNameRequired ? &FileNode->FileName : 0, 0, &Request);
|
||||||
|
|
||||||
/* populate the Cleanup request */
|
/* populate the Cleanup request */
|
||||||
Request->Kind = FspFsctlTransactCleanupKind;
|
Request->Kind = FspFsctlTransactCleanupKind;
|
||||||
|
@ -47,22 +47,22 @@ static NTSTATUS FspFsvolClose(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* is this a valid FileObject? */
|
/* is this a valid FileObject? */
|
||||||
if (!FspFileContextIsValid(IrpSp->FileObject->FsContext))
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired;
|
BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_CONTEXT *FsContext = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
UINT64 UserContext = FsContext->UserContext;
|
UINT64 UserContext = FileNode->UserContext;
|
||||||
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* dereference the FsContext (and delete if no more references) */
|
/* dereference the FileNode (and delete if no more references) */
|
||||||
FspFileContextRelease(FsContext);
|
FspFileNodeRelease(FileNode);
|
||||||
|
|
||||||
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLOSE cannot fail */
|
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLOSE cannot fail */
|
||||||
FspIopCreateRequestMustSucceed(0, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
|
FspIopCreateRequestMustSucceed(0, FileNameRequired ? &FileNode->FileName : 0, 0, &Request);
|
||||||
|
|
||||||
/* populate the Close request */
|
/* populate the Close request */
|
||||||
Request->Kind = FspFsctlTransactCloseKind;
|
Request->Kind = FspFsctlTransactCloseKind;
|
||||||
|
152
src/sys/create.c
152
src/sys/create.c
@ -15,7 +15,7 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
||||||
static VOID FspFsvolCreatePostClose(
|
static VOID FspFsvolCreatePostClose(
|
||||||
FSP_FILE_CONTEXT *FsContext, UINT64 UserContext2);
|
FSP_FILE_NODE *FileNode, UINT64 UserContext2);
|
||||||
static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
|
static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini;
|
||||||
static FSP_IOP_REQUEST_FINI FspFsvolCreateOverwriteRequestFini;
|
static FSP_IOP_REQUEST_FINI FspFsvolCreateOverwriteRequestFini;
|
||||||
FSP_DRIVER_DISPATCH FspCreate;
|
FSP_DRIVER_DISPATCH FspCreate;
|
||||||
@ -38,11 +38,11 @@ FSP_DRIVER_DISPATCH FspCreate;
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* CreateRequest */
|
/* CreateRequest */
|
||||||
RequestFsContext = 0,
|
RequestFileNode = 0,
|
||||||
RequestAccessToken = 1,
|
RequestAccessToken = 1,
|
||||||
RequestProcess = 2,
|
RequestProcess = 2,
|
||||||
/* OverwriteRequest */
|
/* OverwriteRequest */
|
||||||
//RequestFsContext = 0,
|
//RequestFileNode = 0,
|
||||||
RequestFileObject = 1,
|
RequestFileObject = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
BOOLEAN IsAbsoluteSecurityDescriptor = FALSE;
|
BOOLEAN IsAbsoluteSecurityDescriptor = FALSE;
|
||||||
BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE;
|
BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE;
|
||||||
BOOLEAN HasTrailingBackslash = FALSE;
|
BOOLEAN HasTrailingBackslash = FALSE;
|
||||||
FSP_FILE_CONTEXT *FsContext, *RelatedFsContext;
|
FSP_FILE_NODE *FileNode, *RelatedFileNode;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* cannot open files by fileid */
|
/* cannot open files by fileid */
|
||||||
@ -185,10 +185,10 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
/* is this a relative or absolute open? */
|
/* is this a relative or absolute open? */
|
||||||
if (0 != RelatedFileObject)
|
if (0 != RelatedFileObject)
|
||||||
{
|
{
|
||||||
RelatedFsContext = RelatedFileObject->FsContext;
|
RelatedFileNode = RelatedFileObject->FsContext;
|
||||||
|
|
||||||
/* is this a valid RelatedFileObject? */
|
/* is this a valid RelatedFileObject? */
|
||||||
if (!FspFileContextIsValid(RelatedFsContext))
|
if (!FspFileNodeIsValid(RelatedFileNode))
|
||||||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
|
|
||||||
/* must be a relative path */
|
/* must be a relative path */
|
||||||
@ -201,34 +201,34 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
FILE_OVERWRITE_IF == CreateDisposition ||
|
FILE_OVERWRITE_IF == CreateDisposition ||
|
||||||
FILE_SUPERSEDE == CreateDisposition ||
|
FILE_SUPERSEDE == CreateDisposition ||
|
||||||
BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY)) &&
|
BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY)) &&
|
||||||
sizeof(WCHAR) == RelatedFsContext->FileName.Length && 0 == FileName.Length)
|
sizeof(WCHAR) == RelatedFileNode->FileName.Length && 0 == FileName.Length)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
/* cannot FILE_DELETE_ON_CLOSE on the root directory */
|
/* cannot FILE_DELETE_ON_CLOSE on the root directory */
|
||||||
if (FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE) &&
|
if (FlagOn(CreateOptions, FILE_DELETE_ON_CLOSE) &&
|
||||||
sizeof(WCHAR) == RelatedFsContext->FileName.Length && 0 == FileName.Length)
|
sizeof(WCHAR) == RelatedFileNode->FileName.Length && 0 == FileName.Length)
|
||||||
return STATUS_CANNOT_DELETE;
|
return STATUS_CANNOT_DELETE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no need to lock our accesses of RelatedFileObject->FsContext->FileName,
|
* There is no need to lock our accesses of RelatedFileObject->FileNode->FileName,
|
||||||
* because RelatedFileObject->FsContext->Filename is read-only (after creation) and
|
* because RelatedFileObject->FileNode->Filename is read-only (after creation) and
|
||||||
* because RelatedFileObject->FsContext is guaranteed to exist while RelatedFileObject
|
* because RelatedFileObject->FileNode is guaranteed to exist while RelatedFileObject
|
||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
BOOLEAN AppendBackslash =
|
BOOLEAN AppendBackslash =
|
||||||
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFsContext->FileName.Length &&
|
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFileNode->FileName.Length &&
|
||||||
sizeof(WCHAR) <= FileName.Length && L':' != FileName.Buffer[0];
|
sizeof(WCHAR) <= FileName.Length && L':' != FileName.Buffer[0];
|
||||||
Result = FspFileContextCreate(FsvolDeviceObject,
|
Result = FspFileNodeCreate(FsvolDeviceObject,
|
||||||
RelatedFsContext->FileName.Length + AppendBackslash * sizeof(WCHAR) + FileName.Length,
|
RelatedFileNode->FileName.Length + AppendBackslash * sizeof(WCHAR) + FileName.Length,
|
||||||
&FsContext);
|
&FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &RelatedFsContext->FileName);
|
Result = RtlAppendUnicodeStringToString(&FileNode->FileName, &RelatedFileNode->FileName);
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
if (AppendBackslash)
|
if (AppendBackslash)
|
||||||
{
|
{
|
||||||
Result = RtlAppendUnicodeToString(&FsContext->FileName, L"\\");
|
Result = RtlAppendUnicodeToString(&FileNode->FileName, L"\\");
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,31 +252,31 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
sizeof(WCHAR) == FileName.Length)
|
sizeof(WCHAR) == FileName.Length)
|
||||||
return STATUS_CANNOT_DELETE;
|
return STATUS_CANNOT_DELETE;
|
||||||
|
|
||||||
Result = FspFileContextCreate(FsvolDeviceObject,
|
Result = FspFileNodeCreate(FsvolDeviceObject,
|
||||||
FileName.Length,
|
FileName.Length,
|
||||||
&FsContext);
|
&FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = RtlAppendUnicodeStringToString(&FsContext->FileName, &FileName);
|
Result = RtlAppendUnicodeStringToString(&FileNode->FileName, &FileName);
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
/* create the user-mode file system request */
|
/* create the user-mode file system request */
|
||||||
Result = FspIopCreateRequestEx(Irp, &FsContext->FileName, SecurityDescriptorSize,
|
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, SecurityDescriptorSize,
|
||||||
FspFsvolCreateRequestFini, &Request);
|
FspFsvolCreateRequestFini, &Request);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
FspFileContextRelease(FsContext);
|
FspFileNodeRelease(FileNode);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The new request is associated with our IRP. Go ahead and associate our FsContext
|
* The new request is associated with our IRP. Go ahead and associate our FileNode
|
||||||
* with the Request as well. After this is done completing our IRP will automatically
|
* with the Request as well. After this is done completing our IRP will automatically
|
||||||
* delete the Request and any associated resources.
|
* delete the Request and any associated resources.
|
||||||
*/
|
*/
|
||||||
FspIopRequestContext(Request, RequestFsContext) = FsContext;
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
|
|
||||||
/* populate the Create request */
|
/* populate the Create request */
|
||||||
Request->Kind = FspFsctlTransactCreateKind;
|
Request->Kind = FspFsctlTransactCreateKind;
|
||||||
@ -328,7 +328,7 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
||||||
HANDLE UserModeAccessToken;
|
HANDLE UserModeAccessToken;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
FSP_FILE_CONTEXT *FsContext;
|
FSP_FILE_NODE *FileNode;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
|
||||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
if (FspFsctlTransactCreateKind == Request->Kind)
|
||||||
@ -370,11 +370,11 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
}
|
}
|
||||||
else if (FspFsctlTransactOverwriteKind == Request->Kind)
|
else if (FspFsctlTransactOverwriteKind == Request->Kind)
|
||||||
{
|
{
|
||||||
FsContext = FspIopRequestContext(Request, RequestFsContext);
|
FileNode = FspIopRequestContext(Request, RequestFileNode);
|
||||||
FileObject = FspIopRequestContext(Request, RequestFileObject);
|
FileObject = FspIopRequestContext(Request, RequestFileObject);
|
||||||
|
|
||||||
/* lock the FsContext for Paging IO */
|
/* lock the FileNode for Paging IO */
|
||||||
Success = FspFileContextPgioLockExclusive(FsContext, FALSE);
|
Success = FspFileNodePgioLockExclusive(FileNode, FALSE);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
{
|
{
|
||||||
/* repost the IRP to retry later */
|
/* repost the IRP to retry later */
|
||||||
@ -389,19 +389,19 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
|
|
||||||
/* see what the MM thinks about all this */
|
/* see what the MM thinks about all this */
|
||||||
LARGE_INTEGER Zero = { 0 };
|
LARGE_INTEGER Zero = { 0 };
|
||||||
Success = MmCanFileBeTruncated(&FsContext->NonPaged->SectionObjectPointers, &Zero);
|
Success = MmCanFileBeTruncated(&FileNode->NonPaged->SectionObjectPointers, &Zero);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
{
|
{
|
||||||
FspFileContextPgioUnlock(FsContext);
|
FspFileNodePgioUnlock(FileNode);
|
||||||
|
|
||||||
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
|
FspFsvolCreatePostClose(FileNode, (UINT_PTR)FileObject->FsContext2);
|
||||||
FspFileContextClose(FsContext, FileObject, 0);
|
FspFileNodeClose(FileNode, FileObject, 0);
|
||||||
|
|
||||||
return STATUS_USER_MAPPED_FILE;
|
return STATUS_USER_MAPPED_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* purge any caches on this file */
|
/* purge any caches on this file */
|
||||||
CcPurgeCacheSection(&FsContext->NonPaged->SectionObjectPointers, 0, 0, FALSE);
|
CcPurgeCacheSection(&FileNode->NonPaged->SectionObjectPointers, 0, 0, FALSE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -422,8 +422,8 @@ VOID FspFsvolCreateComplete(
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
FSP_FILE_CONTEXT *FsContext = FspIopRequestContext(Request, RequestFsContext);
|
FSP_FILE_NODE *FileNode = FspIopRequestContext(Request, RequestFileNode);
|
||||||
FSP_FILE_CONTEXT *OpenedFsContext;
|
FSP_FILE_NODE *OpenedFileNode;
|
||||||
UNICODE_STRING ReparseFileName;
|
UNICODE_STRING ReparseFileName;
|
||||||
BOOLEAN DeleteOnClose;
|
BOOLEAN DeleteOnClose;
|
||||||
|
|
||||||
@ -494,36 +494,36 @@ VOID FspFsvolCreateComplete(
|
|||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* populate the FsContext fields from the Response */
|
/* populate the FileNode fields from the Response */
|
||||||
FsContext->Header.AllocationSize.QuadPart = Response->Rsp.Create.Opened.AllocationSize;
|
FileNode->Header.AllocationSize.QuadPart = Response->Rsp.Create.Opened.AllocationSize;
|
||||||
FsContext->Header.FileSize.QuadPart = Response->Rsp.Create.Opened.FileSize;
|
FileNode->Header.FileSize.QuadPart = Response->Rsp.Create.Opened.FileSize;
|
||||||
FsContext->UserContext = Response->Rsp.Create.Opened.UserContext;
|
FileNode->UserContext = Response->Rsp.Create.Opened.UserContext;
|
||||||
|
|
||||||
DeleteOnClose = BooleanFlagOn(Request->Req.Create.CreateOptions, FILE_DELETE_ON_CLOSE);
|
DeleteOnClose = BooleanFlagOn(Request->Req.Create.CreateOptions, FILE_DELETE_ON_CLOSE);
|
||||||
|
|
||||||
/* open the FsContext */
|
/* open the FileNode */
|
||||||
OpenedFsContext = FspFileContextOpen(FsContext, FileObject,
|
OpenedFileNode = FspFileNodeOpen(FileNode, FileObject,
|
||||||
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
||||||
DeleteOnClose,
|
DeleteOnClose,
|
||||||
&Result);
|
&Result);
|
||||||
if (0 == OpenedFsContext)
|
if (0 == OpenedFileNode)
|
||||||
{
|
{
|
||||||
/* unable to open the FsContext; post a Close request */
|
/* unable to open the FileNode; post a Close request */
|
||||||
FspFsvolCreatePostClose(FsContext,
|
FspFsvolCreatePostClose(FileNode,
|
||||||
Response->Rsp.Create.Opened.UserContext2);
|
Response->Rsp.Create.Opened.UserContext2);
|
||||||
|
|
||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
FsContext = OpenedFsContext;
|
FileNode = OpenedFileNode;
|
||||||
|
|
||||||
/* set up the FileObject */
|
/* set up the FileObject */
|
||||||
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
||||||
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
||||||
FileObject->SectionObjectPointer = &FsContext->NonPaged->SectionObjectPointers;
|
FileObject->SectionObjectPointer = &FileNode->NonPaged->SectionObjectPointers;
|
||||||
FileObject->PrivateCacheMap = 0;
|
FileObject->PrivateCacheMap = 0;
|
||||||
FileObject->FsContext = FsContext;
|
FileObject->FsContext = FileNode;
|
||||||
FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2;
|
FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2;
|
||||||
|
|
||||||
if (FILE_OPENED == Response->IoStatus.Information)
|
if (FILE_OPENED == Response->IoStatus.Information)
|
||||||
@ -540,12 +540,12 @@ VOID FspFsvolCreateComplete(
|
|||||||
if (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
|
if (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) ||
|
||||||
DeleteOnClose)
|
DeleteOnClose)
|
||||||
{
|
{
|
||||||
if (!MmFlushImageSection(&FsContext->NonPaged->SectionObjectPointers,
|
if (!MmFlushImageSection(&FileNode->NonPaged->SectionObjectPointers,
|
||||||
MmFlushForWrite))
|
MmFlushForWrite))
|
||||||
{
|
{
|
||||||
FspFsvolCreatePostClose(FsContext,
|
FspFsvolCreatePostClose(FileNode,
|
||||||
Response->Rsp.Create.Opened.UserContext2);
|
Response->Rsp.Create.Opened.UserContext2);
|
||||||
FspFileContextClose(FsContext, FileObject, 0);
|
FspFileNodeClose(FileNode, FileObject, 0);
|
||||||
|
|
||||||
Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
@ -553,7 +553,7 @@ VOID FspFsvolCreateComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SUCCESS! */
|
/* SUCCESS! */
|
||||||
FspIopRequestContext(Request, RequestFsContext) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information;
|
Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information;
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -571,17 +571,17 @@ VOID FspFsvolCreateComplete(
|
|||||||
|
|
||||||
/* create the Overwrite request; MustSucceed because we must either overwrite or close */
|
/* create the Overwrite request; MustSucceed because we must either overwrite or close */
|
||||||
FspIopCreateRequestFunnel(Irp,
|
FspIopCreateRequestFunnel(Irp,
|
||||||
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FsContext->FileName : 0, 0,
|
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FileNode->FileName : 0, 0,
|
||||||
FspFsvolCreateOverwriteRequestFini, TRUE,
|
FspFsvolCreateOverwriteRequestFini, TRUE,
|
||||||
&Request);
|
&Request);
|
||||||
|
|
||||||
/* associate the FsContext and FileObject with the Overwrite request */
|
/* associate the FileNode and FileObject with the Overwrite request */
|
||||||
FspIopRequestContext(Request, RequestFsContext) = FsContext;
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
FspIopRequestContext(Request, RequestFileObject) = FileObject;
|
FspIopRequestContext(Request, RequestFileObject) = FileObject;
|
||||||
|
|
||||||
/* populate the Overwrite request */
|
/* populate the Overwrite request */
|
||||||
Request->Kind = FspFsctlTransactOverwriteKind;
|
Request->Kind = FspFsctlTransactOverwriteKind;
|
||||||
Request->Req.Overwrite.UserContext = FsContext->UserContext;
|
Request->Req.Overwrite.UserContext = FileNode->UserContext;
|
||||||
Request->Req.Overwrite.UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
Request->Req.Overwrite.UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
||||||
Request->Req.Overwrite.FileAttributes = IrpSp->Parameters.Create.FileAttributes;
|
Request->Req.Overwrite.FileAttributes = IrpSp->Parameters.Create.FileAttributes;
|
||||||
Request->Req.Overwrite.Supersede = FILE_SUPERSEDED == Response->IoStatus.Information;
|
Request->Req.Overwrite.Supersede = FILE_SUPERSEDED == Response->IoStatus.Information;
|
||||||
@ -597,7 +597,7 @@ VOID FspFsvolCreateComplete(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* SUCCESS! */
|
/* SUCCESS! */
|
||||||
FspIopRequestContext(Request, RequestFsContext) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information;
|
Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information;
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -612,9 +612,9 @@ VOID FspFsvolCreateComplete(
|
|||||||
/* did the user-mode file system sent us a failure code? */
|
/* did the user-mode file system sent us a failure code? */
|
||||||
if (!NT_SUCCESS(Response->IoStatus.Status))
|
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||||
{
|
{
|
||||||
FspFileContextPgioUnlock(FsContext);
|
FspFileNodePgioUnlock(FileNode);
|
||||||
|
|
||||||
FspFileContextClose(FsContext, FileObject, 0);
|
FspFileNodeClose(FileNode, FileObject, 0);
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Result = Response->IoStatus.Status;
|
Result = Response->IoStatus.Status;
|
||||||
@ -622,14 +622,14 @@ VOID FspFsvolCreateComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* file was successfully overwritten/superseded */
|
/* file was successfully overwritten/superseded */
|
||||||
FsContext->Header.AllocationSize.QuadPart = Response->Rsp.Overwrite.AllocationSize;
|
FileNode->Header.AllocationSize.QuadPart = Response->Rsp.Overwrite.AllocationSize;
|
||||||
FsContext->Header.FileSize.QuadPart = Response->Rsp.Overwrite.FileSize;
|
FileNode->Header.FileSize.QuadPart = Response->Rsp.Overwrite.FileSize;
|
||||||
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&FsContext->Header.AllocationSize);
|
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize);
|
||||||
|
|
||||||
FspFileContextPgioUnlock(FsContext);
|
FspFileNodePgioUnlock(FileNode);
|
||||||
|
|
||||||
/* SUCCESS! */
|
/* SUCCESS! */
|
||||||
FspIopRequestContext(Request, RequestFsContext) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
Irp->IoStatus.Information = Request->Req.Overwrite.Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
Irp->IoStatus.Information = Request->Req.Overwrite.Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -642,22 +642,22 @@ VOID FspFsvolCreateComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VOID FspFsvolCreatePostClose(
|
static VOID FspFsvolCreatePostClose(
|
||||||
FSP_FILE_CONTEXT *FsContext, UINT64 UserContext2)
|
FSP_FILE_NODE *FileNode, UINT64 UserContext2)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* create the user-mode file system request; MustSucceed because we cannot fail */
|
/* create the user-mode file system request; MustSucceed because we cannot fail */
|
||||||
FspIopCreateRequestMustSucceed(0,
|
FspIopCreateRequestMustSucceed(0,
|
||||||
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FsContext->FileName : 0,
|
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FileNode->FileName : 0,
|
||||||
0, &Request);
|
0, &Request);
|
||||||
|
|
||||||
/* populate the Close request */
|
/* populate the Close request */
|
||||||
Request->Kind = FspFsctlTransactCloseKind;
|
Request->Kind = FspFsctlTransactCloseKind;
|
||||||
Request->Req.Close.UserContext = FsContext->UserContext;
|
Request->Req.Close.UserContext = FileNode->UserContext;
|
||||||
Request->Req.Close.UserContext2 = UserContext2;
|
Request->Req.Close.UserContext2 = UserContext2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -678,10 +678,10 @@ static VOID FspFsvolCreateRequestFini(PVOID Context[3])
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (0 != Context[RequestFsContext])
|
if (0 != Context[RequestFileNode])
|
||||||
{
|
{
|
||||||
FspFileContextRelease(Context[RequestFsContext]);
|
FspFileNodeRelease(Context[RequestFileNode]);
|
||||||
Context[RequestFsContext] = 0;
|
Context[RequestFileNode] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Context[RequestAccessToken])
|
if (0 != Context[RequestAccessToken])
|
||||||
@ -717,21 +717,21 @@ static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (0 != Context[RequestFsContext])
|
if (0 != Context[RequestFileNode])
|
||||||
{
|
{
|
||||||
FSP_FILE_CONTEXT *FsContext = Context[RequestFsContext];
|
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
|
||||||
PFILE_OBJECT FileObject = Context[RequestFileObject];
|
PFILE_OBJECT FileObject = Context[RequestFileObject];
|
||||||
|
|
||||||
if (0 != FileObject)
|
if (0 != FileObject)
|
||||||
{
|
{
|
||||||
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
|
FspFsvolCreatePostClose(FileNode, (UINT_PTR)FileObject->FsContext2);
|
||||||
FspFileContextClose(FsContext, FileObject, 0);
|
FspFileNodeClose(FileNode, FileObject, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFileContextRelease(FsContext);
|
FspFileNodeRelease(FileNode);
|
||||||
|
|
||||||
Context[RequestFileObject] = 0;
|
Context[RequestFileObject] = 0;
|
||||||
Context[RequestFsContext] = 0;
|
Context[RequestFileNode] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,13 +505,13 @@ NTSTATUS FspVolumeWork(
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
/* file objects */
|
/* file objects */
|
||||||
#define FspFileContextKind(FsContext) \
|
#define FspFileNodeKind(FileNode) \
|
||||||
(((FSP_FILE_CONTEXT *)FsContext)->Header.NodeTypeCode)
|
(((FSP_FILE_NODE *)FileNode)->Header.NodeTypeCode)
|
||||||
#define FspFileContextIsValid(FsContext)\
|
#define FspFileNodeIsValid(FileNode)\
|
||||||
(0 != (FsContext) && FspFileContextFileKind == ((FSP_FILE_CONTEXT *)FsContext)->Header.NodeTypeCode)
|
(0 != (FileNode) && FspFileNodeFileKind == ((FSP_FILE_NODE *)FileNode)->Header.NodeTypeCode)
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FspFileContextFileKind = 'BZ',
|
FspFileNodeFileKind = 'BZ',
|
||||||
};
|
};
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -519,11 +519,11 @@ typedef struct
|
|||||||
ERESOURCE PagingIoResource;
|
ERESOURCE PagingIoResource;
|
||||||
FAST_MUTEX HeaderFastMutex;
|
FAST_MUTEX HeaderFastMutex;
|
||||||
SECTION_OBJECT_POINTERS SectionObjectPointers;
|
SECTION_OBJECT_POINTERS SectionObjectPointers;
|
||||||
} FSP_FILE_CONTEXT_NONPAGED;
|
} FSP_FILE_NODE_NONPAGED;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FSRTL_ADVANCED_FCB_HEADER Header;
|
FSRTL_ADVANCED_FCB_HEADER Header;
|
||||||
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
FSP_FILE_NODE_NONPAGED *NonPaged;
|
||||||
/* interlocked access */
|
/* interlocked access */
|
||||||
LONG RefCount;
|
LONG RefCount;
|
||||||
/* locked access (ContextTable lock) */
|
/* locked access (ContextTable lock) */
|
||||||
@ -540,55 +540,55 @@ typedef struct
|
|||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
WCHAR FileNameBuf[];
|
WCHAR FileNameBuf[];
|
||||||
} FSP_FILE_CONTEXT;
|
} FSP_FILE_NODE;
|
||||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
||||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext);
|
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
||||||
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
|
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
|
||||||
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
PBOOLEAN PDeletePending);
|
PBOOLEAN PDeletePending);
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext)
|
VOID FspFileNodeRetain(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&FsContext->RefCount);
|
InterlockedIncrement(&FileNode->RefCount);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextRelease(FSP_FILE_CONTEXT *FsContext)
|
VOID FspFileNodeRelease(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
LONG RefCount = InterlockedDecrement(&FsContext->RefCount);
|
LONG RefCount = InterlockedDecrement(&FileNode->RefCount);
|
||||||
if (0 == RefCount)
|
if (0 == RefCount)
|
||||||
FspFileContextDelete(FsContext);
|
FspFileNodeDelete(FileNode);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspFileContextLockShared(FSP_FILE_CONTEXT *FsContext, BOOLEAN Wait)
|
BOOLEAN FspFileNodeLockShared(FSP_FILE_NODE *FileNode, BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
return ExAcquireResourceSharedLite(FsContext->Header.Resource, Wait);
|
return ExAcquireResourceSharedLite(FileNode->Header.Resource, Wait);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspFileContextLockExclusive(FSP_FILE_CONTEXT *FsContext, BOOLEAN Wait)
|
BOOLEAN FspFileNodeLockExclusive(FSP_FILE_NODE *FileNode, BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
return ExAcquireResourceExclusiveLite(FsContext->Header.Resource, Wait);
|
return ExAcquireResourceExclusiveLite(FileNode->Header.Resource, Wait);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextUnlock(FSP_FILE_CONTEXT *FsContext)
|
VOID FspFileNodeUnlock(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
ExReleaseResourceLite(FsContext->Header.Resource);
|
ExReleaseResourceLite(FileNode->Header.Resource);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspFileContextPgioLockShared(FSP_FILE_CONTEXT *FsContext, BOOLEAN Wait)
|
BOOLEAN FspFileNodePgioLockShared(FSP_FILE_NODE *FileNode, BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
return ExAcquireResourceSharedLite(FsContext->Header.PagingIoResource, Wait);
|
return ExAcquireResourceSharedLite(FileNode->Header.PagingIoResource, Wait);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspFileContextPgioLockExclusive(FSP_FILE_CONTEXT *FsContext, BOOLEAN Wait)
|
BOOLEAN FspFileNodePgioLockExclusive(FSP_FILE_NODE *FileNode, BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
return ExAcquireResourceExclusiveLite(FsContext->Header.PagingIoResource, Wait);
|
return ExAcquireResourceExclusiveLite(FileNode->Header.PagingIoResource, Wait);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileContextPgioUnlock(FSP_FILE_CONTEXT *FsContext)
|
VOID FspFileNodePgioUnlock(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
ExReleaseResourceLite(FsContext->Header.PagingIoResource);
|
ExReleaseResourceLite(FileNode->Header.PagingIoResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debug */
|
/* debug */
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sys/filectx.c
|
|
||||||
*
|
|
||||||
* @copyright 2015 Bill Zissimopoulos
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/driver.h>
|
|
||||||
|
|
||||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
|
||||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
|
||||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
|
|
||||||
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
|
||||||
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
|
|
||||||
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
|
||||||
PBOOLEAN PDeletePending);
|
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
|
||||||
#pragma alloc_text(PAGE, FspFileContextCreate)
|
|
||||||
#pragma alloc_text(PAGE, FspFileContextDelete)
|
|
||||||
#pragma alloc_text(PAGE, FspFileContextOpen)
|
|
||||||
#pragma alloc_text(PAGE, FspFileContextClose)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
|
||||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
*PFsContext = 0;
|
|
||||||
|
|
||||||
FSP_FILE_CONTEXT_NONPAGED *NonPaged = FspAllocNonPaged(sizeof *NonPaged);
|
|
||||||
if (0 == NonPaged)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
FSP_FILE_CONTEXT *FsContext = FspAlloc(sizeof *FsContext + ExtraSize);
|
|
||||||
if (0 == FsContext)
|
|
||||||
{
|
|
||||||
FspFree(NonPaged);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlZeroMemory(NonPaged, sizeof *NonPaged);
|
|
||||||
ExInitializeResourceLite(&NonPaged->Resource);
|
|
||||||
ExInitializeResourceLite(&NonPaged->PagingIoResource);
|
|
||||||
ExInitializeFastMutex(&NonPaged->HeaderFastMutex);
|
|
||||||
|
|
||||||
RtlZeroMemory(FsContext, sizeof *FsContext + ExtraSize);
|
|
||||||
FsContext->Header.NodeTypeCode = FspFileContextFileKind;
|
|
||||||
FsContext->Header.NodeByteSize = sizeof *FsContext;
|
|
||||||
FsContext->Header.IsFastIoPossible = FastIoIsQuestionable;
|
|
||||||
FsContext->Header.Resource = &NonPaged->Resource;
|
|
||||||
FsContext->Header.PagingIoResource = &NonPaged->PagingIoResource;
|
|
||||||
FsContext->Header.ValidDataLength.QuadPart = 0x7fffffffffffffffLL;
|
|
||||||
/* disable ValidDataLength functionality */
|
|
||||||
FsRtlSetupAdvancedHeader(&FsContext->Header, &NonPaged->HeaderFastMutex);
|
|
||||||
FsContext->NonPaged = NonPaged;
|
|
||||||
FsContext->RefCount = 1;
|
|
||||||
FsContext->FsvolDeviceObject = DeviceObject;
|
|
||||||
FspDeviceRetain(FsContext->FsvolDeviceObject);
|
|
||||||
RtlInitEmptyUnicodeString(&FsContext->FileName, FsContext->FileNameBuf, (USHORT)ExtraSize);
|
|
||||||
|
|
||||||
*PFsContext = FsContext;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FsRtlTeardownPerStreamContexts(&FsContext->Header);
|
|
||||||
|
|
||||||
FspDeviceRelease(FsContext->FsvolDeviceObject);
|
|
||||||
|
|
||||||
ExDeleteResourceLite(&FsContext->NonPaged->PagingIoResource);
|
|
||||||
ExDeleteResourceLite(&FsContext->NonPaged->Resource);
|
|
||||||
FspFree(FsContext->NonPaged);
|
|
||||||
|
|
||||||
FspFree(FsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
|
||||||
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Attempt to insert our FsContext into the volume device's generic table.
|
|
||||||
* If an FsContext with the same UserContext already exists, then use that
|
|
||||||
* FsContext instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
|
|
||||||
FSP_FILE_CONTEXT *OpenedFsContext;
|
|
||||||
BOOLEAN Inserted;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
OpenedFsContext = FspFsvolDeviceInsertContext(FsvolDeviceObject,
|
|
||||||
FsContext->UserContext, FsContext, &FsContext->ElementStorage, &Inserted);
|
|
||||||
ASSERT(0 != OpenedFsContext);
|
|
||||||
|
|
||||||
if (Inserted)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The new FsContext was inserted into the Context table. Set its share access
|
|
||||||
* and retain and open it. There should be (at least) two references to this
|
|
||||||
* FsContext, one from our caller and one from the Context table.
|
|
||||||
*/
|
|
||||||
ASSERT(OpenedFsContext == FsContext);
|
|
||||||
|
|
||||||
IoSetShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The new FsContext was NOT inserted into the Context table. Instead we are
|
|
||||||
* opening a prior FsContext that we found in the table.
|
|
||||||
*/
|
|
||||||
ASSERT(OpenedFsContext != FsContext);
|
|
||||||
|
|
||||||
if (OpenedFsContext->Flags.DeletePending)
|
|
||||||
{
|
|
||||||
Result = STATUS_DELETE_PENDING;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FastFat says to do the following on Vista and above.
|
|
||||||
*
|
|
||||||
* Quote:
|
|
||||||
* Do an extra test for writeable user sections if the user did not allow
|
|
||||||
* write sharing - this is neccessary since a section may exist with no handles
|
|
||||||
* open to the file its based against.
|
|
||||||
*/
|
|
||||||
if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) &&
|
|
||||||
FlagOn(GrantedAccess,
|
|
||||||
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) &&
|
|
||||||
MmDoesFileHaveUserWritableReferences(&FsContext->NonPaged->SectionObjectPointers))
|
|
||||||
{
|
|
||||||
Result = STATUS_SHARING_VIOLATION;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* share access check */
|
|
||||||
Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (0 != PResult)
|
|
||||||
*PResult = Result;
|
|
||||||
|
|
||||||
OpenedFsContext = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != OpenedFsContext)
|
|
||||||
{
|
|
||||||
FspFileContextRetain(OpenedFsContext);
|
|
||||||
OpenedFsContext->OpenCount++;
|
|
||||||
|
|
||||||
if (DeleteOnClose)
|
|
||||||
OpenedFsContext->Flags.DeleteOnClose = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
return OpenedFsContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
|
||||||
PBOOLEAN PDeletePending)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Close the FsContext. If the OpenCount becomes zero remove it
|
|
||||||
* from the Context table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
|
|
||||||
BOOLEAN Deleted = FALSE, DeletePending;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
if (FsContext->Flags.DeleteOnClose)
|
|
||||||
FsContext->Flags.DeletePending = TRUE;
|
|
||||||
DeletePending = 0 != FsContext->Flags.DeletePending;
|
|
||||||
|
|
||||||
IoRemoveShareAccess(FileObject, &FsContext->ShareAccess);
|
|
||||||
if (0 == --FsContext->OpenCount)
|
|
||||||
FspFsvolDeviceDeleteContext(FsvolDeviceObject, FsContext->UserContext, &Deleted);
|
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
if (Deleted)
|
|
||||||
FspFileContextRelease(FsContext);
|
|
||||||
|
|
||||||
if (0 != PDeletePending)
|
|
||||||
*PDeletePending = Deleted && DeletePending;
|
|
||||||
}
|
|
205
src/sys/node.c
Normal file
205
src/sys/node.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/**
|
||||||
|
* @file sys/node.c
|
||||||
|
*
|
||||||
|
* @copyright 2015 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
||||||
|
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
||||||
|
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
|
||||||
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
PBOOLEAN PDeletePending);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeCreate)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeDelete)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeOpen)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeClose)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
*PFileNode = 0;
|
||||||
|
|
||||||
|
FSP_FILE_NODE_NONPAGED *NonPaged = FspAllocNonPaged(sizeof *NonPaged);
|
||||||
|
if (0 == NonPaged)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
FSP_FILE_NODE *FileNode = FspAlloc(sizeof *FileNode + ExtraSize);
|
||||||
|
if (0 == FileNode)
|
||||||
|
{
|
||||||
|
FspFree(NonPaged);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(NonPaged, sizeof *NonPaged);
|
||||||
|
ExInitializeResourceLite(&NonPaged->Resource);
|
||||||
|
ExInitializeResourceLite(&NonPaged->PagingIoResource);
|
||||||
|
ExInitializeFastMutex(&NonPaged->HeaderFastMutex);
|
||||||
|
|
||||||
|
RtlZeroMemory(FileNode, sizeof *FileNode + ExtraSize);
|
||||||
|
FileNode->Header.NodeTypeCode = FspFileNodeFileKind;
|
||||||
|
FileNode->Header.NodeByteSize = sizeof *FileNode;
|
||||||
|
FileNode->Header.IsFastIoPossible = FastIoIsQuestionable;
|
||||||
|
FileNode->Header.Resource = &NonPaged->Resource;
|
||||||
|
FileNode->Header.PagingIoResource = &NonPaged->PagingIoResource;
|
||||||
|
FileNode->Header.ValidDataLength.QuadPart = 0x7fffffffffffffffLL;
|
||||||
|
/* disable ValidDataLength functionality */
|
||||||
|
FsRtlSetupAdvancedHeader(&FileNode->Header, &NonPaged->HeaderFastMutex);
|
||||||
|
FileNode->NonPaged = NonPaged;
|
||||||
|
FileNode->RefCount = 1;
|
||||||
|
FileNode->FsvolDeviceObject = DeviceObject;
|
||||||
|
FspDeviceRetain(FileNode->FsvolDeviceObject);
|
||||||
|
RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize);
|
||||||
|
|
||||||
|
*PFileNode = FileNode;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FsRtlTeardownPerStreamContexts(&FileNode->Header);
|
||||||
|
|
||||||
|
FspDeviceRelease(FileNode->FsvolDeviceObject);
|
||||||
|
|
||||||
|
ExDeleteResourceLite(&FileNode->NonPaged->PagingIoResource);
|
||||||
|
ExDeleteResourceLite(&FileNode->NonPaged->Resource);
|
||||||
|
FspFree(FileNode->NonPaged);
|
||||||
|
|
||||||
|
FspFree(FileNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Attempt to insert our FileNode into the volume device's generic table.
|
||||||
|
* If an FileNode with the same UserContext already exists, then use that
|
||||||
|
* FileNode instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
|
FSP_FILE_NODE *OpenedFileNode;
|
||||||
|
BOOLEAN Inserted;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
OpenedFileNode = FspFsvolDeviceInsertContext(FsvolDeviceObject,
|
||||||
|
FileNode->UserContext, FileNode, &FileNode->ElementStorage, &Inserted);
|
||||||
|
ASSERT(0 != OpenedFileNode);
|
||||||
|
|
||||||
|
if (Inserted)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The new FileNode was inserted into the Context table. Set its share access
|
||||||
|
* and retain and open it. There should be (at least) two references to this
|
||||||
|
* FileNode, one from our caller and one from the Context table.
|
||||||
|
*/
|
||||||
|
ASSERT(OpenedFileNode == FileNode);
|
||||||
|
|
||||||
|
IoSetShareAccess(GrantedAccess, ShareAccess, FileObject,
|
||||||
|
&OpenedFileNode->ShareAccess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The new FileNode was NOT inserted into the Context table. Instead we are
|
||||||
|
* opening a prior FileNode that we found in the table.
|
||||||
|
*/
|
||||||
|
ASSERT(OpenedFileNode != FileNode);
|
||||||
|
|
||||||
|
if (OpenedFileNode->Flags.DeletePending)
|
||||||
|
{
|
||||||
|
Result = STATUS_DELETE_PENDING;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FastFat says to do the following on Vista and above.
|
||||||
|
*
|
||||||
|
* Quote:
|
||||||
|
* Do an extra test for writeable user sections if the user did not allow
|
||||||
|
* write sharing - this is neccessary since a section may exist with no handles
|
||||||
|
* open to the file its based against.
|
||||||
|
*/
|
||||||
|
if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) &&
|
||||||
|
FlagOn(GrantedAccess,
|
||||||
|
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) &&
|
||||||
|
MmDoesFileHaveUserWritableReferences(&OpenedFileNode->NonPaged->SectionObjectPointers))
|
||||||
|
{
|
||||||
|
Result = STATUS_SHARING_VIOLATION;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* share access check */
|
||||||
|
Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject,
|
||||||
|
&OpenedFileNode->ShareAccess, TRUE);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 != PResult)
|
||||||
|
*PResult = Result;
|
||||||
|
|
||||||
|
OpenedFileNode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != OpenedFileNode)
|
||||||
|
{
|
||||||
|
FspFileNodeRetain(OpenedFileNode);
|
||||||
|
OpenedFileNode->OpenCount++;
|
||||||
|
|
||||||
|
if (DeleteOnClose)
|
||||||
|
OpenedFileNode->Flags.DeleteOnClose = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
return OpenedFileNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
PBOOLEAN PDeletePending)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Close the FileNode. If the OpenCount becomes zero remove it
|
||||||
|
* from the Context table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
|
BOOLEAN Deleted = FALSE, DeletePending;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (FileNode->Flags.DeleteOnClose)
|
||||||
|
FileNode->Flags.DeletePending = TRUE;
|
||||||
|
DeletePending = 0 != FileNode->Flags.DeletePending;
|
||||||
|
|
||||||
|
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
|
||||||
|
if (0 == --FileNode->OpenCount)
|
||||||
|
FspFsvolDeviceDeleteContext(FsvolDeviceObject, FileNode->UserContext, &Deleted);
|
||||||
|
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (Deleted)
|
||||||
|
FspFileNodeRelease(FileNode);
|
||||||
|
|
||||||
|
if (0 != PDeletePending)
|
||||||
|
*PDeletePending = Deleted && DeletePending;
|
||||||
|
}
|
Reference in New Issue
Block a user