Hi, I've been working some on a WDB reader lately I can't seem to figure how they compute the length, sometimes it's the first byte before the string but often it's packed in some weird way.
I remember pre mop they were just stored as normal null terminated strings, anyone who has done this before that could shed some light on this?
It's used like this in DbQuestCache_Unpack and many other places.
PHP Code:
LOWORD(a2a) = 0x800;
v6 = CDataStore::GetStrLen((CDataStore *)&v9, (int)store);
v7 = v6;
*(_DWORD *)(this + 0x14) = v6;
result = CDataStore::GetCString_2(v3, (void *)(this + 0x14), v6);
thisa = v3;
LOWORD(v14) = 0x800;
v10 = 2 * CDataStore::GetStrLen((CDataStore *)&thisa, a3);
*(_DWORD *)(v4 + 96) = v10 | CDataStore_sub_65BD22((CDataStore *)&thisa);// Set length for Name
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 608) = sub_67B804((CDataStore *)&thisa, a3);// Set length for ObjectiveText
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 3608) = sub_67B804((CDataStore *)&thisa, a3);// Set length for Description
LOBYTE(a3) = 0;
v11 = 2 * CDataStore::GetStrLen((CDataStore *)&thisa, a3);
*(_DWORD *)(v4 + 6608) = v11 | CDataStore_sub_65BD22((CDataStore *)&thisa);// Set length for EndText
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 7148) = sub_6816AA((CDataStore *)&thisa, a3);// Set length for PortraitGiverText
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 8172) = CDataStore::GetStrLen((CDataStore *)&thisa, a3);// Set length for PortraitGiverName
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 8428) = sub_6816AA((CDataStore *)&thisa, a3);// Set length for PortraitTurnInDescription
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 9452) = CDataStore::GetStrLen((CDataStore *)&thisa, a3);// Set length for PortraitTurnInName
LOBYTE(a3) = 0;
*(_DWORD *)(v4 + 9708) = sub_661CEC((CDataStore *)&thisa, a3);// Set length for CompletionText
All related subs
PHP Code:
unsigned int __thiscall sub_67B804(CDataStore *this, int _18)
{
int v2; // ebx@1
unsigned int v3; // eax@1
int a2; // [sp+Ch] [bp-4h]@0
LOBYTE(a2) = 0;
v2 = (int)this;
v3 = CDataStore::GetStrLen(this, a2);
LOBYTE(a2) = 0;
return 16 * v3 | CDataStore::GetLoByte(v2, a2);
}
int __thiscall sub_661CEC(CDataStore *this, int _18)
{
unsigned int v2; // eax@1
int a2; // [sp+Ch] [bp-4h]@0
LOBYTE(a2) = 0;
v2 = CDataStore::GetStrLen(this, a2);
LOBYTE(a2) = 0;
return 8 * v2 | sub_65BB09(a2);
}
unsigned int __thiscall CDataStore::GetStrLen(CDataStore *this, int a2)
{
char v3; // cl@1
unsigned int result; // eax@2
unsigned int v5; // esi@3
unsigned __int8 v6; // [sp+7h] [bp-1h]@1
v3 = BYTE1(this->m_data);
v6 = 0;
if ( v3 == 8 )
{
CDataStore::GetInt8((CDataStore *)&v6);
result = v6;
}
else
{
v5 = (unsigned int)LOBYTE(this->m_data) >> v3;
CDataStore::GetInt8((CDataStore *)&v6);
result = (v5 << BYTE1(this->m_data)) | ((unsigned int)v6 >> (8 - BYTE1(this->m_data)));
LOBYTE(this->m_data) = v6 << BYTE1(this->m_data);
}
return result;
}
unsigned int __thiscall CDataStore::GetLoByte(CDataStore *this, int a2)
{
CDataStore *v2; // esi@1
unsigned __int8 v3; // cl@1
unsigned __int8 v4; // dl@2
unsigned int result; // eax@2
unsigned int v6; // edi@5
unsigned __int8 v7; // bl@5
char v8; // dl@5
unsigned int v9; // eax@5
char v10; // cl@5
unsigned __int8 v11; // [sp+7h] [bp-1h]@3
v2 = this;
v3 = BYTE1(this->m_data);
if ( v3 > 4u )
{
v11 = 0;
if ( v3 == 8 )
{
CDataStore::GetInt8((CDataStore *)&v11);
result = (unsigned int)v11 >> 4;
LOBYTE(v2->m_data) = 16 * v11;
BYTE1(v2->m_data) = 4;
}
else
{
v6 = (unsigned int)LOBYTE(v2->m_data) >> v3;
CDataStore::GetInt8((CDataStore *)&v11);
v7 = v11;
v8 = BYTE1(v2->m_data) - 4;
v9 = (unsigned int)v11 >> (8 - v8);
v10 = BYTE1(v2->m_data) - 4;
BYTE1(v2->m_data) = v8;
result = (v6 << v10) | v9;
LOBYTE(v2->m_data) = v7 << v10;
}
}
else
{
v4 = LOBYTE(v2->m_data);
result = (unsigned int)v4 >> 4;
LOBYTE(v2->m_data) = 16 * v4;
BYTE1(v2->m_data) = v3 + 4;
}
return result;
}
unsigned int __thiscall CDataStore_sub_65BD22(CDataStore *this)
{
CDataStore *v1; // esi@1
unsigned __int8 v2; // cl@3
unsigned int result; // eax@3
char v4; // [sp+7h] [bp-1h]@2
v1 = this;
if ( BYTE1(this->m_data) == 8 )
{
v4 = 0;
CDataStore::GetInt8((CDataStore *)&v4);
LOBYTE(v1->m_data) = v4;
BYTE1(v1->m_data) = 0;
}
v2 = LOBYTE(v1->m_data);
result = (unsigned int)v2 >> 7;
++BYTE1(v1->m_data);
LOBYTE(v1->m_data) = 2 * v2;
return result;
}
unsigned int __thiscall CDataStore_sub_65BB09(CDataStore *this, int a2)
{
CDataStore *v2; // esi@1
unsigned __int8 v3; // cl@1
unsigned __int8 v4; // dl@2
unsigned int result; // eax@2
unsigned int v6; // edi@5
unsigned __int8 v7; // bl@5
char v8; // dl@5
unsigned int v9; // eax@5
char v10; // cl@5
unsigned __int8 v11; // [sp+7h] [bp-1h]@3
v2 = this;
v3 = BYTE1(this->m_data);
if ( v3 > 5u )
{
v11 = 0;
if ( v3 == 8 )
{
CDataStore::GetInt8((CDataStore *)&v11);
result = (unsigned int)v11 >> 5;
LOBYTE(v2->m_data) = 8 * v11;
BYTE1(v2->m_data) = 3;
}
else
{
v6 = (unsigned int)LOBYTE(v2->m_data) >> v3;
CDataStore::GetInt8((CDataStore *)&v11);
v7 = v11;
v8 = BYTE1(v2->m_data) - 5;
v9 = (unsigned int)v11 >> (8 - v8);
v10 = BYTE1(v2->m_data) - 5;
BYTE1(v2->m_data) = v8;
result = (v6 << v10) | v9;
LOBYTE(v2->m_data) = v7 << v10;
}
}
else
{
v4 = LOBYTE(v2->m_data);
result = (unsigned int)v4 >> 5;
LOBYTE(v2->m_data) = 8 * v4;
BYTE1(v2->m_data) = v3 + 3;
}
return result;
}