[NTOSKRNL:CC] Pin Support Protocols :: added functions
Completed Implementation for:: *CcPreparePinWrite *CcMapData *CcAllocateObcb Reconstructed/Guessed OBCB Structure
This commit is contained in:
parent
dac01f6510
commit
a40c3d4200
@ -14,8 +14,52 @@
|
||||
|
||||
extern "C"
|
||||
|
||||
/* Move Typedef later to cctypes in sdk */
|
||||
/* NOTE: This structure have reconstructed analyzing CcAllocateObcb, might be icomplete to one in Windows NT Kernel*/
|
||||
/* We just need API Compatibility, so it doesn't matter */
|
||||
typedef struct _OBCB
|
||||
{
|
||||
short NodeTypeCode;
|
||||
short NodeByteSize;
|
||||
ULONG ByteLength;
|
||||
LARGE_INTEGER FileOffset;
|
||||
struct PCC_BCB Bcbs[1];
|
||||
long __PADDING__[1];
|
||||
} OBCB, *POBCB;
|
||||
|
||||
/*Internal Function*/
|
||||
POBCB
|
||||
NTAPI
|
||||
CcAllocateObcb(
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_In_ ULONG Length,
|
||||
_In_ PCC_BCB Bcb)
|
||||
{
|
||||
|
||||
|
||||
/*Calculate the size needed for the OBCB*/
|
||||
SIZE_T AllocationSize = sizeof(OBCB) + ((Length + PAGE_SIZE - 1 + FileOffset->LowPart - *reinterpret_cast<ULONG*>(reinterpret_cast<ULONG_PTR>(FirstBcb) & ~1UL) - *reinterpret_cast<ULONG*>((reinterpret_cast<ULONG_PTR>(FirstBcb) & ~1UL) + sizeof(ULONG))) >> PAGE_SHIFT) * sizeof(PVOID);
|
||||
|
||||
/*Allocate memory for the OBCB*/
|
||||
POBCB NewObcb = reinterpret_cast<POBCB>(ExAllocatePoolWithTag(NonPagedPool,AllocationSize,'cObC'));
|
||||
|
||||
if (NewObcb == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Initialize the OBCB */
|
||||
RtlZeroMemory(NewObcb, AllocationSize);
|
||||
|
||||
NewObcb->NodeByteSize = static_cast<USHORT>(AllocationSize);
|
||||
NewObcb->NodeTypeCode = 762;
|
||||
NewObcb->ByteLength = Length;
|
||||
NewObcb->FileOffset = *FileOffset;
|
||||
NewObcb->Bcbs[0] = Bcb;
|
||||
|
||||
return NewObcb;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
@ -183,48 +227,44 @@ CcUnpinFileDataEx(
|
||||
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
VECTORCALL
|
||||
CcPinFileData(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN IsReadOnly,
|
||||
IN BOOLEAN IsWriteOnly,
|
||||
IN ULONG Flags,
|
||||
OUT PCC_BCB *Bcb,
|
||||
OUT PVOID *BaseAddress,
|
||||
OUT PLARGE_INTEGER BeyondLastByte)
|
||||
{
|
||||
// Unimplemented
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcMapData(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID *Bcb,
|
||||
OUT PVOID *Buffer)
|
||||
_In_ In PFILE_OBJECT FileObject,
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_In_ ULONG Length,
|
||||
_In_ ULONG Flags,
|
||||
_Out_ PVOID *Bcb,
|
||||
_Out_ PVOID *Buffer)
|
||||
{
|
||||
//Unimplemented
|
||||
PVOID LocalBuffer = nullptr;
|
||||
/* Call CcMapDataCommon to perform the actual mapping */
|
||||
if (!CcMapDataCommon(FileObject,FileOffset,Length,Flags,Bcb,&LocalBuffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/* Check if we need to read the data */
|
||||
if (!(Flags & MAP_NO_READ))
|
||||
{
|
||||
/* Read the data */
|
||||
if (!CcMapAndRead(Length, 0, true, LocalBuffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* Set Bcb to point after the LocalBuffer */
|
||||
*Bcb = reinterpret_cast<PVOID>(reinterpret_cast<ULONG_PTR>(LocalBuffer) + sizeof(PVOID));
|
||||
/* Set the output Buffer */
|
||||
*Buffer = LocalBuffer;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
CcMapDataCommon(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID *Bcb,
|
||||
OUT PVOID *Buffer)
|
||||
{
|
||||
//Unimplemented
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
@ -254,15 +294,74 @@ CcPinRead(
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcPreparePinWrite(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Zero,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID *Bcb,
|
||||
OUT PVOID *Buffer)
|
||||
_In_ PFILE_OBJECT FileObject,
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_In_ ULONG Length,
|
||||
_In_ BOOLEAN Zero,
|
||||
_In_ ULONG Flags,
|
||||
_Out_ PVOID *Bcb,
|
||||
_Out_ PVOID *Buffer)
|
||||
{
|
||||
//Unimplemented
|
||||
LARGE_INTEGER LocalFileOffset = *FileOffset;
|
||||
LARGE_INTEGER BeyondLastByte ={0};
|
||||
ULONG RemainingLength = Length;
|
||||
POBCB localbcb = nullptr;
|
||||
PCC_BCB *localbcbPtr = nullptr;
|
||||
PVOID LocalBuffer = nullptr;
|
||||
BOOLEAN Result = false;
|
||||
|
||||
|
||||
|
||||
|
||||
if (Flags & PIN_WAIT)
|
||||
{
|
||||
return CcMapDataForOverwrite(FileObject, FileOffset, Length, Bcb, Buffer);
|
||||
}
|
||||
|
||||
/*Pinning Loop*/
|
||||
while(true)
|
||||
{
|
||||
if (localbcb)
|
||||
{
|
||||
if (localbcbPtr == reinterpret_cast<PCC_BCB>(&localbcb))
|
||||
{
|
||||
localbcb = CcAllocateObcb(&LocalFileOffset, RemainingLength, localbcb);
|
||||
localbcbPtr = localbcb->Bcbs;
|
||||
*Buffer = LocalBuffer;
|
||||
}
|
||||
RemainingLength += LocalFileOffset.QuadPart - BeyondLastByte.QuadPart;
|
||||
LocalFileOffset.QuadPart = BeyondLastByte.QuadPart;
|
||||
localbcbPtr++;
|
||||
}
|
||||
|
||||
if (!CcPinFileData(FileObject, &LocalFileOffset,RemainingLength,false,false,Flags,localbcbPtr,&LocalBuffer, &BeyondLastByte))
|
||||
{
|
||||
/* Pinning failed */
|
||||
if (localbcb)
|
||||
{
|
||||
CcUnpinData(localbcb);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(BeyondLastByte.QuadPart < LocalFileOffset.QuadPart + RemainingLength)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (localbcbPtr == reinterpret_cast<PCC_BCB*>(&localbcb))
|
||||
{
|
||||
*Buffer = LocalBuffer;
|
||||
}
|
||||
|
||||
if (Zero)
|
||||
{
|
||||
RtlZeroMemory(*Buffer, Length);
|
||||
}
|
||||
|
||||
CcSetDirtyPinnedData(localbcb, nullptr);
|
||||
*Bcb = localbcb;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
VOID
|
||||
@ -295,7 +394,7 @@ CcUnpinData(
|
||||
PCC_BCB Bcb = reinterpret_cast<PCC_BCB>(BcbPtr);
|
||||
BOOLEAN WRITE_FLAG = NULL;
|
||||
|
||||
if (reinterpret_cast<ULONG_PTR>((Bcb & 1))
|
||||
if (reinterpret_cast<ULONG_PTR>((Bcb) & 1))
|
||||
{
|
||||
WRITE_FLAG = TRUE;
|
||||
Bcb = reinterpret_cast<PCC_BCB>(reinterpret_cast<ULONG_PTR>(Bcb) & ~(1));
|
||||
@ -329,7 +428,7 @@ CcUnpinDataForThread(IN PVOID BcbPtr,
|
||||
PCC_BCB Bcb = BcbPtr;
|
||||
BOOLEAN WRITE_FLAG = NULL;
|
||||
|
||||
if (reinterpret_cast<ULONG_PTR>((Bcb & 1))
|
||||
if (reinterpret_cast<ULONG_PTR>((Bcb) & 1))
|
||||
{
|
||||
WRITE_FLAG = TRUE;
|
||||
Bcb = reinterpret_cast<PCC_BCB>(reinterpret_cast<ULONG_PTR>(Bcb) & ~(1));
|
||||
|
Loading…
Reference in New Issue
Block a user