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

📄 i5comp.c

📁 InstallShield v5.x Compression
💻 C
📖 第 1 页 / 共 4 页
字号:
		SetupTypes = (SETUPTYPETABLE) ((LPBYTE)pCabDesc + pSTH->ofsSTypeTab);
	}

	{// Calculate Components & File Groups tables location
		DWORD ofsEntry;
		long i;

		cComponents = 0;
		Components = (COMPONENTTABLE) Alloc(CSFG_MAX * sizeof(Components[0]));

		for (i = 0; i < CFG_MAX; i++) {
			ofsEntry = pCabDesc->ofsComponent[i];
			while (ofsEntry != 0) {
				Components[cComponents++] = GetCompEntry(pCabDesc, ofsEntry)->ofsDesc;
				ofsEntry = GetCompEntry(pCabDesc, ofsEntry)->ofsNext;
				if (cComponents >= CSFG_MAX)
					TooManyEntries("Components");
			}
		}

 		cFileGroups = 0;
		FileGroups = (FILEGROUPTABLE) Alloc(CSFG_MAX * sizeof(FileGroups[0]));

		for (i = 0; i < CFG_MAX; i++) {
			ofsEntry = pCabDesc->ofsFileGroup[i];
			while (ofsEntry != 0) {
				FileGroups[cFileGroups++] = GetFileGroupEntry(pCabDesc, ofsEntry)->ofsDesc;
				ofsEntry = GetFileGroupEntry(pCabDesc, ofsEntry)->ofsNext;
				if (cFileGroups >= CSFG_MAX)
					TooManyEntries("File Groups");
			}
		}
	}

	// Read Dirs & Files table
	DFT = Alloc(pCabDesc->cbDFT);
	SetFilePointer(hCabHdr, CabHdr.ofsCabDesc + pCabDesc->ofsDFT, NULL, FILE_BEGIN);
	if (!ReadFile(hCabHdr, DFT, pCabDesc->cbDFT, &dwRead, NULL) ||
		dwRead != pCabDesc->cbDFT)
		CantReadFile(GetLastError());

	// generate Cab filename pattern
	if (IsSingleVolume()) {
		pCabPattern = Alloc(strlen(cabfile) + 1);
		strcpy(pCabPattern, cabfile);
	} else {
		LPSTR pdot;
		int pos;
		pCabPattern = Alloc(strlen(cabfile) + 2);
		strcpy(pCabPattern, cabfile);
		pdot = strrchr(cabfile, '.');
		pos = pdot ? pdot - cabfile : strlen(cabfile);
		pCabPattern[pos - 1] = '\0';
		strcat(pCabPattern, "%d");
		if (pdot)
			strcat(pCabPattern, pdot);
	}
}

void SaveCabHeaders()
{
	DWORD dwWritten;

	SetFilePointer(hCabHdr, 0, NULL, FILE_BEGIN);
	if (!WriteFile(hCabHdr, &CabHdr, sizeof(CabHdr), &dwWritten, NULL) ||
		dwWritten != sizeof(CabHdr))
			CantWriteFile(GetLastError());
	
	SetFilePointer(hCabHdr, CabHdr.ofsCabDesc, NULL, FILE_BEGIN);
	if (!WriteFile(hCabHdr, pCabDesc, CabHdr.cbCabDesc, &dwWritten, NULL) ||
		dwWritten != CabHdr.cbCabDesc)
			CantWriteFile(GetLastError());

	SetFilePointer(hCabHdr, CabHdr.ofsCabDesc + pCabDesc->ofsDFT, NULL, FILE_BEGIN);
	if (!WriteFile(hCabHdr, DFT, pCabDesc->cbDFT, &dwWritten, NULL) ||
		dwWritten != pCabDesc->cbDFT)
		CantWriteFile(GetLastError());

	SetFilePointer(hCabFile, 0, NULL, FILE_BEGIN);
	if (!WriteFile(hCabFile, FirstVolHdr, sizeof(CABHEADER), &dwWritten, NULL) ||
		dwWritten != sizeof(CABHEADER))
			CantWriteFile(GetLastError());
}

BOOL IsSingleVolume()
{
	return FirstVolHdr->NextVol == 0;
}

BOOL IsFirstVolume()
{
	return FirstVolHdr->NextVol == 0 || FirstVolHdr->NextVol == 2;
}

void InitCompressLib()
{
	if (ZDataInit(optVersion)) {
		fprintf(stderr, "Could not load/init the much needed ZData dll\n");
		CleanExit(1);
	}
}

