IopBuildDeviceIoControlRequest

_IRP *__stdcall IopBuildDeviceIoControlRequest(
        UINT64 IoControlCode,
        _DEVICE_OBJECT *DeviceObject,
        PVOID InputBuffer,
        UINT64 InputBufferLength,
        PVOID OutputBuffer,
        UINT64 OutputBufferLength,
        UINT8 InternalDeviceIoControl,
        _KEVENT *Event,
        _IO_STATUS_BLOCK *IoStatusBlock,
        PVOID ReturnAddress){
  UINT64 v10; 
  int v13; 
  IRP *v14; 
  IRP *v15; 
  __int64 v16; 
  unsigned int v17; 
  UINT64 v18; 
  CHAR *v19; 
  int v20; 
  _ETHREAD *CurrentThread; 
  char *v22; 
  _QWORD *v23; 
  unsigned __int8 CurrentIrql; 
  UINT64 *v25; 
  __int64 v26; 
  PVOID v27; 
  PVOID v28; 
  __int64 v29; 
  int v30; 
  int v31; 
  CHAR *Pool_1; 
  int v34; 
  unsigned int v35; 
  INT64 v36; 
  _MDL *Mdl; 
  PIRP Irp; 
  v10 = (unsigned int)InputBufferLength;
  v13 = IoControlCode;
  v14 = IopAllocateIrpExReturn(DeviceObject, *((_BYTE *)DeviceObject + 76), 0, ReturnAddress);
  v15 = v14;
  if( !v14 )
    return 0i64;
  v16 = *((_QWORD *)v14 + 23);
  *(_BYTE *)(v16 - 72) = (InternalDeviceIoControl != 0) + 14;
  *(_DWORD *)(v16 - 64) = OutputBufferLength;
  *(_DWORD *)(v16 - 56) = v10;
  *(_DWORD *)(v16 - 48) = v13;
  v17 = v13 & 3;
  if( v17 )
  {
    if( v17 > 2 )
    {
      *((_QWORD *)v14 + 14) = OutputBuffer;
      *(_QWORD *)(v16 - 40) = InputBuffer;
      goto LABEL_13;
    }
    if( InputBuffer )
    {
      Pool_1 = IopVerifierExAllocatePool_1(NonPagedPoolNxCacheAligned, v10);
      *((_QWORD *)v15 + 3) = Pool_1;
      if( !Pool_1 )
        goto LABEL_34;
      memmove((UINT8 *)Pool_1, (UINT8 *)InputBuffer, v10);
      v34 = 48;
      v35 = 0;
    }
    else
    {
      v35 = 0;
      v34 = 0;
    }
    *((_DWORD *)v15 + 4) = v34;
    if( !OutputBuffer )
      goto LABEL_13;
    Mdl = IoAllocateMdl(OutputBuffer, OutputBufferLength, 0, 0, 0i64);
    *((_QWORD *)v15 + 1) = Mdl;
    if( Mdl )
    {
      if( v17 != 1 )
        v35 = 1;
      LODWORD(Irp) = *(unsigned __int8 *)(v16 - 72);
      IopProbeAndLockPages(Mdl, v36, v35, DeviceObject, (INT64)Irp);
      goto LABEL_13;
    }
    if( InputBuffer )
      ExFreePoolWithTag(*((PVOID *)v15 + 3), 0);
LABEL_34:
    IoFreeIrp(v15);
    return 0i64;
  }
  if( (_DWORD)v10 || (_DWORD)OutputBufferLength )
  {
    v18 = (unsigned int)v10;
    if( (unsigned int)v10 <= (unsigned int)OutputBufferLength )
      v18 = (unsigned int)OutputBufferLength;
    v19 = IopVerifierExAllocatePool_1(NonPagedPoolNxCacheAligned, v18);
    *((_QWORD *)v15 + 3) = v19;
    if( v19 )
    {
      if( InputBuffer )
        memmove((UINT8 *)v19, (UINT8 *)InputBuffer, v10);
      *((_DWORD *)v15 + 4) = 48;
      *((_QWORD *)v15 + 14) = OutputBuffer;
      v20 = *((_DWORD *)v15 + 4);
      if( OutputBuffer )
        v20 = 112;
      *((_DWORD *)v15 + 4) = v20;
      goto LABEL_13;
    }
    goto LABEL_34;
  }
  *((_DWORD *)v14 + 4) = 0;
  *((_QWORD *)v14 + 14) = 0i64;
LABEL_13:
  *((_QWORD *)v15 + 9) = IoStatusBlock;
  *((_QWORD *)v15 + 10) = Event;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *((_QWORD *)v15 + 19) = CurrentThread;
  v22 = (char *)CurrentThread + 1200;
  v23 = (_QWORD *)((char *)v15 + 32);
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  v25 = (UINT64 *)((char *)CurrentThread + 1416);
  KxAcquireSpinLock((UINT64 *)CurrentThread + 177);
  v26 = *(_QWORD *)v22;
  if( *(char **)(*(_QWORD *)v22 + 8i64) != v22 )
    __fastfail(3u);
  *v23 = v26;
  *((_QWORD *)v15 + 5) = v22;
  *(_QWORD *)(v26 + 8) = v23;
  *(_QWORD *)v22 = v23;
  KxReleaseSpinLock(v25);
  __writecr8(CurrentIrql);
  PsGetBaseIoPriorityThread(*((KDPC **)v15 + 19), v27, *((PVOID *)v15 + 19), v28);
  v31 = v30;
  if( v30 < 2 && (struct _KTHREAD *)v29 == KeGetCurrentThread() )
  {
    if( *(_DWORD *)(v29 + 1360) )
      v31 = 2;
  }
  *((_DWORD *)v15 + 4) = *((_DWORD *)v15 + 4) & 0xFFF1FFFF | ((v31 << 17) + 0x20000);
  return v15;
}

Referenced by:

FsRtlGetVirtualDiskNestingLevel
IoBuildDeviceIoControlRequest
IopAssignBootDriveLetter
IopCreateArcNamesCd
IopGetBootDiskInformation
SbpAddTransportToInstance
SbpStartLanman
VhdiMountVhdFile