You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

755 lines
19 KiB

//HEADER_GOES_HERE
#include "../types.h"
int mpqapi_cpp_init_value; // weak
int sgdwMpqOffset; // idb
char mpq_buf[4096];
_HASHENTRY *sgpHashTbl;
bool save_archive_modified; // weak
_BLOCKENTRY *sgpBlockTbl;
bool save_archive_open; // weak
const int mpqapi_inf = 0x7F800000; // weak
//note: 32872 = 32768 + 104 (sizeof(_FILEHEADER))
/* data */
HANDLE sghArchive = (HANDLE)0xFFFFFFFF; // idb
struct mpqapi_cpp_init {
mpqapi_cpp_init()
{
mpqapi_cpp_init_value = mpqapi_inf;
}
} _mpqapi_cpp_init;
// 47F148: using guessed type int mpqapi_inf;
// 659B00: using guessed type int mpqapi_cpp_init_value;
bool __fastcall mpqapi_set_hidden(const char *pszArchive, bool hidden)
{
const char *v2; // edi
BOOL v3; // esi
DWORD v4; // eax
bool result; // al
DWORD v6; // esi
v2 = pszArchive;
v3 = hidden;
v4 = GetFileAttributes(pszArchive);
if (v4 == -1)
return GetLastError() == ERROR_FILE_NOT_FOUND;
v6 = v3 != 0 ? FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN : 0;
if (v4 == v6)
result = 1;
else
result = SetFileAttributes(v2, v6);
return result;
}
void __fastcall mpqapi_store_creation_time(const char *pszArchive, int dwChar)
{
int v2; // esi
const char *v3; // ebx
HANDLE v4; // eax
int v5; // esi
struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h]
char dst[160]; // [esp+148h] [ebp-A0h]
v2 = dwChar;
v3 = pszArchive;
if (gbMaxPlayers != 1) {
mpqapi_reg_load_modification_time(dst, 160);
v4 = FindFirstFile(v3, &FindFileData);
if (v4 != (HANDLE)-1) {
FindClose(v4);
v5 = 16 * v2;
*(_DWORD *)&dst[v5] = FindFileData.ftCreationTime.dwLowDateTime;
*(_DWORD *)&dst[v5 + 4] = FindFileData.ftCreationTime.dwHighDateTime;
mpqapi_reg_store_modification_time(dst, 160);
}
}
}
// 679660: using guessed type char gbMaxPlayers;
bool __fastcall mpqapi_reg_load_modification_time(char *dst, int size)
{
unsigned int v2; // esi
char *v3; // edi
unsigned int v6; // esi
char *v7; // ecx
int nbytes_read; // [esp+8h] [ebp-4h]
v2 = size;
v3 = dst;
memset(dst, 0, size);
if (!SRegLoadData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2, (unsigned long *)&nbytes_read) || nbytes_read != v2)
return 0;
if (v2 >= 8) {
v6 = v2 >> 3;
do {
v7 = v3;
v3 += 8;
mpqapi_xor_buf(v7);
--v6;
} while (v6);
}
return 1;
}
void __fastcall mpqapi_xor_buf(char *pbData)
{
signed int v1; // eax
char *v2; // esi
signed int v3; // edi
v1 = 0xF0761AB;
v2 = pbData;
v3 = 8;
do {
*v2 ^= v1;
++v2;
v1 = _rotl(v1, 1);
--v3;
} while (v3);
}
void __fastcall mpqapi_update_multi_creation_time(DWORD dwChar)
{
}
bool __fastcall mpqapi_reg_store_modification_time(char *pbData, int dwLen)
{
int v2; // ebx
char *v3; // ebp
char *v4; // edi
unsigned int v5; // esi
char *v6; // ecx
v2 = dwLen;
v3 = pbData;
v4 = pbData;
if ((unsigned int)dwLen >= 8) {
v5 = (unsigned int)dwLen >> 3;
do {
v6 = v4;
v4 += 8;
mpqapi_xor_buf(v6);
--v5;
} while (v5);
}
return SRegSaveData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2);
}
void __fastcall mpqapi_remove_hash_entry(const char *pszName)
{
int v1; // eax
_HASHENTRY *v2; // ecx
_BLOCKENTRY *v3; // eax
int v4; // esi
int v5; // edi
v1 = mpqapi_get_hash_index_of_path(pszName);
if (v1 != -1) {
v2 = &sgpHashTbl[v1];
v3 = &sgpBlockTbl[v2->block];
v2->block = -2;
v4 = v3->offset;
v5 = v3->sizealloc;
memset(v3, 0, 0x10u);
mpqapi_free_block(v4, v5);
save_archive_modified = 1;
}
}
// 65AB0C: using guessed type int save_archive_modified;
void __fastcall mpqapi_free_block(int block_offset, int block_size)
{
int v2; // esi
int v3; // edi
_BLOCKENTRY *v4; // eax
signed int v5; // edx
signed int v6; // ecx
int v7; // ecx
bool v8; // zf
_BLOCKENTRY *v9; // eax
v2 = block_size;
v3 = block_offset;
LABEL_2:
v4 = sgpBlockTbl;
v5 = 2048;
while (1) {
v6 = v5--;
if (!v6)
break;
v7 = v4->offset;
if (v4->offset && !v4->flags && !v4->sizefile) {
if (v7 + v4->sizealloc == v3) {
v3 = v4->offset;
LABEL_11:
v2 += v4->sizealloc;
memset(v4, 0, 0x10u);
goto LABEL_2;
}
if (v3 + v2 == v7)
goto LABEL_11;
}
++v4;
}
v8 = v3 + v2 == sgdwMpqOffset;
if (v3 + v2 > sgdwMpqOffset) {
TermMsg("MPQ free list error");
v8 = v3 + v2 == sgdwMpqOffset;
}
if (v8) {
sgdwMpqOffset = v3;
} else {
v9 = mpqapi_new_block(0);
v9->offset = v3;
v9->sizealloc = v2;
v9->sizefile = 0;
v9->flags = 0;
}
}
_BLOCKENTRY *__fastcall mpqapi_new_block(int *block_index)
{
_BLOCKENTRY *result; // eax
unsigned int v2; // edx
result = sgpBlockTbl;
v2 = 0;
while (result->offset || result->sizealloc || result->flags || result->sizefile) {
++v2;
++result;
if (v2 >= 0x800) {
TermMsg("Out of free block entries");
return 0;
}
}
if (block_index)
*block_index = v2;
return result;
}
int __fastcall mpqapi_get_hash_index_of_path(const char *pszName) // FetchHandle
{
const char *v1; // esi
int v2; // ST00_4
int v3; // edi
short v4; // ax
v1 = pszName;
v2 = Hash(pszName, 2); // MPQ_HASH_NAME_B
v3 = Hash(v1, 1); // MPQ_HASH_NAME_A
v4 = Hash(v1, 0); // MPQ_HASH_TABLE_INDEX
return mpqapi_get_hash_index(v4, v3, v2, 0);
}
int __fastcall mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale)
{
int v4; // ecx
signed int v5; // eax
signed int v6; // edx
_HASHENTRY *v7; // ecx
int v8; // edi
int v10; // [esp+Ch] [ebp-8h]
int i; // [esp+10h] [ebp-4h]
v4 = index & 0x7FF;
v10 = hash_a;
v5 = 2048;
for (i = v4;; i = (i + 1) & 0x7FF) {
v7 = &sgpHashTbl[v4];
v8 = v7->block;
if (v8 == -1)
return -1;
v6 = v5--;
if (!v6)
return -1;
if (v7->hashcheck[0] == v10 && v7->hashcheck[1] == hash_b && v7->lcid == locale && v8 != -2)
break;
v4 = (i + 1) & 0x7FF;
}
return i;
}
void __fastcall mpqapi_remove_hash_entries(BOOL(__stdcall *fnGetName)(DWORD, char *))
{
BOOL(__stdcall * v1)
(DWORD, char *); // edi
DWORD v2; // esi
BOOL i; // eax
DWORD v4; // eax
char v5[260]; // [esp+8h] [ebp-104h]
v1 = fnGetName;
v2 = 1;
for (i = fnGetName(0, v5); i; i = v1(v4, v5)) {
mpqapi_remove_hash_entry(v5);
v4 = v2++;
}
}
BOOL __fastcall mpqapi_write_file(const char *pszName, const BYTE *pbData, DWORD dwLen)
{
const BYTE *v3; // edi
const char *v4; // esi
_BLOCKENTRY *v5; // eax
v3 = pbData;
v4 = pszName;
save_archive_modified = 1;
mpqapi_remove_hash_entry(pszName);
v5 = mpqapi_add_file(v4, 0, 0);
if (mpqapi_write_file_contents(v4, v3, dwLen, v5))
return 1;
mpqapi_remove_hash_entry(v4);
return 0;
}
// 65AB0C: using guessed type int save_archive_modified;
_BLOCKENTRY *__fastcall mpqapi_add_file(const char *pszName, _BLOCKENTRY *pBlk, int block_index)
{
const char *v3; // edi
short v4; // si
int v5; // ebx
signed int v6; // edx
int v7; // esi
int v8; // ecx
int v9; // esi
int v11; // [esp+Ch] [ebp-8h]
_BLOCKENTRY *v12; // [esp+10h] [ebp-4h]
v12 = pBlk;
v3 = pszName;
v4 = Hash(pszName, 0);
v5 = Hash(v3, 1);
v11 = Hash(v3, 2);
if (mpqapi_get_hash_index(v4, v5, v11, 0) != -1)
TermMsg("Hash collision between \"%s\" and existing file\n", v3);
v6 = 2048;
v7 = v4 & 0x7FF;
while (1) {
--v6;
v8 = sgpHashTbl[v7].block;
if (v8 == -1 || v8 == -2)
break;
v7 = (v7 + 1) & 0x7FF;
if (!v6) {
v6 = -1;
break;
}
}
if (v6 < 0)
TermMsg("Out of hash space");
if (!v12)
v12 = mpqapi_new_block(&block_index);
v9 = v7;
sgpHashTbl[v9].hashcheck[0] = v5;
sgpHashTbl[v9].hashcheck[1] = v11;
sgpHashTbl[v9].lcid = 0;
sgpHashTbl[v9].block = block_index;
return v12;
}
bool __fastcall mpqapi_write_file_contents(const char *pszName, const BYTE *pbData, int dwLen, _BLOCKENTRY *pBlk)
{
const char *v4; // esi
const char *v5; // eax
unsigned int destsize; // ebx
const char *v7; // eax
unsigned int v8; // esi
_BLOCKENTRY *v9; // edi
int v10; // eax
signed int v11; // eax
unsigned int v13; // eax
unsigned int v14; // eax
int v15; // ecx
int size; // [esp+Ch] [ebp-10h]
const BYTE *v17; // [esp+10h] [ebp-Ch]
int v18; // [esp+14h] [ebp-8h]
DWORD nNumberOfBytesToWrite; // [esp+18h] [ebp-4h]
v4 = pszName;
v17 = pbData;
v5 = strchr(pszName, ':');
destsize = 0;
while (v5) {
v4 = v5 + 1;
v5 = strchr(v5 + 1, ':');
}
while (1) {
v7 = strchr(v4, '\\');
if (!v7)
break;
v4 = v7 + 1;
}
Hash(v4, 3);
v8 = dwLen;
v9 = pBlk;
size = 4 * ((unsigned int)(dwLen + 4095) >> 12) + 4;
nNumberOfBytesToWrite = 4 * ((unsigned int)(dwLen + 4095) >> 12) + 4;
v10 = mpqapi_find_free_block(size + dwLen, &pBlk->sizealloc);
v9->offset = v10;
v9->sizefile = v8;
v9->flags = 0x80000100;
if (SetFilePointer(sghArchive, v10, NULL, FILE_BEGIN) == -1)
return 0;
pBlk = 0;
v18 = 0;
while (v8) {
v11 = 0;
do
mpq_buf[v11++] -= 86;
while (v11 < 4096);
dwLen = v8;
if (v8 >= 0x1000)
dwLen = 4096;
memcpy(mpq_buf, v17, dwLen);
v17 += dwLen;
dwLen = PkwareCompress(mpq_buf, dwLen);
if (!v18) {
nNumberOfBytesToWrite = size;
pBlk = (_BLOCKENTRY *)DiabloAllocPtr(size);
memset(pBlk, 0, nNumberOfBytesToWrite);
if (!WriteFile(sghArchive, pBlk, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0))
goto LABEL_25;
destsize += nNumberOfBytesToWrite;
}
*(&pBlk->offset + v18) = destsize;
if (!WriteFile(sghArchive, mpq_buf, dwLen, (LPDWORD)&dwLen, 0))
goto LABEL_25;
++v18;
if (v8 <= 0x1000)
v8 = 0;
else
v8 -= 4096;
destsize += dwLen;
}
*(&pBlk->offset + v18) = destsize;
if (SetFilePointer(sghArchive, -destsize, NULL, FILE_CURRENT) == -1
|| !WriteFile(sghArchive, pBlk, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0)
|| SetFilePointer(sghArchive, destsize - nNumberOfBytesToWrite, NULL, FILE_CURRENT) == -1) {
LABEL_25:
if (pBlk)
mem_free_dbg(pBlk);
return 0;
}
mem_free_dbg(pBlk);
v13 = v9->sizealloc;
if (destsize < v13) {
v14 = v13 - destsize;
if (v14 >= 0x400) {
v15 = destsize + v9->offset;
v9->sizealloc = destsize;
mpqapi_free_block(v15, v14);
}
}
return 1;
}
int __fastcall mpqapi_find_free_block(int size, int *block_size)
{
_BLOCKENTRY *v2; // eax
signed int v3; // esi
int result; // eax
int v5; // esi
bool v6; // zf
v2 = sgpBlockTbl;
v3 = 2048;
while (1) {
--v3;
if (v2->offset) {
if (!v2->flags && !v2->sizefile && v2->sizealloc >= (unsigned int)size)
break;
}
++v2;
if (!v3) {
*block_size = size;
result = sgdwMpqOffset;
sgdwMpqOffset += size;
return result;
}
}
v5 = v2->offset;
*block_size = size;
v2->offset += size;
v6 = v2->sizealloc == size;
v2->sizealloc -= size;
if (v6)
memset(v2, 0, 0x10u);
return v5;
}
void __fastcall mpqapi_rename(char *pszOld, char *pszNew)
{
char *v2; // esi
int v3; // eax
_HASHENTRY *v4; // eax
int v5; // ST00_4
_BLOCKENTRY *v6; // edx
v2 = pszNew;
v3 = mpqapi_get_hash_index_of_path(pszOld);
if (v3 != -1) {
v4 = &sgpHashTbl[v3];
v5 = v4->block;
v6 = &sgpBlockTbl[v5];
v4->block = -2;
mpqapi_add_file(v2, v6, v5);
save_archive_modified = 1;
}
}
// 65AB0C: using guessed type int save_archive_modified;
BOOL __fastcall mpqapi_has_file(const char *pszName)
{
return mpqapi_get_hash_index_of_path(pszName) != -1;
}
BOOL __fastcall mpqapi_open_archive(const char *pszArchive, BOOL hidden, int dwChar) // OpenMPQ
{
const char *v3; // ebp
BOOL v4; // esi
DWORD v6; // edi
int v8; // eax
int v10; // eax
const char *lpFileName; // [esp+10h] [ebp-70h]
DWORD dwTemp; // [esp+14h] [ebp-6Ch]
_FILEHEADER fhdr; // [esp+18h] [ebp-68h]
v3 = pszArchive;
v4 = hidden;
lpFileName = pszArchive;
InitHash();
if (!mpqapi_set_hidden(v3, v4))
return 0;
v6 = (unsigned char)gbMaxPlayers > 1u ? FILE_FLAG_WRITE_THROUGH : 0;
save_archive_open = 0;
sghArchive = CreateFile(v3, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, v6, NULL);
if (sghArchive == (HANDLE)-1) {
sghArchive = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, v6 | (v4 != 0 ? FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN : 0), NULL);
if (sghArchive == (HANDLE)-1)
return 0;
save_archive_open = 1;
save_archive_modified = 1;
}
if (!sgpBlockTbl || !sgpHashTbl) {
memset(&fhdr, 0, 0x68u);
if (!mpqapi_parse_archive_header(&fhdr, &sgdwMpqOffset)) {
LABEL_15:
mpqapi_close_archive(lpFileName, 1, dwChar);
return 0;
}
sgpBlockTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000);
memset(sgpBlockTbl, 0, 0x8000u);
if (fhdr.blockcount) {
if (SetFilePointer(sghArchive, 104, NULL, FILE_BEGIN) == -1
|| !ReadFile(sghArchive, sgpBlockTbl, 0x8000u, &dwTemp, NULL)) {
goto LABEL_15;
}
v8 = Hash("(block table)", 3);
Decrypt(sgpBlockTbl, 0x8000, v8);
}
sgpHashTbl = (_HASHENTRY *)DiabloAllocPtr(0x8000);
memset(sgpHashTbl, 255, 0x8000u);
if (fhdr.hashcount) {
if (SetFilePointer(sghArchive, 32872, NULL, FILE_BEGIN) == -1
|| !ReadFile(sghArchive, sgpHashTbl, 0x8000u, &dwTemp, NULL)) {
goto LABEL_15;
}
v10 = Hash("(hash table)", 3);
Decrypt(sgpHashTbl, 0x8000, v10);
}
}
return 1;
}
// 65AB0C: using guessed type int save_archive_modified;
// 65AB14: using guessed type char save_archive_open;
// 679660: using guessed type char gbMaxPlayers;
bool __fastcall mpqapi_parse_archive_header(_FILEHEADER *pHdr, int *pdwNextFileStart) // ParseMPQHeader
{
int *v2; // ebp
_FILEHEADER *v3; // esi
DWORD v4; // eax
DWORD v5; // edi
DWORD NumberOfBytesRead; // [esp+10h] [ebp-4h]
v2 = pdwNextFileStart;
v3 = pHdr;
v4 = GetFileSize(sghArchive, 0);
v5 = v4;
*v2 = v4;
if (v4 == -1
|| v4 < 0x68
|| !ReadFile(sghArchive, v3, 0x68u, &NumberOfBytesRead, NULL)
|| NumberOfBytesRead != 104
|| v3->signature != '\x1AQPM'
|| v3->headersize != 32
|| v3->version > 0u
|| v3->sectorsizeid != 3
|| v3->filesize != v5
|| v3->hashoffset != 32872
|| v3->blockoffset != 104
|| v3->hashcount != 2048
|| v3->blockcount != 2048) {
if (SetFilePointer(sghArchive, 0, NULL, FILE_BEGIN) == -1 || !SetEndOfFile(sghArchive))
return 0;
memset(v3, 0, 0x68u);
v3->signature = '\x1AQPM';
v3->headersize = 32;
v3->sectorsizeid = 3;
v3->version = 0;
*v2 = 0x10068;
save_archive_modified = 1;
save_archive_open = 1;
}
return 1;
}
// 65AB0C: using guessed type int save_archive_modified;
// 65AB14: using guessed type char save_archive_open;
void __fastcall mpqapi_close_archive(const char *pszArchive, BOOL bFree, int dwChar) // CloseMPQ
{
const char *v3; // esi
_BLOCKENTRY *v4; // ecx
_HASHENTRY *v5; // ecx
v3 = pszArchive;
if (bFree) {
v4 = sgpBlockTbl;
sgpBlockTbl = 0;
mem_free_dbg(v4);
v5 = sgpHashTbl;
sgpHashTbl = 0;
mem_free_dbg(v5);
}
if (sghArchive != (HANDLE)-1) {
CloseHandle(sghArchive);
sghArchive = (HANDLE)-1;
}
if (save_archive_modified) {
save_archive_modified = 0;
mpqapi_store_modified_time(v3, dwChar);
}
if (save_archive_open) {
save_archive_open = 0;
mpqapi_store_creation_time(v3, dwChar);
}
}
// 65AB0C: using guessed type int save_archive_modified;
// 65AB14: using guessed type char save_archive_open;
void __fastcall mpqapi_store_modified_time(const char *pszArchive, int dwChar)
{
int v2; // esi
const char *v3; // ebx
HANDLE v4; // eax
int v5; // esi
struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h]
char dst[160]; // [esp+148h] [ebp-A0h]
v2 = dwChar;
v3 = pszArchive;
if (gbMaxPlayers != 1) {
mpqapi_reg_load_modification_time(dst, 160);
v4 = FindFirstFile(v3, &FindFileData);
if (v4 != (HANDLE)-1) {
FindClose(v4);
v5 = 16 * v2;
*(_DWORD *)&dst[v5 + 8] = FindFileData.ftLastWriteTime.dwLowDateTime;
*(_DWORD *)&dst[v5 + 12] = FindFileData.ftLastWriteTime.dwHighDateTime;
mpqapi_reg_store_modification_time(dst, 160);
}
}
}
// 679660: using guessed type char gbMaxPlayers;
void __fastcall mpqapi_flush_and_close(const char *pszArchive, BOOL bFree, int dwChar)
{
if (sghArchive != (HANDLE)-1) {
if (save_archive_modified) {
if (mpqapi_can_seek()) {
if (mpqapi_write_header()) {
if (mpqapi_write_block_table())
mpqapi_write_hash_table();
}
}
}
}
mpqapi_close_archive(pszArchive, bFree, dwChar);
}
// 65AB0C: using guessed type int save_archive_modified;
bool __cdecl mpqapi_write_header() // WriteMPQHeader
{
bool result; // al
_FILEHEADER fhdr; // [esp+8h] [ebp-6Ch]
DWORD NumberOfBytesWritten; // [esp+70h] [ebp-4h]
memset(&fhdr, 0, 0x68u);
fhdr.signature = '\x1AQPM';
fhdr.headersize = 32;
fhdr.filesize = GetFileSize(sghArchive, 0);
fhdr.version = 0;
fhdr.sectorsizeid = 3;
fhdr.hashoffset = 32872;
fhdr.blockoffset = 104;
fhdr.hashcount = 2048;
fhdr.blockcount = 2048;
if (SetFilePointer(sghArchive, 0, NULL, FILE_BEGIN) != -1 && WriteFile(sghArchive, &fhdr, 0x68u, &NumberOfBytesWritten, 0))
result = NumberOfBytesWritten == 104;
else
result = 0;
return result;
}
bool __cdecl mpqapi_write_block_table()
{
int v1; // eax
BOOL v2; // ebx
int v3; // eax
DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h]
if (SetFilePointer(sghArchive, 104, NULL, FILE_BEGIN) == -1)
return 0;
v1 = Hash("(block table)", 3);
Encrypt(sgpBlockTbl, 0x8000, v1);
v2 = WriteFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesWritten, 0);
v3 = Hash("(block table)", 3);
Decrypt(sgpBlockTbl, 0x8000, v3);
return v2 && NumberOfBytesWritten == 0x8000;
}
bool __cdecl mpqapi_write_hash_table()
{
int v1; // eax
BOOL v2; // ebx
int v3; // eax
DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h]
if (SetFilePointer(sghArchive, 32872, NULL, FILE_BEGIN) == -1)
return 0;
v1 = Hash("(hash table)", 3);
Encrypt(sgpHashTbl, 0x8000, v1);
v2 = WriteFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesWritten, 0);
v3 = Hash("(hash table)", 3);
Decrypt(sgpHashTbl, 0x8000, v3);
return v2 && NumberOfBytesWritten == 0x8000;
}
bool __cdecl mpqapi_can_seek()
{
bool result; // al
if (SetFilePointer(sghArchive, sgdwMpqOffset, NULL, FILE_BEGIN) == -1)
result = 0;
else
result = SetEndOfFile(sghArchive);
return result;
}