sys: improve support for FileStatLxInformation

This commit is contained in:
Bill Zissimopoulos 2019-04-18 15:57:22 -07:00
parent a08fdccb17
commit 969651f5f6
4 changed files with 149 additions and 28 deletions

View File

@ -252,6 +252,8 @@ const char *FileInformationClassSym(FILE_INFORMATION_CLASS FileInformationClass)
SYM(FileReplaceCompletionInformation) SYM(FileReplaceCompletionInformation)
SYM(FileHardLinkFullIdInformation) SYM(FileHardLinkFullIdInformation)
SYM(FileIdExtdBothDirectoryInformation) SYM(FileIdExtdBothDirectoryInformation)
case 68: return "FileStatInformation";
case 70: return "FileStatLxInformation";
default: default:
return "FILE_INFORMATION_CLASS:Unknown"; return "FILE_INFORMATION_CLASS:Unknown";
} }

View File

@ -494,6 +494,10 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength);
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength, PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength); PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);

View File

@ -45,13 +45,13 @@ static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject,
static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo); const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStatBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo); const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatLxInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStatLxBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo); const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatLxInformationEa( static NTSTATUS FspFsvolQueryStatLxEaInformation(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject, PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd); PVOID *PBuffer, PVOID BufferEnd);
static NTSTATUS FspFsvolQueryStreamInformationCopy( static NTSTATUS FspFsvolQueryStreamInformationCopy(
@ -61,6 +61,9 @@ static NTSTATUS FspFsvolQueryStreamInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolQueryStreamInformationSuccess( static NTSTATUS FspFsvolQueryStreamInformationSuccess(
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
static NTSTATUS FspFsvolQueryInformationEffectiveAccess(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PACCESS_MASK PEffectiveAccess);
static NTSTATUS FspFsvolQueryInformation( static NTSTATUS FspFsvolQueryInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete;
@ -106,12 +109,13 @@ FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
#pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation) #pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation)
#pragma alloc_text(PAGE, FspFsvolQueryPositionInformation) #pragma alloc_text(PAGE, FspFsvolQueryPositionInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStandardInformation) #pragma alloc_text(PAGE, FspFsvolQueryStandardInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatInformation) #pragma alloc_text(PAGE, FspFsvolQueryStatBaseInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatLxInformation) #pragma alloc_text(PAGE, FspFsvolQueryStatLxBaseInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatLxInformationEa) #pragma alloc_text(PAGE, FspFsvolQueryStatLxEaInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationCopy) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformationCopy)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformation) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationSuccess) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformationSuccess)
#pragma alloc_text(PAGE, FspFsvolQueryInformationEffectiveAccess)
#pragma alloc_text(PAGE, FspFsvolQueryInformation) #pragma alloc_text(PAGE, FspFsvolQueryInformation)
#pragma alloc_text(PAGE, FspFsvolQueryInformationComplete) #pragma alloc_text(PAGE, FspFsvolQueryInformationComplete)
#pragma alloc_text(PAGE, FspFsvolQueryInformationRequestFini) #pragma alloc_text(PAGE, FspFsvolQueryInformationRequestFini)
@ -429,7 +433,7 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolQueryStatInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStatBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo) const FSP_FSCTL_FILE_INFO *FileInfo)
{ {
@ -460,14 +464,13 @@ static NTSTATUS FspFsvolQueryStatInformation(PFILE_OBJECT FileObject,
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL; FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
Info->ReparseTag = FileInfo->ReparseTag; Info->ReparseTag = FileInfo->ReparseTag;
Info->NumberOfLinks = 1; Info->NumberOfLinks = 1;
Info->EffectiveAccess = FileDesc->GrantedAccess;
*PBuffer = (PVOID)(Info + 1); *PBuffer = (PVOID)(Info + 1);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolQueryStatLxInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStatLxBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo) const FSP_FSCTL_FILE_INFO *FileInfo)
{ {
@ -498,14 +501,13 @@ static NTSTATUS FspFsvolQueryStatLxInformation(PFILE_OBJECT FileObject,
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL; FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
Info->ReparseTag = FileInfo->ReparseTag; Info->ReparseTag = FileInfo->ReparseTag;
Info->NumberOfLinks = 1; Info->NumberOfLinks = 1;
Info->EffectiveAccess = FileDesc->GrantedAccess;
*PBuffer = (PVOID)(Info + 1); *PBuffer = (PVOID)(Info + 1);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolQueryStatLxInformationEa( static NTSTATUS FspFsvolQueryStatLxEaInformation(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject, PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd) PVOID *PBuffer, PVOID BufferEnd)
{ {
@ -532,14 +534,14 @@ static NTSTATUS FspFsvolQueryStatLxInformationEa(
union union
{ {
FILE_GET_EA_INFORMATION V; FILE_GET_EA_INFORMATION V;
UINT8 B[256]; UINT8 B[64];
} GetEaBuf; } GetEaBuf;
PFILE_GET_EA_INFORMATION GetEa = &GetEaBuf.V; PFILE_GET_EA_INFORMATION GetEa = &GetEaBuf.V;
ULONG GetEaLength = 0; ULONG GetEaLength = 0;
union union
{ {
FILE_FULL_EA_INFORMATION V; FILE_FULL_EA_INFORMATION V;
UINT8 B[256]; UINT8 B[128];
} EaBuf; } EaBuf;
ULONG EaLength = sizeof EaBuf; ULONG EaLength = sizeof EaBuf;
STRING EaName, CmpName; STRING EaName, CmpName;
@ -847,6 +849,69 @@ static NTSTATUS FspFsvolQueryStreamInformationSuccess(
return Result; return Result;
} }
static NTSTATUS FspFsvolQueryInformationEffectiveAccess(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PACCESS_MASK PEffectiveAccess)
{
union
{
SECURITY_DESCRIPTOR V;
UINT8 B[256];
} SecurityDescriptorBuf;
PSECURITY_DESCRIPTOR SecurityDescriptor = &SecurityDescriptorBuf.V;
ULONG Length;
SECURITY_SUBJECT_CONTEXT SecuritySubjectContext;
ACCESS_MASK EffectiveAccess;
NTSTATUS Result;
BOOLEAN AccessResult;
*PEffectiveAccess = 0;
Length = sizeof SecurityDescriptorBuf;
Result = FspSendQuerySecurityIrp(FsvolDeviceObject/* bypass filters */, FileObject,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
SecurityDescriptor, &Length);
if (STATUS_BUFFER_OVERFLOW == Result)
{
SecurityDescriptor = FspAlloc(Length);
if (0 == SecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
Result = FspSendQuerySecurityIrp(FsvolDeviceObject/* bypass filters */, FileObject,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
SecurityDescriptor, &Length);
}
if (!NT_SUCCESS(Result))
goto exit;
SeCaptureSubjectContext(&SecuritySubjectContext);
AccessResult = SeAccessCheck(
SecurityDescriptor,
&SecuritySubjectContext,
FALSE,
MAXIMUM_ALLOWED,
0,
0,
IoGetFileObjectGenericMapping(),
UserMode,
&EffectiveAccess,
&Result);
if (!AccessResult)
goto exit;
*PEffectiveAccess = EffectiveAccess;
exit:
if (&SecurityDescriptorBuf.V != SecurityDescriptor && 0 != SecurityDescriptor)
FspFree(SecurityDescriptor);
return Result;
}
static NTSTATUS FspFsvolQueryInformation( static NTSTATUS FspFsvolQueryInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -922,10 +987,10 @@ static NTSTATUS FspFsvolQueryInformation(
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0);
break; break;
case 68/*FileStatInformation*/: case 68/*FileStatInformation*/:
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, 0); Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, 0);
break; break;
case 70/*FileStatLxInformation*/: case 70/*FileStatLxInformation*/:
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, 0); Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, 0);
break; break;
default: default:
Result = STATUS_INVALID_PARAMETER; Result = STATUS_INVALID_PARAMETER;
@ -937,15 +1002,23 @@ static NTSTATUS FspFsvolQueryInformation(
FspFileNodeAcquireShared(FileNode, Main); FspFileNodeAcquireShared(FileNode, Main);
if (70/*FileStatLxInformation*/ == FileInformationClass) switch (FileInformationClass)
{ {
Result = FspFsvolQueryStatLxInformationEa( case 68/*FileStatInformation*/:
FspFsvolQueryInformationEffectiveAccess(
FsvolDeviceObject, FileObject, &((FSP_FILE_STAT_INFORMATION *)Buffer)->EffectiveAccess);
break;
case 70/*FileStatLxInformation*/:
FspFsvolQueryInformationEffectiveAccess(
FsvolDeviceObject, FileObject, &((FSP_FILE_STAT_LX_INFORMATION *)Buffer)->EffectiveAccess);
Result = FspFsvolQueryStatLxEaInformation(
FsvolDeviceObject, FileObject, &Buffer, BufferEnd); FsvolDeviceObject, FileObject, &Buffer, BufferEnd);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
return Result; return Result;
} }
break;
} }
if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf))
@ -975,10 +1048,10 @@ static NTSTATUS FspFsvolQueryInformation(
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
case 68/*FileStatInformation*/: case 68/*FileStatInformation*/:
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
case 70/*FileStatLxInformation*/: case 70/*FileStatLxInformation*/:
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
default: default:
ASSERT(0); ASSERT(0);
@ -1091,10 +1164,10 @@ NTSTATUS FspFsvolQueryInformationComplete(
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
case 68/*FileStatInformation*/: case 68/*FileStatInformation*/:
Result = FspFsvolQueryStatInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
case 70/*FileStatLxInformation*/: case 70/*FileStatLxInformation*/:
Result = FspFsvolQueryStatLxInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
default: default:
ASSERT(0); ASSERT(0);

View File

@ -26,6 +26,10 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength);
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength, PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength); PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
@ -127,6 +131,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspCreateGuid)
#pragma alloc_text(PAGE, FspGetDeviceObjectPointer) #pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
#pragma alloc_text(PAGE, FspSendSetInformationIrp) #pragma alloc_text(PAGE, FspSendSetInformationIrp)
#pragma alloc_text(PAGE, FspSendQuerySecurityIrp)
#pragma alloc_text(PAGE, FspSendQueryEaIrp) #pragma alloc_text(PAGE, FspSendQueryEaIrp)
#pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspBufferUserBuffer)
#pragma alloc_text(PAGE, FspLockUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer)
@ -317,7 +322,49 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
if (STATUS_PENDING == Result) if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0); KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
return NT_SUCCESS(Result) ? Context.IoStatus.Status : Result; return Context.IoStatus.Status;
}
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength)
{
PAGED_CODE();
NTSTATUS Result;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
FSP_SEND_IRP_CONTEXT Context;
ULONG Length = *PLength;
*PLength = 0;
if (0 == DeviceObject)
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (0 == Irp)
return STATUS_INSUFFICIENT_RESOURCES;
IrpSp = IoGetNextIrpStackLocation(Irp);
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = SecurityDescriptor;
Irp->UserBuffer = SecurityDescriptor;
IrpSp->MajorFunction = IRP_MJ_QUERY_SECURITY;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
IrpSp->Parameters.QuerySecurity.Length = Length;
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
Result = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
*PLength = (ULONG)Context.IoStatus.Information;
return Context.IoStatus.Status;
} }
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
@ -358,12 +405,7 @@ NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
if (STATUS_PENDING == Result) if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0); KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
if (!NT_SUCCESS(Result)) *PEaLength = (ULONG)Context.IoStatus.Information;
return Result;
if (NT_SUCCESS(Context.IoStatus.Status))
*PEaLength = (ULONG)Context.IoStatus.Information;
return Context.IoStatus.Status; return Context.IoStatus.Status;
} }