📄 i5comp.c
字号:
{
LPFILEGROUPDESC pFG;
LPFILEDESC pFile, pNewFile;
DWORD i, Start, End;
pFG = GetFileGroupDesc(pCabDesc, FileGroups, FGIndex);
Start = pFG->FirstFile;
End = pFG->LastFile + 1;
pFG->FirstFile = *NextFile;
for (i = Start; i < End; i++) {
pFile = GetFileDesc(OldT, pCabDesc->cDirs + i);
NewT[cNewDirs + *NextFile] = *ofsNextDesc;
*ofsNextDesc += sizeof(FILEDESC);
pNewFile = GetFileDesc(NewT, cNewDirs + *NextFile);
*pNewFile = *pFile;
if ( !(pNewFile->DescStatus & DESC_INVALID) ) {
LPSTR pNewName = GetString(NewT, *ofsNextName);
strcpy(pNewName, GetString(OldT, pFile->ofsName));
pNewFile->ofsName = *ofsNextName;
*ofsNextName += strlen(pNewName) + 1;
}
(*NextFile)++;
}
pFG->LastFile = *NextFile - 1;
}
LPDIRARRAY DirsArrayBuild()
{
LPDIRARRAY pDs;
DWORD i;
pDs = Alloc(sizeof(DIRARRAY) + pCabDesc->cDirs * sizeof(LPSTR));
for (i=0; i < pCabDesc->cDirs; i++)
pDs->Dirs[i] = GetString(DFT, DFT[i]);
pDs->Count = pCabDesc->cDirs;
return pDs;
}
long DirsArrayFind(LPDIRARRAY pDA, LPSTR DirName)
{
DWORD i;
i = 0;
while (i < pDA->Count && _stricmp(pDA->Dirs[i], DirName) != 0)
i++;
if (i < pDA->Count)
return i;
else
return -1;
}
long DirsArrayAddDir(LPDIRARRAY* ppDA, LPSTR DirName)
{
LPDIRARRAY pDs = *ppDA;
DWORD NewSize;
DWORD Ind;
Ind = DirsArrayFind(pDs, DirName);
if (Ind != -1)
return Ind;
NewSize = sizeof(DIRARRAY) + (pDs->Count + 1) * sizeof(LPSTR);
if (NewSize > _msize(pDs))
pDs = ReAlloc(pDs, NewSize + 3 * sizeof(LPSTR));
Ind = pDs->Count;
pDs->Dirs[Ind] = DirName;
pDs->Count++;
*ppDA = pDs;
return Ind;
}
void DeleteFiles()
{
LPFILEDESC pFile;
LPFILEGROUPDESC pFG;
HANDLE hCabWrite;
LPSTR pName;
DWORD i;
LPCABFILELIST pCurrent = pFileList;
if (!IsSingleVolume())
MultipleNotSupported();
hCabWrite = OpenForWrite(pCabPattern, OPEN_EXISTING);
while (pCurrent) {
i = pCurrent->CabIndex;
pFile = GetFileDesc(DFT, pCabDesc->cDirs + i);
pName = GetString(DFT, pFile->ofsName);
pFG = GetGroupByFile(i);
{// Clean out the old file from cab
HANDLE hCabRead;
DWORD MoveSize;
DWORD MoveShift;
DWORD i2;
DWORD FileSize;
DWORD Top, Bottom;
DWORD ofsTop;
DWORD ofsBottom;
LPFILEDESC pF;
hCabRead = OpenForRead(pCabPattern);
FileSize = ofsTop = GetFileSize(hCabRead, NULL);
ofsBottom = pFile->ofsData + pFile->cbCompressed;
// Find file right after the one removing and the last file
for (i2=0; i2 < pCabDesc->cFiles; i2++) {
pF = GetFileDesc(DFT, pCabDesc->cDirs + i2);
if (pF->DescStatus & DESC_INVALID)
continue;
if (pF->ofsData > pFile->ofsData && pF->ofsData < ofsTop) {
Top = i2;
ofsTop = pF->ofsData;
}
if (pF->ofsData > pFile->ofsData && pF->ofsData + pF->cbCompressed > ofsBottom) {
Bottom = i2;
ofsBottom = pF->ofsData + pF->cbCompressed;
}
}
MoveSize = FileSize - ofsTop;
MoveShift = ofsTop - pFile->ofsData;
SetFilePointer(hCabWrite, pFile->ofsData, NULL, FILE_BEGIN);
// Shift data up if necessary
if (MoveSize) {
SetFilePointer(hCabRead, ofsTop, NULL, FILE_BEGIN);
TransferData(hCabRead, hCabWrite, MoveSize, CRYPT_NONE);
}
CloseHandle(hCabRead);
SetEndOfFile(hCabWrite);
// Update file descriptors to reflect the change in file position
for (i2=0; i2 < pCabDesc->cFiles; i2++) {
pF = GetFileDesc(DFT, pCabDesc->cDirs + i2);
if (pF->DescStatus & DESC_INVALID)
continue;
if (pF->ofsData > pFile->ofsData)
pF->ofsData -= MoveShift;
}
}
if (optPrintAll) {
LPSTR pDir = GetString(DFT, DFT[pFile->DirIndex]);
if (*pDir != '\0')
fprintf(stderr, "%s\\", pDir);
fprintf(stderr, "%s\n", pName);
}
if (pFG) {
pFG->cbExpanded -= pFile->cbExpanded;
pFG->cbCompressed -= pFile->cbCompressed;
}
*pName = '\0';
pFile->DescStatus = DESC_INVALID;
pCurrent = pCurrent->pNext;
}
CloseHandle(hCabWrite);
SaveCabHeaders();
}
void ListFiles()
{
DWORD i;
LPFILEDESC pFile;
int files=0, osize=0, csize=0;
FILETIME filetime;
SYSTEMTIME systime;
LPSTR pDir, pName;
char attrs[5];
int ia;
LPCABFILELIST pCurrent = pFileList;
if (optPrintAll) {
fprintf(stderr, "\n");
fprintf(stderr, "Date Time OrigSize Attr CompSize Ind FileName\n");
fprintf(stderr, "========== ===== ========= ==== ========= ==== =================\n");
}
if (optFGasDir) {
for (i = 0; i < cFileGroups; i++) {
LPFILEGROUPDESC pFG = GetFileGroupDesc(pCabDesc, FileGroups, i);
fprintf(stdout, "01-01-2000 12:00 %9d ____ %9d %4d %s\\\n",
pFG->cbExpanded, pFG->cbCompressed, -1, GetString(pCabDesc, pFG->ofsName));
}
}
while (pCurrent) {
i = pCurrent->CabIndex;
pFile = GetFileDesc(DFT, pCabDesc->cDirs + i);
DosDateTimeToFileTime((WORD)pFile->FatDate, (WORD)pFile->FatTime, &filetime);
FileTimeToSystemTime(&filetime, &systime);
fprintf(stdout, "%02d-%02d-%04d %02d:%02d", systime.wMonth, systime.wDay, systime.wYear, systime.wHour, systime.wMinute);
strcpy(attrs, FileAttrChars);
for (ia=0; ia < 4; ia++)
if (!(pFile->Attrs & FileAttrVals[ia]))
attrs[ia] = '_';
fprintf(stdout, " %9d %s %9d %4d ", pFile->cbExpanded, attrs, pFile->cbCompressed, i);
pDir = GetString(DFT, DFT[pFile->DirIndex]);
if (optFGasDir)
fprintf(stdout, "%s\\", GetGroupNameByFile(i));
if (*pDir != '\0')
fprintf(stdout, "%s\\", pDir);
pName = GetString(DFT, pFile->ofsName);
fprintf(stdout, "%s\n", pName);
files++;
osize += pFile->cbExpanded;
csize += pFile->cbCompressed;
pCurrent = pCurrent->pNext;
}
if (optPrintAll) {
fprintf(stderr, " --------- --------- -------------------\n");
fprintf(stderr, " %9d %9d %4d file(s) total\n", osize, csize, files);
}
}
LPSTR GetGroupNameByFile(DWORD Index)
{
LPFILEGROUPDESC pFG = GetGroupByFile(Index);
return GetString(pCabDesc, pFG->ofsName);
}
void ListSetupTypes()
{
DWORD i;
LPSETUPTYPEDESC pST;
if (optPrintAll)
fprintf(stderr, "\nSetup Types\n===============\n");
for (i=0; i < cSetupTypes; i++) {
pST = GetSetupTypeDesc(pCabDesc, SetupTypes, i);
if (optPrintAll) fprintf(stderr, "Name : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pST->ofsName));
if (optPrintAll) fprintf(stderr, "Display Name : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pST->ofsDispName));
if (optPrintAll) fprintf(stderr, "Description : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pST->ofsDescription));
if (optPrintAll) fprintf(stderr, "\n");
}
}
void ListComponents()
{
DWORD i, fgi;
LPCOMPONENTDESC pComp;
if (optPrintAll)
fprintf(stderr, "\nComponents\n===============\n");
for (i=0; i < cComponents; i++) {
pComp = GetCompDesc(pCabDesc, Components, i);
if (optPrintAll) fprintf(stderr, "Name : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pComp->ofsName));
if (optPrintAll) fprintf(stderr, "Display Name : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pComp->ofsDispName));
if (optPrintAll) fprintf(stderr, "Description : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pComp->ofsDescription));
if (optPrintAll) fprintf(stderr, "Target Dir : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pComp->ofsTargetDir));
if (optPrintAll) fprintf(stderr, "Password : ");
fprintf(stdout, "%s\n", GetString(pCabDesc, pComp->ofsPassword));
if (optPrintAll) fprintf(stderr, "File Groups : ");
for (fgi=0; fgi < pComp->cFileGroups; fgi++) {
fprintf(stdout, "%s", GetString(pCabDesc, ((LPDWORD)((LPBYTE)pCabDesc + pComp->ofsFileGroups))[fgi]));
if (fgi + 1 != pComp->cFileGroups)
fprintf(stdout, ", ");
}
fprintf(stdout, "\n");
if (optPrintAll) fprintf(stderr, "\n");
}
}
void ListFileGroups()
{
DWORD i;
LPFILEGROUPDESC pFG;
DWORD Start, End;
if (optPrintAll) {
fprintf(stderr, "\n");
fprintf(stderr, "VB - Cab volume number where the group begins (1-based)\n");
fprintf(stderr, "VE - Cab volume number where the group ends\n");
fprintf(stderr, "FF - Index of the first file in the group (0-based)\n");
fprintf(stderr, "LF - Index of the last file in the group\n");
fprintf(stderr, "\n");
fprintf(stderr, " OrigSize CompSize VB VE FF LF Ind Name\n");
fprintf(stderr, "========= ========= === === ==== ==== === =====================\n");
}
if (optFileGroup == -1)
Start = 0, End = cFileGroups;
else
Start = optFileGroup, End = optFileGroup + 1;
for (i = Start; i < End; i++) {
pFG = GetFileGroupDesc(pCabDesc, FileGroups, i);
fprintf(stdout, "%9d %9d %3d %3d %4d %4d %3d %s\n",
pFG->cbExpanded, pFG->cbCompressed,
pFG->FirstVolume, pFG->LastVolume, pFG->FirstFile, pFG->LastFile,
i,
GetString(pCabDesc, pFG->ofsName));
}
}
void CantReadFile(int code)
{
fprintf(stderr, "\nCan not read from file, error code %d\n", code);
CleanExit(3);
}
void CantWriteFile(int code)
{
fprintf(stderr, "\nCan not write to file, error code %d\n", code);
CleanExit(12);
}
void CantOpenFile(LPSTR filename)
{
fprintf(stderr, "\nCould not open %s\n", filename);
CleanExit(2);
}
void NotIShield5()
{
fprintf(stderr, "\nThis does not look like IShield 5 cab =)\nAre u sure u know what u are doing ?\n");
CleanExit(4);
}
void InvalidCab()
{
fprintf(stderr, "\nInvalid or unsupported cab file\n");
CleanExit(9);
}
void NoMemory()
{
fprintf(stderr, "\nCan not grab enough memory, giving up =)\nGo get a better 'puter !");
CleanExit(6);
}
void MultipleNotSupported()
{
fprintf(stderr, "\nThis operation is not supported on a multi-volume cab\nConvert to a single volume first\n");
CleanExit(10);
}
void CantDecompress(LPSTR filename)
{
fprintf(stderr, "SJiT! Can not decompress %s. ZData returned an error\n", filename);
}
void CantCompressError(LPSTR filename)
{
fprintf(stderr, "SJiT! Can not compress %s. ZData returned an error\n", filename);
CleanExit(13);
}
void CantCompressStore(LPSTR filename)
{
fprintf(stderr, "SJiT! Can not compress %s. Storing...\n", filename);
}
void NotInAnyGroups(LPSTR filename)
{
fprintf(stderr, "\n%s is not in any FileGroups\n", filename);
}
void InvalidFileIndex()
{
fprintf(stderr, "\nInvalid file index specified\n");
CleanExit(12);
}
void BadFileGroup()
{
fprintf(stderr, "Invalid FileGroup specified\n");
CleanExit(22);
}
void NotEnoughParams(LPSTR str)
{
fprintf(stderr, "%sNot enough parameters\n", str);
CleanExit(24);
}
void NoFilesMatched()
{
fprintf(stderr, "\nNo files matched the criteria, duh !\n");
CleanExit(0);
}
void ExceptInDecompress()
{
fprintf(stderr, "\nException in decompression routine\nDid you forget to specify -v<n> ?\n(or if u did, try a different one =)\n");
CleanExit(26);
}
void GeneralException()
{
fprintf(stderr, "\nAn exception occured\nThis might be a new version of InstallShield unsupported at this moment\n");
CleanExit(27);
}
void TooManyEntries(LPSTR str)
{
fprintf(stderr, "\nToo many %s, recompile with a larger buffer\n", str);
CleanExit(28);
}
void NoMatchBytesOut()
{
fprintf(stderr, " WARNING: file size does not match File Descriptor in cab");
}
HANDLE OpenForRead(LPSTR filename)
{
HANDLE hnd;
hnd = CreateFile(filename,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_RANDOM_ACCESS,
NULL);
if (hnd == INVALID_HANDLE_VALUE)
CantOpenFile(filename);
return hnd;
}
HANDLE OpenForWrite(LPSTR filename, DWORD Flags)
{
HANDLE hnd;
hnd = CreateFile(filename,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
Flags,
FILE_FLAG_RANDOM_ACCESS,
NULL);
if (hnd == INVALID_HANDLE_VALUE)
CantOpenFile(filename);
return hnd;
}
HANDLE OpenForAccess(LPSTR filename, DWORD Access)
{
HANDLE hnd;
hnd = CreateFile(filename,
Access,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_RANDOM_ACCESS,
NULL);
if (hnd == INVALID_HANDLE_VALUE)
CantOpenFile(filename);
return hnd;
}
void ReadCabHeader(HANDLE hCab)
{
DWORD dwRead;
if (!ReadFile(hCab, &CabHdr, sizeof(CabHdr), &dwRead, NULL) ||
dwRead != sizeof(CabHdr))
CantReadFile(GetLastError());
if (CabHdr.Signature != CAB_SIG)
NotIShield5();
if (!(CabHdr.Version & 0x01000000))
NotIShield5();
if (!IsFirstVolume()) {
fprintf(stderr, "Can only operate on the first cab volume\n");
CleanExit(5);
}
}
HANDLE ReadCabHeaderFile(LPSTR cabfile, DWORD Access)
{
LPSTR pdot;
CHAR CabHeader[512];
HANDLE hFile;
strcpy(CabHeader, cabfile);
pdot = strrchr(CabHeader, '.');
if (pdot == 0)
pdot = CabHeader + strlen(CabHeader);
strcpy(pdot, ".hdr");
hFile = OpenForAccess(CabHeader, Access);
ReadCabHeader(hFile);
return hFile;
}
void InitCabFile(LPSTR cabfile, DWORD Access)
{
DWORD dwRead;
hCabFile = OpenForAccess(cabfile, Access);
// Read Cab header
ReadCabHeader(hCabFile);
if (CabHdr.cbCabDesc == 0) {
// cab descriptor is in .hdr file
ver = ver55;
// copy first vol hdr to its place
_FirstVolHdr = CabHdr;
hCabHdr = ReadCabHeaderFile(cabfile, Access);
} else {
// all in one file - older version
hCabHdr = OpenForAccess(cabfile, Access);
FirstVolHdr = &CabHdr;
}
pCabDesc = Alloc(CabHdr.cbCabDesc);
// Read Cab Descriptor and all descriptor data
SetFilePointer(hCabHdr, CabHdr.ofsCabDesc, NULL, FILE_BEGIN);
if (!ReadFile(hCabHdr, pCabDesc, CabHdr.cbCabDesc, &dwRead, NULL) ||
dwRead != CabHdr.cbCabDesc)
CantReadFile(GetLastError());
{// Calculate Setup Types table location
LPSETUPTYPEHEADER pSTH;
pSTH = (LPSETUPTYPEHEADER) ((LPBYTE)pCabDesc + pCabDesc->ofsSTypes);
cSetupTypes = pSTH->cSTypes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -