LdrpSetAlternateResourceModuleHandle

UINT8 __stdcall LdrpSetAlternateResourceModuleHandle(
        VOID *Module,
        VOID **AlternateModule,
        VOID **AlternateFileHandle,
        VOID *ModuleManifest,
        UINT16 LangId,
        UINT64 Flags,
        INT64 ErrorCode,
        UINT64 AlternateFileSize,
        UINT64 a9){
  VOID *v11; 
  unsigned int i; 
  unsigned __int64 v13; 
  char *v14; 
  VOID **v15; 
  unsigned int j; 
  unsigned __int64 v17; 
  unsigned __int64 v18; 
  __int16 v19; 
  __int64 v20; 
  int v21; 
  int v22; 
  unsigned __int64 v23; 
  char *v24; 
  VOID *v25; 
  VOID **v26; 
  VOID **PoolWithTag; 
  int v28; 
  PLARGE_INTEGER Timeout; 
  INT64 v31; 
  INT64 v32; 
  INT64 v33; 

  v11 = 0i64;
  if( !Module || (Flags & 0xFFFFFFCC) != 0 || (Flags & 3) == 3 || (Flags & 1) != 0 && !AlternateModule )
    return 0;
  LdrpInitMuiCrits(
    (INT64 *)Module,
    AlternateModule,
    (INT64)AlternateFileHandle,
    (INT64)ModuleManifest,
    (INT64)Timeout,
    v31,
    v32,
    v33);
  KeWaitForSingleObject((UINT64)&MuiMutex, 0, 0, 0, 0i64);
  for( i = 0; i < (unsigned int)AlternateResourceModuleCount; ++i )
  {
    v13 = (unsigned __int64)i << 6;
    if( *(VOID **)((char *)AlternateResourceModules + v13 + 8) == Module )
    {
      if( (Flags & 2) != 0 && *(_QWORD *)((char *)AlternateResourceModules + v13 + 16) )
        goto LABEL_53;
      if( (Flags & 1) != 0
        && *((_QWORD *)AlternateResourceModules + 8 * (unsigned __int64)i + 4)
        && LangId
        && *(_WORD *)((char *)AlternateResourceModules + v13) == LangId )
      {
        if( *AlternateModule != (VOID *)-1i64 )
        {
          MmUnmapViewInSystemSpace(*AlternateModule);
          if( AlternateFileHandle )
            ZwClose((_HANDLE)*AlternateFileHandle);
        }
        v14 = (char *)AlternateResourceModules;
        *AlternateModule = *(VOID **)((char *)AlternateResourceModules + v13 + 32);
        if( AlternateFileHandle )
          *AlternateFileHandle = *(VOID **)&v14[v13 + 40];
        goto LABEL_53;
      }
    }
  }
  if( (Flags & 0x10) != 0 )
    goto LABEL_53;
  v15 = (VOID **)AlternateResourceModules;
  if( AlternateResourceModules )
  {
    if( (unsigned int)AlternateResourceModuleCount >= AltResMemBlockCount )
    {
      PoolWithTag = ExAllocatePoolWithTag(
                      1ui64,
                      (unsigned __int64)(unsigned int)(AltResMemBlockCount + 32) << 6,
                      1766880370i64);
      v15 = PoolWithTag;
      if( !PoolWithTag )
        goto LABEL_53;
      v28 = AltResMemBlockCount;
      memset(PoolWithTag, 0i64, (AltResMemBlockCount + 32) << 6);
      memmove(v15, AlternateResourceModules, v28 << 6);
      ExFreePoolWithTag(AlternateResourceModules, 0);
      AlternateResourceModules = v15;
      AltResMemBlockCount += 32;
    }
  }
  else
  {
    v26 = ExAllocatePoolWithTag(1ui64, 0x800ui64, 1766880370i64);
    v15 = v26;
    if( !v26 )
      goto LABEL_53;
    memset(v26, 0i64, 0x800u);
    AlternateResourceModules = v15;
    AltResMemBlockCount = 32;
  }
  for( j = 0; j < (unsigned int)AlternateResourceModuleCount; ++j )
  {
    v17 = (unsigned __int64)j << 6;
    if( *(VOID **)((char *)v15 + v17 + 8) == Module )
    {
      if( (Flags & 2) != 0 && !*(VOID **)((char *)v15 + v17 + 16) )
      {
        *(VOID **)((char *)v15 + v17 + 16) = ModuleManifest;
        *(_DWORD *)((char *)v15 + v17 + 56) = ErrorCode;
        goto LABEL_53;
      }
      if( (Flags & 1) != 0 )
      {
        v18 = (unsigned __int64)j << 6;
        if( !*(VOID **)((char *)v15 + v18 + 32) )
        {
          v19 = *(_WORD *)((char *)v15 + v18);
          if( v19 == LangId || !v19 )
          {
            *(VOID **)((char *)v15 + v18 + 32) = *AlternateModule;
            if( AlternateFileHandle )
              v11 = *AlternateFileHandle;
            *(VOID **)((char *)v15 + v18 + 40) = v11;
            *(_WORD *)((char *)v15 + v18) = LangId;
            *(_DWORD *)((char *)v15 + v18 + 56) = ErrorCode;
            *(VOID **)((char *)v15 + v18 + 48) = (VOID *)AlternateFileSize;
            goto LABEL_53;
          }
        }
      }
    }
  }
  LODWORD(v20) = RtlImageNtHeader((unsigned __int64)Module & 0xFFFFFFFFFFFFFFFCui64);
  if( v20 )
  {
    v21 = *(_DWORD *)(v20 + 88);
    v22 = AlternateResourceModuleCount;
    v23 = (unsigned __int64)(unsigned int)AlternateResourceModuleCount << 6;
    v24 = (char *)AlternateResourceModules;
    *(_QWORD *)((char *)AlternateResourceModules + v23 + 8) = Module;
    *(_QWORD *)&v24[v23 + 16] = ModuleManifest;
    if( (Flags & 1) != 0 )
    {
      if( AlternateModule )
        v25 = *AlternateModule;
      else
        v25 = 0i64;
      *(_QWORD *)&v24[v23 + 32] = v25;
      if( AlternateFileHandle )
        v11 = *AlternateFileHandle;
      *(_QWORD *)&v24[v23 + 40] = v11;
      *(_QWORD *)&v24[v23 + 48] = AlternateFileSize;
    }
    else
    {
      *(_QWORD *)&v24[v23 + 32] = 0i64;
      *(_QWORD *)&v24[v23 + 40] = 0i64;
      *(_QWORD *)&v24[v23 + 48] = 0i64;
    }
    *(_WORD *)&v24[v23] = LangId;
    *(_DWORD *)&v24[v23 + 24] = v21;
    *(_DWORD *)&v24[v23 + 56] = ErrorCode;
    LODWORD(AlternateResourceModuleCount) = v22 + 1;
  }
LABEL_53:
  KeReleaseMutant(&MuiMutex, 1i64, 0, 0);
  return 1;
}

Referenced by:

LdrLoadAlternateResourceModuleEx
LdrResGetRCConfig
LdrpGetRcConfig