sys: FileRenameResource implementation

This commit is contained in:
Bill Zissimopoulos 2016-02-07 11:01:15 -08:00
parent 3ef9042071
commit 9c200f2a62
5 changed files with 135 additions and 30 deletions

View File

@ -12,6 +12,8 @@ static NTSTATUS FspFsvrtCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolCreate( static NTSTATUS FspFsvolCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
@ -27,6 +29,7 @@ FSP_DRIVER_DISPATCH FspCreate;
#pragma alloc_text(PAGE, FspFsctlCreate) #pragma alloc_text(PAGE, FspFsctlCreate)
#pragma alloc_text(PAGE, FspFsvrtCreate) #pragma alloc_text(PAGE, FspFsvrtCreate)
#pragma alloc_text(PAGE, FspFsvolCreate) #pragma alloc_text(PAGE, FspFsvolCreate)
#pragma alloc_text(PAGE, FspFsvolCreateNoLock)
#pragma alloc_text(PAGE, FspFsvolCreatePrepare) #pragma alloc_text(PAGE, FspFsvolCreatePrepare)
#pragma alloc_text(PAGE, FspFsvolCreateComplete) #pragma alloc_text(PAGE, FspFsvolCreateComplete)
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen) #pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
@ -43,14 +46,16 @@ FSP_DRIVER_DISPATCH FspCreate;
enum enum
{ {
/* Create */ /* Create */
RequestFileDesc = 0, RequestDeviceObject = 0,
RequestAccessToken = 1, RequestFileDesc = 1,
RequestProcess = 2, RequestAccessToken = 2,
RequestProcess = 3,
/* TryOpen/Overwrite */ /* TryOpen/Overwrite */
//RequestFileDesc = 0, //RequestDeviceObject = 0,
RequestFileObject = 1, //RequestFileDesc = 1,
RequestState = 2, RequestFileObject = 2,
RequestState = 3,
/* RequestState */ /* RequestState */
RequestPending = 0, RequestPending = 0,
@ -92,6 +97,27 @@ static NTSTATUS FspFsvolCreate(
{ {
PAGED_CODE(); PAGED_CODE();
NTSTATUS Result = STATUS_SUCCESS;
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
try
{
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp);
}
finally
{
if (FSP_STATUS_IOQ_POST != Result)
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
}
return Result;
}
static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
NTSTATUS Result; NTSTATUS Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
@ -180,6 +206,11 @@ static NTSTATUS FspFsvolCreate(
{ {
RelatedFileNode = RelatedFileObject->FsContext; RelatedFileNode = RelatedFileObject->FsContext;
/*
* Accesses of RelatedFileNode->FileName are protected
* by FSP_FSVOL_DEVICE_EXTENSION::FileRenameResource.
*/
/* is this a valid RelatedFileObject? */ /* is this a valid RelatedFileObject? */
if (!FspFileNodeIsValid(RelatedFileNode)) if (!FspFileNodeIsValid(RelatedFileNode))
return STATUS_OBJECT_PATH_NOT_FOUND; return STATUS_OBJECT_PATH_NOT_FOUND;
@ -202,12 +233,6 @@ static NTSTATUS FspFsvolCreate(
sizeof(WCHAR) == RelatedFileNode->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->FileNode->FileName,
* because RelatedFileObject->FileNode->Filename is read-only (after creation) and
* because RelatedFileObject->FileNode is guaranteed to exist while RelatedFileObject
* exists.
*/
BOOLEAN AppendBackslash = BOOLEAN AppendBackslash =
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFileNode->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];
@ -320,6 +345,8 @@ static NTSTATUS FspFsvolCreate(
* delete the Request and any associated resources. * delete the Request and any associated resources.
*/ */
FileDesc->FileNode = FileNode; FileDesc->FileNode = FileNode;
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
/* populate the Create request */ /* populate the Create request */
@ -589,25 +616,20 @@ NTSTATUS FspFsvolCreateComplete(
if (FileNode->IsDirectory) if (FileNode->IsDirectory)
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY); SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
/* delete the old request */ /* disassociate the FileDesc momentarily from the Request */
FspIrpRequest(Irp) = 0; FspIopRequestContext(Request, RequestDeviceObject) = 0;
FspIopRequestContext(Request, RequestFileDesc) = 0; FspIopRequestContext(Request, RequestFileDesc) = 0;
/* disassociate the FileDesc from the old Request as we want to keep it around! */
FspIopDeleteRequest(Request);
/* create the Overwrite request; MustSucceed because we must either overwrite or close */ /* reset the request */
FspIopCreateRequestFunnel(Irp, Request->Kind = FspFsctlTransactOverwriteKind;
FsvolDeviceExtension->VolumeParams.FileNameRequired ? &FileNode->FileName : 0, 0, RtlZeroMemory(&Request->Req.Create, sizeof Request->Req.Create);
FspFsvolCreateOverwriteRequestFini, TRUE, FspIopResetRequest(Request, FspFsvolCreateOverwriteRequestFini);
&Request); FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
/* associate the FileDesc and FileObject with the Overwrite request */
FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject; FspIopRequestContext(Request, RequestFileObject) = FileObject;
FspIopRequestContext(Request, RequestState) = (PVOID)RequestPending; FspIopRequestContext(Request, RequestState) = (PVOID)RequestPending;
/* populate the Overwrite request */ /* populate the Overwrite request */
Request->Kind = FspFsctlTransactOverwriteKind;
Request->Req.Overwrite.UserContext = FileNode->UserContext; Request->Req.Overwrite.UserContext = FileNode->UserContext;
Request->Req.Overwrite.UserContext2 = FileDesc->UserContext2; Request->Req.Overwrite.UserContext2 = FileDesc->UserContext2;
Request->Req.Overwrite.FileAttributes = FileAttributes; Request->Req.Overwrite.FileAttributes = FileAttributes;
@ -681,13 +703,17 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
if (FspFsctlTransactCreateKind == Request->Kind) if (FspFsctlTransactCreateKind == Request->Kind)
{ {
PDEVICE_OBJECT FsvolDeviceObject = FspIopRequestContext(Request, RequestDeviceObject);
/* disassociate the FileDesc momentarily from the Request */ /* disassociate the FileDesc momentarily from the Request */
Request = FspIrpRequest(Irp); Request = FspIrpRequest(Irp);
FspIopRequestContext(Request, RequestDeviceObject) = 0;
FspIopRequestContext(Request, RequestFileDesc) = 0; FspIopRequestContext(Request, RequestFileDesc) = 0;
/* reset the Request and reassociate the FileDesc and FileObject with it */ /* reset the Request and reassociate the FileDesc and FileObject with it */
Request->Kind = FspFsctlTransactReservedKind; Request->Kind = FspFsctlTransactReservedKind;
FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini); FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini);
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject; FspIopRequestContext(Request, RequestFileObject) = FileObject;
FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage; FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage;
@ -761,10 +787,11 @@ static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc)
*/ */
} }
static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]) static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{ {
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc]; FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
HANDLE AccessToken = Context[RequestAccessToken]; HANDLE AccessToken = Context[RequestAccessToken];
PEPROCESS Process = Context[RequestProcess]; PEPROCESS Process = Context[RequestProcess];
@ -798,12 +825,16 @@ static VOID FspFsvolCreateRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Con
ObDereferenceObject(Process); ObDereferenceObject(Process);
} }
if (0 != FsvolDeviceObject)
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
} }
static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]) static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{ {
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc]; FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
PFILE_OBJECT FileObject = Context[RequestFileObject]; PFILE_OBJECT FileObject = Context[RequestFileObject];
@ -816,12 +847,16 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV
FspFileNodeDereference(FileDesc->FileNode); FspFileNodeDereference(FileDesc->FileNode);
FspFileDescDelete(FileDesc); FspFileDescDelete(FileDesc);
} }
if (0 != FsvolDeviceObject)
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
} }
static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]) static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{ {
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
FSP_FILE_DESC *FileDesc = Context[RequestFileDesc]; FSP_FILE_DESC *FileDesc = Context[RequestFileDesc];
PFILE_OBJECT FileObject = Context[RequestFileObject]; PFILE_OBJECT FileObject = Context[RequestFileObject];
ULONG State = (ULONG)(UINT_PTR)Context[RequestState]; ULONG State = (ULONG)(UINT_PTR)Context[RequestState];
@ -839,6 +874,9 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request,
FspFileNodeDereference(FileDesc->FileNode); FspFileNodeDereference(FileDesc->FileNode);
FspFileDescDelete(FileDesc); FspFileDescDelete(FileDesc);
} }
if (0 != FsvolDeviceObject)
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
} }
NTSTATUS FspCreate( NTSTATUS FspCreate(

View File

@ -25,6 +25,11 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject);
static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject); static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject);
static IO_TIMER_ROUTINE FspFsvolDeviceTimerRoutine; static IO_TIMER_ROUTINE FspFsvolDeviceTimerRoutine;
static WORKER_THREAD_ROUTINE FspFsvolDeviceExpirationRoutine; static WORKER_THREAD_ROUTINE FspFsvolDeviceExpirationRoutine;
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier); PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
@ -60,6 +65,11 @@ VOID FspDeviceDeleteAll(VOID);
#pragma alloc_text(PAGE, FspDeviceDelete) #pragma alloc_text(PAGE, FspDeviceDelete)
#pragma alloc_text(PAGE, FspFsvolDeviceInit) #pragma alloc_text(PAGE, FspFsvolDeviceInit)
#pragma alloc_text(PAGE, FspFsvolDeviceFini) #pragma alloc_text(PAGE, FspFsvolDeviceFini)
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameAcquireShared)
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameAcquireExclusive)
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameSetOwner)
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameRelease)
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameReleaseOwner)
#pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable) #pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable)
#pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable) #pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable)
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContext) #pragma alloc_text(PAGE, FspFsvolDeviceLookupContext)
@ -437,6 +447,58 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
FspDeviceDereference(DeviceObject); FspDeviceDereference(DeviceObject);
} }
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
ExAcquireResourceSharedLite(&FsvolDeviceExtension->FileRenameResource, TRUE);
}
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->FileRenameResource, TRUE);
}
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
Owner = (PVOID)((UINT_PTR)Owner | 3);
ExSetResourceOwnerPointer(&FsvolDeviceExtension->FileRenameResource, Owner);
}
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
ExReleaseResourceLite(&FsvolDeviceExtension->FileRenameResource);
}
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
Owner = (PVOID)((UINT_PTR)Owner | 3);
if (ExIsResourceAcquiredLite(&FsvolDeviceExtension->FileRenameResource))
ExReleaseResourceLite(&FsvolDeviceExtension->FileRenameResource);
else
ExReleaseResourceForThreadLite(&FsvolDeviceExtension->FileRenameResource, (ERESOURCE_THREAD)Owner);
}
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject) VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject)
{ {
PAGED_CODE(); PAGED_CODE();

View File

@ -419,7 +419,7 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp);
#define FspIopPostWorkRequestBestEffort(D, R)\ #define FspIopPostWorkRequestBestEffort(D, R)\
FspIopPostWorkRequestFunnel(D, R, TRUE) FspIopPostWorkRequestFunnel(D, R, TRUE)
#define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE) #define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE)
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]); typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]);
NTSTATUS FspIopCreateRequestFunnel( NTSTATUS FspIopCreateRequestFunnel(
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini,
BOOLEAN MustSucceed, BOOLEAN MustSucceed,
@ -522,6 +522,11 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject); VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject); BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject); VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameAcquireShared(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameAcquireExclusive(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject); VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier); PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);

View File

@ -851,7 +851,7 @@ NTSTATUS FspFsvolSetInformationComplete(
IrpSp->FileObject); IrpSp->FileObject);
} }
static VOID FspFsvolInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]) static VOID FspFsvolInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{ {
PAGED_CODE(); PAGED_CODE();

View File

@ -84,7 +84,7 @@ static PVOID FspAllocateIrpMustSucceed(CCHAR StackSize)
typedef struct typedef struct
{ {
FSP_IOP_REQUEST_FINI *RequestFini; FSP_IOP_REQUEST_FINI *RequestFini;
PVOID Context[3]; PVOID Context[4];
FSP_FSCTL_TRANSACT_RSP *Response; FSP_FSCTL_TRANSACT_RSP *Response;
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[]; __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[];
} FSP_FSCTL_TRANSACT_REQ_HEADER; } FSP_FSCTL_TRANSACT_REQ_HEADER;