BOOL TranslatePathToGroup(LPSTR* ppPath, LPSTR* ppFGName)
{
	LPSTR pSlash;
	DWORD i;

	*ppFGName = NULL;

	if (*ppPath == NULL || !optFGasDir)
		return FALSE;

	if (**ppPath == '\\')
		*ppPath++;

	// attemp to parse out FG Name
	pSlash = strchr(*ppPath, '\\');
	// slash found: either a dir or FG name
	if (pSlash)
		*pSlash = 0;

	i = GetGroupIndexByName(*ppPath);
	if (i != -1) {		// it's an FG name
		optFileGroup = i;
		*ppFGName = *ppPath;
		if (pSlash) {	// there is more of path/mask in a param
			*ppPath = pSlash + 1;
		} else			// it was FG only
			*ppPath = NULL;
		return TRUE;
	}
	
	// it wasn't an FG name
	if (pSlash)	// restore the path
		*pSlash = '\\';
	
	return FALSE;
}

// both params may be NULL
void CabBasedFileList(LPSTR CabParam, LPSTR DiskParam)
{
	long CabInd;
	BOOL CabByName = FALSE;
	BOOL CabIsMask = FALSE;
	BOOL DiskIsDir = FALSE;
	char dparam[MAX_PATH];
	char buf[MAX_PATH];
	LPFILEDESC pFile;
	LPSTR pDir;
	LPSTR pName;
	LPCABFILELIST pCurrent;
	DWORD NewSize;
	DWORD i, Start, End;
	LPSTR pFGName = NULL;

	// check if file-index 
	CabInd = strtolong(CabParam);
	
	if (CabInd == -1) {	// not an index
		TranslatePathToGroup(&CabParam, &pFGName);
		CabByName = TRUE;
		CabIsMask = IsMask(CabParam);

	} else if (CabInd < 0 || CabInd > (long)pCabDesc->cFiles - 1)
		InvalidFileIndex();
	
	if (CabIsMask || (!DiskParam) || DiskParam[strlen(DiskParam) - 1] == '\\')
		DiskIsDir = TRUE;
	
	if (DiskParam) {
		strcpy(dparam, DiskParam);
		if (DiskIsDir && DiskParam[strlen(DiskParam) - 1] != '\\')
			strcat(dparam, "\\");
	} else
		dparam[0] = '\0';

	if (!CabByName) {
		if (optFileGroup != -1)
			fprintf(stderr, "WARNING: FileGroup specified when referencing file by index, option ignored\n");
		pFile = GetFileDesc(DFT, pCabDesc->cDirs + CabInd);
		if (pFile->DescStatus & DESC_INVALID)
			InvalidFileIndex();
		buf[0] = '\0';
		if (DiskIsDir) {
			strcat(buf, dparam);
			pDir = GetString(DFT, DFT[pFile->DirIndex]);
			if (optRecurseSubdirs && *pDir != '\0') {
				strcat(buf, pDir);
				strcat(buf, "\\");
			}
			strcat(buf, GetString(DFT, pFile->ofsName));
		} else
			strcat(buf, dparam);
		pFileList = Alloc(sizeof(CABFILELIST) + strlen(buf) + 1);
		pFileList->CabIndex = CabInd;
		pFileList->pNext = NULL;
		strcpy(pFileList->FileName, buf);
		FileCount = 1;

		return;
	}

	if (optFileGroup == -1) {
		Start = 0;
		End = pCabDesc->cFiles;
	} else {
		LPFILEGROUPDESC pFG = GetFileGroupDesc(pCabDesc, FileGroups, optFileGroup);
		Start = pFG->FirstFile;
		End = pFG->LastFile + 1;
	}
	for (i = Start; i < End; i++) {
		pFile = GetFileDesc(DFT, pCabDesc->cDirs + i);
		if (pFile->DescStatus & DESC_INVALID)
			continue;
		
		buf[0] = '\0';
		pDir = GetString(DFT, DFT[pFile->DirIndex]);
		pName = GetString(DFT, pFile->ofsName);
		
		if (optMatchWithDirs && *pDir != '\0') {
			strcat(buf, pDir);
			strcat(buf, "\\");
		}
		strcat(buf, pName);

		if (!WildMatch(buf, CabParam))
			continue;

		buf[0] = '\0';
		if (DiskIsDir) {
			strcat(buf, dparam);
			if (optRecurseSubdirs) {
				if (pFGName != NULL)
					strcat(strcat(buf, pFGName), "\\");
				if (*pDir != '\0')
					strcat(strcat(buf, pDir), "\\");
			}
			strcat(buf, pName);
		} else
			strcat(buf, dparam);
		
		NewSize = sizeof(CABFILELIST) + strlen(buf) + 1;
		if (pFileList) {
			pCurrent->pNext = Alloc(NewSize);
			pCurrent = pCurrent->pNext;
		} else {
			pFileList = Alloc(NewSize);
			pCurrent = pFileList;
		}
		pCurrent->CabIndex = i;
		pCurrent->pNext = NULL;
		strcpy(pCurrent->FileName, buf);
		FileCount++;
	}
	if (!FileCount)
		NoFilesMatched();
}

