sys: rename FsContext to FileNode

This commit is contained in:
Bill Zissimopoulos
2016-01-18 12:25:56 -08:00
parent 1dede99423
commit b17d70e462
8 changed files with 329 additions and 327 deletions

View File

@ -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" />

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }
} }

View File

@ -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 */

View File

@ -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
View 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;
}