RtlDecompressBufferLZNT1

NTSTATUS __stdcall RtlDecompressBufferLZNT1(
        VOID *UncompressedBuffer,
        UINT64 UncompressedBufferSize,
        UINT8 *CompressedBuffer,
        UINT64 CompressedBufferSize,
        UINT64 ExplicitChunkSize,
        UINT64 *FinalUncompressedSize,
        VOID *WorkSpace){
  UINT8 *v7; 
  UINT8 *v8; 
  UINT8 *v9; 
  UINT8 *v10; 
  int v11; 
  __int16 v12; 
  __int64 v13; 
  INT32 v14; 
  unsigned __int32 v15; 
  __int64 v16; 
  UINT64 *v17; 
  unsigned __int32 v19; 
  __int64 v20; 
  char *v21; 
  UINT64 ExplicitChunkSizea; 
  _ASYNC_DECOMPRESS_CONTEXT AsyncDecompressContext; 
  __int64 v24; 
  int v25; 
  INT32 FinalUncompressedChunkSize; 

  v25 = (int)UncompressedBuffer;
  v7 = CompressedBuffer;
  v8 = (UINT8 *)UncompressedBuffer;
  memset(&AsyncDecompressContext, 0, sizeof(AsyncDecompressContext));
  v9 = (UINT8 *)UncompressedBuffer + (unsigned int)UncompressedBufferSize;
  v10 = &CompressedBuffer[(unsigned int)CompressedBufferSize];
  v11 = 0;
  KeInitializeEvent((INT64)&AsyncDecompressContext, 1, 0);
  v24 = 1i64;
  v12 = *(_WORD *)v7;
  FinalUncompressedChunkSize = 0;
  while( 1 )
  {
    v16 = (v12 & 0xFFFu) + 3;
    if( &v7[v16] > v10 )
    {
LABEL_32:
      v17 = FinalUncompressedSize;
LABEL_20:
      v11 = -1073741246;
      *(_DWORD *)v17 = (_DWORD)v7;
      goto LABEL_14;
    }
    v13 = (unsigned int)v16;
    if( v12 >= 0 )
    {
      if( (unsigned int)v16 < 2ui64 )
        goto LABEL_32;
      v19 = v16 - 2;
      FinalUncompressedChunkSize = v19;
      if( &v8[v19] > v9 )
      {
        v19 = (_DWORD)v9 - (_DWORD)v8;
        FinalUncompressedChunkSize = (_DWORD)v9 - (_DWORD)v8;
      }
      if( &v7[v19 + 2] > v10 )
        goto LABEL_32;
      memmove(v8, v7 + 2, v19);
LABEL_28:
      v15 = FinalUncompressedChunkSize;
      goto LABEL_6;
    }
    v14 = ExplicitChunkSize;
    if( !(_DWORD)ExplicitChunkSize )
    {
      v11 = LZNT1DecompressChunk(v8, v9, v7 + 2, (INT64)&v7[v16], &FinalUncompressedChunkSize);
      if( v11 < 0 )
      {
        *(_DWORD *)FinalUncompressedSize = FinalUncompressedChunkSize;
        goto LABEL_14;
      }
      goto LABEL_28;
    }
    LODWORD(ExplicitChunkSizea) = ExplicitChunkSize;
    v11 = LZNT1DecompressChunkNewThread(&AsyncDecompressContext, v8, v9, v7 + 2, &v7[v16], ExplicitChunkSizea);
    if( v11 < 0 )
      break;
    v15 = v14;
    FinalUncompressedChunkSize = v14;
LABEL_6:
    v7 += v13;
    v8 += v15;
    if( v8 == v9 || v7 > v10 - 2 || (v12 = *(_WORD *)v7) == 0 )
    {
LABEL_12:
      v17 = FinalUncompressedSize;
      if( v7 <= v10 )
      {
        *(_DWORD *)FinalUncompressedSize = (_DWORD)v8 - v25;
        goto LABEL_14;
      }
      goto LABEL_20;
    }
    if( v15 < 0x1000 )
    {
      v20 = (int)(4096 - v15);
      v21 = (char *)&v8[v20];
      if( &v8[v20] >= v9 )
        goto LABEL_12;
      memset(v8, 0i64, v20);
      v8 = (UINT8 *)v21;
    }
  }
  *(_DWORD *)FinalUncompressedSize = FinalUncompressedChunkSize;
LABEL_14:
  if( _InterlockedExchangeAdd((volatile signed __int32 *)&v24, 0xFFFFFFFF) == 1 )
    KeSetEvent((PRKEVENT)&AsyncDecompressContext, 0, 0);
  KeWaitForSingleObject((UINT64)&AsyncDecompressContext, 0, 0, 0, 0i64);
  if( v11 >= 0 && v24 < 0 )
    return HIDWORD(v24);
  return v11;
}

Referenced by:

No references.