#include "FsRecovery.h"
//
// FsRecovery - UEFI Module (Regenerated from IDA)
// Total functions: 77
//
// Function: ZeroMem @ 0x260 (0x20 bytes)
// Index: 1/77
void *__cdecl ZeroMem(void *buf, unsigned int count)
{
memset(buf, 0, count); /*0x277*/
return buf; /*0x27e*/
}
// Function: CopyMem @ 0x280 (0x3f bytes)
// Index: 2/77
char *__cdecl CopyMem(char *dst, char *src, unsigned int count)
{
unsigned int count_1; // edx
char *dst_1; // edi
char *src_1; // esi
count_1 = count; /*0x28a*/
if ( src < dst && &src[count - 1] >= dst ) /*0x298*/
{
src_1 = &src[count - 1]; /*0x2ac*/
dst_1 = &dst[count - 1]; /*0x2ae*/
}
else
{
count_1 = count & 3; /*0x29c*/
qmemcpy(dst, src, 4 * (count >> 2)); /*0x2a5*/
src_1 = &src[4 * (count >> 2)]; /*0x2a5*/
dst_1 = &dst[4 * (count >> 2)]; /*0x2a5*/
}
qmemcpy(dst_1, src_1, count_1); /*0x2b5*/
return dst; /*0x2bc*/
}
// Function: SetMem @ 0x2c0 (0x15 bytes)
// Index: 3/77
void *__cdecl SetMem(void *buf, unsigned int count, char value)
{
memset(buf, value, count); /*0x2cd*/
return buf; /*0x2d3*/
}
// Function: SetMem32 @ 0x2e0 (0x1f bytes)
// Index: 4/77
int __cdecl SetMem32(int a1, int a2, int a3, int a4)
{
do /*0x2f9*/
{
*(_DWORD *)(a1 + 8 * a2 - 8) = a3; /*0x2f1*/
*(_DWORD *)(a1 + 8 * a2-- - 4) = a4; /*0x2f5*/
}
while ( a2 ); /*0x2f9*/
return a1; /*0x2fd*/
}
// Function: SetMem32_2 @ 0x300 (0x15 bytes)
// Index: 5/77
void *__cdecl SetMem32_2(void *buf, unsigned int count, int value)
{
memset32(buf, value, count); /*0x30d*/
return buf; /*0x313*/
}
// Function: _ModuleEntryPoint @ 0x320 (0x18 bytes)
// Index: 6/77
EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
gSystemTable = (int)SystemTable; /*0x32a*/
return (*(int (__cdecl **)(EFI_SYSTEM_TABLE *, void *))(LODWORD(SystemTable->Hdr.Signature) + 24))( /*0x337*/
SystemTable,
&unk_4B98);
}
// Function: MatchWildcard @ 0x338 (0xe1 bytes)
// Index: 7/77
bool __fastcall MatchWildcard(char *Pattern, char *StrToMatch, int CaseSensitive, int MaxLen)
{
char *Pattern_1; // ebx
int StrLenResult; // edx
char PatChar; // dl
char PatChar_2; // al
char PatChar_1; // cl
Pattern_1 = Pattern; /*0x341*/
StrLen(Pattern); /*0x343*/
if ( StrLen(StrToMatch) ) /*0x34c*/
{
while ( 1 ) /*0x35c*/
{
if ( !MaxLen ) /*0x35e*/
return !StrLenResult || *Pattern_1 == 44; /*0x35e*/
PatChar = *Pattern_1++; /*0x364*/
switch ( PatChar ) /*0x370*/
{
case 0: /*0x370*/
return 1; /*0x370*/
case 42: /*0x370*/
while ( *StrToMatch ) /*0x3ea*/
{
if ( MatchWildcard(Pattern_1, StrToMatch, CaseSensitive, MaxLen) ) /*0x3da*/
return 1; /*0x3e3*/
++StrToMatch; /*0x3e5*/
--MaxLen; /*0x3e6*/
}
goto LABEL_23; /*0x3ea*/
case 44: /*0x370*/
return 1; /*0x37f*/
}
if ( PatChar == 46 ) /*0x389*/
break; /*0x389*/
if ( PatChar != 63 ) /*0x38e*/
goto LABEL_11; /*0x38e*/
if ( !*StrToMatch ) /*0x390*/
return 0; /*0x392*/
LABEL_16:
++StrToMatch; /*0x3c0*/
--MaxLen; /*0x3c1*/
LABEL_23:
StrLen(Pattern_1); /*0x3ec*/
if ( !StrLen(StrToMatch) ) /*0x3f7*/
return !StrLenResult || *Pattern_1 == 44; /*0x3fe*/
}
if ( (_BYTE)CaseSensitive == 1 ) /*0x39c*/
{
while ( *StrToMatch == 32 ) /*0x3ce*/
{
++StrToMatch; /*0x3c8*/
--MaxLen; /*0x3c9*/
}
goto LABEL_23; /*0x3ce*/
}
LABEL_11:
PatChar_2 = *StrToMatch; /*0x39e*/
if ( (unsigned __int8)(*StrToMatch - 97) <= 0x19u ) /*0x3a9*/
PatChar_2 -= 32; /*0x3ab*/
PatChar_1 = PatChar; /*0x3ae*/
if ( (unsigned __int8)(PatChar - 97) <= 0x19u ) /*0x3b7*/
PatChar_1 = PatChar - 32; /*0x3b9*/
if ( PatChar_2 != PatChar_1 ) /*0x3be*/
return 0; /*0x396*/
goto LABEL_16; /*0x3be*/
}
return !StrLenResult || *Pattern_1 == 44; /*0x40f*/
}
// Function: MatchNameWildcard @ 0x419 (0x54 bytes)
// Index: 8/77
int __fastcall MatchNameWildcard(char *DirEntry, int CaseSensitive, int MaxLen, char *Pattern)
{
if ( !*DirEntry || !MaxLen ) /*0x430*/
return -2147483646; /*0x424*/
while ( 1 ) /*0x437*/
{
if ( *Pattern == 44 ) /*0x43a*/
++Pattern; /*0x43c*/
if ( MatchWildcard(Pattern, DirEntry, CaseSensitive, MaxLen) ) /*0x446*/
break; /*0x44f*/
while ( *Pattern != 44 ) /*0x460*/
{
if ( !*Pattern ) /*0x459*/
return -2147483646; /*0x466*/
++Pattern; /*0x45b*/
}
}
return 0; /*0x454*/
}
// Function: FormatShortName @ 0x46d (0xed bytes)
// Index: 9/77
void __fastcall FormatShortName(char *SrcName, int OutputBuf_1)
{
unsigned int i; // esi
unsigned int NameLen; // edx
int DestOffset; // esi
char SrcByte; // al
unsigned int ShortNameIdx; // esi
int BufOffset; // edx
char CurChar; // cl
int BufIdx; // eax
unsigned int ShortNameIdx_1; // edi
char *CharIdx; // ecx
char ExtChar; // al
int OutputBuf; // [esp+10h] [ebp-14h]
_BYTE v14[16]; // [esp+14h] [ebp-10h] BYREF
OutputBuf = OutputBuf_1; /*0x474*/
if ( byte_4BE9 ) /*0x480*/
{
for ( i = 0; i < 0xD; ++i ) /*0x482*/
{
v14[i] = SrcName[2 * i]; /*0x487*/
if ( !*(_WORD *)&SrcName[2 * i] ) /*0x48b*/
break; /*0x48f*/
}
}
else
{
NameLen = 0; /*0x49d*/
DestOffset = v14 - SrcName; /*0x49f*/
do /*0x4af*/
{
SrcByte = *SrcName; /*0x4a1*/
SrcName[DestOffset] = *SrcName; /*0x4a3*/
if ( !SrcByte ) /*0x4a8*/
break; /*0x4a8*/
++NameLen; /*0x4aa*/
++SrcName; /*0x4ab*/
}
while ( NameLen < 0xD ); /*0x4af*/
OutputBuf_1 = OutputBuf; /*0x4b1*/
}
ShortNameIdx = 0; /*0x4ba*/
if ( v14[0] ) /*0x4bc*/
{
BufOffset = OutputBuf_1 - (_DWORD)v14; /*0x4c2*/
do /*0x4e2*/
{
CurChar = v14[ShortNameIdx]; /*0x4c4*/
if ( CurChar == 46 ) /*0x4cb*/
break; /*0x4cb*/
if ( (unsigned __int8)(CurChar - 97) <= 0x19u ) /*0x4d5*/
CurChar -= 32; /*0x4d7*/
BufIdx = BufOffset + ShortNameIdx++; /*0x4da*/
v14[BufIdx] = CurChar; /*0x4de*/
}
while ( v14[ShortNameIdx] ); /*0x4e2*/
}
ShortNameIdx_1 = ShortNameIdx; /*0x4ec*/
if ( ShortNameIdx < 8 ) /*0x4f0*/
{
ReservedFunc1(); /*0x4fe*/
ShortNameIdx = 8; /*0x506*/
}
if ( v14[ShortNameIdx_1] == 46 ) /*0x511*/
{
for ( CharIdx = &v14[ShortNameIdx_1 + 1]; *CharIdx; ++CharIdx ) /*0x518*/
{
ExtChar = *CharIdx; /*0x526*/
if ( (unsigned __int8)(*CharIdx - 97) <= 0x19u ) /*0x529*/
ExtChar -= 32; /*0x52b*/
*(_BYTE *)(ShortNameIdx + OutputBuf) = ExtChar; /*0x52e*/
++ShortNameIdx; /*0x531*/
}
}
if ( ShortNameIdx < 0xB ) /*0x53a*/
{
ReservedFunc1(); /*0x545*/
ShortNameIdx = 11; /*0x54d*/
}
*(_BYTE *)(ShortNameIdx + OutputBuf) = 0; /*0x550*/
}
// Function: IsLongFileName @ 0x55a (0x87 bytes)
// Index: 10/77
bool __fastcall IsLongFileName(_WORD *FileName, int Param2)
{
unsigned __int8 NameLen; // al
unsigned __int8 NameLen_1; // dl
unsigned __int8 NameLen_3; // cl
int WideChar; // eax
unsigned __int8 NameLen_2; // al
if ( *(_BYTE *)(BootSector + 12) != 2 ) /*0x567*/
return 0; /*0x56b*/
if ( IsUnicode ) /*0x574*/
{
NameLen = StrLen_Unicode(FileName); /*0x576*/
NameLen_1 = NameLen; /*0x57b*/
if ( NameLen > 0xCu ) /*0x580*/
return 1; /*0x584*/
NameLen_3 = 0; /*0x586*/
if ( NameLen ) /*0x58a*/
{
while ( 1 ) /*0x594*/
{
WideChar = (unsigned __int16)FileName[NameLen_3]; /*0x594*/
if ( (unsigned __int16)WideChar > 0xFFu ) /*0x59b*/
return 1; /*0x59b*/
if ( WideChar != 46 && ++NameLen_3 < NameLen_1 ) /*0x5a6*/
continue; /*0x5a6*/
goto LABEL_10; /*0x5a6*/
}
}
}
else
{
NameLen_2 = StrLen(FileName); /*0x5be*/
NameLen_1 = NameLen_2; /*0x5c3*/
if ( NameLen_2 > 0xCu ) /*0x5c8*/
return 1; /*0x5c8*/
NameLen_3 = 0; /*0x5ca*/
if ( NameLen_2 ) /*0x5ce*/
{
do /*0x5dd*/
{
if ( *((_BYTE *)FileName + NameLen_3) == 46 ) /*0x5d7*/
break; /*0x5d7*/
++NameLen_3; /*0x5d9*/
}
while ( NameLen_3 < NameLen_2 ); /*0x5dd*/
LABEL_10:
if ( NameLen_3 > 8u ) /*0x5ab*/
return 1; /*0x5ab*/
}
}
return NameLen_1 - NameLen_3 > 4; /*0x5bb*/
}
// Function: ExtractDirEntryName @ 0x5e1 (0xc8 bytes)
// Index: 11/77
char __fastcall ExtractDirEntryName(_BYTE *LfnEntryPtr, int a2)
{
unsigned int EntryCount; // ebp
int OutIdx; // esi
__int16 *CurEntryPtr; // ecx
char IsUnicode; // ah
__int16 *v6; // edi
int NamePart1Len; // ebx
__int16 v8; // ax
__int16 *CurEntryPtr_1; // edi
int NamePart2Len; // ebx
__int16 v11; // ax
__int16 *v12; // edi
int ExtPartLen; // ebx
__int16 v14; // ax
char AsciiByte; // al
char *CurEntryPtr_2; // edi
int n6; // ebx
char AsciiChar; // al
_BYTE *AsciiExtPtr; // edi
int n2; // ebx
unsigned int EntryCount_1; // [esp+10h] [ebp-4h]
EntryCount = 0; /*0x5ee*/
EntryCount_1 = *LfnEntryPtr & 0x1F; /*0x5f0*/
OutIdx = 0; /*0x5f8*/
CurEntryPtr = (__int16 *)&LfnEntryPtr[32 * EntryCount_1 - 18]; /*0x5fa*/
IsUnicode = ::IsUnicode; /*0x5fc*/
do /*0x68d*/
{
v6 = (__int16 *)((char *)CurEntryPtr - 13); /*0x603*/
NamePart1Len = 5; /*0x608*/
if ( IsUnicode ) /*0x60b*/
{
do /*0x61b*/
{
v8 = *v6++; /*0x60d*/
*(_WORD *)(a2 + 2 * OutIdx++) = v8; /*0x613*/
--NamePart1Len; /*0x618*/
}
while ( NamePart1Len ); /*0x61b*/
CurEntryPtr_1 = CurEntryPtr; /*0x61f*/
NamePart2Len = 6; /*0x621*/
do /*0x630*/
{
v11 = *CurEntryPtr_1++; /*0x622*/
*(_WORD *)(a2 + 2 * OutIdx++) = v11; /*0x628*/
--NamePart2Len; /*0x62d*/
}
while ( NamePart2Len ); /*0x630*/
v12 = CurEntryPtr + 7; /*0x634*/
ExtPartLen = 2; /*0x637*/
do /*0x646*/
{
v14 = *v12++; /*0x638*/
*(_WORD *)(a2 + 2 * OutIdx++) = v14; /*0x63e*/
--ExtPartLen; /*0x643*/
}
while ( ExtPartLen ); /*0x646*/
IsUnicode = ::IsUnicode; /*0x648*/
}
else
{
do /*0x65c*/
{
AsciiByte = *(_BYTE *)v6++; /*0x650*/
*(_BYTE *)(OutIdx + a2) = AsciiByte; /*0x655*/
++OutIdx; /*0x658*/
--NamePart1Len; /*0x659*/
}
while ( NamePart1Len ); /*0x65c*/
CurEntryPtr_2 = (char *)CurEntryPtr; /*0x660*/
n6 = 6; /*0x662*/
do /*0x66f*/
{
AsciiChar = *CurEntryPtr_2; /*0x663*/
CurEntryPtr_2 += 2; /*0x665*/
*(_BYTE *)(OutIdx + a2) = AsciiChar; /*0x668*/
++OutIdx; /*0x66b*/
--n6; /*0x66c*/
}
while ( n6 ); /*0x66f*/
AsciiExtPtr = CurEntryPtr + 7; /*0x673*/
n2 = 2; /*0x676*/
do /*0x683*/
{
LOBYTE(v14) = *AsciiExtPtr; /*0x677*/
AsciiExtPtr += 2; /*0x679*/
*(_BYTE *)(OutIdx + a2) = v14; /*0x67c*/
++OutIdx; /*0x67f*/
--n2; /*0x680*/
}
while ( n2 ); /*0x683*/
}
CurEntryPtr -= 16; /*0x685*/
++EntryCount; /*0x688*/
}
while ( EntryCount < EntryCount_1 ); /*0x68d*/
if ( IsUnicode ) /*0x695*/
{
*(_WORD *)(a2 + 2 * OutIdx) = 0; /*0x699*/
LOBYTE(v14) = 0; /*0x697*/
}
else
{
*(_BYTE *)(OutIdx + a2) = 0; /*0x69f*/
}
return v14; /*0x6a3*/
}
// Function: StrCmpUnicodeOrAscii @ 0x6a9 (0xd9 bytes)
// Index: 12/77
char __fastcall StrCmpUnicodeOrAscii(_WORD *Str1, _WORD *Str2)
{
unsigned int Len1; // esi
unsigned __int8 CharIdx; // bl
int Idx1; // esi
__int16 Ch1; // cx
__int16 Ch2; // dx
__int16 Ch1_1; // ax
int Len2; // eax
int Len2_1; // edx
unsigned __int8 CharIdxA; // bl
unsigned int CharIdxA_1; // esi
int IdxA; // ecx
char Ch1A; // dl
char Ch1A_2; // cl
char Ch1A_1; // al
if ( IsUnicode ) /*0x6b8*/
{
Len1 = StrLen_Unicode(Str1); /*0x6c1*/
if ( Len1 != StrLen_Unicode(Str2) ) /*0x6ca*/
return 0; /*0x6ce*/
CharIdx = 0; /*0x6d5*/
if ( StrLen_Unicode(Str1) ) /*0x6d7*/
{
Idx1 = 0; /*0x6e6*/
while ( 1 ) /*0x6e9*/
{
Ch1 = Str1[Idx1]; /*0x6e9*/
if ( (unsigned __int16)(Ch1 - 97) <= 0x19u ) /*0x6f3*/
Ch1 -= 32; /*0x6f5*/
Ch2 = Str2[Idx1]; /*0x6f8*/
Ch1_1 = Ch2 - 32; /*0x706*/
if ( (unsigned __int16)(Ch2 - 97) > 0x19u ) /*0x709*/
Ch1_1 = Str2[Idx1]; /*0x70b*/
if ( Ch1 != Ch1_1 ) /*0x710*/
break; /*0x710*/
Idx1 = ++CharIdx; /*0x716*/
if ( CharIdx >= StrLen_Unicode(Str1) ) /*0x723*/
return 1; /*0x723*/
}
return 0; /*0x710*/
}
}
else
{
StrLen(Str1); /*0x727*/
Len2 = StrLen(Str2); /*0x730*/
if ( Len2_1 != Len2 ) /*0x737*/
return 0; /*0x737*/
CharIdxA = 0; /*0x73b*/
CharIdxA_1 = StrLen(Str1); /*0x742*/
if ( CharIdxA_1 ) /*0x746*/
{
IdxA = 0; /*0x748*/
while ( 1 ) /*0x750*/
{
Ch1A = *((_BYTE *)Str1 + IdxA); /*0x750*/
if ( (unsigned __int8)(Ch1A - 97) <= 0x19u ) /*0x755*/
Ch1A -= 32; /*0x757*/
Ch1A_2 = *((_BYTE *)Str2 + IdxA); /*0x75a*/
Ch1A_1 = Ch1A_2; /*0x762*/
if ( (unsigned __int8)(Ch1A_2 - 97) <= 0x19u ) /*0x765*/
Ch1A_1 = Ch1A_2 - 32; /*0x767*/
if ( Ch1A != Ch1A_1 ) /*0x76c*/
break; /*0x76c*/
IdxA = ++CharIdxA; /*0x774*/
if ( CharIdxA >= CharIdxA_1 ) /*0x779*/
return 1; /*0x779*/
}
return 0; /*0x76c*/
}
}
return 1; /*0x77d*/
}
// Function: ReadBlocks @ 0x782 (0x114 bytes)
// Index: 13/77
int __fastcall ReadBlocks(int a1, int a2, __int64 a3, unsigned int BufSize, unsigned int DstBuffer)
{
unsigned __int64 AbsBlockAddr; // kr00_8
unsigned __int64 AlignedBlockAddr; // rax
int ByteOffset; // esi
int BlockAddrHi; // ebp
int AlignedBlockAddr_1; // ebx
int PageCount; // edx
int result; // eax
int CacheBufAddr; // ecx
int IoStatus; // edi
unsigned int ReadSize; // [esp+14h] [ebp-Ch]
int CacheBufAddr_1; // [esp+18h] [ebp-8h] BYREF
int AllocSize; // [esp+24h] [ebp+4h]
AbsBlockAddr = *(_QWORD *)(a2 + 21) + a3; /*0x79a*/
if ( *(_DWORD *)a2 == 4096 ) /*0x7a5*/
{
AlignedBlockAddr = RShiftU64(AbsBlockAddr); /*0x7a9*/
ByteOffset = AbsBlockAddr & 0xFFF; /*0x7ae*/
}
else if ( *(_DWORD *)a2 == 2048 ) /*0x7bc*/
{
AlignedBlockAddr = RShiftU64(AbsBlockAddr); /*0x7c0*/
ByteOffset = AbsBlockAddr & 0x7FF; /*0x7c5*/
}
else
{
AlignedBlockAddr = RShiftU64(AbsBlockAddr); /*0x7cf*/
ByteOffset = AbsBlockAddr & 0x1FF; /*0x7d4*/
}
BlockAddrHi = HIDWORD(AlignedBlockAddr); /*0x7da*/
AlignedBlockAddr_1 = AlignedBlockAddr; /*0x7dc*/
ReadSize = *(_DWORD *)a2 * ((BufSize - 1 + *(_DWORD *)a2 + ByteOffset) / *(_DWORD *)a2); /*0x7f5*/
PageCount = (ReadSize >> 12) /*0x80a*/
+ (((*(_WORD *)a2 * (unsigned __int16)((BufSize - 1 + *(_DWORD *)a2 + ByteOffset) / *(_DWORD *)a2)) & 0xFFF) != 0);
AllocSize = PageCount << 12; /*0x811*/
if ( ::AllocSize >= (unsigned int)(PageCount << 12) ) /*0x81b*/
{
CacheBufAddr = ::CacheBufAddr; /*0x84f*/
}
else
{
result = (*(int (__cdecl **)(int, int, int, int *))(*(_DWORD *)a1 + 72))(a1, 4, PageCount, &CacheBufAddr_1); /*0x830*/
if ( result < 0 ) /*0x838*/
return result; /*0x838*/
CacheBufAddr = CacheBufAddr_1; /*0x83a*/
::CacheBufAddr = CacheBufAddr_1; /*0x842*/
::AllocSize = AllocSize; /*0x848*/
}
IoStatus = (*(int (__cdecl **)(int, _DWORD, _DWORD, int, int, unsigned int, int))(*(_DWORD *)(a2 + 4) + 8))( /*0x86a*/
a1,
*(_DWORD *)(a2 + 4),
*(_DWORD *)(a2 + 8),
AlignedBlockAddr_1,
BlockAddrHi,
ReadSize,
CacheBufAddr);
if ( IoStatus >= 0 ) /*0x871*/
CopyMemEx(DstBuffer, (char *)(ByteOffset + ::CacheBufAddr), BufSize); /*0x884*/
return IoStatus; /*0x88e*/
}
// Function: IsValidMbrPartition @ 0x896 (0x42 bytes)
// Index: 14/77
int __thiscall IsValidMbrPartition(char *this)
{
int result; // eax
unsigned __int8 n0x80; // dl
char v3; // cl
result = 0; /*0x89b*/
if ( *(_WORD *)(this + 11) <= 0x1000u ) /*0x8a1*/
{
n0x80 = *(this + 13); /*0x8a3*/
if ( n0x80 ) /*0x8a8*/
{
if ( n0x80 <= 0x80u ) /*0x8ad*/
{
if ( *((_WORD *)this + 7) ) /*0x8af*/
{
if ( *(this + 16) ) /*0x8b5*/
{
if ( *((_WORD *)this + 255) == 0xAA55 ) /*0x8c6*/
{
v3 = *this; /*0x8c8*/
if ( v3 == -21 || v3 == -23 ) /*0x8d2*/
return 1; /*0x8d6*/
}
}
}
}
}
}
return result; /*0x8d7*/
}
// Function: ReadClusterChain @ 0x8d8 (0x51 bytes)
// Index: 15/77
int __fastcall ReadClusterChain(int ClusterNum)
{
int ClusterNum_1; // esi
int CacheOffset; // edx
int result; // eax
ClusterNum_1 = ClusterNum; /*0x8d9*/
CacheOffset = *(_DWORD *)(i_0[0] + 12); /*0x8e1*/
if ( (unsigned int)(CacheOffset + ClusterNum) >= *(_DWORD *)(i_0[0] + 16) ) /*0x8ea*/
ClusterNum_1 = *(_DWORD *)(i_0[0] + 16) - CacheOffset; /*0x8ef*/
result = ReadBlocks( /*0x911*/
SystemTable,
BootSector,
*(_QWORD *)(BootSector + 29) + (unsigned int)(4 * ClusterNum_1),
*(_DWORD *)(i_0[0] + 4),
*(_DWORD *)i_0[0]);
if ( result >= 0 ) /*0x91b*/
{
*(_DWORD *)(i_0[0] + 8) = ClusterNum_1; /*0x922*/
return 0; /*0x925*/
}
return result; /*0x927*/
}
// Function: InitCache @ 0x929 (0xdd bytes)
// Index: 16/77
int __fastcall InitCache(int BlockIoHandle, int BootSector, unsigned int n0x20000)
{
int CacheStructPtr; // eax
int result; // eax
int CacheBlockSize; // ecx
int v8; // [esp+10h] [ebp-8h] BYREF
CacheStructPtr = i_0[0]; /*0x92b*/
if ( !i_0[0] ) /*0x93a*/
{
result = (*(int (__cdecl **)(int, int, int *))(*(_DWORD *)BlockIoHandle + 76))(BlockIoHandle, 20, i_0); /*0x946*/
if ( result < 0 ) /*0x94e*/
return result; /*0x94e*/
result = (*(int (__cdecl **)(int, int, int, int *))(*(_DWORD *)BlockIoHandle + 72))(BlockIoHandle, 4, 32, &v8); /*0x960*/
if ( result < 0 ) /*0x968*/
{
i_0[0] = 0; /*0x96a*/
return result; /*0x971*/
}
*(_DWORD *)i_0[0] = v8; /*0x97f*/
CacheStructPtr = i_0[0]; /*0x981*/
}
CacheBlockSize = n0x20000; /*0x98f*/
if ( n0x20000 >= 0x20000 ) /*0x993*/
CacheBlockSize = 0x4000; /*0x995*/
*(_DWORD *)(CacheStructPtr + 4) = CacheBlockSize; /*0x99a*/
ZeroMemEx(i_0[0], *(char **)i_0[0], *(_DWORD *)(i_0[0] + 4), 0); /*0x9a9*/
result = ReadBlocks( /*0x9c5*/
BlockIoHandle,
BootSector,
*(_QWORD *)(BootSector + 29),
*(_DWORD *)(i_0[0] + 4),
*(_DWORD *)i_0[0]);
if ( result >= 0 )
{
*(_DWORD *)(i_0[0] + 8) = 0; /*0x9d6*/
*(_DWORD *)(i_0[0] + 12) = n0x20000 < 0x20000 ? -1 : 4096;
*(_DWORD *)(i_0[0] + 16) = n0x20000 >> 2; /*0x9fa*/
return 0; /*0x9fd*/
}
return result; /*0x9ff*/
}
// Function: WalkClusterChain @ 0xa06 (0x15d bytes)
// Index: 17/77
int __fastcall WalkClusterChain(char FatType, unsigned int ClusterNum, char **p_i, char SequentialOnly)
{
unsigned int ClusterNum_1; // ebx
int ClusterCount; // esi
unsigned int ClusterNum_2; // ecx
_DWORD *FatTablePtr; // edx
_DWORD *i; // edx
unsigned int FatEntryVal; // ecx
ClusterNum_1 = ClusterNum; /*0xa0c*/
ClusterCount = 0; /*0xa0e*/
switch ( FatType ) /*0xa14*/
{
case 1: /*0xa14*/
ClusterCount = 1; /*0xa1b*/
ClusterNum_2 = *(unsigned __int16 *)(*(_DWORD *)i_0[0] + 2 * ClusterNum); /*0xa1e*/
if ( ClusterNum_2 <= 0xFFF7 ) /*0xa28*/
{
while ( ClusterNum_2 == ClusterNum_1 + 1 || !SequentialOnly ) /*0xa37*/
{
ClusterNum_1 = ClusterNum_2; /*0xa39*/
++ClusterCount; /*0xa3b*/
ClusterNum_2 = *(unsigned __int16 *)(*(_DWORD *)i_0[0] + 2 * ClusterNum_2); /*0xa3c*/
if ( ClusterNum_2 > 0xFFF7 ) /*0xa46*/
goto LABEL_6; /*0xa46*/
}
LABEL_17:
*p_i = (char *)ClusterNum_2; /*0xaa9*/
return ClusterCount; /*0xaaf*/
}
LABEL_6:
*p_i = 0; /*0xa48*/
return ClusterCount; /*0xa4e*/
case 2: /*0xa14*/
for ( FatTablePtr = (_DWORD *)i_0[0]; /*0xa58*/
;
ClusterNum_1 = *(_DWORD *)(*FatTablePtr + 4 * (ClusterNum_1 - FatTablePtr[2])) & 0xFFFFFFF )
{
++ClusterCount; /*0xa5e*/
if ( ClusterNum_1 < FatTablePtr[2] || ClusterNum_1 >= FatTablePtr[2] + FatTablePtr[3] ) /*0xa6c*/
{
if ( ReadClusterChain(ClusterNum_1) < 0 ) /*0xa77*/
return 0; /*0xa77*/
FatTablePtr = (_DWORD *)i_0[0]; /*0xa79*/
}
ClusterNum_2 = *(_DWORD *)(*FatTablePtr + 4 * (ClusterNum_1 - FatTablePtr[2])) & 0xFFFFFFF; /*0xa89*/
if ( ClusterNum_2 > 0xFFFFFF7 ) /*0xa95*/
break; /*0xa95*/
if ( ClusterNum_2 != ClusterNum_1 + 1 && SequentialOnly ) /*0xaa3*/
goto LABEL_17; /*0xaa3*/
}
goto LABEL_6; /*0xa95*/
case 5: /*0xa14*/
for ( i = (_DWORD *)i_0[0]; ; ClusterNum_1 = *(_DWORD *)(*i + 4 * (ClusterNum_1 - i[2])) ) /*0xac0*/
{
++ClusterCount; /*0xac6*/
if ( ClusterNum_1 < i[2] || ClusterNum_1 >= i[2] + i[3] ) /*0xad4*/
{
if ( ReadClusterChain(ClusterNum_1) < 0 ) /*0xadf*/
return 0; /*0xab6*/
i = (_DWORD *)i_0[0]; /*0xae1*/
}
ClusterNum_2 = *(_DWORD *)(*i + 4 * (ClusterNum_1 - i[2])); /*0xaee*/
if ( ClusterNum_2 > 0xFFFFFFF7 || !ClusterNum_2 ) /*0xafc*/
goto LABEL_6; /*0xafc*/
if ( ClusterNum_2 != ClusterNum_1 + 1 && SequentialOnly ) /*0xb0e*/
goto LABEL_17; /*0xb0e*/
}
break;
}
while ( 1 )
{
++ClusterCount; /*0xb21*/
FatEntryVal = *(unsigned __int16 *)(*(_DWORD *)i_0[0] + (ClusterNum_1 >> 1) + ClusterNum_1); /*0xb26*/
ClusterNum_2 = (ClusterNum_1 & 1) != 0 ? FatEntryVal >> 4 : FatEntryVal & 0xFFF;
if ( ClusterNum_2 > 0xFF7 ) /*0xb40*/
break; /*0xb40*/
if ( ClusterNum_2 != ClusterNum_1 + 1 && SequentialOnly ) /*0xb4b*/
goto LABEL_17; /*0xb4b*/
ClusterNum_1 = ClusterNum_2; /*0xb51*/
}
*p_i = 0; /*0xb59*/
return ClusterCount; /*0xb5d*/
}
// Function: ReadFileData @ 0xb63 (0x8a bytes)
// Index: 18/77
int __fastcall ReadFileData(
int BlockIoHandle,
int BootSector,
char *StartCluster,
unsigned int BytesRemaining,
unsigned int DstBuffer)
{
char *StartCluster_1; // ebx
int BootSector_1; // eax
unsigned int DstBuffer_1; // ebp
unsigned int i; // esi
unsigned int i_1; // edi
int ClusterChainLen; // eax
__int64 BlockOffset; // rax
int result; // eax
StartCluster_1 = StartCluster; /*0xb66*/
BootSector_1 = BootSector; /*0xb6a*/
DstBuffer_1 = DstBuffer; /*0xb6d*/
for ( i = BytesRemaining; ; i -= i_1 ) /*0xb72*/
{
i_1 = i; /*0xb8b*/
ClusterChainLen = WalkClusterChain(*(_BYTE *)(BootSector_1 + 12), (unsigned int)StartCluster_1, &StartCluster, 1); /*0xb8d*/
if ( i > ClusterChainLen * *(_DWORD *)(BootSector + 53) ) /*0xba2*/
i_1 = ClusterChainLen * *(_DWORD *)(BootSector + 53); /*0xba4*/
BlockOffset = MultU64x32((unsigned int)(StartCluster_1 - 2)); /*0xbae*/
result = ReadBlocks(BlockIoHandle, BootSector, *(_QWORD *)(BootSector + 45) + BlockOffset, i_1, DstBuffer_1); /*0xbc8*/
if ( result < 0 ) /*0xbd2*/
break; /*0xbd2*/
StartCluster_1 = StartCluster; /*0xbd4*/
if ( !StartCluster ) /*0xbda*/
break; /*0xbda*/
BootSector_1 = BootSector; /*0xbdc*/
DstBuffer_1 += i_1; /*0xbe0*/
}
return result; /*0xbe6*/
}
// Function: ParseNtfsBootSector @ 0xbed (0x1bf bytes)
// Index: 19/77
int __fastcall ParseNtfsBootSector(char *Buffer, int BootSector, unsigned int NtfsVbr)
{
unsigned int NtfsVbr_1; // edi
unsigned int NtfsVbr_2; // ecx
int BytesPerSectorVal; // ebp
int TotalSectorsVal; // eax
int MftZoneSectors; // eax
int MftStartLba; // esi
unsigned int MftByteSize; // ebp
__int64 MftOffset; // rax
unsigned int DataOffset; // ecx
bool v13; // cf
char ClusterFactorVal; // al
char *CacheBufPtr; // esi
int Status; // eax
int i; // eax
char *AllocBufSize; // ecx
int TotalSectorsVal_1; // [esp+10h] [ebp-10h]
unsigned int ClustersPerMftRec; // [esp+10h] [ebp-10h]
int CacheByteSize; // [esp+14h] [ebp-Ch]
char *AllocBufPtr; // [esp+18h] [ebp-8h] BYREF
NtfsVbr_1 = NtfsVbr; /*0xbf4*/
AllocBufPtr = Buffer; /*0xbfa*/
if ( *(_WORD *)(NtfsVbr + 22) ) /*0xbfe*/
NtfsVbr_2 = *(unsigned __int16 *)(NtfsVbr + 22); /*0xc07*/
else
NtfsVbr_2 = *(_DWORD *)(NtfsVbr + 36); /*0xc0f*/
NtfsVbr = NtfsVbr_2; /*0xc09*/
BytesPerSectorVal = *(unsigned __int16 *)(NtfsVbr_1 + 11); /*0xc16*/
CacheByteSize = NtfsVbr_2 * BytesPerSectorVal; /*0xc1f*/
TotalSectorsVal = *(unsigned __int16 *)(NtfsVbr_1 + 19); /*0xc23*/
if ( !(_WORD)TotalSectorsVal ) /*0xc2a*/
TotalSectorsVal = *(_DWORD *)(NtfsVbr_1 + 32); /*0xc2c*/
TotalSectorsVal_1 = TotalSectorsVal; /*0xc2f*/
MftZoneSectors = (BytesPerSectorVal + 32 * *(unsigned __int16 *)(NtfsVbr_1 + 17) - 1) / BytesPerSectorVal; /*0xc47*/
MftStartLba = *(unsigned __int16 *)(NtfsVbr_1 + 14); /*0xc49*/
MftByteSize = MftZoneSectors * BytesPerSectorVal; /*0xc53*/
ClustersPerMftRec = (TotalSectorsVal_1 - NtfsVbr * *(unsigned __int8 *)(NtfsVbr_1 + 16) - MftStartLba - MftZoneSectors) /*0xc64*/
/ *(unsigned __int8 *)(NtfsVbr_1 + 13);
MftOffset = MftStartLba * *(unsigned __int16 *)(NtfsVbr_1 + 11); /*0xc6f*/
*(_QWORD *)(BootSector + 29) = MftOffset; /*0xc70*/
DataOffset = NtfsVbr * *(unsigned __int16 *)(NtfsVbr_1 + 11) * *(unsigned __int8 *)(NtfsVbr_1 + 16); /*0xc83*/
v13 = __CFADD__(*(_DWORD *)(BootSector + 29), DataOffset); /*0xc88*/
*(_DWORD *)(BootSector + 37) = *(_DWORD *)(BootSector + 29) + DataOffset; /*0xc8b*/
*(_DWORD *)(BootSector + 41) = HIDWORD(MftOffset) + v13; /*0xc92*/
v13 = __CFADD__(*(_DWORD *)(BootSector + 37), MftByteSize); /*0xc97*/
*(_DWORD *)(BootSector + 45) = *(_DWORD *)(BootSector + 37) + MftByteSize; /*0xc9a*/
*(_DWORD *)(BootSector + 49) = *(_DWORD *)(BootSector + 41) + v13; /*0xca0*/
*(_DWORD *)(BootSector + 53) = *(unsigned __int16 *)(NtfsVbr_1 + 11) * *(unsigned __int8 *)(NtfsVbr_1 + 13); /*0xcb2*/
if ( ClustersPerMftRec < 0xFFF5 ) /*0xcba*/
ClusterFactorVal = ClustersPerMftRec >= 0xFF5; /*0xcc8*/
else
ClusterFactorVal = 2; /*0xcbe*/
CacheBufPtr = AllocBufPtr; /*0xcc9*/
*(_BYTE *)(BootSector + 12) = ClusterFactorVal; /*0xcd3*/
Index = *(unsigned __int16 *)(NtfsVbr_1 + 17); /*0xcdc*/
Status = InitCache((int)CacheBufPtr, BootSector, CacheByteSize); /*0xce1*/
if ( Status >= 0 ) /*0xce9*/
{
if ( !MftByteSize ) /*0xcf1*/
{
MftByteSize = WalkClusterChain(2, *(_DWORD *)(NtfsVbr_1 + 44), (char **)&NtfsVbr, 0) /*0xd06*/
* *(_DWORD *)(BootSector + 53);
Index = MftByteSize >> 5; /*0xd10*/
}
i = i_1; /*0xd2a*/
NtfsVbr = ((MftByteSize >> 12) + ((MftByteSize & 0xFFF) != 0)) << 12; /*0xd34*/
if ( i_1 >= NtfsVbr ) /*0xd3a*/
{
AllocBufSize = i; /*0xd66*/
}
else
{
Status = (*(int (__cdecl **)(char *, int, unsigned int, char **))(*(_DWORD *)CacheBufPtr + 72))( /*0xd47*/
CacheBufPtr,
4,
(MftByteSize >> 12) + ((MftByteSize & 0xFFF) != 0),
&AllocBufPtr);
if ( Status < 0 ) /*0xd4f*/
return Status; /*0xd4f*/
AllocBufSize = AllocBufPtr; /*0xd51*/
i = NtfsVbr; /*0xd55*/
i = AllocBufPtr; /*0xd59*/
i_1 = NtfsVbr; /*0xd5f*/
}
ZeroMemEx(i, AllocBufSize, i, 0); /*0xd70*/
if ( *(_BYTE *)(BootSector + 12) == 2 ) /*0xd87*/
return ReadFileData((int)CacheBufPtr, BootSector, *(char **)(NtfsVbr_1 + 44), MftByteSize, (unsigned int)i); /*0xd8c*/
else
return ReadBlocks((int)CacheBufPtr, BootSector, *(_QWORD *)(BootSector + 37), MftByteSize, (unsigned int)i); /*0xd9c*/
}
return Status; /*0xda4*/
}
// Function: MountNtfsVolume @ 0xdac (0xcf bytes)
// Index: 20/77
int __fastcall MountNtfsVolume(char *BlockIoHandle, int BootSector, unsigned int *a3, unsigned int DstBuffer)
{
int FileIdx; // esi
int result; // eax
unsigned int VbrBufPtr; // edi
unsigned int NumFoundFiles; // edi
int v10; // eax
unsigned int EntrySize; // edx
unsigned int NumFoundFiles_1; // [esp+14h] [ebp-8h] BYREF
int BlockIoHandle_1; // [esp+18h] [ebp-4h]
FileIdx = 0; /*0xdbd*/
BlockIoHandle_1 = (int)BlockIoHandle; /*0xdcb*/
result = ReadBlocks((int)BlockIoHandle, BootSector, 0, 0x200u, DataPtr + 512); /*0xdcf*/
if ( result >= 0 ) /*0xdd9*/
{
VbrBufPtr = DataPtr + 512; /*0xde5*/
if ( !(unsigned __int8)IsValidMbrPartition((char *)(DataPtr + 512)) ) /*0xded*/
return -2147483634; /*0xded*/
::BootSector = BootSector; /*0xdf9*/
result = ParseNtfsBootSector(BlockIoHandle, BootSector, VbrBufPtr); /*0xe01*/
if ( result < 0 ) /*0xe09*/
return result; /*0xe09*/
LocateRecoveryInDir((int *)&NumFoundFiles_1); /*0xe11*/
NumFoundFiles = NumFoundFiles_1; /*0xe16*/
if ( NumFoundFiles_1 ) /*0xe1e*/
{
while ( 1 ) /*0xe24*/
{
v10 = dword_4F80[FileIdx]; /*0xe24*/
EntrySize = *(_DWORD *)(v10 + 28); /*0xe2b*/
if ( *a3 >= EntrySize /*0xe56*/
&& ReadFileData(
BlockIoHandle_1,
BootSector,
(char *)(*(unsigned __int16 *)(v10 + 26) + (*(unsigned __int16 *)(v10 + 20) << 16)),
EntrySize,
DstBuffer) >= 0 )
{
break; /*0xe56*/
}
if ( ++FileIdx >= NumFoundFiles ) /*0xe5b*/
return -2147483634; /*0xe5b*/
}
*a3 = *(_DWORD *)(dword_4F80[FileIdx] + 28); /*0xe74*/
return 0; /*0xe77*/
}
else
{
return -2147483634; /*0xe5d*/
}
}
return result; /*0xe62*/
}
// Function: MountVolume @ 0xe7b (0xd0 bytes)
// Index: 21/77
int __cdecl MountVolume(char *BlockIoHandle, int p_n4, unsigned int *a3, unsigned int ia)
{
int result; // eax
int PartResult; // ebx
bool IsSuccess; // zf
*(_DWORD *)(p_n4 + 21) = 0; /*0xe93*/
*(_DWORD *)(p_n4 + 25) = 0; /*0xe96*/
result = MountNtfsVolume(BlockIoHandle, p_n4, a3, ia); /*0xe99*/
if ( result < 0 ) /*0xea2*/
{
result = ReadBlocks((int)BlockIoHandle, p_n4, 0, 0x200u, DataPtr); /*0xeba*/
if ( result >= 0 ) /*0xec4*/
{
if ( *(_WORD *)(DataPtr + 510) == 0xAA55 ) /*0xed7*/
{
n4 = 0; /*0xed9*/
LbaOffset = 0; /*0xedf*/
dword_4D08 = 0; /*0xee5*/
ExtendFlag = 1; /*0xeeb*/
do /*0xefc*/
{
PartResult = ParsePartitionEntry((int)BlockIoHandle, p_n4); /*0xefc*/
IsSuccess = PartResult == 0; /*0xefe*/
if ( PartResult >= 0 ) /*0xf00*/
{
if ( byte_4BE8 && (!byte_4BCC || MatchFlag) ) /*0xf1b*/
{
result = MountNtfsVolume(BlockIoHandle, p_n4, a3, ia); /*0xf28*/
if ( result >= 0 ) /*0xf31*/
{
byte_4BE8 = 0; /*0xf42*/
return result; /*0xf42*/
}
}
IsSuccess = PartResult == 0; /*0xf33*/
}
}
while ( IsSuccess ); /*0xefc*/
}
return -2147483634; /*0xf37*/
}
}
return result; /*0xf3c*/
}
// Function: ParseFatBootSector @ 0xf4b (0x168 bytes)
// Index: 22/77
int __fastcall ParseFatBootSector(int BlockIoPtr, int *p_n4, unsigned int *a3, unsigned int dst)
{
int v6; // eax
int result; // eax
unsigned int VolumeSize_1; // edi
int i; // eax
unsigned int i_1; // esi
char *BlockIoHandle; // ecx
unsigned int NumEntries; // edi
int EntryIdx; // esi
int EntryAddr; // eax
unsigned int SectorSize; // ecx
unsigned int n4; // [esp-8h] [ebp-82Ch]
int NumEntries_1; // [esp+10h] [ebp-814h] BYREF
int BlockIoPtr_1; // [esp+14h] [ebp-810h]
char *TmpBufPtr; // [esp+18h] [ebp-80Ch] BYREF
_BYTE dst_1[158]; // [esp+20h] [ebp-804h] BYREF
int v21; // [esp+BEh] [ebp-766h]
unsigned int VolumeSize; // [esp+C6h] [ebp-75Eh]
BlockIoPtr_1 = BlockIoPtr; /*0xf5d*/
n4 = *p_n4; /*0xf66*/
v6 = 16 * *p_n4; /*0xf68*/
*(int *)((char *)p_n4 + 21) = 0; /*0xf6d*/
*(int *)((char *)p_n4 + 25) = 0; /*0xf70*/
result = ReadBlocks(BlockIoPtr, (int)p_n4, (unsigned int)v6, n4, (unsigned int)dst_1); /*0xf76*/
if ( result < 0 ) /*0xf80*/
return result; /*0xf80*/
if ( dst_1[0] != 1 || AsciiStrCmp(&dst_1[1], "CD001", 5) ) /*0xf9c*/
return -2147483634; /*0xfa4*/
VolumeSize_1 = VolumeSize; /*0xfaa*/
i = i_1; /*0xfc6*/
i_1 = ((VolumeSize >> 12) + ((VolumeSize & 0xFFF) != 0)) << 12; /*0xfcd*/
if ( i_1 >= i_1 ) /*0xfd2*/
{
BlockIoHandle = i; /*0x1001*/
}
else
{
result = (*(int (__cdecl **)(int, int, unsigned int, char **))(*(_DWORD *)BlockIoPtr + 72))( /*0xfe0*/
BlockIoPtr,
4,
(VolumeSize >> 12) + ((VolumeSize & 0xFFF) != 0),
&TmpBufPtr);
if ( result < 0 ) /*0xfe8*/
return result; /*0xfe8*/
BlockIoHandle = TmpBufPtr; /*0xfee*/
i = i_1; /*0xff2*/
i = TmpBufPtr; /*0xff4*/
i_1 = i_1; /*0xffa*/
}
ZeroMemEx(i, BlockIoHandle, i, 0); /*0x100b*/
result = ReadBlocks(BlockIoPtr, (int)p_n4, (unsigned int)(v21 * *p_n4), VolumeSize_1, (unsigned int)i); /*0x102b*/
if ( result >= 0 ) /*0x1035*/
{
ParseVolumeLabelEntries(VolumeSize_1, &NumEntries_1); /*0x103f*/
NumEntries = NumEntries_1; /*0x1044*/
if ( NumEntries_1 ) /*0x104c*/
{
EntryIdx = 0; /*0x104e*/
while ( 1 ) /*0x105b*/
{
EntryAddr = dword_4CE0[EntryIdx]; /*0x105b*/
SectorSize = *(_DWORD *)(EntryAddr + 10); /*0x1062*/
if ( *a3 >= SectorSize /*0x108b*/
&& ReadBlocks(BlockIoPtr_1, (int)p_n4, (unsigned int)(*p_n4 * *(_DWORD *)(EntryAddr + 2)), SectorSize, dst) >= 0 )
{
break; /*0x108b*/
}
if ( ++EntryIdx >= NumEntries ) /*0x1090*/
return -2147483634; /*0x1090*/
}
*a3 = *(_DWORD *)(dword_4CE0[EntryIdx] + 10); /*0x10ac*/
return 0; /*0x10af*/
}
return -2147483634; /*0x1092*/
}
return result; /*0x1097*/
}
// Function: MountFatVolume @ 0x10b3 (0xe5 bytes)
// Index: 23/77
int __cdecl MountFatVolume(char *BlockIoHandle, int *p_n4, unsigned int *a3, unsigned int dst)
{
int result; // eax
int BootEntryOff; // eax
char dst_; // [esp+8h] [ebp-800h] BYREF
_BYTE v7[6]; // [esp+9h] [ebp-7FFh] BYREF
_BYTE v8[33]; // [esp+Fh] [ebp-7F9h] BYREF
int BootCatSector; // [esp+30h] [ebp-7D8h]
int VoldescSector; // [esp+4Fh] [ebp-7B9h]
if ( *p_n4 != 2048 ) /*0x10c9*/
return -2147483645; /*0x118e*/
result = ParseFatBootSector((int)BlockIoHandle, p_n4, a3, dst); /*0x10da*/
if ( result < 0 ) /*0x10e3*/
{
result = ReadBlocks((int)BlockIoHandle, (int)p_n4, (unsigned int)(17 * *p_n4), *p_n4, (unsigned int)&dst_); /*0x10fc*/
if ( result >= 0 ) /*0x1106*/
{
if ( dst_ || AsciiStrCmp(v7, "CD001", 5) || v7[5] != 1 || AsciiStrCmp(v8, "EL TORITO SPECIFICATION", 23) ) /*0x113a*/
{
return -2147483634; /*0x1187*/
}
else
{
result = ReadBlocks( /*0x1159*/
(int)BlockIoHandle,
(int)p_n4,
(unsigned int)(VoldescSector * *p_n4),
*p_n4,
(unsigned int)&dst_);
if ( result >= 0 ) /*0x1163*/
{
BootEntryOff = BootCatSector * *p_n4; /*0x116d*/
*(int *)((char *)p_n4 + 25) = 0; /*0x1172*/
*(int *)((char *)p_n4 + 21) = BootEntryOff; /*0x117a*/
return MountVolume(BlockIoHandle, (int)p_n4, a3, dst); /*0x117d*/
}
}
}
}
return result; /*0x1193*/
}
// Function: FsRecoveryEntry @ 0x1198 (0xe3 bytes)
// Index: 24/77
int __fastcall FsRecoveryEntry(int *BlockIoHandle, int PartitionIdx, int a3, unsigned int *p_ImageSize, int dst)
{
int result; // eax
int SystemTable; // eax
int AllocStatus; // ecx
int MountIdx; // esi
int (__cdecl **MountFuncPtr)(int, int *, unsigned int *, int); // eax
unsigned int DataPtr; // [esp+10h] [ebp-54h] BYREF
int v13; // [esp+18h] [ebp-4Ch] BYREF
char v14; // [esp+1Ch] [ebp-48h]
int v15; // [esp+24h] [ebp-40h]
char buf[4]; // [esp+28h] [ebp-3Ch] BYREF
int v17; // [esp+2Ch] [ebp-38h]
int PartitionIdx_1; // [esp+30h] [ebp-34h]
if ( !a3 || !p_ImageSize || *p_ImageSize && !dst ) /*0x11c5*/
return -2147483646; /*0x126e*/
ZeroMemEx((int)buf, buf, 0x39u, 0); /*0x11d4*/
result = (*(int (__cdecl **)(int *, int, int, int *))(a3 + 4))(BlockIoHandle, a3, PartitionIdx, &v13); /*0x11e1*/
if ( result >= 0 ) /*0x11e9*/
{
if ( v14 /*0x122c*/
&& (*(_DWORD *)buf = v15,
dword_4F5C = v13,
SystemTable = *BlockIoHandle,
v17 = a3,
PartitionIdx_1 = PartitionIdx,
AllocStatus = (*(int (__cdecl **)(int *, int, int, unsigned int *))(SystemTable + 72))(
BlockIoHandle,
4,
1,
&DataPtr),
AllocStatus >= 0) )
{
MountIdx = 0; /*0x1232*/
DataPtr = DataPtr; /*0x1234*/
if ( MountFatVolume ) /*0x1240*/
{
MountFuncPtr = &off_4300; /*0x1242*/
do /*0x1265*/
{
AllocStatus = (*MountFuncPtr)((int)BlockIoHandle, (int *)buf, p_ImageSize, dst); /*0x1254*/
if ( !AllocStatus ) /*0x125b*/
break; /*0x125b*/
++MountIdx; /*0x125d*/
MountFuncPtr = &off_4300 + MountIdx; /*0x125e*/
}
while ( *MountFuncPtr ); /*0x1265*/
}
return AllocStatus; /*0x126a*/
}
else
{
return -2147483634; /*0x11f6*/
}
}
return result; /*0x1273*/
}
// Function: GetRecoveryImageConfig @ 0x127b (0xcf bytes)
// Index: 25/77
int __fastcall GetRecoveryImageConfig(int ecx0, _DWORD *a2, _DWORD *a3, _BYTE *a4)
{
int DriverImageHandle; // eax
int result; // eax
int (__cdecl **v8)(_DWORD, __int16 *, void *, _DWORD, int *, void *); // [esp+Ch] [ebp-8h] BYREF
int ConfigBufSize; // [esp+10h] [ebp-4h] BYREF
ConfigBufSize = 560; /*0x1285*/
DriverImageHandle = GetImageHandle(); /*0x128e*/
result = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int (__cdecl ***)(_DWORD, __int16 *, void *, _DWORD, int *, void *)))(*(_DWORD *)DriverImageHandle + 32))( /*0x12a3*/
DriverImageHandle,
&unk_4B00,
0,
0,
&v8);
if ( result >= 0 ) /*0x12ab*/
{
if ( (*v8)( /*0x12d1*/
v8,
aFlashupdateima, // "FlashUpdateImageName"
&unk_4B40,
0,
&ConfigBufSize,
&unk_4D20) < 0 )
{
if ( a2 ) /*0x1310*/
{
*a2 = "HR6N0.BIN"; /*0x1312*/
byte_4BE9 = 0; /*0x1318*/
}
if ( a3 ) /*0x1324*/
*a3 = 0x1000000; /*0x1326*/
if ( a4 ) /*0x1331*/
*a4 = 0; /*0x1333*/
return ValidateRecoveryParams(ecx0, a2, a3, a4); /*0x133c*/
}
else
{
if ( a2 ) /*0x12d5*/
*a2 = &unk_4D4A; /*0x12d7*/
if ( a3 ) /*0x12e2*/
*a3 = dword_4F4C; /*0x12e9*/
if ( a4 ) /*0x12f0*/
*a4 = 0; /*0x12f2*/
byte_4BE9 = 1; /*0x12f5*/
byte_4BCC = 1; /*0x12fe*/
byte_4BC0 = 1; /*0x1305*/
return 0; /*0x12fc*/
}
}
return result; /*0x1343*/
}
// Function: GetRecoveryCaps @ 0x134a (0x17 bytes)
// Index: 26/77
int __cdecl GetRecoveryCaps(int a1, int a2, _DWORD *a3)
{
if ( !a3 ) /*0x1350*/
return -2147483646; /*0x1352*/
*a3 = 1; /*0x1358*/
return 0; /*0x1357*/
}
// Function: GetRecoveryImageInfo @ 0x1361 (0x4a bytes)
// Index: 27/77
int __cdecl GetRecoveryImageInfo(int a1, int a2, int a3, _DWORD *a4, _DWORD *a5)
{
int result; // eax
if ( !a4 ) /*0x1368*/
return -2147483646; /*0x136a*/
if ( a3 ) /*0x1375*/
return -2147483634; /*0x1377*/
result = GetRecoveryImageConfig(a1, 0, a4, 0); /*0x1388*/
if ( result >= 0 ) /*0x1391*/
{
if ( a5 ) /*0x1399*/
{
*a5 = unk_4220; /*0x13a1*/
a5[1] = unk_4224; /*0x13a2*/
a5[2] = unk_4228; /*0x13a3*/
a5[3] = unk_422C; /*0x13a4*/
}
return 0; /*0x13a6*/
}
return result; /*0x136f*/
}
// Function: FindRecoveryImage @ 0x13ab (0x148 bytes)
// Index: 28/77
int __cdecl FindRecoveryImage(int *i, int a2, int a3, int dst)
{
int result; // eax
int HandleIdx; // ebx
int PartitionIdx; // edi
unsigned int RetryCount; // ebx
int RecoveryResult; // eax
unsigned int ImageSize; // ebp
int TmpResult; // [esp-10h] [ebp-34h]
char v11; // [esp+7h] [ebp-1Dh] BYREF
unsigned int ImageSize_1; // [esp+8h] [ebp-1Ch] BYREF
int (__cdecl **v13)(int *, _DWORD, unsigned int *); // [esp+Ch] [ebp-18h] BYREF
unsigned __int16 *v14; // [esp+10h] [ebp-14h] BYREF
unsigned int ImageSize_2; // [esp+14h] [ebp-10h] BYREF
unsigned int NumPartitions; // [esp+18h] [ebp-Ch] BYREF
int HandleIdx_1; // [esp+1Ch] [ebp-8h]
_BYTE v18[4]; // [esp+20h] [ebp-4h] BYREF
DebugLogPrint(-1, (int)i, "..BLOCK DEVICE.."); /*0x13bb*/
if ( !dst ) /*0x13c8*/
return -2147483646; /*0x13ca*/
if ( a3 ) /*0x13d9*/
return -2147483634; /*0x13db*/
result = GetRecoveryImageConfig((int)i, 0, &ImageSize_2, &v11); /*0x13f3*/
if ( result >= 0 ) /*0x13fc*/
{
result = (*(int (__cdecl **)(int *, void *, _DWORD, _BYTE *, int (__cdecl ***)(int *, _DWORD, unsigned int *)))(*i + 32))( /*0x1419*/
i,
&unk_4B20,
0,
v18,
&v13);
for ( HandleIdx = 1; ; ++HandleIdx ) /*0x1421*/
{
HandleIdx_1 = HandleIdx; /*0x14db*/
if ( result < 0 ) /*0x14e1*/
break; /*0x14e1*/
if ( (*v13)(i, v13, &NumPartitions) >= 0 && NumPartitions ) /*0x1444*/
{
PartitionIdx = 0; /*0x1446*/
while ( 2 ) /*0x1448*/
{
RetryCount = 0; /*0x1448*/
ImageSize_1 = ImageSize_2; /*0x144e*/
do /*0x14b4*/
{
RecoveryResult = FsRecoveryEntry(i, PartitionIdx, (int)v13, &ImageSize_1, dst); /*0x1463*/
if ( RecoveryResult == -2147483646 ) /*0x1470*/
break; /*0x1470*/
if ( RecoveryResult >= 0 ) /*0x1474*/
{
ImageSize = ImageSize_1; /*0x147c*/
if ( (*(int (__cdecl **)(int *, unsigned __int16 **))(*i + 48))(i, &v14) < 0 /*0x1496*/
|| FindBootEntry(TmpResult, &v14) >= 0 )
{
*(_DWORD *)((char *)v14 + 37) = ImageSize; /*0x149c*/
}
if ( v11 || ImageSize_1 == ImageSize_2 ) /*0x14ae*/
return 0; /*0x14e9*/
}
++RetryCount; /*0x14b0*/
}
while ( RetryCount < 3 ); /*0x14b4*/
if ( ++PartitionIdx <= NumPartitions ) /*0x14bb*/
continue; /*0x14bb*/
break;
}
HandleIdx = HandleIdx_1; /*0x14bd*/
}
result = (*(int (__cdecl **)(int *, void *, int, _BYTE *, int (__cdecl ***)(int *, _DWORD, unsigned int *)))(*i + 32))( /*0x14d4*/
i,
&unk_4B20,
HandleIdx,
v18,
&v13);
}
}
return result; /*0x14ee*/
}
// Function: ParseVolumeLabelEntries @ 0x14f3 (0x90 bytes)
// Index: 29/77
char __usercall ParseVolumeLabelEntries@<al>(unsigned int TotalSize@<edx>, int *p_NumEntries)
{
int SystemTable; // ecx
char *VolumeLabelEntry; // esi
unsigned int TotalSize_1; // ebx
int *p_NumEntries_1; // edi
int RecoveryImageConfig; // eax
char *NextEntry; // ecx
unsigned int SemicolonOff; // edx
int NumEntries; // eax
int SemicolonOff_1; // [esp-8h] [ebp-1Ch]
char *v13; // [esp+10h] [ebp-4h] BYREF
SystemTable = SystemTable; /*0x14f4*/
VolumeLabelEntry = i; /*0x1501*/
TotalSize_1 = 0; /*0x1507*/
p_NumEntries_1 = p_NumEntries; /*0x150a*/
*p_NumEntries = 0; /*0x1516*/
RecoveryImageConfig = GetRecoveryImageConfig(SystemTable, &v13, &p_NumEntries, 0); /*0x1518*/
if ( RecoveryImageConfig >= 0 && TotalSize ) /*0x1525*/
{
do /*0x1527*/
{
LOBYTE(RecoveryImageConfig) = *VolumeLabelEntry; /*0x1527*/
NextEntry = VolumeLabelEntry + 33; /*0x1529*/
LOBYTE(p_NumEntries) = RecoveryImageConfig; /*0x152c*/
if ( !(_BYTE)RecoveryImageConfig ) /*0x1532*/
break; /*0x1532*/
SemicolonOff = 0; /*0x1534*/
if ( *NextEntry != 59 ) /*0x1539*/
{
do /*0x1548*/
{
if ( SemicolonOff >= (unsigned __int8)VolumeLabelEntry[32] ) /*0x1541*/
break; /*0x1541*/
++SemicolonOff; /*0x1543*/
}
while ( NextEntry[SemicolonOff] != 59 ); /*0x1548*/
}
if ( *v13 ) /*0x154e*/
{
SemicolonOff_1 = SemicolonOff; /*0x1554*/
LOBYTE(SemicolonOff) = 0; /*0x1555*/
if ( MatchNameWildcard(NextEntry, SemicolonOff, SemicolonOff_1, v13) >= 0 ) /*0x1560*/
{
NumEntries = *p_NumEntries_1; /*0x1571*/
dword_4CE0[NumEntries] = (int)VolumeLabelEntry; /*0x1573*/
RecoveryImageConfig = NumEntries + 1; /*0x157a*/
*p_NumEntries_1 = RecoveryImageConfig; /*0x157b*/
return RecoveryImageConfig; /*0x157b*/
}
}
LOBYTE(RecoveryImageConfig) = (_BYTE)p_NumEntries; /*0x1562*/
TotalSize_1 += (unsigned __int8)p_NumEntries; /*0x1567*/
VolumeLabelEntry += (unsigned __int8)p_NumEntries; /*0x1569*/
}
while ( TotalSize_1 < TotalSize ); /*0x1527*/
}
return RecoveryImageConfig; /*0x157d*/
}
// Function: LocateRecoveryInDir @ 0x1583 (0x395 bytes)
// Index: 30/77
char __cdecl LocateRecoveryInDir(int *FoundIndexOut)
{
int gSystemTable; // ecx
char *DirEntriesBuf; // ebp
unsigned int EntryIdx; // ebx
int *FoundIndexOut_1; // edi
char *Status; // eax
char *i; // esi
unsigned int PathLenW; // eax
int v8; // edx
int PathIdxW; // ecx
int v10; // edx
char *DirEntryPtr; // edi
_WORD *v12; // edx
unsigned int PathLenA; // eax
int PathIdxA; // ecx
unsigned int Index_1; // edi
char *DirEntriesBuf_2; // ecx
_WORD *v17; // edx
unsigned int EntryIdx2_1; // edi
int EntryOffset; // edi
unsigned int ClusterSize; // esi
int StartCluster; // ecx
int CaseSensitive_1; // edx
unsigned int EntryIdx2; // eax
char *DirEntriesBuf_3; // ecx
int FoundIdx; // eax
unsigned int EntryWithExt; // ecx
int CaseSensitive; // edx
unsigned int TotalEntries; // esi
int OutIndex; // eax
char *DirEntriesBuf_1; // [esp+10h] [ebp-124h] BYREF
char *RecoveryNamePtr; // [esp+14h] [ebp-120h] BYREF
unsigned int Index; // [esp+18... [8544 chars total]
// Function: DispatchRead @ 0x1918 (0x47 bytes)
// Index: 31/77
int __cdecl DispatchRead(int a1)
{
int v1; // ecx
int v2; // edx
unsigned int gDataPtr; // ebx
int v4; // edi
int (__cdecl *v5)(int, char, int, unsigned int); // eax
int v6; // esi
char gExtendFlag; // [esp+Ch] [ebp-8h]
v2 = 0; /*0x1922*/
gDataPtr = gDataPtr; /*0x1925*/
gExtendFlag = gExtendFlag; /*0x192d*/
v4 = v1; /*0x1930*/
v5 = (int (__cdecl *)(int, char, int, unsigned int))dword_4BD4; /*0x1932*/
v6 = 0; /*0x1937*/
while ( v5 ) /*0x1954*/
{
v2 = v5(v4, gExtendFlag, a1, gDataPtr); /*0x1948*/
v5 = (int (__cdecl *)(int, char, int, unsigned int))gCacheStruct[v6++]; /*0x194a*/
}
return v2; /*0x1956*/
}
// Function: ParsePartitionEntry @ 0x195f (0x2f7 bytes)
// Index: 32/77
int __fastcall ParsePartitionEntry(int BlockIo, int PartitionInfo)
{
char HasExtendedParts; // al
unsigned int PartIdx; // edx
char PartitionType; // ch
int LbaStartOffset; // ecx
__int64 TempStart; // rax
int Status; // eax
int EntryOffset; // eax
__int64 TempBlock; // rax
bool IsBootable; // zf
__int64 TempRead; // rax
int GptSlotIdx; // edi
__int64 v15; // rax
unsigned int GptEntryPtr; // edi
__int64 SizeResult; // rax
int *ComparePtr; // edx
char IsMatchingPart; // cl
unsigned int OffsetValue; // edi
int CmpLen; // esi
__int64 TempSize; // rax
int n4; // ecx
unsigned int BlockBufPtr; // [esp-Ch] [ebp-20h]
unsigned int DataPtr; // [esp-Ch] [ebp-20h]
HasExtendedParts = ExtendFlag; /*0x1960*/
PartIdx = n4; /*0x196c*/
if ( ExtendFlag ) /*0x1977*/
{
if ( (unsigned int)n4 < 4 ) /*0x1980*/
{
while ( 1 ) /*0x1990*/
{
PartitionType = *(_BYTE *)(DataPtr + 16 * PartIdx + 450); /*0x1990*/
if ( PartitionType == -18 ) /*0x199a*/
break; /*0x199a*/
if ( byte_4BCC ) /*0x19a7*/
MatchFlag = *(_DWORD *)(DataPtr + 440) == dword_4D38 && n2 == 1; /*0x19cb*/
if ( PartitionType == 5 || PartitionType == 15 ) /*0x19d8*/
{
LbaStartOffset = *(_DWORD *)(DataPtr + 16 * PartIdx + 454); /*0x19df*/
if ( dword_4D08 ) /*0x19e8*/
LbaStartOffset += dword_4D08; /*0x19f2*/
else
dword_4D08 = *(_DWORD *)(DataPtr + 16 * PartIdx + 454); /*0x19ea*/
LbaOffset = LbaStartOffset; /*0x19f6*/
TempStart = MultU64x32(512); /*0x1a02*/
BlockBufPtr = DataPtr; /*0x1a07*/
*(_QWORD *)(PartitionInfo + 21) = TempStart; /*0x1a1b*/
Status = ReadBlocks(BlockIo, PartitionInfo, 0, 0x200u, BlockBufPtr); /*0x1a1e*/
if ( Status < 0 ) /*0x1a28*/
return Status; /*0x1a28*/
PartIdx = 0; /*0x1a2e*/
n4 = 0; /*0x1a30*/
}
EntryOffset = 16 * PartIdx; /*0x1a42*/
if ( *(_BYTE *)(16 * PartIdx + DataPtr + 450) /*0x1a58*/
&& *(_DWORD *)(EntryOffset + DataPtr + 458)
&& *(_DWORD *)(EntryOffset + DataPtr + 454) )
{
TempSize = MultU64x32(512); /*0x1bfd*/
n4 = n4 + 1; /*0x1c08*/
*(_QWORD *)(PartitionInfo + 21) = TempSize; /*0x1c09*/
n4 = n4; /*0x1c12*/
goto LABEL_39; /*0x1c12*/
}
n4 = ++PartIdx; /*0x1a66*/
if ( PartIdx >= 4 ) /*0x1a6f*/
{
HasExtendedParts = ExtendFlag; /*0x1a75*/
goto LABEL_18; /*0x1a75*/
}
}
ExtendFlag = 0; /*0x1c3a*/
n4 = 0; /*0x1c40*/
LABEL_20:
TempBlock = MultU64x32(1); /*0x1a8a*/
Status = ReadBlocks(BlockIo, PartitionInfo, TempBlock, 0x200u, DataPtr); /*0x1aa5*/
if ( Status < 0 ) /*0x1aaf*/
return Status; /*0x1aaf*/
if ( *(_BYTE *)DataPtr == 69 && *(_BYTE *)(DataPtr + 1) == 70 && *(_BYTE *)(DataPtr + 2) == 73 ) /*0x1ad2*/
{
IsBootable = *(_DWORD *)(DataPtr + 84) == 128; /*0x1ad8*/
n4_0 = *(_DWORD *)(DataPtr + 80); /*0x1ae2*/
if ( IsBootable ) /*0x1ae7*/
{
TempRead = MultU64x32(2); /*0x1af2*/
Status = ReadBlocks(BlockIo, PartitionInfo, TempRead, 0x200u, DataPtr); /*0x1b08*/
if ( Status < 0 ) /*0x1b12*/
return Status; /*0x1b12*/
PartIdx = n4; /*0x1b18*/
goto LABEL_27; /*0x1b18*/
}
}
return -2147483634; /*0x1c4b*/
}
LABEL_18:
if ( HasExtendedParts ) /*0x1a7c*/
return -2147483634; /*0x1a7c*/
}
if ( !PartIdx ) /*0x1a84*/
goto LABEL_20; /*0x1a84*/
LABEL_27:
if ( PartIdx >= n4_0 ) /*0x1b24*/
return -2147483634; /*0x1b24*/
GptSlotIdx = PartIdx & 3; /*0x1b2c*/
if ( (PartIdx & 3) == 0 && PartIdx ) /*0x1b33*/
{
v15 = MultU64x32((PartIdx >> 2) + 2); /*0x1b3f*/
DataPtr = DataPtr; /*0x1b44*/
*(_DWORD *)(PartitionInfo + 21) = 0; /*0x1b4c*/
*(_DWORD *)(PartitionInfo + 25) = 0; /*0x1b58*/
Status = ReadBlocks(BlockIo, PartitionInfo, v15, 0x200u, DataPtr); /*0x1b5b*/
if ( Status < 0 ) /*0x1b65*/
return Status; /*0x1b65*/
PartIdx = n4; /*0x1b6b*/
}
GptEntryPtr = DataPtr + (GptSlotIdx << 7); /*0x1b77*/
n4 = PartIdx + 1; /*0x1b7d*/
SizeResult = MultU64x32(*(_QWORD *)(GptEntryPtr + 32)); /*0x1b89*/
*(_QWORD *)(PartitionInfo + 21) = SizeResult; /*0x1b91*/
if ( !SizeResult ) /*0x1b99*/
return -2147483634; /*0x1b99*/
if ( byte_4BCC )
{
ComparePtr = &dword_4D38; /*0x1baf*/
IsMatchingPart = n2 == 2; /*0x1bbb*/
OffsetValue = GptEntryPtr - (_DWORD)&dword_4D38; /*0x1bbe*/
CmpLen = 16; /*0x1bc0*/
do
{
IsMatchingPart = *((_BYTE *)ComparePtr + OffsetValue + 16) != *(_BYTE *)ComparePtr ? 0 : IsMatchingPart;
ComparePtr = (int *)((char *)ComparePtr + 1); /*0x1bce*/
--CmpLen; /*0x1bcf*/
}
while ( CmpLen );
MatchFlag = IsMatchingPart; /*0x1bd4*/
}
LABEL_39:
if ( DispatchRead((unsigned __int8)dword_4F5C) >= 0 ) /*0x1c2b*/
byte_4BE8 = 1; /*0x1c2d*/
return 0; /*0x1c50*/
}
// Function: StrLen_Unicode @ 0x1c56 (0x80 bytes)
// Index: 33/77
unsigned int __fastcall StrLen_Unicode(_WORD *Str)
{
_WORD *Str_1; // ebx
int DebugLib; // eax
int NullCheck; // eax
unsigned int Length; // esi
int DbgAssert; // eax
Str_1 = Str; /*0x1c59*/
if ( !Str ) /*0x1c63*/
{
DebugLib = GetDebugLib(); /*0x1c65*/
if ( DebugLib ) /*0x1c6c*/
(*(void (__cdecl **)(const char *, int, const char *))(DebugLib + 4))( /*0x1c79*/
"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
172,
"String != ((void *) 0)");
}
if ( ((unsigned __int8)Str_1 & 1) != 0 ) /*0x1c82*/
{
NullCheck = GetDebugLib(); /*0x1c84*/
if ( NullCheck ) /*0x1c8b*/
(*(void (__cdecl **)(const char *, int, const char *))(NullCheck + 4))( /*0x1c98*/
"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
173,
"((UINTN) String & 0x00000001) == 0");
}
Length = 0; /*0x1ca0*/
while ( *Str_1 ) /*0x1ccd*/
{
if ( Length >= 0xF4240 ) /*0x1caa*/
{
DbgAssert = GetDebugLib(); /*0x1cac*/
if ( DbgAssert ) /*0x1cb3*/
(*(void (__cdecl **)(const char *, int, const char *))(DbgAssert + 4))( /*0x1cc0*/
"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
181,
"Length < _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength");
}
++Str_1; /*0x1cc6*/
++Length; /*0x1cc9*/
}
return Length; /*0x1ccf*/
}
// Function: GetDebugLib @ 0x1cd6 (0x31 bytes)
// Index: 34/77
int GetDebugLib()
{
int ImageHandle; // eax
_BYTE v2[4]; // [esp+0h] [ebp-8h] BYREF
int v3; // [esp+4h] [ebp-4h] BYREF
ImageHandle = GetImageHandle(); /*0x1cdb*/
if ( (*(int (__cdecl **)(int, void *, _DWORD, _BYTE *, int *))(*(_DWORD *)ImageHandle + 32))( /*0x1cfa*/
ImageHandle,
&unk_4B10,
0,
v2,
&v3) >= 0 )
return v3; /*0x1d00*/
else
return 0; /*0x1cfc*/
}
// Function: DebugPrint @ 0x1d07 (0x2a bytes)
// Index: 35/77
int DebugPrint(int n64, int FW_Capsule_Info_nDefault_Size_%X_n, ...)
{
int result; // eax
int (__cdecl **v3)(int, int, char *); // esi
va_list va; // [esp+10h] [ebp+Ch] BYREF
va_start(va, FW_Capsule_Info_nDefault_Size_%X_n);
result = GetDebugLib(); /*0x1d08*/
v3 = (int (__cdecl **)(int, int, char *))result; /*0x1d0d*/
if ( result ) /*0x1d11*/
{
result = GetDebugPrintLevel(); /*0x1d13*/
if ( (result & n64) != 0 ) /*0x1d1e*/
return (*v3)(n64, FW_Capsule_Info_nDefault_Size_%X_n, (char *)va); /*0x1d2a*/
}
return result; /*0x1d2f*/
}
// Function: DebugAssert @ 0x1d31 (0x1e bytes)
// Index: 36/77
int __fastcall DebugAssert(int e:__hs__MdePkg__Library__BaseLib__X86ReadIdtr.c, int n37, int Idtr____((void__)_0))
{
int result; // eax
result = GetDebugLib(); /*0x1d37*/
if ( result ) /*0x1d3e*/
return (*(int (__cdecl **)(int, int, int))(result + 4))( /*0x1d46*/
e:__hs__MdePkg__Library__BaseLib__X86ReadIdtr.c,
n37,
Idtr____((void__)_0));
return result; /*0x1d4c*/
}
// Function: AsciiStrCmp @ 0x1d4f (0x62 bytes)
// Index: 37/77
int __fastcall AsciiStrCmp(_BYTE *a1, _BYTE *CD001, int n5)
{
_BYTE *v3; // esi
_BYTE *v4; // edi
int n4; // ebx
int v6; // ecx
v3 = a1; /*0x1d56*/
v4 = &a1[n5]; /*0x1d5a*/
n4 = (unsigned __int8)a1 & 3; /*0x1d5c*/
if ( ((unsigned __int8)a1 & 3) != 0 && n4 == ((unsigned __int8)CD001 & 3) ) /*0x1d68*/
{
v6 = 4 - n4; /*0x1d6d*/
if ( n4 != 4 ) /*0x1d6f*/
{
do /*0x1d7c*/
{
if ( *v3 != *CD001 ) /*0x1d75*/
break; /*0x1d75*/
++v3; /*0x1d77*/
++CD001; /*0x1d78*/
--v6; /*0x1d79*/
}
while ( v6 ); /*0x1d7c*/
}
}
while ( v3 <= v4 - 4 && *(_DWORD *)v3 == *(_DWORD *)CD001 ) /*0x1d87*/
{
v3 += 4; /*0x1d89*/
CD001 += 4; /*0x1d8c*/
}
while ( 1 ) /*0x1d9d*/
{
if ( v3 >= v4 ) /*0x1d9f*/
return 0; /*0x1da6*/
if ( *v3 != *CD001 ) /*0x1d99*/
break; /*0x1d99*/
++v3; /*0x1d9b*/
++CD001; /*0x1d9c*/
}
return (char)*v3 - (char)*CD001; /*0x1da3*/
}
// Function: FindDirEntry @ 0x1db1 (0x37 bytes)
// Index: 38/77
int __fastcall FindDirEntry(int TmpResult, unsigned __int16 **a2)
{
unsigned __int16 *v3; // ecx
int n4; // eax
if ( !a2 ) /*0x1db3*/
return -2147483646; /*0x1db5*/
v3 = *a2; /*0x1dbb*/
if ( **a2 == 0xFFFF ) /*0x1dc6*/
return -2147483634; /*0x1ddb*/
while ( 1 ) /*0x1dcc*/
{
v3 = (unsigned __int16 *)((char *)v3 + v3[1]); /*0x1dcc*/
n4 = *v3; /*0x1dce*/
if ( n4 == 4 ) /*0x1dd4*/
break; /*0x1dd4*/
if ( (_WORD)n4 == 0xFFFF ) /*0x1dd9*/
return -2147483634; /*0x1dd9*/
}
*a2 = v3; /*0x1de2*/
return 0; /*0x1dba*/
}
// Function: FindBootEntry @ 0x1de8 (0x49 bytes)
// Index: 39/77
int __fastcall FindBootEntry(int TmpResult, unsigned __int16 **a2)
{
unsigned __int16 *v3; // edi
int v4; // eax
int result; // eax
int TmpResult_1; // [esp-4h] [ebp-10h]
unsigned __int16 *v7; // [esp+8h] [ebp-4h] BYREF
if ( !a2 ) /*0x1df2*/
return -2147483646; /*0x1e26*/
v7 = *a2; /*0x1df6*/
while ( 1 ) /*0x1e15*/
{
result = FindDirEntry(TmpResult, &v7); /*0x1e15*/
if ( result < 0 ) /*0x1e1c*/
break; /*0x1e1c*/
v3 = v7; /*0x1dfb*/
v4 = AsciiStrCmp((_BYTE *)v7 + 8, CD001, 16); /*0x1e08*/
TmpResult = TmpResult_1; /*0x1e0d*/
if ( !v4 ) /*0x1e10*/
{
*a2 = v3; /*0x1e20*/
return 0; /*0x1e24*/
}
}
return result; /*0x1e2b*/
}
// Function: DebugLogPrint @ 0x1e31 (0x72 bytes)
// Index: 40/77
int DebugLogPrint(int a1, int a2, _BYTE *a3, ...)
{
int result; // eax
_BYTE *v4; // eax
va_list va; // [esp+18h] [ebp+14h] BYREF
va_start(va, a3);
result = (*(int (__stdcall **)(int))(*(_DWORD *)a2 + 32))(a2); /*0x1e4a*/
if ( result >= 0 ) /*0x1e52*/
{
if ( a2 ) /*0x1e5a*/
{
result = GetDebugPrintLevel(); /*0x1e5c*/
if ( (result & a1) != 0 ) /*0x1e66*/
{
v4 = a3; /*0x1e68*/
if ( *a3 ) /*0x1e6b*/
{
do /*0x1e8b*/
{
if ( *v4 == 37 ) /*0x1e73*/
{
if ( *++v4 == 115 ) /*0x1e7b*/
{
*v4 = 97; /*0x1e7d*/
}
else if ( *v4 == 71 ) /*0x1e85*/
{
*v4 = 103; /*0x1e87*/
}
}
++v4; /*0x1e8a*/
}
while ( *v4 ); /*0x1e8b*/
v4 = a3; /*0x1e90*/
}
return (*(int (__cdecl **)(int, _BYTE *, char *))a2)(a1, v4, (char *)va); /*0x1e99*/
}
}
}
return result; /*0x1ea1*/
}
// Function: StrLen @ 0x1ea3 (0xe bytes)
// Index: 41/77
// (too small: 0xe bytes)
// Function: RShiftU64 @ 0x1eb1 (0x2d bytes)
// Index: 42/77
unsigned __int64 __cdecl RShiftU64(unsigned __int64 a1)
{
unsigned __int8 n0x40; // cl
unsigned __int64 v2; // rax
v2 = a1; /*0x1ebb*/
if ( n0x40 >= 0x40u ) /*0x1ec4*/
return 0; /*0x1ec6*/
if ( n0x40 >= 0x20u ) /*0x1ecf*/
v2 = HIDWORD(a1); /*0x1ed1*/
return v2 >> (n0x40 & 0x1F); /*0x1eda*/
}
// Function: LShiftU64 @ 0x1ede (0x2d bytes)
// Index: 43/77
__int64 __cdecl LShiftU64(__int64 a1)
{
unsigned __int8 n0x40; // cl
__int64 v2; // rax
v2 = a1; /*0x1ee8*/
if ( n0x40 >= 0x40u ) /*0x1ef1*/
return 0; /*0x1ef3*/
if ( n0x40 >= 0x20u ) /*0x1efc*/
{
HIDWORD(v2) = a1; /*0x1efe*/
LODWORD(v2) = 0; /*0x1f00*/
}
return v2 << (n0x40 & 0x1F); /*0x1f07*/
}
// Function: MultU64x32 @ 0x1f0b (0x28 bytes)
// Index: 44/77
__int64 __cdecl MultU64x32(__int64 a1)
{
unsigned int v1; // ecx
return a1 * v1; /*0x1f2f*/
}
// Function: IsValidNtfsVbr @ 0x1f33 (0x50 bytes)
// Index: 45/77
char __thiscall IsValidNtfsVbr(char *this)
{
char v1; // dl
v1 = 0; /*0x1f33*/
if ( !*(this + 16) /*0x1f7b*/
&& !*(_WORD *)(this + 19)
&& !*((_DWORD *)this + 8)
&& *((_QWORD *)this + 5)
&& *(this + 3) == 78
&& *(this + 4) == 84
&& *(this + 5) == 70
&& *(this + 6) == 83
&& *((_WORD *)this + 255) == 0xAA55
&& (*this == -21 || *this == -23) )
{
return 1; /*0x1f7f*/
}
return v1; /*0x1f82*/
}
// Function: VerifyFileRecord @ 0x1f83 (0x8f bytes)
// Index: 46/77
int __fastcall VerifyFileRecord(_DWORD *MftRef, int ia)
{
_WORD *v3; // ecx
int v4; // esi
_WORD *v6; // edi
_WORD *v7; // edx
if ( (*(_BYTE *)ia != 70 || *(_BYTE *)(ia + 1) != 73 || *(_BYTE *)(ia + 2) != 76 || *(_BYTE *)(ia + 3) != 69) /*0x1fb4*/
&& (*(_BYTE *)ia != 73 || *(_BYTE *)(ia + 1) != 78 || *(_BYTE *)(ia + 2) != 68 || *(_BYTE *)(ia + 3) != 88) )
{
return -2147483634; /*0x2009*/
}
v3 = (_WORD *)(ia + *(unsigned __int16 *)(ia + 4)); /*0x1fbe*/
v4 = (unsigned __int16)(*(_WORD *)(ia + 6) - 1); /*0x1fc2*/
if ( !*v3 ) /*0x1fc5*/
return 0; /*0x1fcb*/
v6 = v3 + 1; /*0x1fcf*/
v7 = (_WORD *)(ia + 510); /*0x1fd2*/
while ( *v7 == *v3 ) /*0x1fde*/
{
v4 += 0xFFFF; /*0x1fe3*/
*v7 = *v6++; /*0x1fe9*/
v7 += *MftRef >> 1; /*0x1ff3*/
if ( !(_WORD)v4 ) /*0x1ff9*/
{
*v3 = 0; /*0x1ffd*/
return 0; /*0x2000*/
}
}
return -2147483638; /*0x200e*/
}
// Function: DecodeCompressedRun @ 0x2012 (0x127 bytes)
// Index: 47/77
int __fastcall DecodeCompressedRun(int *p_ia, _DWORD *p_i, int *p_n5)
{
_BYTE *ia; // esi
unsigned int v4; // ecx
__int64 v5; // kr08_8
unsigned __int8 n8; // bl
unsigned __int8 v8; // bh
_BYTE *v9; // esi
unsigned __int8 *v10; // edi
unsigned int v11; // ebp
__int64 v12; // kr00_8
int v13; // eax
unsigned __int8 n8_1; // bh
unsigned __int8 *v15; // esi
char v16; // al
int v17; // esi
unsigned __int64 v18; // rax
unsigned int v19; // ecx
unsigned __int8 v20; // [esp+13h] [ebp-21h]
char v21; // [esp+13h] [ebp-21h]
int v22; // [esp+14h] [ebp-20h]
int v23; // [esp+20h] [ebp-14h]
int v24; // [esp+28h] [ebp-Ch]
ia = (_BYTE *)*p_ia; /*0x2024*/
v4 = 0; /*0x2026*/
v23 = 0; /*0x202b*/
v22 = 0; /*0x202f*/
v5 = 0; /*0x2041*/
if ( !*ia ) /*0x2035*/
return -2147483617; /*0x2043*/
n8 = *ia >> 4; /*0x204f*/
v8 = *ia & 0xF; /*0x2052*/
v9 = ia + 1; /*0x2055*/
v20 = v8; /*0x2056*/
if ( v8 ) /*0x2060*/
{
v10 = &v9[v8 - 1]; /*0x2068*/
v11 = 0; /*0x206a*/
do /*0x2087*/
{
v12 = *v10 + LShiftU64(__SPAIR64__(v11, v4)); /*0x2081*/
v11 = HIDWORD(v12); /*0x2081*/
v4 = v12; /*0x2081*/
--v10; /*0x2083*/
--v8; /*0x2084*/
}
while ( v8 ); /*0x2087*/
v8 = v20; /*0x208d*/
v22 = HIDWORD(v12); /*0x2091*/
v23 = v12; /*0x2097*/
v5 = 0; /*0x2097*/
}
v13 = v8; /*0x209b*/
n8_1 = n8; /*0x209e*/
v24 = (int)&v9[v13 + n8]; /*0x20a7*/
v15 = (unsigned __int8 *)(v24 - 1); /*0x20ab*/
v16 = *(_BYTE *)(v24 - 1); /*0x20ae*/
v21 = v16; /*0x20b0*/
if ( n8 ) /*0x20b6*/
{
do /*0x20d3*/
{
v5 = *v15-- + LShiftU64(v5); /*0x20cc*/
--n8_1; /*0x20d0*/
}
while ( n8_1 ); /*0x20d3*/
v16 = v21; /*0x20d5*/
}
if ( v16 < 0 && n8 < 8u ) /*0x20e0*/
{
v17 = (unsigned __int8)(8 - n8); /*0x20e6*/
LODWORD(v18) = 0; /*0x20e9*/
v19 = 0; /*0x20ed*/
do /*0x2105*/
{
v18 = RShiftU64(__PAIR64__(v19, v18)); /*0x20f3*/
v19 = HIDWORD(v18) | 0xFF000000; /*0x20fc*/
--v17; /*0x2102*/
}
while ( v17 ); /*0x2105*/
v5 = __PAIR64__(v19 | HIDWORD(v5), (unsigned int)v18 | (unsigned int)v5); /*0x2109*/
}
*(_QWORD *)p_n5 += v5; /*0x2113*/
*p_i = v23; /*0x211c*/
p_i[1] = v22; /*0x2122*/
*p_ia = v24; /*0x212d*/
return 0; /*0x2131*/
}
// Function: FindAttrByType @ 0x2139 (0x2f bytes)
// Index: 48/77
int __fastcall FindAttrByType(int i, unsigned __int8 n0x20, _DWORD *p_i)
{
int j; // esi
int v4; // eax
for ( j = i + *(unsigned __int16 *)(i + 20); ; j += v4 ) /*0x213e*/
{
if ( *(_BYTE *)j == n0x20 ) /*0x2155*/
{
*p_i = j; /*0x215b*/
return 0; /*0x2160*/
}
if ( *(_BYTE *)j > n0x20 ) /*0x2142*/
break; /*0x2142*/
if ( *(_BYTE *)j == 0xFF ) /*0x2146*/
break; /*0x2146*/
v4 = *(_DWORD *)(j + 4); /*0x2148*/
if ( !v4 ) /*0x214d*/
break; /*0x214d*/
}
return -2147483634; /*0x215f*/
}
// Function: ReadFileRecord @ 0x2168 (0x1bb bytes)
// Index: 49/77
int __fastcall ReadFileRecord(
int Volume,
_DWORD *MftRef,
int BootSector,
unsigned int RecordNum,
unsigned __int16 TotalRecords,
_BYTE *OutBuffer)
{
__int64 BlockAddr; // rax
unsigned int BytesPerSector; // ecx
int ClusterSize; // ebp
unsigned int BlockAddr_1; // esi
__int64 RunOffset; // rax
unsigned int RunOffset_1; // edi
unsigned int RunOffsetHi; // eax
__int64 RunStart; // kr08_8
unsigned __int64 RecordIndex; // kr18_8
__int64 BlockAddr_2; // kr00_8
__int64 RunOffset2; // rax
unsigned int RunOffset2_1; // edi
__int64 FinalOffset; // rax
_DWORD *MftRefSaved; // ebp
unsigned int ClusterSize_1; // [esp-10h] [ebp-58h]
unsigned int RunOffsetHi_1; // [esp+14h] [ebp-34h]
int p_ia; // [esp+18h] [ebp-30h] BYREF
unsigned int SectorsPerCluster; // [esp+1Ch] [ebp-2Ch]
unsigned __int64 RecordIndex_1; // [esp+20h] [ebp-28h]
int ClusterBytes; // [esp+28h] [ebp-20h]
unsigned int TotalRecords_1; // [esp+2Ch] [ebp-1Ch]
_DWORD *MftRefCopy; // [esp+30h] [ebp-18h]
int Volume_1; // [esp+34h] [ebp-14h]
int VcnOffset[2]; // [esp+38h] [ebp-10h] BYREF
__int64 RunLength; // [esp+40h] [ebp-8h] BYREF
MftRefCopy = MftRef; /*0x216d*/
VcnOffset[0] = 0; /*0x2171*/
VcnOffset[1] = 0; /*0x2179*/
Volume_1 = Volume; /*0x2188*/
p_ia = gDataPtr + 1024; /*0x218d*/
TotalRecords_1 = TotalRecords; /*0x219c*/
DecodeCompressedRun(&p_ia, &RunLength, VcnOffset); /*0x21aa*/
ClusterBytes = *(unsigned __int16 *)(BootSector + 11) * *(unsigned __int8 *)(BootSector + 13); /*0x21c6*/
BlockAddr = MultU64x32(RunLength); /*0x21ca*/
BytesPerSector = *(unsigned __int16 *)(BootSector + 11); /*0x21cf*/
ClusterSize = 1024; /*0x21d3*/
RunOffsetHi_1 = HIDWORD(BlockAddr); /*0x21db*/
BlockAddr_1 = BlockAddr; /*0x21df*/
if ( (unsigned __int16)BytesPerSector > 0x400u ) /*0x21e4*/
{
SectorsPerCluster = 1; /*0x21f2*/
ClusterSize = BytesPerSector; /*0x21fa*/
}
else
{
SectorsPerCluster = 0x400 / BytesPerSector; /*0x21ec*/
}
RunOffset = MultU64x32(*(__int64 *)VcnOffset); /*0x2208*/
RecordIndex_1 = 0; /*0x2214*/
RunOffset_1 = RunOffset; /*0x221a*/
RunOffsetHi = RunOffsetHi_1; /*0x221c*/
RunStart = __PAIR64__(HIDWORD(RunOffset), RunOffset_1); /*0x2220*/
RecordIndex = 0; /*0x2220*/
do /*0x22b4*/
{
if ( RunOffsetHi || BlockAddr_1 ) /*0x222a*/
{
RunStart += SectorsPerCluster; /*0x228e*/
RunOffsetHi = (__PAIR64__(RunOffsetHi, BlockAddr_1) - (unsigned int)ClusterSize) >> 32; /*0x2293*/
BlockAddr_1 -= ClusterSize; /*0x2293*/
LODWORD(RecordIndex_1) = ++RecordIndex; /*0x2299*/
HIDWORD(RecordIndex_1) = HIDWORD(RecordIndex); /*0x22a0*/
}
else
{
if ( DecodeCompressedRun(&p_ia, &RunLength, VcnOffset) < 0 ) /*0x2243*/
return -2147483634; /*0x2243*/
BlockAddr_2 = MultU64x32(RunLength); /*0x2260*/
BlockAddr_1 = BlockAddr_2; /*0x2260*/
RunOffset2 = MultU64x32(*(__int64 *)VcnOffset); /*0x2270*/
RunOffset2_1 = RunOffset2; /*0x2279*/
RunOffsetHi = HIDWORD(BlockAddr_2); /*0x227b*/
RunStart = __PAIR64__(HIDWORD(RunOffset2), RunOffset2_1); /*0x2288*/
RecordIndex = RecordIndex_1; /*0x2288*/
}
}
while ( RecordIndex < __PAIR64__(TotalRecords_1, RecordNum) ); /*0x22b4*/
FinalOffset = MultU64x32(RunStart); /*0x22c4*/
ClusterSize_1 = ClusterSize; /*0x22d2*/
MftRefSaved = MftRefCopy; /*0x22d3*/
if ( ReadBlocks(Volume_1, (int)MftRefCopy, FinalOffset, ClusterSize_1, (unsigned int)OutBuffer) >= 0 /*0x22fc*/
&& *OutBuffer == 70
&& OutBuffer[1] == 73
&& OutBuffer[2] == 76
&& OutBuffer[3] == 69 )
{
_ImageBase = RunStart; /*0x2304*/
if ( VerifyFileRecord(MftRefSaved, (int)OutBuffer) >= 0 ) /*0x2310*/
return 0; /*0x2314*/
}
return -2147483634; /*0x231b*/
}
// Function: ReadNonResidentAttr @ 0x2323 (0x11e bytes)
// Index: 50/77
int __fastcall ReadNonResidentAttr(int i, int MftRef, int BlockIo, int p_ia, unsigned int ia, int p_i)
{
unsigned int v6; // ebp
int result; // eax
int p_i_1; // esi
__int64 v9; // rax
unsigned __int64 i_3; // rax
unsigned __int64 i_2; // kr00_8
__int64 v12; // rax
__int64 v13; // rax
unsigned int v14; // et0
unsigned int v15; // [esp+10h] [ebp-24h]
unsigned __int64 i_4; // [esp+1Ch] [ebp-18h]
int p_n5[2]; // [esp+24h] [ebp-10h] BYREF
__int64 i_1; // [esp+2Ch] [ebp-8h] BYREF
v6 = 0; /*0x2330*/
v15 = 0; /*0x2332*/
p_n5[0] = 0; /*0x2336*/
p_n5[1] = 0; /*0x233e*/
result = DecodeCompressedRun(&p_ia, &i_1, p_n5); /*0x2350*/
if ( result >= 0 ) /*0x2359*/
{
p_i_1 = p_i; /*0x235f*/
while ( 1 ) /*0x2373*/
{
v9 = MultU64x32(i_1); /*0x2373*/
i_3 = MultU64x32(v9); /*0x237e*/
i_4 = i_3; /*0x238d*/
i_2 = *(_QWORD *)p_i_1; /*0x239d*/
if ( i_3 <= *(_QWORD *)p_i_1 ) /*0x239d*/
i_2 = i_3; /*0x23a1*/
v12 = MultU64x32(*(__int64 *)p_n5); /*0x23b3*/
v13 = MultU64x32(v12); /*0x23c2*/
if ( !i_2 ) /*0x23ce*/
break; /*0x23ce*/
if ( ReadBlocks(i, MftRef, v13, i_2, ia) < 0 /*0x241f*/
|| (ia += i_2, v14 = (i_2 + __PAIR64__(v15, v6)) >> 32,
v6 += i_2,
v15 = v14,
*(_QWORD *)p_i_1 -= i_2,
i_2 == i_4)
&& DecodeCompressedRun(&p_ia, &i_1, p_n5) < 0
|| !*(_QWORD *)p_i_1 )
{
*(_DWORD *)(p_i_1 + 4) = 0; /*0x242a*/
*(_DWORD *)p_i_1 = v6; /*0x2430*/
return 0; /*0x2432*/
}
}
return -2147483638; /*0x2434*/
}
return result; /*0x2439*/
}
// Function: LoadAttrListRecord @ 0x2441 (0x7c bytes)
// Index: 51/77
int __fastcall LoadAttrListRecord(int i, _DWORD *MftRef, int BlockIo, _BYTE *ia, int n144, int a6, int *p_n5)
{
unsigned int v8; // esi
int n144_1; // eax
unsigned int n5; // ebx
int v12; // esi
v8 = gDataPtr + 1664; /*0x244c*/
n144_1 = *(_DWORD *)(gDataPtr + 1664); /*0x2457*/
while ( n144 != n144_1 ) /*0x245d*/
{
v8 += *(unsigned __int16 *)(v8 + 4); /*0x2463*/
a6 -= *(unsigned __int16 *)(v8 + 4); /*0x2469*/
n144_1 = *(_DWORD *)v8; /*0x246b*/
if ( !*(_DWORD *)v8 || !a6 ) /*0x2473*/
return n144_1; /*0x2473*/
}
n5 = *(_DWORD *)(v8 + 16); /*0x247b*/
v12 = *(_DWORD *)(v8 + 20); /*0x247e*/
if ( n5 != *p_n5 || v12 != p_n5[1] ) /*0x2488*/
{
n144_1 = ReadFileRecord(i, MftRef, BlockIo, n5, v12, ia); /*0x2495*/
if ( !n144_1 ) /*0x249f*/
{
*p_n5 = n5; /*0x24ab*/
p_n5[1] = v12; /*0x24ad*/
return DebugLogPrint(-1, i, "\nRecord %x loaded from attribute list\n", n5); /*0x24b0*/
}
}
return n144_1; /*0x24b8*/
}
// Function: ReadNtfsDirectory @ 0x24bd (0x307 bytes)
// Index: 52/77
int __fastcall ReadNtfsDirectory(int Volume, _DWORD *MftRef_1, int BlockIo, int a4, int a5, char *Buffer)
{
int BlockIo_1; // ebp
char *Buffer_1; // edi
int Status; // ebx
int AttrListSize; // eax
char *Buffer_2; // ebx
char *AttrStart; // ecx
unsigned int ResidentSize; // ebp
int AttrStatus; // edi
int v16; // ecx
__int64 i; // kr00_8
int RunResult; // eax
__int64 Temp64; // rax
unsigned __int64 TotalSize; // rax
unsigned int NumPages; // edi
int v22; // [esp-4h] [ebp-38h]
char *AttrPtr; // [esp+14h] [ebp-20h] BYREF
_DWORD *MftRef; // [esp+18h] [ebp-1Ch]
int p_i[2]; // [esp+1Ch] [ebp-18h] BYREF
int RunOffset; // [esp+24h] [ebp-10h] BYREF
int ZeroInit; // [esp+28h] [ebp-Ch]
char *AllocBuf; // [esp+2Ch] [ebp-8h] BYREF
ZeroInit = 0; /*0x24c0*/
BlockIo_1 = BlockIo; /*0x24c9*/
Buffer_1 = Buffer; /*0x24cf*/
RunOffset = 5; /*0x24dd*/
MftRef = MftRef_1; /*0x24e4*/
p_i[0] = (int)Buffer; /*0x24e8*/
Status = ReadFileRecord(Volume, MftRef_1, BlockIo, 5u, 0, Buffer); /*0x24f1*/
if ( Status < 0 )
{
DebugLogPrint(-1, Volume, "\nRead directory: record not found\n");
return Status; /*0x250c*/
}
LOBYTE(Buffer) = 0; /*0x2515*/
AttrPtr = Buffer_1; /*0x251d*/
if ( FindAttrByType((int)Buffer_1, 0x20u, &AttrPtr) || AttrPtr[8] ) /*0x2533*/
{
Buffer_2 = Buffer; /*0x2570*/
}
else
{
AttrListSize = *((unsigned __int16 *)AttrPtr + 10); /*0x2538*/
Buffer_2 = (char *)(*((_DWORD *)AttrPtr + 1) - AttrListSize); /*0x253f*/
LOBYTE(Buffer) = 1; /*0x2541*/
CopyMemEx(gDataPtr + 1664, &AttrPtr[AttrListSize], (unsigned int)Buffer_2); /*0x2555*/
DebugLogPrint(-1, Volume, "\nAttribute list found, size is %x\n", Buffer_2); /*0x2566*/
}
byte_4C94 = 0; /*0x2579*/
if ( (_BYTE)Buffer ) /*0x2580*/
LoadAttrListRecord(Volume, MftRef, BlockIo, Buffer_1, 144, (int)Buffer_2, &RunOffset); /*0x2595*/
AttrPtr = Buffer_1; /*0x25a1*/
if ( !FindAttrByType((int)Buffer_1, 0x90u, &AttrPtr) )
{
AttrStart = &AttrPtr[*((unsigned __int16 *)AttrPtr + 10)]; /*0x25be*/
ResidentSize = *((_DWORD *)AttrStart + 5); /*0x25c3*/
AttrPtr = &AttrStart[*((_DWORD *)AttrStart + 4) + 16]; /*0x25cb*/
if ( ResidentSize >= 0x58 )
{
DebugLogPrint(-1, Volume, "\nRead directory: resident part found\n");
CopyMemEx(gDataPtr + 1408, AttrPtr, ResidentSize); /*0x25f4*/
byte_4C94 = 1; /*0x25fc*/
n0x58 = ResidentSize; /*0x2603*/
}
BlockIo_1 = BlockIo; /*0x2609*/
}
if ( (_BYTE)Buffer ) /*0x2612*/
LoadAttrListRecord(Volume, MftRef, BlockIo_1, Buffer_1, 160, (int)Buffer_2, &RunOffset); /*0x2627*/
AttrStatus = FindAttrByType((int)Buffer_1, 0xA0u, p_i); /*0x263d*/
if ( AttrStatus >= 0 )
{
CopyMemEx(gDataPtr + 1280, (char *)(p_i[0] + *(unsigned __int16 *)(p_i[0] + 32)), 0x80u); /*0x2685*/
RunOffset = 0; /*0x2691*/
Buffer = (char *)(gDataPtr + 1280); /*0x269d*/
ZeroInit = 0; /*0x26a3*/
for ( i = 0; ; i += *(_QWORD *)p_i ) /*0x26a3*/
{
v22 = v16; /*0x26a7*/
RunResult = DecodeCompressedRun((int *)&Buffer, p_i, &RunOffset); /*0x26b5*/
v16 = v22; /*0x26bb*/
if ( RunResult ) /*0x26be*/
break; /*0x26be*/
}
Temp64 = MultU64x32(i); /*0x26d0*/
TotalSize = MultU64x32(Temp64); /*0x26db*/
*(_QWORD *)p_i = TotalSize; /*0x26f0*/
if ( byte_4BC1 )
{
if ( TotalSize > (unsigned int)gAllocBufPtr ) /*0x276b*/
{
p_i[1] = 0; /*0x276d*/
p_i[0] = gAllocBufPtr; /*0x2772*/
}
}
else
{
NumPages = ((TotalSize & 0xFFF) != 0) + (unsigned int)RShiftU64(TotalSize); /*0x2715*/
Status = (*(int (__cdecl **)(int, int, unsigned int, char **))(*(_DWORD *)Volume + 72))( /*0x2724*/
Volume,
4,
NumPages,
&AllocBuf);
if ( Status < 0 )
{
DebugLogPrint(-1, Volume, "\nRead directory: can't allocate memory\n");
return Status; /*0x2732*/
}
gTmpBufPtr = AllocBuf; /*0x2742*/
gAllocBufPtr = NumPages << 12; /*0x2747*/
ZeroMemEx((int)AllocBuf, AllocBuf, NumPages << 12, 0); /*0x274d*/
byte_4BC1 = 1; /*0x2755*/
}
AttrStatus = ReadNonResidentAttr( /*0x2798*/
Volume,
(int)MftRef,
BlockIo_1,
gDataPtr + 1280,
(unsigned int)gTmpBufPtr,
(int)p_i);
if ( AttrStatus < 0 )
DebugLogPrint(-1, Volume, "\nRead directory: error reading dir file\n");
n4096 = p_i[0]; /*0x27b5*/
}
else
{
DebugLogPrint(-1, Volume, "\nRead directory: no index allocation attribute\n");
if ( byte_4C94 ) /*0x265d*/
return 0; /*0x2665*/
}
return AttrStatus; /*0x27bc*/
}
// Function: ReadRootDir @ 0x27c4 (0xba bytes)
// Index: 53/77
int __fastcall ReadRootDir(int i, int MftRef, char *ia)
{
int *ia_1; // edi
__int64 v6; // rax
__int64 v7; // rax
int result; // eax
int v9; // ecx
__int64 v10; // [esp-20h] [ebp-434h]
char iaa[1028]; // [esp+10h] [ebp-404h] BYREF
ia_1 = (int *)ia; /*0x27d0*/
v6 = MultU64x32(*((_QWORD *)ia + 6)); /*0x27e1*/
v7 = MultU64x32(v6); /*0x27ec*/
*(_QWORD *)(MftRef + 29) = v7; /*0x27f1*/
HIDWORD(v10) = HIDWORD(v7); /*0x2805*/
LODWORD(v10) = *(_DWORD *)(MftRef + 29); /*0x2806*/
result = ReadBlocks(i, MftRef, v10, 0x400u, (unsigned int)iaa); /*0x280b*/
if ( result >= 0 ) /*0x2815*/
{
ia = iaa; /*0x281f*/
result = FindAttrByType((int)iaa, 0x80u, &ia); /*0x282c*/
if ( result >= 0 ) /*0x2836*/
{
CopyMemEx(gDataPtr + 1024, &ia[*((unsigned __int16 *)ia + 16)], 0x100u); /*0x2852*/
byte_4BC1 = 0; /*0x285a*/
return ReadNtfsDirectory(i, (_DWORD *)MftRef, (int)ia_1, v9, v9, iaa); /*0x286f*/
}
}
return result; /*0x2877*/
}
// Function: ReadNtfsRoot @ 0x287e (0x188 bytes)
// Index: 54/77
int __fastcall ReadNtfsRoot(int i, _DWORD *MftRef, _DWORD *a3, _BYTE *ia)
{
int v4; // esi
int result; // eax
char *ia_1; // ecx
int RootDir; // ebp
unsigned int p_i_1; // eax
int v11; // ecx
int v12; // [esp-4h] [ebp-20h]
int p_i; // [esp+10h] [ebp-Ch] BYREF
int p_i_2[2]; // [esp+14h] [ebp-8h] BYREF
v4 = 0; /*0x2895*/
result = ReadBlocks(i, (int)MftRef, 0, 0x200u, gDataPtr + 512); /*0x289d*/
if ( result >= 0 ) /*0x28a7*/
{
if ( !IsValidNtfsVbr((char *)(gDataPtr + 512)) ) /*0x28b5*/
{
DebugLogPrint(-1, i, "\nIsNTFS failed\n"); /*0x28c6*/
return -2147483634; /*0x28ce*/
}
RootDir = ReadRootDir(i, (int)MftRef, ia_1); /*0x28e5*/
if ( RootDir >= 0 ) /*0x28ea*/
{
::MftRef = MftRef; /*0x2905*/
FindBootablePartitions(v12, &p_i); /*0x290f*/
p_i_1 = p_i; /*0x2914*/
if ( !p_i ) /*0x291d*/
return -2147483634; /*0x291d*/
p_i = 0; /*0x2923*/
while ( 1 ) /*0x292a*/
{
v11 = dword_4CA0[v4]; /*0x292a*/
if ( __PAIR64__(p_i, *a3) >= *(_QWORD *)(v11 + 64) ) /*0x2943*/
break; /*0x2943*/
if ( ++v4 >= p_i_1 ) /*0x2948*/
return -2147483634; /*0x2948*/
}
p_i = (int)ia; /*0x2956*/
p_i_2[0] = *(_DWORD *)(v11 + 64); /*0x295d*/
p_i_2[1] = *(_DWORD *)(v11 + 68); /*0x2965*/
result = ReadFileRecord(i, MftRef, gDataPtr + 512, *(_DWORD *)v11, *(_WORD *)(v11 + 4), ia); /*0x297e*/
if ( result >= 0 ) /*0x2988*/
{
result = FindAttrByType((int)ia, 0x80u, &p_i); /*0x2997*/
if ( result >= 0 ) /*0x29a1*/
{
CopyMemEx(gDataPtr + 1280, (char *)(p_i + *(unsigned __int16 *)(p_i + 32)), 0x80u); /*0x29c2*/
result = ReadNonResidentAttr(i, (int)MftRef, gDataPtr + 512, gDataPtr + 1280, (unsigned int)ia, (int)p_i_2); /*0x29e8*/
if ( result >= 0 ) /*0x29f2*/
{
*a3 = p_i_2[0]; /*0x29fc*/
return 0; /*0x29ff*/
}
}
}
}
else
{
DebugLogPrint(-1, i, "\nRead root failed\n"); /*0x28f4*/
return RootDir; /*0x28fc*/
}
}
return result; /*0x28d3*/
}
// Function: ParseExt2Superblock @ 0x2a06 (0x21b bytes)
// Index: 55/77
char __fastcall ParseExt2Superblock(int DebugLevel, int DirData, int RemainingSize, char *FileName, int *FoundEntry)
{
int DebugLevel_1; // eax
char *FileName_1; // ebp
int DirData_1; // esi
int NameLen; // edx
char SearchChar; // ch
int EntryPtr; // edi
unsigned int RemainingEntry; // ebx
unsigned __int8 NameLen_1; // cl
char *NameBufPtr; // ebp
char *WideNameSrc; // esi
int NameLen_2; // ebx
char WideChar; // al
int NrdNameLen; // edx
unsigned int TotalEntrySz_1; // ebx
unsigned __int8 NameLenNrd; // cl
char *NameBufPtr_2; // ebp
char *WideSrcNrd; // esi
int NrdNameLen_1; // ebx
char WideCharNrd; // al
bool IsMatch; // zf
unsigned int n4096; // eax
int NrdNameLen_2; // [esp-8h] [ebp-130h]
char *_nResident_file_found:_%s_n; // [esp-8h] [ebp-130h]
char *FileName_2; // [esp-4h] [ebp-12Ch]
char SearchChar_1; // [esp+13h] [ebp-115h]
int n0x58; // [esp+14h] [ebp-114h]
unsigned int TotalEntrySz; // [esp+14h] [ebp-114h]
int DirData_2; // [esp+18h] [ebp-110h]
unsigned __int16 EntrySize; // [esp+20h] [ebp-108h]
unsigned __int16 NrdEntrySize; // [esp+20h] [ebp-108h]
unsigned int TotalEntrySz_2; // [esp+24h] [ebp-104h]
char NameBufPtr_1[256]; // [esp+28h] [ebp-100h] BYREF
DebugLevel_1 = DebugLevel; /*0x2a13*/
FileName_1 = FileName; /*0x2a17*/
DirData_1 = DirData; /*0x2a1f*/
DirData_2 = DirData; /*0x2a26*/
if ( byte_4C94 )
{
DebugLogPrint(-1, DebugLevel, "\nEntering resident search\n"); /*0x2a38*/
SearchChar = *FileName; /*0x2a46*/
EntryPtr = gDataPtr + 1408; /*0x2a49*/
RemainingEntry = n0x58; /*0x2a4f*/
n0x58 = n0x58; /*0x2a55*/
SearchChar_1 = *FileName; /*0x2a59*/
while ( 1 )
{
NameLen_1 = *(_BYTE *)(EntryPtr + 80); /*0x2a5d*/
LOBYTE(NameLen) = 0; /*0x2a60*/
EntrySize = *(_WORD *)(EntryPtr + 8); /*0x2a66*/
if ( NameLen_1 ) /*0x2a6c*/
{
NameLen = NameLen_1; /*0x2a6e*/
NameBufPtr = NameBufPtr_1; /*0x2a71*/
WideNameSrc = (char *)(EntryPtr + 82); /*0x2a75*/
NameLen_2 = NameLen_1; /*0x2a78*/
do /*0x2a86*/
{
WideChar = *WideNameSrc; /*0x2a7a*/
WideNameSrc += 2; /*0x2a7c*/
*NameBufPtr++ = WideChar; /*0x2a7f*/
--NameLen_2; /*0x2a83*/
}
while ( NameLen_2 ); /*0x2a86*/
DirData_1 = DirData_2; /*0x2a88*/
FileName_1 = FileName; /*0x2a8c*/
RemainingEntry = n0x58; /*0x2a93*/
}
NameBufPtr_1[(unsigned __int8)NameLen] = 0; /*0x2a9a*/
if ( SearchChar )
{
LOBYTE(NameLen) = 0; /*0x2aa6*/
if ( MatchNameWildcard(NameBufPtr_1, NameLen, NameLen_1, FileName_1) >= 0 )
{
FileName_2 = FileName_1; /*0x2bce*/
_nResident_file_found:_%s_n = "\nResident file found: %s\n";
LABEL_30:
*FoundEntry = EntryPtr; /*0x2bd4*/
DebugLogPrint(-1, DebugLevel, _nResident_file_found:_%s_n, FileName_2); /*0x2be3*/
return 1; /*0x2bed*/
}
SearchChar = SearchChar_1; /*0x2abd*/
}
RemainingEntry -= EntrySize; /*0x2ac8*/
EntryPtr += EntrySize; /*0x2aca*/
n0x58 = RemainingEntry; /*0x2acc*/
if ( RemainingEntry < 0x58 ) /*0x2ad3*/
{
DebugLevel_1 = DebugLevel; /*0x2ad5*/
break; /*0x2ad5*/
}
}
}
DebugLogPrint(-1, DebugLevel_1, "\nBeginning non-resident search\n"); /*0x2ad9*/
LABEL_13:
if ( *(_BYTE *)DirData_1 == 73
&& *(_BYTE *)(DirData_1 + 1) == 78
&& *(_BYTE *)(DirData_1 + 2) == 68
&& *(_BYTE *)(DirData_1 + 3) == 88
&& VerifyFileRecord(MftRef, DirData_1) >= 0 )
{
TotalEntrySz_1 = *(_DWORD *)(DirData_1 + 28); /*0x2b25*/
EntryPtr = *(_DWORD *)(DirData_1 + 24) + DirData_1 + 24; /*0x2b2e*/
TotalEntrySz = TotalEntrySz_1; /*0x2b30*/
TotalEntrySz_2 = TotalEntrySz_1; /*0x2b34*/
if ( TotalEntrySz_1 >= 0x58 )
{
while ( 1 )
{
NrdEntrySize = *(_WORD *)(EntryPtr + 8); /*0x2b45*/
if ( !NrdEntrySize ) /*0x2b4c*/
break; /*0x2b4c*/
LOBYTE(NrdNameLen) = *(_BYTE *)(EntryPtr + 80); /*0x2b52*/
NameLenNrd = 0; /*0x2b55*/
if ( (_BYTE)NrdNameLen ) /*0x2b59*/
{
NameLenNrd = *(_BYTE *)(EntryPtr + 80); /*0x2b5b*/
NameBufPtr_2 = NameBufPtr_1; /*0x2b5e*/
WideSrcNrd = (char *)(EntryPtr + 82); /*0x2b62*/
NrdNameLen_1 = (unsigned __int8)NrdNameLen; /*0x2b65*/
do /*0x2b73*/
{
WideCharNrd = *WideSrcNrd; /*0x2b67*/
WideSrcNrd += 2; /*0x2b69*/
*NameBufPtr_2++ = WideCharNrd; /*0x2b6c*/
--NrdNameLen_1; /*0x2b70*/
}
while ( NrdNameLen_1 ); /*0x2b73*/
DirData_1 = DirData_2; /*0x2b75*/
TotalEntrySz_1 = TotalEntrySz; /*0x2b79*/
FileName_1 = FileName; /*0x2b7d*/
}
IsMatch = *FileName_1 == 0; /*0x2b84*/
NameBufPtr_1[NameLenNrd] = 0; /*0x2b8b*/
if ( !IsMatch )
{
NrdNameLen_2 = (unsigned __int8)NrdNameLen; /*0x2b9a*/
LOBYTE(NrdNameLen) = 0; /*0x2b9b*/
if ( MatchNameWildcard(NameBufPtr_1, NrdNameLen, NrdNameLen_2, FileName_1) >= 0 )
{
FileName_2 = FileName_1; /*0x2c19*/
_nResident_file_found:_%s_n = "\nNon-resident file found: %s\n";
goto LABEL_30; /*0x2c1f*/
}
}
TotalEntrySz_1 -= NrdEntrySize; /*0x2baf*/
EntryPtr += NrdEntrySize; /*0x2bb1*/
TotalEntrySz = TotalEntrySz_1; /*0x2bb3*/
if ( TotalEntrySz_1 < 0x58 ) /*0x2bba*/
{
if ( TotalEntrySz_2 >= 0x1000 ) /*0x2bc5*/
n4096 = (TotalEntrySz_2 + 256) & 0xFFFFFF00; /*0x2bf4*/
else
n4096 = 4096; /*0x2bc7*/
DirData_1 += n4096; /*0x2bf9*/
IsMatch = RemainingSize == n4096; /*0x2bfb*/
RemainingSize -= n4096; /*0x2bfb*/
DirData_2 = DirData_1; /*0x2c02*/
if ( !IsMatch ) /*0x2c06*/
goto LABEL_13; /*0x2c06*/
return 0; /*0x2c06*/
}
}
}
}
return 0; /*0x2c0e*/
}
// Function: FindBootablePartitions @ 0x2c21 (0xac bytes)
// Index: 56/77
int __cdecl FindBootablePartitions(int a1, int *p_i)
{
int DebugLevel_1; // ecx
int n4096; // ebx
char *gTmpBufPtr; // ebp
int DebugLevel; // esi
int v7; // eax
int i; // ecx
int FoundEntry__1; // eax
int FoundEntry_; // [esp+10h] [ebp-10Ch] BYREF
char *src; // [esp+14h] [ebp-108h] BYREF
int v12; // [esp+18h] [ebp-104h] BYREF
char dst[256]; // [esp+1Ch] [ebp-100h] BYREF
n4096 = n4096; /*0x2c28*/
gTmpBufPtr = gTmpBufPtr; /*0x2c33*/
DebugLevel = DebugLevel_1; /*0x2c44*/
FoundEntry_ = 0; /*0x2c47*/
*p_i = 0; /*0x2c4b*/
if ( GetRecoveryImageConfig(DebugLevel_1, &src, &v12, 0) < 0 ) /*0x2c5b*/
return DebugLogPrint(-1, DebugLevel, "\nGet info error\n"); /*0x2c62*/
v7 = StrLen(src); /*0x2c68*/
CopyMemEx((unsigned int)dst, src, v7 + 1); /*0x2c78*/
if ( !ParseExt2Superblock(DebugLevel, (int)gTmpBufPtr, n4096, dst, &FoundEntry_) ) /*0x2c8c*/
return DebugLogPrint(-1, DebugLevel, "\nRecovery file not found\n"); /*0x2cba*/
i = *p_i; /*0x2c98*/
FoundEntry__1 = FoundEntry_; /*0x2c9a*/
*p_i = 1; /*0x2c9e*/
dword_4CA0[i] = FoundEntry__1; /*0x2ca9*/
return DebugLogPrint(-1, DebugLevel, "\nRecovery file found\n"); /*0x2cc2*/
}
// Function: ReadMbr @ 0x2ccd (0xd5 bytes)
// Index: 57/77
int __cdecl ReadMbr(int i, _DWORD *MftRef, _DWORD *a3, _BYTE *i_1)
{
int result; // eax
int Blocks; // ebx
int v6; // ebx
bool v7; // zf
*(_DWORD *)((char *)MftRef + 21) = 0; /*0x2ce9*/
*(_DWORD *)((char *)MftRef + 25) = 0; /*0x2cec*/
result = ReadNtfsRoot(i, MftRef, a3, i_1); /*0x2cef*/
if ( result < 0 ) /*0x2cf8*/
{
Blocks = ReadBlocks(i, (int)MftRef, 0, 0x200u, gDataPtr); /*0x2d14*/
if ( Blocks >= 0 ) /*0x2d1b*/
{
if ( *(_WORD *)(gDataPtr + 510) == 0xAA55 ) /*0x2d42*/
{
gExtendFlag = 1; /*0x2d58*/
gPartIdx = 0; /*0x2d5f*/
gLbaOffset = 0; /*0x2d64*/
ExtPartLbaOffset = 0; /*0x2d69*/
do /*0x2d94*/
{
v6 = ParsePartitionEntry(i, (int)MftRef); /*0x2d77*/
v7 = v6 == 0; /*0x2d79*/
if ( v6 >= 0 ) /*0x2d7b*/
{
result = ReadNtfsRoot(i, MftRef, a3, i_1); /*0x2d87*/
if ( result >= 0 ) /*0x2d90*/
return result; /*0x2d90*/
v7 = v6 == 0; /*0x2d92*/
}
}
while ( v7 ); /*0x2d94*/
}
else
{
DebugLogPrint(-1, i, "\naa55 not found\n"); /*0x2d4c*/
}
return -2147483634; /*0x2d96*/
}
else
{
DebugLogPrint(-1, i, "\nRead MBR failed\n"); /*0x2d25*/
return Blocks; /*0x2d2d*/
}
}
return result; /*0x2d9b*/
}
// Function: ReadExt4Root @ 0x2da2 (0x21a bytes)
// Index: 58/77
int __fastcall ReadExt4Root(
int *BlockIo,
int MediaDesc,
int Superblock,
int Inode,
unsigned int *BlockIndex,
_DWORD *CurrentOffset)
{
int MediaSaved; // ebp
unsigned int v8; // esi
unsigned int BlockSize; // ebx
unsigned int EntriesPerBlock; // eax
char IndirectionLevel; // cl
int BlockAddr; // eax
unsigned int v13; // ebp
int BlockIoPtr; // edx
int Status; // eax
__int64 BlockOffset; // rax
int BlockIoPtr2; // edx
__int64 Offset2; // rax
unsigned int EntPerBlk; // ecx
unsigned int IndirIndex; // eax
__int64 IndirOffset; // rax
_DWORD AllocBuf[2]; // [esp+18h] [ebp-8h] BYREF
unsigned int EntPerBlkSaved; // [esp+24h] [ebp+4h]
MediaSaved = MediaDesc; /*0x2db4*/
v8 = *BlockIndex; /*0x2dba*/
BlockSize = 1024 << *(_DWORD *)(Superblock + 24); /*0x2dc3*/
EntriesPerBlock = BlockSize >> 2; /*0x2dc7*/
EntPerBlkSaved = BlockSize >> 2; /*0x2dca*/
if ( *BlockIndex < 0xC ) /*0x2dd1*/
{
IndirectionLevel = n2_0; /*0x2dd3*/
if ( !n2_0 ) /*0x2ddb*/
{
BlockAddr = *(_DWORD *)(Inode + 4 * v8 + 40); /*0x2de5*/
LABEL_26:
*CurrentOffset = BlockAddr; /*0x2f91*/
goto LABEL_27; /*0x2f95*/
}
goto LABEL_16; /*0x2ddb*/
}
v13 = EntriesPerBlock + 12; /*0x2dee*/
if ( v8 < EntriesPerBlock + 12 ) /*0x2df3*/
{
IndirectionLevel = n2_0; /*0x2df9*/
if ( n2_0 == 1 ) /*0x2e02*/
goto LABEL_12; /*0x2e02*/
BlockIoPtr = *BlockIo; /*0x2e08*/
n2_0 = 1; /*0x2e10*/
if ( (*(int (__cdecl **)(int *, int, unsigned int, _DWORD *))(BlockIoPtr + 72))( /*0x2e37*/
BlockIo,
4,
(BlockSize >> 12) + ((BlockSize & 0xFFF) != 0),
AllocBuf) < 0 )
{
DebugLogPrint(-1, (int)BlockIo, "\nCan't allocate block pages 1\n"); /*0x2e41*/
return -2147483617; /*0x2e4e*/
}
dst = AllocBuf[0]; /*0x2e59*/
BlockOffset = MultU64x32(*(unsigned int *)(Inode + 88)); /*0x2e67*/
Status = ReadBlocks((int)BlockIo, MediaDesc, BlockOffset, BlockSize, dst); /*0x2e7b*/
if ( Status < 0 ) /*0x2e85*/
return Status; /*0x2e85*/
EntriesPerBlock = BlockSize >> 2; /*0x2e8b*/
}
IndirectionLevel = n2_0; /*0x2e8f*/
LABEL_12:
if ( v8 < v13 && IndirectionLevel == 1 ) /*0x2e9c*/
{
BlockAddr = *(_DWORD *)(dst + 4 * v8 - 48); /*0x2ea3*/
goto LABEL_26; /*0x2ea7*/
}
MediaSaved = MediaDesc; /*0x2eac*/
LABEL_16:
if ( v8 >= EntriesPerBlock + 12 ) /*0x2eb5*/
{
if ( IndirectionLevel != 2 ) /*0x2ebe*/
{
BlockIoPtr2 = *BlockIo; /*0x2ec0*/
n2_0 = 2; /*0x2ec8*/
if ( (*(int (__cdecl **)(int *, int, unsigned int, _DWORD *))(BlockIoPtr2 + 72))( /*0x2eef*/
BlockIo,
4,
(BlockSize >> 12) + ((BlockSize & 0xFFF) != 0),
AllocBuf) < 0 )
{
DebugLogPrint(-1, (int)BlockIo, "\nCan't allocate block pages 2\n"); /*0x2ef6*/
return -2147483617; /*0x2ef6*/
}
dst_0 = AllocBuf[0]; /*0x2f01*/
Offset2 = MultU64x32(*(unsigned int *)(Inode + 92)); /*0x2f0f*/
Status = ReadBlocks((int)BlockIo, MediaSaved, Offset2, BlockSize, dst); /*0x2f21*/
if ( Status < 0 ) /*0x2f2b*/
return Status; /*0x2f2b*/
if ( n2_0 != 2 ) /*0x2f38*/
goto LABEL_27; /*0x2f38*/
}
EntPerBlk = BlockSize >> 2; /*0x2f3a*/
IndirIndex = (v8 - 12) / EntPerBlkSaved; /*0x2f45*/
if ( !((v8 - 12) % EntPerBlkSaved) ) /*0x2f45*/
{
IndirOffset = MultU64x32(*(unsigned int *)(dst + 4 * IndirIndex - 4)); /*0x2f5c*/
Status = ReadBlocks((int)BlockIo, MediaDesc, IndirOffset, BlockSize, dst_0); /*0x2f70*/
if ( Status < 0 ) /*0x2f7a*/
return Status; /*0x2f7a*/
EntPerBlk = BlockSize >> 2; /*0x2f7c*/
IndirIndex = (v8 - 12) / EntPerBlkSaved; /*0x2f80*/
}
BlockAddr = *(_DWORD *)(dst_0 + 4 * (v8 - 12 - EntPerBlk * IndirIndex)); /*0x2f8e*/
goto LABEL_26; /*0x2f8e*/
}
LABEL_27:
*BlockIndex = v8 + 1; /*0x2f97*/
return *CurrentOffset != 0 ? 0 : -2147483617;
}
// Function: ReadExt4DirInode @ 0x2fbc (0x2b4 bytes)
// Index: 59/77
int __fastcall ReadExt4DirInode(
int *BlockIo,
int MediaDesc,
int Superblock,
_WORD *Inode,
unsigned int Buffer,
unsigned int *ReadSize)
{
unsigned int TotalRead; // ebx
_WORD *Inode_1; // eax
unsigned int TotalHi; // edi
int BlockIdx; // ecx
int BlockIdx_1; // esi
int ExtentOff; // edi
__int64 StartBlock; // rax
__int64 BlockAddr; // rax
int v15; // ecx
unsigned int ChunkSize; // esi
int Status; // eax
bool v18; // cf
int RootResult; // esi
__int64 BlockOffset; // rax
bool v21; // zf
int ReadStatus; // eax
unsigned int NewTotal; // kr00_4
unsigned int BlockGroupSz; // [esp+14h] [ebp-20h]
__int64 CurrentOffset; // [esp+1Ch] [ebp-18h] BYREF
unsigned int p_BlockIdx; // [esp+24h] [ebp-10h] BYREF
int BlockOffHi; // [esp+28h] [ebp-Ch]
int BlockOffset_1; // [esp+2Ch] [ebp-8h]
int ReadStatus_1; // [esp+30h] [ebp-4h]
int Superblocka; // [esp+38h] [ebp+4h]
_WORD *Blocks; // [esp+3Ch] [ebp+8h]
TotalRead = 0; /*0x2fd1*/
p_BlockIdx = 0; /*0x2fd3*/
BlockGroupSz = 1024 << *(_DWORD *)(Superblock + 24); /*0x2fe1*/
Inode_1 = Inode; /*0x2fe5*/
TotalHi = 0; /*0x2fea*/
CurrentOffset = 0; /*0x2fec*/
n2_0 = 0; /*0x2ff4*/
if ( Inode[20] == 0xF30A && Inode[22] == 4 ) /*0x3009*/
{
LOWORD(BlockIdx) = 0; /*0x3013*/
p_BlockIdx = (unsigned __int16)Inode[21]; /*0x3017*/
Superblocka = 0; /*0x301b*/
if ( !(_WORD)p_BlockIdx ) /*0x3022*/
return -2147483638; /*0x30bc*/
while ( 1 ) /*0x302c*/
{
BlockIdx_1 = (unsigned __int16)BlockIdx; /*0x302c*/
ExtentOff = 6 * (unsigned __int16)BlockIdx; /*0x3031*/
StartBlock = LShiftU64((unsigned __int16)Inode_1[ExtentOff + 29]); /*0x303c*/
BlockAddr = MultU64x32(*(unsigned int *)&Inode[6 * BlockIdx_1 + 30] + StartBlock); /*0x3057*/
ChunkSize = v15 * (unsigned __int16)Inode[ExtentOff + 28]; /*0x3064*/
if ( *(_QWORD *)ReadSize <= (unsigned __int64)ChunkSize ) /*0x3071*/
break; /*0x3071*/
Status = ReadBlocks((int)BlockIo, MediaDesc, BlockAddr, ChunkSize, Buffer); /*0x3080*/
if ( Status < 0 ) /*0x308a*/
return Status; /*0x308a*/
v18 = *ReadSize < ChunkSize; /*0x3090*/
*ReadSize -= ChunkSize; /*0x3090*/
ReadSize[1] -= v18; /*0x3096*/
Inode_1 = Inode; /*0x309e*/
CurrentOffset += ChunkSize; /*0x309a*/
BlockIdx = Superblocka + 1; /*0x30a7*/
Superblocka = BlockIdx; /*0x30a8*/
if ( (unsigned __int16)BlockIdx >= (unsigned __int16)p_BlockIdx ) /*0x30b1*/
return -2147483638; /*0x30b1*/
}
Status = ReadBlocks((int)BlockIo, MediaDesc, BlockAddr, *ReadSize, Buffer); /*0x30cf*/
if ( Status < 0 ) /*0x30dd*/
{
*(_QWORD *)ReadSize = CurrentOffset; /*0x30df*/
return Status; /*0x30e8*/
}
v18 = __CFADD__((_DWORD)CurrentOffset, *ReadSize); /*0x30ed*/
*ReadSize += CurrentOffset; /*0x30ed*/
ReadSize[1] += HIDWORD(CurrentOffset) + v18; /*0x30f3*/
}
else
{
RootResult = ReadExt4Root(BlockIo, MediaDesc, Superblock, (int)Inode, &p_BlockIdx, &CurrentOffset); /*0x310f*/
if ( RootResult < 0 ) /*0x3116*/
{
*ReadSize = 0; /*0x3124*/
ReadSize[1] = 0; /*0x3126*/
DebugLogPrint(-1, (int)BlockIo, "\nFirst GetNextBlock failed\n"); /*0x3129*/
return RootResult; /*0x3133*/
}
HIDWORD(CurrentOffset) = Buffer; /*0x3140*/
while ( 1 ) /*0x314e*/
{
BlockOffset = MultU64x32(BlockGroupSz); /*0x314e*/
BlockOffHi = HIDWORD(BlockOffset); /*0x3156*/
v21 = ReadSize[1] == 0; /*0x315a*/
BlockOffset_1 = BlockOffset; /*0x3160*/
if ( v21 && *ReadSize <= BlockGroupSz ) /*0x3172*/
break; /*0x3172*/
ReadStatus = ReadBlocks((int)BlockIo, MediaDesc, BlockOffset, BlockGroupSz, HIDWORD(CurrentOffset)); /*0x3185*/
ReadStatus_1 = ReadStatus; /*0x318d*/
if ( ReadStatus < 0 ) /*0x3193*/
{
DebugLogPrint(-1, (int)BlockIo, "\nReading block failed, status = %r\n", ReadStatus); /*0x31fd*/
DebugLogPrint( /*0x321a*/
-1,
(int)BlockIo,
"\nOffset %lx, BlockSize %x, Block %x\n",
BlockOffset_1,
BlockOffHi,
BlockGroupSz);
return ReadStatus_1; /*0x3226*/
}
v18 = *ReadSize < BlockGroupSz; /*0x3199*/
*ReadSize -= BlockGroupSz; /*0x3199*/
ReadSize[1] -= v18; /*0x319f*/
NewTotal = BlockGroupSz + TotalRead; /*0x31a6*/
TotalHi = (__PAIR64__(TotalHi, BlockGroupSz) + TotalRead) >> 32; /*0x31a6*/
TotalRead += BlockGroupSz; /*0x31a6*/
HIDWORD(CurrentOffset) += BlockGroupSz; /*0x31ab*/
if ( ReadExt4Root(BlockIo, MediaDesc, Superblock, (int)Inode, &p_BlockIdx, &CurrentOffset) < 0 ) /*0x31cb*/
{
DebugLogPrint(-1, (int)BlockIo, "\nGetNextBlock failed\n"); /*0x31e5*/
*ReadSize = NewTotal; /*0x31ed*/
ReadSize[1] = TotalHi; /*0x31ef*/
return 0; /*0x31f2*/
}
if ( !*(_QWORD *)ReadSize ) /*0x31cd*/
return -2147483638; /*0x31d2*/
}
Blocks = (_WORD *)ReadBlocks((int)BlockIo, MediaDesc, BlockOffset, *ReadSize, HIDWORD(CurrentOffset)); /*0x323e*/
if ( (int)Blocks < 0 ) /*0x3244*/
{
DebugLogPrint(-1, (int)BlockIo, "\nReading partial block failed\n"); /*0x324e*/
*ReadSize = TotalRead; /*0x325a*/
ReadSize[1] = TotalHi; /*0x325c*/
return (int)Blocks; /*0x325f*/
}
*(_QWORD *)ReadSize += __PAIR64__(TotalHi, TotalRead); /*0x3261*/
}
return 0; /*0x3268*/
}
// Function: ReadExt4BlockBitmap @ 0x3270 (0x1ec bytes)
// Index: 60/77
int __fastcall ReadExt4BlockBitmap(int *BlockIo, int MediaDesc, int Superblock)
{
unsigned int OffsetBlocks; // esi
int BlockSize; // ebp
__int64 BaseAddr; // kr10_8
int Status; // eax
__int64 GroupOffset; // rdi
__int64 BlockAddr; // rax
unsigned int FileSizeLow; // ecx
__int64 FileSizeLow_1; // rax
unsigned int FileSize; // kr08_4
unsigned int NumPages; // esi
int AllocResult; // edi
unsigned int BlocksPerGroup; // [esp+10h] [ebp-3Ch]
unsigned __int64 gAllocBufPtr; // [esp+18h] [ebp-34h] BYREF
char *AllocBuf; // [esp+20h] [ebp-2Ch] BYREF
unsigned int EntryBuf[2]; // [esp+28h] [ebp-24h] BYREF
int BgbtVal; // [esp+30h] [ebp-1Ch]
OffsetBlocks = 0; /*0x3288*/
BlockSize = 1024 << *(_DWORD *)(Superblock + 24); /*0x328e*/
BaseAddr = MultU64x32((unsigned int)BlockSize); /*0x32a0*/
LODWORD(gAllocBufPtr) = HIDWORD(BaseAddr); /*0x32a0*/
BlocksPerGroup = 1; /*0x32aa*/
if ( !*(_DWORD *)(Superblock + 40) ) /*0x32ae*/
{
BlocksPerGroup = 1u % *(_DWORD *)(Superblock + 40); /*0x32ba*/
OffsetBlocks = 32 * (1u / *(_DWORD *)(Superblock + 40)); /*0x32be*/
}
if ( ReadBlocks( /*0x32e2*/
(int)BlockIo,
MediaDesc,
__PAIR64__(gAllocBufPtr, BaseAddr) + OffsetBlocks,
0x20u,
(unsigned int)EntryBuf) < 0 )
{
DebugLogPrint(-1, (int)BlockIo, "\nRead BGBT error\n"); /*0x32ec*/
return -2147483634; /*0x32f9*/
}
BgbtVal = BgbtVal; /*0x330c*/
GroupOffset = MultU64x32(BlocksPerGroup); /*0x331c*/
BlockAddr = MultU64x32((unsigned int)BlockSize); /*0x3323*/
if ( ReadBlocks((int)BlockIo, MediaDesc, BlockAddr + GroupOffset, 0x80u, gDataPtr + 2432) < 0 ) /*0x3350*/
{
DebugLogPrint(-1, (int)BlockIo, "\nRead dir inode error. Inode is %x\n", 2); /*0x335c*/
return -2147483634; /*0x3366*/
}
FileSizeLow_1 = LShiftU64(*(unsigned int *)(gDataPtr + 2540)); /*0x337b*/
FileSizeLow = FileSizeLow_1; /*0x3382*/
LODWORD(FileSizeLow_1) = gDataPtr; /*0x3384*/
FileSize = *(_DWORD *)(gDataPtr + 2436); /*0x3389*/
gAllocBufPtr = __PAIR64__(HIDWORD(FileSizeLow_1), FileSize) + FileSizeLow; /*0x338f*/
if ( byte_4BC1 ) /*0x33a0*/
{
if ( __PAIR64__(HIDWORD(FileSizeLow_1), FileSize) + FileSizeLow > (unsigned int)gAllocBufPtr ) /*0x341f*/
gAllocBufPtr = (unsigned int)gAllocBufPtr; /*0x3421*/
}
else
{
NumPages = ((((_WORD)FileSize + (_WORD)FileSizeLow) & 0xFFF) != 0) /*0x33b9*/
+ (unsigned int)RShiftU64(__PAIR64__(HIDWORD(FileSizeLow_1), FileSize) + FileSizeLow);
AllocResult = (*(int (__cdecl **)(int *, int, unsigned int, char **))(*BlockIo + 72))( /*0x33c8*/
BlockIo,
4,
NumPages,
&AllocBuf);
if ( AllocResult < 0 ) /*0x33cf*/
{
DebugLogPrint(-1, (int)BlockIo, "\nRead EXT dir allocate error\n"); /*0x33d9*/
return AllocResult; /*0x33e3*/
}
gTmpBufPtr = AllocBuf; /*0x33f0*/
gAllocBufPtr = NumPages << 12; /*0x33f5*/
ZeroMemEx((int)AllocBuf, AllocBuf, NumPages << 12, 0); /*0x33fb*/
LODWORD(FileSizeLow_1) = gDataPtr; /*0x3400*/
byte_4BC1 = 1; /*0x3408*/
}
Status = ReadExt4DirInode( /*0x3442*/
BlockIo,
MediaDesc,
Superblock,
(_WORD *)(FileSizeLow_1 + 2432),
(unsigned int)gTmpBufPtr,
(unsigned int *)&gAllocBufPtr);
n4096 = gAllocBufPtr; /*0x344b*/
return Status; /*0x3454*/
}
// Function: ReadExt4FileData @ 0x345c (0x2cc bytes)
// Index: 61/77
int __fastcall ReadExt4FileData(int *BlockIo, int MediaDesc, unsigned int *FileSize, unsigned int ZeroCheck)
{
int Status; // esi
unsigned int i; // eax
int BlockSize; // eax
__int64 BaseAddr; // rax
int EntryIndex; // ebp
unsigned int AdjustedBlock; // esi
int TableOffset; // ecx
int TableSlot; // ecx
__int64 BlockAddr; // rax
unsigned __int64 BaseAddr_2; // kr08_8
__int64 FileSizeHigh; // rax
unsigned int FileSizeLow; // kr04_4
unsigned int TotalFileSize; // kr10_4
int DirResult; // eax
int DirResult_1; // esi
int Superblock; // [esp-4h] [ebp-58h]
unsigned int AddrHi; // [esp+10h] [ebp-44h]
unsigned int BaseAddr_1; // [esp+14h] [ebp-40h]
unsigned int NumEntries; // [esp+18h] [ebp-3Ch] BYREF
unsigned int AdjustedBlock_1; // [esp+1Ch] [ebp-38h]
int BlockSize_1; // [esp+20h] [ebp-34h]
int BlockGroupSz; // [esp+24h] [ebp-30h]
__int64 ReadSize; // [esp+28h] [ebp-2Ch] BYREF
char EntryBuf[8]; // [esp+30h] [ebp-24h] BYREF
int BgbtVal; // [esp+38h] [ebp-1Ch]
Status = ReadBlocks((int)BlockIo, MediaDesc, 0, 0x200u, gDataPtr + 1920); /*0x3481*/
if ( Status < 0 ) /*0x3488*/
{
DebugLogPrint(-1, (int)BlockIo, "\nRead first sector failed\n"); /*0x3492*/
return Status; /*0x3499*/
}
for ( i = 0; i < 0x200; ++i ) /*0x34aa*/
{
if ( *(_BYTE *)(i + gDataPtr + 1920) ) /*0x34ac*/
{
DebugLogPrint(-1, (int)BlockIo, "\nFirst sector not blank\n"); /*0x3713*/
return -2147483634; /*0x3713*/
}
}
ReadBlocks((int)BlockIo, MediaDesc, 1024, 0x200u, gDataPtr + 1920); /*0x34c9*/
if ( *(_WORD *)(gDataPtr + 1976) != 0xEF53 /*0x3511*/
|| *(_DWORD *)(gDataPtr + 1944) >= 4u
|| *(_DWORD *)(gDataPtr + 1940) >= 2u
|| *(_DWORD *)(gDataPtr + 1932) >= *(_DWORD *)(gDataPtr + 1924)
|| *(_DWORD *)(gDataPtr + 1936) >= *(_DWORD *)(gDataPtr + 1920) )
{
DebugLogPrint(-1, (int)BlockIo, "\nIsExt failed\n"); /*0x3709*/
return -2147483634; /*0x3718*/
}
Superblock = gDataPtr + 1920; /*0x3517*/
byte_4BC1 = 0; /*0x351b*/
Status = ReadExt4BlockBitmap(BlockIo, MediaDesc, gDataPtr + 1920); /*0x3529*/
if ( Status < 0 ) /*0x352f*/
{
DebugLogPrint(-1, (int)BlockIo, "\nRead EXT root failed\n"); /*0x3536*/
return Status; /*0x3536*/
}
ReadElToritoBoot(Superblock, (char *)&NumEntries); /*0x3544*/
if ( !NumEntries ) /*0x3552*/
return -2147483634; /*0x3554*/
BlockSize = *(unsigned __int16 *)(gDataPtr + 2008); /*0x356d*/
BlockGroupSz = 1024 << *(_DWORD *)(gDataPtr + 1944); /*0x357a*/
BlockSize_1 = BlockSize; /*0x3582*/
BaseAddr = MultU64x32((unsigned int)BlockGroupSz); /*0x3587*/
BaseAddr_1 = BaseAddr; /*0x358f*/
EntryIndex = 0; /*0x3593*/
AddrHi = HIDWORD(BaseAddr); /*0x3595*/
while ( 1 ) /*0x35b2*/
{
AdjustedBlock = *(_DWORD *)dword_4C60[EntryIndex] - 1; /*0x35b2*/
TableOffset = 0; /*0x35b3*/
AdjustedBlock_1 = *(_DWORD *)(gDataPtr + 1960); /*0x35b5*/
if ( AdjustedBlock > AdjustedBlock_1 ) /*0x35bb*/
{
TableSlot = AdjustedBlock / AdjustedBlock_1; /*0x35c5*/
AdjustedBlock %= AdjustedBlock_1; /*0x35c7*/
TableOffset = 32 * TableSlot; /*0x35c9*/
}
if ( ReadBlocks( /*0x35ed*/
(int)BlockIo,
MediaDesc,
__PAIR64__(AddrHi, BaseAddr_1) + (unsigned int)TableOffset,
0x20u,
(unsigned int)EntryBuf) < 0 )
{
DebugLogPrint(-1, (int)BlockIo, "\nRead BGBT error\n"); /*0x3702*/
return -2147483634; /*0x3702*/
}
::BgbtVal = BgbtVal; /*0x35f7*/
BlockAddr = MultU64x32(AdjustedBlock); /*0x3606*/
BaseAddr_2 = MultU64x32((unsigned int)BlockGroupSz) + BlockAddr; /*0x3638*/
AddrHi = HIDWORD(BaseAddr_2); /*0x3638*/
BaseAddr_1 = BaseAddr_2; /*0x3638*/
if ( ReadBlocks((int)BlockIo, MediaDesc, __SPAIR64__(AddrHi, BaseAddr_1), 0x80u, gDataPtr + 2560) >= 0 ) /*0x3652*/
{
FileSizeHigh = LShiftU64(*(unsigned int *)(gDataPtr + 2668)); /*0x3663*/
FileSizeLow = *(_DWORD *)(gDataPtr + 2564); /*0x3670*/
ReadSize = FileSizeHigh + FileSizeLow; /*0x3676*/
TotalFileSize = FileSizeHigh + FileSizeLow; /*0x367a*/
DebugLogPrint(-1, (int)BlockIo, "\nSize of file found is %lx\n", (_DWORD)FileSizeHigh + FileSizeLow); /*0x368b*/
if ( *FileSize >= TotalFileSize ) /*0x3699*/
break; /*0x3699*/
}
if ( ++EntryIndex >= NumEntries ) /*0x36a0*/
return -2147483634; /*0x36a0*/
}
DirResult = ReadExt4DirInode( /*0x36cc*/
BlockIo,
MediaDesc,
gDataPtr + 1920,
(_WORD *)(gDataPtr + 2560),
ZeroCheck,
(unsigned int *)&ReadSize);
DirResult_1 = DirResult; /*0x36d1*/
if ( DirResult < 0 ) /*0x36d8*/
{
DebugLogPrint(-1, (int)BlockIo, "\nRead of file returned %r\n", DirResult); /*0x36f1*/
return DirResult_1; /*0x36f9*/
}
else
{
*FileSize = ReadSize; /*0x36e2*/
return 0; /*0x36e4*/
}
}
// Function: ReadIsoRoot @ 0x3728 (0xa8 bytes)
// Index: 62/77
int __cdecl ReadIsoRoot(int *i, int MftRef, unsigned int *FileSize, unsigned int ZeroCheck)
{
int result; // eax
int v5; // ebx
bool v6; // zf
*(_DWORD *)(MftRef + 21) = 0; /*0x3740*/
*(_DWORD *)(MftRef + 25) = 0; /*0x3743*/
result = ReadExt4FileData(i, MftRef, FileSize, ZeroCheck); /*0x3746*/
if ( result < 0 ) /*0x374f*/
{
result = ReadBlocks((int)i, MftRef, 0, 0x200u, gDataPtr); /*0x3763*/
if ( result >= 0 ) /*0x376d*/
{
if ( *(_WORD *)(gDataPtr + 510) == 0xAA55 ) /*0x3780*/
{
gPartIdx = 0; /*0x3782*/
gLbaOffset = 0; /*0x3788*/
ExtPartLbaOffset = 0; /*0x378e*/
gExtendFlag = 1; /*0x3794*/
do /*0x37c3*/
{
v5 = ParsePartitionEntry((int)i, MftRef); /*0x37a5*/
v6 = v5 == 0; /*0x37a7*/
if ( v5 >= 0 ) /*0x37a9*/
{
result = ReadExt4FileData(i, MftRef, FileSize, ZeroCheck); /*0x37b6*/
if ( result >= 0 ) /*0x37bf*/
return result; /*0x37bf*/
v6 = v5 == 0; /*0x37c1*/
}
}
while ( v6 ); /*0x37c3*/
}
return -2147483634; /*0x37c5*/
}
}
return result; /*0x37ca*/
}
// Function: ReadIsoDir @ 0x37d0 (0x9c bytes)
// Index: 63/77
char __fastcall ReadIsoDir(int i, int n4096, char *dst, _DWORD *p_RecoveryImageConfig)
{
int n4096_1; // ebp
unsigned __int16 v6; // di
unsigned __int8 v7; // bl
char *v8; // ecx
int n4096_3; // ebp
int n4096_4; // [esp-8h] [ebp-A0h]
int n4096_2; // [esp+10h] [ebp-88h]
char v13[128]; // [esp+18h] [ebp-80h] BYREF
n4096_1 = n4096; /*0x37d9*/
n4096_2 = n4096; /*0x37de*/
while ( 1 ) /*0x37e2*/
{
v6 = *(_WORD *)(i + 4); /*0x37e2*/
if ( !v6 ) /*0x37ed*/
return 0; /*0x385e*/
LOBYTE(n4096) = *(_BYTE *)(i + 6); /*0x37ef*/
v7 = 0; /*0x37f2*/
if ( (_BYTE)n4096 ) /*0x37f6*/
{
v8 = v13; /*0x37f8*/
v7 = *(_BYTE *)(i + 6); /*0x37fc*/
n4096_3 = (unsigned __int8)n4096; /*0x3805*/
do /*0x3811*/
{
*v8 = v8[i - (_DWORD)v13 + 8]; /*0x380b*/
++v8; /*0x380d*/
--n4096_3; /*0x380e*/
}
while ( n4096_3 ); /*0x3811*/
n4096_1 = n4096_2; /*0x3817*/
}
v13[v7] = 0; /*0x381e*/
if ( *dst ) /*0x382a*/
{
n4096_4 = (unsigned __int8)n4096; /*0x3837*/
LOBYTE(n4096) = 0; /*0x3838*/
if ( MatchNameWildcard(v13, n4096, n4096_4, dst) >= 0 ) /*0x3843*/
break; /*0x3843*/
}
i += v6; /*0x3848*/
n4096_1 -= v6; /*0x384a*/
n4096_2 = n4096_1; /*0x384c*/
if ( !n4096_1 ) /*0x3850*/
return 0; /*0x3850*/
}
*p_RecoveryImageConfig = i; /*0x3866*/
return 1; /*0x3854*/
}
// Function: ReadElToritoBoot @ 0x386c (0x82 bytes)
// Index: 64/77
char __cdecl ReadElToritoBoot(int Superblock, char *p_NumEntries)
{
int v2; // ecx
char *gTmpBufPtr; // ebx
char *p_NumEntries_1; // esi
int n4096; // edi
int RecoveryImageConfig; // eax
int v7; // eax
int NumEntries; // ecx
char dst[256]; // [esp+Ch] [ebp-108h] BYREF
int v11; // [esp+10Ch] [ebp-8h] BYREF
int p_RecoveryImageConfig; // [esp+110h] [ebp-4h] BYREF
gTmpBufPtr = gTmpBufPtr; /*0x3876*/
p_NumEntries_1 = p_NumEntries; /*0x3880*/
n4096 = n4096; /*0x3886*/
p_RecoveryImageConfig = 0; /*0x388d*/
*(_DWORD *)p_NumEntries = 0; /*0x3890*/
RecoveryImageConfig = GetRecoveryImageConfig(v2, &p_NumEntries, &v11, 0); /*0x3896*/
if ( RecoveryImageConfig >= 0 ) /*0x389f*/
{
v7 = StrLen(p_NumEntries); /*0x38a4*/
CopyMemEx((unsigned int)dst, p_NumEntries, v7 + 1); /*0x38b5*/
LOBYTE(RecoveryImageConfig) = ReadIsoDir((int)gTmpBufPtr, n4096, dst, &p_RecoveryImageConfig); /*0x38c9*/
if ( (_BYTE)RecoveryImageConfig ) /*0x38d3*/
{
NumEntries = *(_DWORD *)p_NumEntries_1; /*0x38d5*/
RecoveryImageConfig = p_RecoveryImageConfig; /*0x38d7*/
*(_DWORD *)p_NumEntries_1 = 1; /*0x38da*/
dword_4C60[NumEntries] = RecoveryImageConfig; /*0x38e0*/
}
}
return RecoveryImageConfig; /*0x38e7*/
}
// Function: ReadElToritoCatalog @ 0x38ee (0xcf bytes)
// Index: 65/77
int __fastcall ReadElToritoCatalog(
int buf,
int BootSector,
unsigned int i,
unsigned int n4,
unsigned int dst,
unsigned int dsta)
{
unsigned int i_1; // edi
__int64 v9; // rax
int Blocks; // eax
int Blocks_1; // esi
int result; // eax
unsigned int n4_2; // ebx
unsigned int n4_3; // ebp
int v15; // eax
__int64 v16; // rax
unsigned int n4_1; // [esp-8h] [ebp-1Ch]
unsigned int dsta_1; // [esp-4h] [ebp-18h]
unsigned int dst_1; // [esp-4h] [ebp-18h]
i_1 = i; /*0x38fc*/
if ( (_BYTE)dst ) /*0x3904*/
{
dsta_1 = dsta; /*0x3906*/
n4_1 = n4; /*0x3910*/
v9 = MultU64x32(i - 2); /*0x3917*/
Blocks = ReadBlocks(buf, BootSector, *(_QWORD *)(BootSector + 45) + v9, n4_1, dsta_1); /*0x392b*/
Blocks_1 = Blocks; /*0x3930*/
if ( Blocks < 0 ) /*0x3937*/
DebugLogPrint(-1, buf, "\nRead status is %r\n", Blocks); /*0x3942*/
return Blocks_1; /*0x394a*/
}
else
{
n4_2 = n4; /*0x3956*/
dst = dsta; /*0x395a*/
while ( 1 ) /*0x3969*/
{
n4_3 = n4_2; /*0x3969*/
v15 = WalkClusterChain(5, i_1, (char **)&i, 1); /*0x396b*/
if ( n4_2 > v15 * *(_DWORD *)(BootSector + 53) ) /*0x397c*/
n4_3 = v15 * *(_DWORD *)(BootSector + 53); /*0x397e*/
dst_1 = dst; /*0x3980*/
v16 = MultU64x32(i_1 - 2); /*0x398b*/
result = ReadBlocks(buf, BootSector, *(_QWORD *)(BootSector + 45) + v16, n4_3, dst_1); /*0x39a1*/
if ( result < 0 ) /*0x39ab*/
break; /*0x39ab*/
i_1 = i; /*0x39ad*/
if ( !i ) /*0x39b3*/
break; /*0x39b3*/
dst += n4_3; /*0x39b5*/
n4_2 -= n4_3; /*0x39b9*/
}
}
return result; /*0x394c*/
}
// Function: ReadIso9660_2 @ 0x39bd (0x172 bytes)
// Index: 66/77
int __fastcall ReadIso9660_2(int buf, int BootSector, int a3)
{
unsigned int v4; // ebx
int v5; // esi
unsigned int n0x20000; // edi
__int64 v7; // rax
bool v8; // cf
int result; // eax
unsigned int n4; // esi
int gAllocBufPtr; // eax
int v12; // ebx
char *gTmpBufPtr; // ecx
char *p_i; // [esp+14h] [ebp-Ch] BYREF
char *bufa; // [esp+18h] [ebp-8h] BYREF
p_i = 0; /*0x39d1*/
v4 = 1 << *(_BYTE *)(a3 + 108); /*0x39db*/
v5 = (v4 << *(_BYTE *)(a3 + 109)) / v4; /*0x39eb*/
n0x20000 = v4 * *(_DWORD *)(a3 + 84); /*0x39ed*/
*(_QWORD *)(BootSector + 29) = MultU64x32(*(unsigned int *)(a3 + 80)); /*0x3a04*/
*(_QWORD *)(BootSector + 45) = MultU64x32(*(unsigned int *)(a3 + 88)); /*0x3a1e*/
v7 = MultU64x32((unsigned int)(v5 * (*(_DWORD *)(a3 + 96) - 2))); /*0x3a34*/
v8 = __CFADD__(*(_DWORD *)(BootSector + 45), (_DWORD)v7); /*0x3a3e*/
*(_DWORD *)(BootSector + 37) = *(_DWORD *)(BootSector + 45) + v7; /*0x3a41*/
*(_DWORD *)(BootSector + 41) = *(_DWORD *)(BootSector + 49) + v8 + HIDWORD(v7); /*0x3a4b*/
*(_DWORD *)(BootSector + 53) = v4 << *(_BYTE *)(a3 + 109); /*0x3a57*/
*(_BYTE *)(BootSector + 12) = 5; /*0x3a5a*/
result = InitCache(buf, BootSector, n0x20000); /*0x3a5e*/
if ( result >= 0 ) /*0x3a68*/
{
n4 = WalkClusterChain(5, *(_DWORD *)(a3 + 96), &p_i, 0) * *(_DWORD *)(BootSector + 53); /*0x3a86*/
Index = n4 >> 5; /*0x3a9a*/
gAllocBufPtr = gAllocBufPtr; /*0x3aaa*/
if ( gAllocBufPtr >= ((n4 >> 12) + ((n4 & 0xFFF) != 0)) << 12 ) /*0x3ab6*/
{
gTmpBufPtr = gTmpBufPtr; /*0x3af7*/
}
else
{
v12 = (*(int (__cdecl **)(int, int, unsigned int, char **))(*(_DWORD *)buf + 72))( /*0x3ac7*/
buf,
4,
(n4 >> 12) + ((n4 & 0xFFF) != 0),
&bufa);
if ( v12 < 0 ) /*0x3ace*/
{
DebugLogPrint(-1, buf, "\nAllocate for root pages failed\n"); /*0x3ad8*/
return v12; /*0x3ae2*/
}
gTmpBufPtr = bufa; /*0x3ae4*/
gAllocBufPtr = ((n4 >> 12) + ((n4 & 0xFFF) != 0)) << 12; /*0x3ae8*/
gTmpBufPtr = bufa; /*0x3aea*/
gAllocBufPtr = gAllocBufPtr; /*0x3af0*/
}
ZeroMemEx(gAllocBufPtr, gTmpBufPtr, gAllocBufPtr, 0); /*0x3b01*/
return ReadElToritoCatalog(buf, BootSector, *(_DWORD *)(a3 + 96), n4, 0, (unsigned int)gTmpBufPtr); /*0x3b1f*/
}
return result; /*0x3b27*/
}
// Function: SearchVolume @ 0x3b2f (0x165 bytes)
// Index: 67/77
int __fastcall SearchVolume(int buf, int BootSector, unsigned int *a3, unsigned int i)
{
int v4; // edi
int Blocks; // ebx
unsigned __int8 n9; // cl
unsigned int dst_1; // ebp
int v11; // ecx
unsigned int n4; // ebx
int v13; // [esp-4h] [ebp-20h]
unsigned int dst; // [esp+14h] [ebp-8h] BYREF
int BootSectora; // [esp+18h] [ebp-4h]
v4 = 0; /*0x3b40*/
BootSectora = BootSector; /*0x3b4e*/
Blocks = ReadBlocks(buf, BootSector, 0, 0x200u, gDataPtr + 512); /*0x3b57*/
if ( Blocks < 0 ) /*0x3b5e*/
{
DebugLogPrint(-1, buf, "\nRead boot sector failed\n"); /*0x3b68*/
return Blocks; /*0x3b72*/
}
n9 = *(_BYTE *)(gDataPtr + 620); /*0x3b81*/
if ( n9 < 9u /*0x3bcc*/
|| n9 > 0xCu
|| *(_BYTE *)(gDataPtr + 523)
|| *(_BYTE *)(gDataPtr + 515) != 69
|| *(_BYTE *)(gDataPtr + 516) != 88
|| *(_BYTE *)(gDataPtr + 517) != 70
|| *(_BYTE *)(gDataPtr + 518) != 65
|| *(_BYTE *)(gDataPtr + 519) != 84 )
{
return -2147483634; /*0x3bcc*/
}
Blocks = ReadIso9660_2(buf, BootSector, gDataPtr + 512); /*0x3bdc*/
if ( Blocks < 0 ) /*0x3be1*/
{
DebugLogPrint(-1, buf, "\nRead root failed\n"); /*0x3be8*/
return Blocks; /*0x3be8*/
}
ValidateFwCapsule(v13, (char *)&dst); /*0x3bf6*/
dst_1 = dst; /*0x3bfb*/
if ( !dst ) /*0x3c04*/
return -2147483634; /*0x3c89*/
DebugLogPrint(-1, buf, "\nFound a recovery file\n"); /*0x3c0e*/
while ( 1 ) /*0x3c1a*/
{
v11 = dword_4C20[v4]; /*0x3c1a*/
n4 = *(_DWORD *)(v11 + 24); /*0x3c25*/
if ( *a3 >= n4 ) /*0x3c2a*/
break; /*0x3c2a*/
DebugLogPrint(-1, buf, "\nFile size is wrong, %x\n", *(_DWORD *)(v11 + 24)); /*0x3c35*/
LABEL_20:
if ( ++v4 >= dst_1 ) /*0x3c7b*/
return -2147483634; /*0x3c7b*/
}
LOBYTE(dst) = (*(_BYTE *)(v11 + 1) & 2) != 0; /*0x3c4e*/
if ( ReadElToritoCatalog(buf, BootSectora, *(_DWORD *)(v11 + 20), n4, dst, i) < 0 ) /*0x3c66*/
{
DebugLogPrint(-1, buf, "\nError reading recovery file\n"); /*0x3c70*/
goto LABEL_20; /*0x3c70*/
}
*a3 = n4; /*0x3c8e*/
return 0; /*0x3c82*/
}
// Function: ReadBgbt @ 0x3c94 (0xc3 bytes)
// Index: 68/77
int __cdecl ReadBgbt(int i, int BootSector, unsigned int *a3, unsigned int i_1)
{
int result; // eax
int Blocks; // ebx
int v6; // ebx
bool v7; // zf
*(_DWORD *)(BootSector + 21) = 0; /*0x3cb0*/
*(_DWORD *)(BootSector + 25) = 0; /*0x3cb3*/
result = SearchVolume(i, BootSector, a3, i_1); /*0x3cb6*/
if ( result < 0 ) /*0x3cbf*/
{
Blocks = ReadBlocks(i, BootSector, 0, 0x200u, gDataPtr); /*0x3cdb*/
if ( Blocks >= 0 ) /*0x3ce2*/
{
if ( *(_WORD *)(gDataPtr + 510) == 0xAA55 ) /*0x3d09*/
{
gExtendFlag = 1; /*0x3d0d*/
gPartIdx = 0; /*0x3d14*/
gLbaOffset = 0; /*0x3d19*/
ExtPartLbaOffset = 0; /*0x3d1e*/
do /*0x3d49*/
{
v6 = ParsePartitionEntry(i, BootSector); /*0x3d2c*/
v7 = v6 == 0; /*0x3d2e*/
if ( v6 >= 0 ) /*0x3d30*/
{
result = SearchVolume(i, BootSector, a3, i_1); /*0x3d3c*/
if ( result >= 0 ) /*0x3d45*/
return result; /*0x3d45*/
v7 = v6 == 0; /*0x3d47*/
}
}
while ( v7 ); /*0x3d49*/
}
return -2147483634; /*0x3d4b*/
}
else
{
DebugLogPrint(-1, i, "\nRead MBR failed\n"); /*0x3cec*/
return Blocks; /*0x3cf4*/
}
}
return result; /*0x3d50*/
}
// Function: GetRecoveryFileData @ 0x3d57 (0xfd bytes)
// Index: 69/77
char __usercall GetRecoveryFileData@<al>(int i@<edx>, unsigned int Index, char *dst, _DWORD *p_RecoveryImageConfig)
{
int v4; // edi
int i_1; // ebp
unsigned __int8 MaxLen_1; // bh
_WORD *j; // esi
char v8; // al
int v9; // eax
_BYTE *CaseSensitive_2; // ebp
int CaseSensitive; // edx
unsigned __int8 n15; // bl
bool v13; // zf
unsigned __int8 MaxLen_2; // [esp+12h] [ebp-8Eh]
unsigned __int8 MaxLen; // [esp+13h] [ebp-8Dh]
int CaseSensitive_1; // [esp+18h] [ebp-88h]
_WORD *v19; // [esp+1Ch] [ebp-84h]
char v20[128]; // [esp+20h] [ebp-80h] BYREF
v4 = 0; /*0x3d61*/
i_1 = i; /*0x3d63*/
if ( !Index ) /*0x3d70*/
return 0; /*0x3e42*/
MaxLen_1 = MaxLen; /*0x3d76*/
for ( j = (_WORD *)(i + 38); ; j += 16 ) /*0x3d7a*/
{
v8 = *((_BYTE *)j - 38); /*0x3d7d*/
if ( !v8 ) /*0x3d82*/
return 0; /*0x3d82*/
if ( v8 == -123 ) /*0x3d88*/
break; /*0x3d88*/
LABEL_17:
if ( ++v4 >= Index ) /*0x3e30*/
return 0; /*0x3e30*/
}
v9 = v4 + 1; /*0x3da0*/
if ( *((_BYTE *)j - 6) == 0xC0 ) /*0x3da3*/
{
MaxLen_1 = 0; /*0x3da8*/
MaxLen = *((_BYTE *)j - 3); /*0x3daa*/
MaxLen_2 = MaxLen; /*0x3dae*/
v9 = v4 + 2; /*0x3db2*/
*j = *(j - 17); /*0x3db5*/
v19 = j - 3; /*0x3db8*/
}
CaseSensitive_2 = (_BYTE *)(32 * v9 + i_1); /*0x3dbf*/
LABEL_8:
if ( *CaseSensitive_2 != 0xC1 ) /*0x3dc5*/
{
i_1 = i; /*0x3e21*/
goto LABEL_17; /*0x3e21*/
}
CaseSensitive = (int)CaseSensitive_2; /*0x3dc7*/
CaseSensitive_2 += 32; /*0x3dc9*/
CaseSensitive_1 = CaseSensitive; /*0x3dcc*/
n15 = 0; /*0x3dd0*/
while ( 1 ) /*0x3dd2*/
{
v13 = MaxLen_2-- == 1; /*0x3dd2*/
v20[MaxLen_1] = *(_BYTE *)(CaseSensitive + 2 * n15 + 2); /*0x3de1*/
if ( !v13 ) /*0x3de5*/
goto LABEL_14; /*0x3de5*/
n15 = 15; /*0x3dee*/
v20[MaxLen_1 + 1] = 0; /*0x3df0*/
if ( !*dst ) /*0x3df5*/
goto LABEL_14; /*0x3df8*/
LOBYTE(CaseSensitive) = 0; /*0x3e05*/
if ( MatchNameWildcard(v20, CaseSensitive, MaxLen, dst) >= 0 ) /*0x3e10*/
break; /*0x3e10*/
CaseSensitive = CaseSensitive_1; /*0x3e12*/
LABEL_14:
++n15; /*0x3e16*/
++MaxLen_1; /*0x3e18*/
if ( n15 >= 0xFu ) /*0x3e1d*/
goto LABEL_8; /*0x3e1d*/
}
*p_RecoveryImageConfig = v19; /*0x3e4e*/
return 1; /*0x3e38*/
}
// Function: ValidateFwCapsule @ 0x3e54 (0x81 bytes)
// Index: 70/77
char __cdecl ValidateFwCapsule(int a1, char *p_dst)
{
int v2; // ecx
unsigned int Index; // ebx
char *p_dst_1; // esi
char *gTmpBufPtr; // edi
int RecoveryImageConfig; // eax
int v7; // eax
int dst_1; // ecx
char dst[256]; // [esp+Ch] [ebp-108h] BYREF
int v11; // [esp+10Ch] [ebp-8h] BYREF
int p_RecoveryImageConfig; // [esp+110h] [ebp-4h] BYREF
Index = Index; /*0x3e5e*/
p_dst_1 = p_dst; /*0x3e68*/
gTmpBufPtr = gTmpBufPtr; /*0x3e6e*/
p_RecoveryImageConfig = 0; /*0x3e75*/
*(_DWORD *)p_dst = 0; /*0x3e78*/
RecoveryImageConfig = GetRecoveryImageConfig(v2, &p_dst, &v11, 0); /*0x3e7e*/
if ( RecoveryImageConfig >= 0 ) /*0x3e87*/
{
v7 = StrLen(p_dst); /*0x3e8c*/
CopyMemEx((unsigned int)dst, p_dst, v7 + 1); /*0x3e9d*/
LOBYTE(RecoveryImageConfig) = GetRecoveryFileData((int)gTmpBufPtr, Index, dst, &p_RecoveryImageConfig); /*0x3eb0*/
if ( (_BYTE)RecoveryImageConfig ) /*0x3eba*/
{
dst_1 = *(_DWORD *)p_dst_1; /*0x3ebc*/
RecoveryImageConfig = p_RecoveryImageConfig; /*0x3ebe*/
*(_DWORD *)p_dst_1 = 1; /*0x3ec1*/
dword_4C20[dst_1] = RecoveryImageConfig; /*0x3ec7*/
}
}
return RecoveryImageConfig; /*0x3ece*/
}
// Function: ValidateRecoveryParams @ 0x3ed5 (0x11b bytes)
// Index: 71/77
int __fastcall ValidateRecoveryParams(int a1, _DWORD *a2, _DWORD *a3, _BYTE *a4)
{
int result; // eax
int v7; // ebp
double v8; // [esp-8h] [ebp-30h]
int v9; // [esp+0h] [ebp-28h]
int (__cdecl **v10)(_DWORD, const __int16 *, _DWORD *, _DWORD, int *, char *); // [esp+10h] [ebp-18h] BYREF
int n29; // [esp+14h] [ebp-14h] BYREF
_DWORD v12[4]; // [esp+18h] [ebp-10h] BYREF
v10 = 0; /*0x3ee4*/
v12[0] = -1757269547; /*0x3ee8*/
v12[1] = 1154608459; /*0x3ef2*/
v12[2] = 1372483720; /*0x3efa*/
v12[3] = 1749926236; /*0x3f02*/
if ( !a2 && !a3 ) /*0x3f10*/
return -2147483645; /*0x3f17*/
if ( a4 ) /*0x3f22*/
*a4 = 1; /*0x3f24*/
if ( a3 ) /*0x3f29*/
{
DebugPrint(64, (int)"FW Capsule Info\nDefault Size %X\n", *a3); /*0x3f38*/
if ( *a3 < 0x1004000u ) /*0x3f47*/
*a3 = 16793600; /*0x3f49*/
if ( a2 ) /*0x3f4d*/
{
HIDWORD(v8) = *a3; /*0x3f53*/
LODWORD(v8) = *a2; /*0x3f55*/
DebugPrint(64, (int)"Default Name %a, Size %X\n", v8, v9); /*0x3f5e*/
result = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int (__cdecl ***)(_DWORD, const __int16 *, _DWORD *, _DWORD, int *, char *)))(*(_DWORD *)a1 + 32))( /*0x3f72*/
a1,
&unk_4B00,
0,
0,
&v10);
if ( result < 0 ) /*0x3f7a*/
return result; /*0x3f7a*/
n29 = 29; /*0x3f85*/
v7 = (*v10)(v10, L"AmiFlashUpd", v12, 0, &n29, &byte_4C00); /*0x3fa0*/
if ( v7 >= 0 ) /*0x3fa7*/
{
if ( byte_4C00 == 1 ) /*0x3fb0*/
{
if ( byte_4C05 ) /*0x3fb9*/
*a2 = &byte_4C05; /*0x3fbb*/
}
*a3 = dword_4C15; /*0x3fc6*/
(*(void (__cdecl **)(int, int))(*(_DWORD *)a1 + 44))(a1, 18); /*0x3fcd*/
}
DebugPrint(64, (int)"ReFlash variable %r\nImage Name %a, Size %X\n", v7, *a2, *a3); /*0x3fde*/
}
}
return 0; /*0x3fe8*/
}
// Function: GetImageHandle @ 0x3ff0 (0x32 bytes)
// Index: 72/77
int GetImageHandle()
{
int v0; // esi
_BYTE v2[2]; // [esp+4h] [ebp-8h] BYREF
int v3; // [esp+6h] [ebp-6h]
ReservedFunc2(v2); /*0x3ff9*/
v0 = *(_DWORD *)(v3 - 4); /*0x4001*/
if ( !v0 ) /*0x4006*/
DebugAssert( /*0x4015*/
(int)"e:\\hs\\MdePkg\\Library\\PeiServicesTablePointerLibIdt\\PeiServicesTablePointer.c",
48,
(int)"PeiServices != ((void *) 0)");
return v0; /*0x401d*/
}
// Function: GetDebugPrintLevel @ 0x4022 (0x4f bytes)
// Index: 73/77
int GetDebugPrintLevel()
{
unsigned __int8 v0; // al
char n3; // al
char n3_1; // cl
v0 = __inbyte(0x70u); /*0x4028*/
__outbyte(0x70u, v0 & 0x80 | 0x4A); /*0x402d*/
n3 = __inbyte(0x71u); /*0x4034*/
n3_1 = n3; /*0x4035*/
if ( (unsigned __int8)n3 <= 3u ) /*0x403a*/
{
LABEL_4:
if ( !n3_1 ) /*0x4055*/
return 0; /*0x4055*/
goto LABEL_5; /*0x4055*/
}
n3_1 = n3; /*0x403c*/
if ( !n3 ) /*0x4044*/
{
n3_1 = MEMORY[0xFDAF0490] & 2 | 1; /*0x4050*/
goto LABEL_4; /*0x4050*/
}
LABEL_5:
if ( n3_1 != -1 )
return n3_1 != 1 ? -2147483578 : -2147483644;
return 0; /*0x406d*/
}
// Function: ReservedFunc2 @ 0x4071 (0x23 bytes)
// Index: 74/77
void *__thiscall ReservedFunc2(void *this)
{
void *this_1; // eax
if ( !this ) /*0x4077*/
DebugAssert((int)"e:\\hs\\MdePkg\\Library\\BaseLib\\X86ReadIdtr.c", 37, (int)"Idtr != ((void *) 0)"); /*0x4086*/
this_1 = this; /*0x408c*/
__sidt(this); /*0x408f*/
return this_1; /*0x4093*/
}
// Function: ReservedFunc1 @ 0x40a0 (0xa bytes)
// Index: 75/77
// (too small: 0xa bytes)
// Function: ZeroMemEx @ 0x40aa (0x48 bytes)
// Index: 76/77
char *__usercall ZeroMemEx@<eax>(int value@<eax>, char *buf, unsigned int n4, char a4)
{
unsigned int n4_1; // ecx
char *buf_1; // edi
__int16 value_1; // bx
int value_2; // eax
int v8; // edx
char n4_2; // dl
unsigned int count; // ecx
n4_1 = n4; /*0x40aa*/
LOBYTE(value) = a4; /*0x40ae*/
buf_1 = buf; /*0x40b3*/
BYTE1(value) = a4; /*0x40bc*/
value_1 = value; /*0x40be*/
value_2 = value << 16; /*0x40c1*/
LOWORD(value_2) = value_1; /*0x40c4*/
if ( n4 >= 4 ) /*0x40ca*/
{
v8 = (unsigned __int8)buf & 3; /*0x40ce*/
if ( ((unsigned __int8)buf & 3) != 0 ) /*0x40d1*/
{
memset(buf, value_1, 4 - v8); /*0x40dc*/
buf_1 = &buf[4 - v8]; /*0x40dc*/
n4_1 = n4 - (4 - v8); /*0x40de*/
}
n4_2 = n4_1; /*0x40e0*/
count = n4_1 >> 2; /*0x40e2*/
memset32(buf_1, value_2, count); /*0x40e5*/
buf_1 += 4 * count; /*0x40e5*/
n4_1 = n4_2 & 3; /*0x40ea*/
}
memset(buf_1, value_1, n4_1); /*0x40ec*/
return buf; /*0x40f0*/
}
// Function: CopyMemEx @ 0x4100 (0x91 bytes)
// Index: 77/77
unsigned int __cdecl CopyMemEx(unsigned int dst, char *src, unsigned int n4)
{
char *src_1; // esi
unsigned int dst_1; // edi
unsigned int n4_1; // ecx
char v10; // dl
char *n4_2; // eax
unsigned int count; // eax
int count_1; // ebx
char n4_3; // al
unsigned int v15; // ecx
int n4_4; // eax
__asm { pushfw } /*0x4106*/
src_1 = src; /*0x410b*/
dst_1 = dst; /*0x410e*/
n4_1 = n4; /*0x4111*/
v10 = 0; /*0x4114*/
n4_2 = &src[-dst]; /*0x4118*/
if ( (unsigned int)src < dst ) /*0x411a*/
{
n4_2 = (char *)(dst - (_DWORD)src); /*0x411f*/
if ( (unsigned int)&src[n4] >= dst ) /*0x4123*/
{
src_1 = &src[n4]; /*0x4125*/
dst_1 = n4 + dst; /*0x4127*/
v10 = 1; /*0x412a*/
}
}
if ( n4 < 4 || (unsigned int)n4_2 < 4 ) /*0x4135*/
goto LABEL_19; /*0x4135*/
count = (unsigned __int8)src_1 & 3; /*0x413b*/
count_1 = dst_1 & 3; /*0x413e*/
if ( v10 ) /*0x4143*/
{
--src_1; /*0x4145*/
--dst_1; /*0x4146*/
}
if ( count == count_1 && count ) /*0x414d*/
{
if ( !v10 ) /*0x4151*/
count = 4 - count; /*0x4155*/
qmemcpy((void *)dst_1, src_1, count); /*0x415b*/
src_1 += count; /*0x415b*/
dst_1 += count; /*0x415b*/
n4_1 = n4 - count; /*0x415d*/
}
if ( v10 ) /*0x4161*/
{
src_1 -= 3; /*0x4163*/
dst_1 -= 3; /*0x4166*/
}
n4_3 = n4_1; /*0x4169*/
v15 = n4_1 >> 2; /*0x416b*/
qmemcpy((void *)dst_1, src_1, 4 * v15); /*0x416e*/
src_1 += 4 * v15; /*0x416e*/
dst_1 += 4 * v15; /*0x416e*/
n4_4 = n4_3 & 3; /*0x4170*/
if ( n4_4 ) /*0x4173*/
{
if ( v10 ) /*0x4177*/
{
src_1 += 4; /*0x4179*/
dst_1 += 4; /*0x417c*/
}
n4_1 = n4_4; /*0x417f*/
LABEL_19:
if ( v10 ) /*0x4183*/
{
--src_1; /*0x4185*/
--dst_1; /*0x4186*/
}
qmemcpy((void *)dst_1, src_1, n4_1); /*0x4187*/
}
__asm { popfw } /*0x4189*/
return dst; /*0x418c*/
}