⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i5comp.c

📁 InstallShield v5.x Compression
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	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 + -