📄 i5comp.c
字号:
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 + -