// DiskParam may not be NULL
void DiskBasedFileList(LPSTR CabParam, LPSTR DiskParam)
{
	char cpath[MAX_PATH] = "";
	char begdp[MAX_PATH] = "";
	char curdp[MAX_PATH] = "";
	char mask[MAX_PATH];
	char tmpdp[MAX_PATH] = "";
	char nulldp[] = "";
	long tmp;
	LPSTR pFGName = NULL;


	if (CabParam) {	// we were passed a Cab Path
		// parse out the path
		TranslatePathToGroup(&CabParam, &pFGName);

		if (CabParam) {
			strcpy(cpath, CabParam);
			tmp = strlen(cpath);
			if (cpath[tmp - 1] == '\\')
				cpath[tmp - 1] = '\0';
		}
	}

	if (pFGName == NULL) {	// there was no Group in CabParam
		if (TranslatePathToGroup(&DiskParam, &pFGName)) {
			// path resolved to FileGroup name
			strcat(strcpy(begdp, pFGName), "\\");
			if (DiskParam == NULL)
				DiskParam = nulldp;
		}
	}

	tmp = strlen(DiskParam);
	if (IsMask(DiskParam)) {
		// we were passed a mask parse out starting dir and file mask
		LPSTR pSlash;
		pSlash = strrchr(DiskParam, '\\');
		if (pSlash) {
			tmp = pSlash - DiskParam + 1;
			strncpy(tmpdp, DiskParam, tmp);
			tmpdp[tmp] = '\0';
			pSlash++;
		} else {
			pSlash = DiskParam;
		}
		strcpy(mask, pSlash);

	} else if (tmp == 0 || DiskParam[tmp - 1] == '\\' || DirExists(DiskParam)) {
		// we were passed a dir - parse it
		// or it was a Group name
		LPSTR pSlash;
		strcpy(tmpdp, DiskParam);
		if (DiskParam[tmp - 1] == '\\')
			tmpdp[tmp - 1] = '\0';
		pSlash = strrchr(tmpdp, '\\');
		if (!pSlash)
			pSlash = tmpdp - 1;
		pSlash++;
		strcpy(curdp, pSlash);
		*pSlash = '\0';
		strcpy(mask, "*");
	
	} else { // we were passed a file
		LPSTR pSlash;
		strcpy(tmpdp, DiskParam);
		pSlash = strrchr(tmpdp, '\\');
		if (!pSlash)
			pSlash = tmpdp - 1;
		pSlash++;
		strcpy(mask, pSlash);
		*pSlash = '\0';
	}
	
	if (*tmpdp != 0)
		strcat(strcat(begdp, tmpdp), "\\");

	RecurseBuildDiskList(begdp, curdp, mask, cpath);
	if (!FileCount)
		NoFilesMatched();
}

void RecurseBuildDiskList(LPSTR BegDP, LPSTR CurDP, LPSTR Mask, LPSTR CabPath)
{
	HANDLE hFind;
	WIN32_FIND_DATA fd;
	char buf[MAX_PATH];
	BOOL Found;
	LPSTR pSubDir;
	static LPDISKFILELIST pCurrent;

	strcpy(buf, BegDP);
	strcat(buf, CurDP);
	if (*CurDP != '\0')
		strcat(buf, "\\");
	strcat(buf, "*");

	hFind = FindFirstFile(buf, &fd);
	if (hFind == INVALID_HANDLE_VALUE)
		return;
	
	// setup CurDirPath for subsequent recursive calls
	strcpy(buf, CurDP);
	pSubDir = strchr(buf, '\0');
	if (pSubDir != buf)
		*(pSubDir++) = '\\';

	Found = TRUE;
	while (Found) {
		if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			if (optRecurseSubdirs &&
					strcmp(fd.cFileName, ".") != 0 &&
					strcmp(fd.cFileName, "..") != 0) {
				strcpy(pSubDir, fd.cFileName);
				RecurseBuildDiskList(BegDP, buf, Mask, CabPath);
			}
		} else if (WildMatch(fd.cFileName, Mask) && 
					!(CurDP[0] == '\0' && _stricmp(pCabPattern, fd.cFileName) == 0) ) { // matched the wildcard
			DWORD Size;
			DWORD ofsDisk, ofsCab;
			Size = sizeof(DISKFILELIST) + strlen(fd.cFileName) + 1; // size of struct + size of FileName
			ofsDisk = Size;
			Size += strlen(BegDP) + strlen(CurDP) + 2; // size of disk path
			ofsCab = Size;
			Size += strlen(CabPath) + 2;
			if (optRecurseSubdirs)
				Size += strlen(CurDP);
			
			if (pDiskList) {
				pCurrent->pNext = Alloc(Size);
				pCurrent = pCurrent->pNext;
			} else {
				pDiskList = Alloc(Size);
				pCurrent = pDiskList;
			}
			strcpy(pCurrent->FileName, fd.cFileName);
			
			pCurrent->DiskDir = (LPSTR)pCurrent + ofsDisk;
			strcpy(pCurrent->DiskDir, BegDP);
			strcat(pCurrent->DiskDir, CurDP);
			if (CurDP[0] != '\0')
				strcat(pCurrent->DiskDir, "\\");
			
			pCurrent->CabDir = (LPSTR)pCurrent + ofsCab;
			strcpy(pCurrent->CabDir, CabPath);
			if (optRecurseSubdirs && CurDP[0] != '\0') {
				if (CabPath[0] != '\0')
					strcat(pCurrent->CabDir, "\\");
				strcat(pCurrent->CabDir, CurDP);
			}
			
			pCurrent->pNext = NULL;
			FileCount++;
			//fprintf(stderr, "%s, %s, %s\n", pCurrent->FileName, pCurrent->DiskDir, pCurrent->CabDir);
		}
		Found = FindNextFile(hFind, &fd);
	}

}

