RtlDecompressBufferXpressLzProgress

NTSTATUS __stdcall RtlDecompressBufferXpressLzProgress(
        UINT8 *UncompressedBuffer,
        UINT64 UncompressedBufferSize,
        UINT8 *CompressedBuffer,
        UINT64 CompressedBufferSize,
        UINT64 *FinalUncompressedSize,
        VOID *Callback,
        VOID *a7,
        VOID *CallbackContext,
        UINT64 ProgressBytes){
  UINT8 *v9; 
  UINT8 *v10; 
  int v11; 
  UINT8 *v12; 
  UINT8 *v13; 
  UINT8 *v14; 
  unsigned __int64 v15; 
  unsigned __int64 v16; 
  UINT8 *v17; 
  UINT8 *v18; 
  int v19; 
  UINT8 *v20; 
  unsigned __int64 XpressCallback; 
  int v22; 
  bool v23; 
  unsigned __int64 v24; 
  char v25; 
  unsigned __int64 v26; 
  unsigned __int64 v27; 
  unsigned __int64 v28; 
  unsigned __int64 v29; 
  unsigned __int64 v30; 
  signed __int64 v31; 
  UINT8 *v32; 
  unsigned __int64 v33; 
  UINT8 v34; 
  __int64 v35; 
  _DWORD *v36; 
  unsigned __int64 v37; 
  unsigned __int64 v38; 
  unsigned __int64 v39; 
  char v40; 
  unsigned __int64 v41; 
  unsigned __int64 v42; 
  unsigned __int64 v43; 
  unsigned __int64 v44; 
  UINT8 *v45; 
  unsigned __int64 v46; 
  UINT8 v47; 
  __int64 v48; 
  unsigned __int64 v49; 
  int v50; 
  unsigned __int64 v51; 
  __int16 v53; 
  unsigned __int64 v54; 
  char v55; 
  __int64 v56; 
  unsigned __int64 v57; 
  unsigned __int64 v58; 
  unsigned __int64 v59; 
  unsigned __int64 v60; 
  unsigned __int64 v61; 
  UINT8 *v62; 
  UINT8 *v63; 
  __int64 v64[2]; 
  int v65; 
  int v66; 

  v66 = 0;
  v9 = CompressedBuffer;
  v10 = UncompressedBuffer;
  v11 = 4096;
  if( (unsigned int)CompressedBufferSize < 5 )
    return -1073741246;
  v12 = UncompressedBuffer;
  v13 = &CompressedBuffer[(unsigned int)CompressedBufferSize];
  v14 = &UncompressedBuffer[(unsigned int)UncompressedBufferSize];
  v62 = v14;
  v15 = (unsigned __int64)(v13 - 86);
  v16 = (unsigned __int64)(v14 - 352);
  v63 = v14 - 352;
  if( !Callback || (unsigned int)UncompressedBufferSize < 0x1000 )
    v11 = UncompressedBufferSize;
  v17 = &UncompressedBuffer[v11];
  v64[0] = (__int64)Callback;
  v64[1] = (__int64)a7;
  v65 = v11;
  if( v16 < (unsigned __int64)v17 )
    v17 = v14 - 352;
  v18 = 0i64;
LABEL_8:
  v19 = *(_DWORD *)v9;
  v20 = v9;
  v9 += 4;
  if( (unsigned __int64)v9 < v15 )
  {
    if( v12 >= v17 )
    {
      if( (unsigned __int64)v12 >= v16 )
      {
LABEL_123:
        v51 = (unsigned __int64)v62;
        goto LABEL_124;
      }
      XpressCallback = RtlpMakeXpressCallback((__int64)v64, v16, (__int64)v12);
      v16 = (unsigned __int64)v63;
      v17 = (UINT8 *)XpressCallback;
      v10 = UncompressedBuffer;
    }
    v22 = 2 * v19 + 1;
    if( v19 >= 0 )
    {
      while( 1 )
      {
        if( v22 < 0 )
        {
          *v12++ = *v9++;
          goto LABEL_20;
        }
        v23 = (v22 & 0x40000000) != 0;
        v22 *= 2;
        if( v23 )
        {
          *(_WORD *)v12 = *(_WORD *)v9;
          v12 += 2;
          v9 += 2;
          goto LABEL_20;
        }
        v23 = (v22 & 0x40000000) != 0;
        v22 *= 2;
        *(_DWORD *)v12 = *(_DWORD *)v9;
        if( v23 )
        {
          v12 += 3;
          v9 += 3;
          goto LABEL_20;
        }
        v12 += 4;
        v9 += 4;
        v23 = (v22 & 0x40000000) != 0;
        v22 *= 2;
        if( v23 )
          goto LABEL_20;
LABEL_54:
        v22 *= 2;
      }
    }
    while( 1 )
    {
      v24 = *(unsigned __int16 *)v9;
      v9 += 2;
      v25 = v24;
      v26 = (v24 >> 3) + 1;
      v27 = v25 & 7;
      if( v27 == 7 )
      {
        if( v18 )
        {
          v28 = (unsigned __int64)*v18 >> 4;
          v18 = 0i64;
        }
        else
        {
          v18 = v9++;
          v28 = *v18 & 0xF;
        }
        if( v28 == 15 )
        {
          if( (unsigned __int64)(v9 + 7) >= v15 )
            goto LABEL_67;
          v29 = *v9++;
          if( v29 == 255 )
          {
            v30 = *(unsigned __int16 *)v9;
            v9 += 2;
            if( !v30 )
            {
              v30 = *(unsigned int *)v9;
              v9 += 4;
            }
            if( v30 < 0x16 || &v12[v30 + 3] < v12 )
              return -1073741246;
            v29 = v30 - 22;
          }
          v28 = v29 + 15;
        }
        v27 = v28 + 7;
      }
      v31 = v27 + 3;
      v32 = &v12[-v26];
      if( &v12[-v26] < v10 )
        return -1073741246;
      if( v26 >= 4 )
      {
LABEL_44:
        *(_DWORD *)v12 = *(_DWORD *)v32;
        *((_DWORD *)v12 + 1) = *((_DWORD *)v32 + 1);
        if( v31 >= 9 )
        {
          v12 += 8;
          v36 = v32 + 8;
          for( v31 -= 8i64; ; v31 -= 16i64 )
          {
            if( v12 >= v17 )
            {
              if( (unsigned __int64)v12 >= v16 )
                goto LABEL_113;
              v37 = RtlpMakeXpressCallback((__int64)v64, v16, (__int64)v12);
              v16 = (unsigned __int64)v63;
              v17 = (UINT8 *)v37;
            }
            *(_DWORD *)v12 = *v36;
            *((_DWORD *)v12 + 1) = v36[1];
            *((_DWORD *)v12 + 2) = v36[2];
            *((_DWORD *)v12 + 3) = v36[3];
            if( v31 < 17 )
              break;
            v12 += 16;
            v36 += 4;
          }
          v10 = UncompressedBuffer;
        }
        v12 += v31;
        goto LABEL_53;
      }
      *v12 = *v32;
      v33 = v26 - 1;
      if( v33 )
      {
        v12[1] = v32[1];
        if( v33 == 1 )
        {
          v12 += 2;
          v35 = -2i64;
          goto LABEL_43;
        }
        v34 = v32[2];
      }
      else
      {
        v12[1] = *v32;
        v34 = *v32;
      }
      v12[2] = v34;
      v35 = -3i64;
      v12 += 3;
LABEL_43:
      v31 += v35;
      if( v31 )
        goto LABEL_44;
LABEL_53:
      if( v22 >= 0 )
        goto LABEL_54;
LABEL_20:
      v22 *= 2;
      if( !v22 )
        goto LABEL_8;
    }
  }
  while( 1 )
  {
    v9 = v20 + 4;
    if( v12 >= v17 )
    {
      if( (unsigned __int64)v12 >= v16 )
        goto LABEL_123;
      v38 = RtlpMakeXpressCallback((__int64)v64, v16, (__int64)v12);
      v16 = (unsigned __int64)v63;
      v17 = (UINT8 *)v38;
      v10 = UncompressedBuffer;
    }
    v22 = 2 * v19 + 1;
    if( v19 < 0 )
      break;
    while( v22 >= 0 )
    {
      v23 = (v22 & 0x40000000) != 0;
      v22 *= 2;
      if( v23 )
      {
        if( v9 + 1 >= v13 )
          return -1073741246;
        *(_WORD *)v12 = *(_WORD *)v9;
        v12 += 2;
        v9 += 2;
        goto LABEL_110;
      }
      v23 = (v22 & 0x40000000) != 0;
      v22 *= 2;
      if( v23 )
      {
        if( v9 + 2 >= v13 )
          return -1073741246;
        *(_WORD *)v12 = *(_WORD *)v9;
        v12[2] = v9[2];
        v12 += 3;
        v9 += 3;
        goto LABEL_110;
      }
      v22 *= 2;
      if( v9 + 3 >= v13 )
        return -1073741246;
      v50 = *(_DWORD *)v9;
      v9 += 4;
      *(_DWORD *)v12 = v50;
      v12 += 4;
      if( v22 < 0 )
        goto LABEL_110;
LABEL_97:
      v22 *= 2;
    }
    if( v9 >= v13 )
      return -1073741246;
    *v12++ = *v9++;
LABEL_110:
    v20 = v9;
    v22 *= 2;
    if( v22 )
      break;
    if( v9 + 3 >= v13 )
      return -1073741246;
    v19 = *(_DWORD *)v9;
  }
  if( v9 == v13 )
  {
    v51 = (unsigned __int64)v62;
    while( 1 )
    {
LABEL_118:
      if( v22 >= 0 )
      {
        v22 *= 2;
        goto LABEL_125;
      }
LABEL_120:
      while( 1 )
      {
        v22 *= 2;
        if( v22 )
          break;
        if( v9 + 3 >= v13 )
          return -1073741246;
        v19 = *(_DWORD *)v9;
        v9 += 4;
LABEL_124:
        v22 = 2 * v19 + 1;
        if( v19 < 0 )
          break;
LABEL_125:
        while( v22 >= 0 )
        {
          v22 *= 2;
          if( v9 + 2 > v13 || (unsigned __int64)(v12 + 2) > v51 )
            return -1073741246;
          v53 = *(_WORD *)v9;
          v9 += 2;
          *(_WORD *)v12 = v53;
          v12 += 2;
          if( v22 < 0 )
            goto LABEL_120;
          v22 *= 2;
        }
        if( v9 >= v13 || (unsigned __int64)v12 >= v51 )
          return -1073741246;
        *v12++ = *v9++;
      }
      if( v9 == v13 )
        break;
      if( v9 + 1 >= v13 )
      {
        if( (unsigned __int64)v12 < v51 )
          return -1073741246;
        break;
      }
      v54 = *(unsigned __int16 *)v9;
      v9 += 2;
      v55 = v54;
      v56 = (v54 >> 3) + 1;
      v57 = v55 & 7;
      if( v57 == 7 )
      {
        if( v18 )
        {
          v58 = (unsigned __int64)*v18 >> 4;
          v18 = 0i64;
        }
        else
        {
          if( v9 >= v13 )
            return -1073741246;
          v18 = v9++;
          v58 = *v18 & 0xF;
        }
        if( v58 == 15 )
        {
          if( v9 >= v13 )
            return -1073741246;
          v59 = *v9++;
          if( v59 == 255 )
          {
            if( v9 + 1 >= v13 )
              return -1073741246;
            v60 = *(unsigned __int16 *)v9;
            v9 += 2;
            if( !v60 )
            {
              if( v9 + 3 >= v13 )
                return -1073741246;
              v60 = *(unsigned int *)v9;
              v9 += 4;
            }
            if( v60 < 0x16 || &v12[v60 + 3] < v12 )
              return -1073741246;
            v59 = v60 - 22;
          }
          v58 = v59 + 15;
        }
        v57 = v58 + 7;
      }
      v61 = v57 + 3;
      if( &v12[-v56] < v10 || (unsigned __int64)&v12[v61] > v51 )
        return -1073741246;
      qmemcpy(v12, &v12[-v56], v61);
      v12 += v61;
    }
    *(_DWORD *)FinalUncompressedSize = (_DWORD)v12 - (_DWORD)v10;
    return 0;
  }
  if( v9 + 1 < v13 )
  {
    v39 = *(unsigned __int16 *)v9;
    v9 += 2;
    v40 = v39;
    v26 = (v39 >> 3) + 1;
    v41 = v40 & 7;
    if( v41 == 7 )
    {
      if( v18 )
      {
        v42 = (unsigned __int64)*v18 >> 4;
        v18 = 0i64;
      }
      else
      {
        if( v9 >= v13 )
          return -1073741246;
        v18 = v9++;
        v42 = *v18 & 0xF;
      }
      if( v42 == 15 )
      {
LABEL_67:
        if( v9 >= v13 )
          return -1073741246;
        v43 = *v9++;
        if( v43 == 255 )
        {
          if( v9 + 1 >= v13 )
            return -1073741246;
          v44 = *(unsigned __int16 *)v9;
          v9 += 2;
          if( !v44 )
          {
            if( v9 + 3 >= v13 )
              return -1073741246;
            v44 = *(unsigned int *)v9;
            v9 += 4;
          }
          if( v44 < 0x16 || &v12[v44 + 3] < v12 )
            return -1073741246;
          v43 = v44 - 22;
        }
        v42 = v43 + 15;
      }
      v41 = v42 + 7;
    }
    v31 = v41 + 3;
    v45 = &v12[-v26];
    if( &v12[-v26] < v10 )
      return -1073741246;
    if( v26 >= 4 )
    {
LABEL_87:
      *(_DWORD *)v12 = *(_DWORD *)v45;
      *((_DWORD *)v12 + 1) = *((_DWORD *)v45 + 1);
      if( v31 >= 9 )
      {
        v12 += 8;
        v36 = v45 + 8;
        for( v31 -= 8i64; ; v31 -= 16i64 )
        {
          if( v12 >= v17 )
          {
            if( (unsigned __int64)v12 >= v16 )
            {
LABEL_113:
              v51 = (unsigned __int64)v62;
              if( &v12[v31] <= v62 )
              {
                v10 = UncompressedBuffer;
                qmemcpy(v12, v36, v31);
                v12 += v31;
                goto LABEL_118;
              }
              return -1073741246;
            }
            v49 = RtlpMakeXpressCallback((__int64)v64, v16, (__int64)v12);
            v16 = (unsigned __int64)v63;
            v17 = (UINT8 *)v49;
          }
          *(_DWORD *)v12 = *v36;
          *((_DWORD *)v12 + 1) = v36[1];
          *((_DWORD *)v12 + 2) = v36[2];
          *((_DWORD *)v12 + 3) = v36[3];
          if( v31 < 17 )
            break;
          v12 += 16;
          v36 += 4;
        }
        v10 = UncompressedBuffer;
      }
      v12 += v31;
LABEL_96:
      if( v22 < 0 )
        goto LABEL_110;
      goto LABEL_97;
    }
    *v12 = *v45;
    v46 = v26 - 1;
    if( v46 )
    {
      v12[1] = v45[1];
      if( v46 == 1 )
      {
        v12 += 2;
        v48 = -2i64;
        goto LABEL_86;
      }
      v47 = v45[2];
    }
    else
    {
      v12[1] = *v45;
      v47 = *v45;
    }
    v12[2] = v47;
    v48 = -3i64;
    v12 += 3;
LABEL_86:
    v31 += v48;
    if( !v31 )
      goto LABEL_96;
    goto LABEL_87;
  }
  v51 = (unsigned __int64)v62;
  if( v12 >= v62 )
    goto LABEL_118;
  return -1073741246;
}

Referenced by:

RtlDecompressBufferProgress