ObpSetDeviceMap

NTSTATUS __stdcall ObpSetDeviceMap(
        VOID *ServerSilo,
        _EPROCESS *TargetProcess,
        VOID *DirectoryHandle,
        _KPROCESSOR_MODE PreviousMode,
        UINT64 Flags,
        _DEVICE_MAP **DeviceMap){
  NTSTATUS result; 
  _ADAPTER_OBJECT *v9; 
  VOID **PoolWithTag; 
  _DEVICE_MAP *v11; 
  int v12; 
  _DEVICE_MAP *v13; 
  VOID **p_DosDevicesDirectory; 
  _ESERVERSILO_GLOBALS *ServerSiloGlobals; 
  _ETHREAD *CurrentThread; 
  _ESERVERSILO_GLOBALS *v17; 
  _OBJECT_DIRECTORY *v18; 
  __int64 v19; 
  _OBJECT_DIRECTORY *DosDevicesDirectory; 
  NTSTATUS v21; 
  _EJOB *v22; 
  _KPROCESSOR_MODE AccessMode; 
  VOID *Object; 

  Object = 0i64;
  result = ObReferenceObjectByHandle(DirectoryHandle, 2ui64, DmaAdapter, PreviousMode, &Object, 0i64);
  if( result < 0 )
    return result;
  v9 = (_ADAPTER_OBJECT *)Object;
  if( (Flags & 4) == 0 && (*((_DWORD *)Object + 84) & 4) != 0 )
  {
    v21 = -1073741811;
LABEL_25:
    HalPutDmaAdapter(v9);
    return v21;
  }
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x48ui64, 1833198159i64);
  v11 = (_DEVICE_MAP *)PoolWithTag;
  if( !PoolWithTag )
  {
    v21 = -1073741670;
    goto LABEL_25;
  }
  memset(PoolWithTag, 0i64, 0x48u);
  v11->ReferenceCount = 1;
  v11->DosDevicesDirectory = (_OBJECT_DIRECTORY *)v9;
  LOBYTE(AccessMode) = 0;
  v12 = ObOpenObjectByPointer(v9, 0x200ui64, 0i64, 983055, DmaAdapter, AccessMode, &v11->DosDevicesDirectoryHandle);
  if( v12 < 0 )
  {
    HalPutDmaAdapter(v9);
    ExFreePoolWithTag(v11, 0x6D44624Fu);
    return v12;
  }
  else
  {
    if( ServerSilo )
    {
      ObfReferenceObjectWithTag(ServerSilo, 0x6D44624Fui64);
      v11->ServerSilo = (_EJOB *)ServerSilo;
    }
    v13 = 0i64;
    p_DosDevicesDirectory = 0i64;
    ServerSiloGlobals = PsGetServerSiloGlobals((_EJOB *)ServerSilo);
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    v17 = ServerSiloGlobals;
    --CurrentThread->Tcb.SpecialApcDisable;
    ExAcquirePushLockExclusiveEx(&ServerSiloGlobals->ObSiloState.DeviceMapLock, 0i64);
    v18 = (_OBJECT_DIRECTORY *)Object;
    v19 = *((_QWORD *)Object + 38);
    if( v19 )
    {
      p_DosDevicesDirectory = (VOID **)&v11->DosDevicesDirectory;
      v11 = (_DEVICE_MAP *)*((_QWORD *)Object + 38);
      _InterlockedIncrement((volatile signed __int32 *)(v19 + 24));
    }
    else
    {
      if( (Flags & 1) != 0 )
        v17->ObSiloState.SystemDeviceMap = v11;
      v18->DeviceMap = v11;
      if( (Flags & 2) != 0 )
      {
        DosDevicesDirectory = v17->ObSiloState.SystemDeviceMap->DosDevicesDirectory;
        if( v18 != DosDevicesDirectory )
          v11->GlobalDosDevicesDirectory = DosDevicesDirectory;
      }
    }
    if( TargetProcess )
    {
      v13 = (_DEVICE_MAP *)TargetProcess->DeviceMap;
      TargetProcess->DeviceMap = v11;
    }
    ExReleasePushLockEx((_DWORD)v17 + 120, 0);
    KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
    if( p_DosDevicesDirectory )
    {
      ObpCloseHandle(p_DosDevicesDirectory[2], 0i64);
      HalPutDmaAdapter((PADAPTER_OBJECT)Object);
      v22 = v11->ServerSilo;
      if( v22 )
        ObfDereferenceObjectWithTag(v22, 0x6D44624Fui64);
      ExFreePoolWithTag(p_DosDevicesDirectory, 0x6D44624Fu);
    }
    if( v13 )
      ObfDereferenceDeviceMap(v13);
    if( DeviceMap )
      *DeviceMap = v11;
    return 0;
  }
}

Referenced by:

ObSetProcessDeviceMap
ObpSetSiloDeviceMap
SeGetTokenDeviceMap