ObRegisterCallbacks
NTSTATUS __stdcall ObRegisterCallbacks(_OB_CALLBACK_REGISTRATION *CallbackRegistration, VOID **RegistrationHandle){
unsigned int v3;
int inserted;
int OperationRegistrationCount;
size_t v7;
VOID **PoolWithTag;
unsigned __int16 *v9;
size_t Length;
char *v11;
unsigned int v12;
OB_OPERATION_REGISTRATION *v13;
POB_PRE_OPERATION_CALLBACK PreOperation;
POB_POST_OPERATION_CALLBACK PostOperation;
unsigned __int16 *v16;
_OBJECT_TYPE *v17;
__int64 v18;
unsigned __int16 *v20;
_ETHREAD *CurrentThread;
__int64 v22;
unsigned __int16 **v23;
v3 = 0;
inserted = 0;
if( (CallbackRegistration->Version & 0xFF00) != 256 )
return -1073741811;
OperationRegistrationCount = CallbackRegistration->OperationRegistrationCount;
if( !(_WORD)OperationRegistrationCount )
return -1073741811;
v7 = (OperationRegistrationCount << 6) + CallbackRegistration->Altitude.Length + 32;
PoolWithTag = ExAllocatePoolWithTag(1ui64, v7, 1816552015i64);
v9 = (unsigned __int16 *)PoolWithTag;
if( !PoolWithTag )
return -1073741670;
memset(PoolWithTag, 0i64, v7);
*v9 = 256;
*((_QWORD *)v9 + 1) = CallbackRegistration->RegistrationContext;
Length = CallbackRegistration->Altitude.Length;
v9[9] = Length;
v9[8] = Length;
v11 = (char *)v9 + v7 - Length;
*((_QWORD *)v9 + 3) = v11;
memmove(v11, CallbackRegistration->Altitude.Buffer, Length);
v12 = 0;
if( CallbackRegistration->OperationRegistrationCount )
{
while( 1 )
{
v13 = &CallbackRegistration->OperationRegistration[v12];
if( !v13->Operations || ((*v13->ObjectType)->TypeInfo._bf_0 & 0x40) == 0 )
break;
PreOperation = v13->PreOperation;
if( PreOperation )
{
if( !MmVerifyCallbackFunctionCheckFlags(PreOperation) )
goto LABEL_21;
}
else if( !v13->PostOperation )
{
break;
}
PostOperation = v13->PostOperation;
if( PostOperation && !MmVerifyCallbackFunctionCheckFlags(PostOperation) )
{
LABEL_21:
inserted = -1073741790;
goto LABEL_22;
}
v16 = &v9[32 * (unsigned __int64)v12 + 16];
*((_QWORD *)v16 + 1) = v16;
*(_QWORD *)v16 = v16;
ExInitializePushLock((PULONG_PTR)v16 + 7);
*((_DWORD *)v16 + 4) = v13->Operations;
*((_QWORD *)v16 + 3) = v9;
v17 = *v13->ObjectType;
*((_QWORD *)v16 + 4) = v17;
*((_QWORD *)v16 + 5) = v13->PreOperation;
*((_QWORD *)v16 + 6) = v13->PostOperation;
inserted = ObpInsertCallbackByAltitude(v17, (_OB_CALLBACK_CONTEXT_BLOCK *)v16);
if( inserted >= 0 )
{
++v9[1];
if( ++v12 < CallbackRegistration->OperationRegistrationCount )
continue;
}
goto LABEL_12;
}
inserted = -1073741811;
}
LABEL_12:
if( inserted < 0 )
{
LABEL_22:
if( v9[1] )
{
do
{
v20 = &v9[32 * (unsigned __int64)v3 + 16];
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(*((_QWORD *)v20 + 4) + 184i64), 0i64);
v22 = *(_QWORD *)v20;
if( *(unsigned __int16 **)(*(_QWORD *)v20 + 8i64) != v20
|| (v23 = (unsigned __int16 **)*((_QWORD *)v20 + 1), *v23 != v20) )
{
__fastfail(3u);
}
*v23 = (unsigned __int16 *)v22;
*(_QWORD *)(v22 + 8) = v23;
ExReleasePushLockEx(*((_QWORD *)v20 + 4) + 184, 0);
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
++v3;
}
while( v3 < v9[1] );
}
ExFreePoolWithTag(v9, 0x6C46624Fu);
}
else
{
if( v9[1] )
{
do
{
v18 = v3++;
*(_DWORD *)&v9[32 * v18 + 26] |= 1u;
}
while( v3 < v9[1] );
}
*RegistrationHandle = v9;
}
return inserted;
}Referenced by:
No references.