BOOL DirExists(LPSTR DirName)
{
	WIN32_FIND_DATA fd;
	HANDLE fh;

	fh = FindFirstFile(DirName, &fd);
	if (fh == INVALID_HANDLE_VALUE)
		return FALSE;
	FindClose(fh);
	if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		return TRUE;
	else
		return FALSE;
}

void TranslateFileGroup()
{
	if (optFileGroup == -1)
		return;
	if (optFileGroup > 0x1000)
		optFileGroup = GetGroupIndexByName((LPSTR)optFileGroup);
	if (optFileGroup < 0 || optFileGroup > cFileGroups - 1) {
		fprintf(stderr, "Invalid FileGroup specified\n");
		CleanExit(22);
	}
}

DWORD GetGroupIndexByName(LPSTR GroupName)
{
	LPFILEGROUPDESC pFG;
	DWORD i = 0;

	while (	i < cFileGroups &&
		(_stricmp(GroupName, GetString(pCabDesc, (pFG=GetFileGroupDesc(pCabDesc, FileGroups, i))->ofsName)) != 0) )
			i++;
	return i < cFileGroups ? i : -1;
}

BOOL IsMask(LPSTR str)
{
	return (!str) || strchr(str, '*') || strchr(str, '?');
}

BOOL WildMatch(LPSTR str, LPSTR wildcard)
{
	LPSTR tstr;

	if (!wildcard)
		return TRUE;
	if (!str)
		return FALSE;

	while (*wildcard != '\0' && (toupper(*str) == toupper(*wildcard) || *wildcard == '*' || *wildcard == '?')) {
		if (*wildcard == '?') {
			wildcard++;
			if (*str == '\0')
				return FALSE;
			str++;
		} else if (*wildcard == '*') {
			wildcard++;
			if (*wildcard == '\0')
				return TRUE;
			tstr = str;
			while (*tstr != '\0' && !WildMatch(tstr, wildcard))
				tstr++;
			if (*tstr != '\0')
				str = tstr;
		} else {
			*wildcard++;
			*str++;
		}
	}
	return toupper(*str) == toupper(*wildcard);
}

// accepts part of the string
// returns -1 if no conversion possible
long strtolong(char* str)
{
	char* pend;
	long retval;

	if (!str)
		return -1;

	retval = strtol(str, &pend, 10);
	if (!(*pend == '\0' || *pend == ',' || *pend == '-'))
		retval = -1;

	return retval;
}

// must convert the entire the string
// returns -1 if no conversion possible
long atolong(char* str)
{
	char* pend;
	long retval;

	if (!str)
		return -1;

	retval = strtol(str, &pend, 10);
	if (*pend != '\0')
		retval = -1;

	return retval;
}

void Free(LPVOID ptr)
{
	if (ptr != NULL)
		free(ptr);
}

LPVOID Alloc(DWORD NewSize)
{
	LPVOID tempPtr = malloc(NewSize);
	if (!tempPtr)
		NoMemory();

	return tempPtr;
}

LPVOID ReAlloc(LPVOID Ptr, DWORD NewSize)
{
	LPVOID tempPtr = realloc(Ptr, NewSize);
	if (!tempPtr)
		NoMemory();
	
	return tempPtr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -