mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- Add a function MatchFileNamePattern for matching a file against a pattern (imported from Busybox under GPL2 or later license, heavily modified for our purposes, more information in the function comments)
- Add support for multiple search criterias, which are actually checked. This makes it possible to pass parameters like "*.rbuild *.txt" to the cabman command line for adding, displaying and extracting files in a cabinet. - Overhaul CreateSimpleCabinet, make it able to add multiple files to the cabinet using the new search criteria functions. - Fix some comments and indentation here and there. svn path=/trunk/; revision=32127
This commit is contained in:
parent
38c6c12999
commit
7356090407
5 changed files with 401 additions and 82 deletions
|
@ -18,6 +18,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if !defined(WIN32)
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
# include <sys/stat.h>
|
||||
#endif // __FreeBSD__
|
||||
|
@ -315,10 +318,12 @@ CCabinet::CCabinet()
|
|||
CabinetReservedFileBuffer = NULL;
|
||||
CabinetReservedFileSize = 0;
|
||||
|
||||
FolderListHead = NULL;
|
||||
FolderListTail = NULL;
|
||||
FileListHead = NULL;
|
||||
FileListTail = NULL;
|
||||
FolderListHead = NULL;
|
||||
FolderListTail = NULL;
|
||||
FileListHead = NULL;
|
||||
FileListTail = NULL;
|
||||
CriteriaListHead = NULL;
|
||||
CriteriaListTail = NULL;
|
||||
|
||||
Codec = NULL;
|
||||
CodecId = -1;
|
||||
|
@ -511,6 +516,82 @@ void CCabinet::SetDestinationPath(char* DestinationPath)
|
|||
NormalizePath(DestPath, MAX_PATH);
|
||||
}
|
||||
|
||||
ULONG CCabinet::AddSearchCriteria(char* SearchCriteria)
|
||||
/*
|
||||
* FUNCTION: Adds a criteria to the search criteria list
|
||||
* ARGUMENTS:
|
||||
* SearchCriteria = String with the search criteria to add
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PSEARCH_CRITERIA Criteria;
|
||||
|
||||
// Add the criteria to the list of search criteria
|
||||
Criteria = (PSEARCH_CRITERIA)AllocateMemory(sizeof(SEARCH_CRITERIA));
|
||||
if(!Criteria)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return CAB_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
Criteria->Prev = CriteriaListTail;
|
||||
Criteria->Next = NULL;
|
||||
|
||||
if(CriteriaListTail)
|
||||
CriteriaListTail->Next = Criteria;
|
||||
else
|
||||
CriteriaListHead = Criteria;
|
||||
|
||||
CriteriaListTail = Criteria;
|
||||
|
||||
// Set the actual criteria string
|
||||
Criteria->Search = (char*)AllocateMemory(strlen(SearchCriteria) + 1);
|
||||
if (!Criteria->Search)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return CAB_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
strcpy(Criteria->Search, SearchCriteria);
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void CCabinet::DestroySearchCriteria()
|
||||
/*
|
||||
* FUNCTION: Destroys the list with the search criteria
|
||||
*/
|
||||
{
|
||||
PSEARCH_CRITERIA Criteria;
|
||||
PSEARCH_CRITERIA NextCriteria;
|
||||
|
||||
Criteria = CriteriaListHead;
|
||||
|
||||
while(Criteria)
|
||||
{
|
||||
NextCriteria = Criteria->Next;
|
||||
|
||||
FreeMemory(Criteria->Search);
|
||||
FreeMemory(Criteria);
|
||||
|
||||
Criteria = NextCriteria;
|
||||
}
|
||||
|
||||
CriteriaListHead = NULL;
|
||||
CriteriaListTail = NULL;
|
||||
}
|
||||
|
||||
bool CCabinet::HasSearchCriteria()
|
||||
/*
|
||||
* FUNCTION: Returns whether we have search criteria
|
||||
* RETURNS:
|
||||
* Whether we have search criteria or not.
|
||||
*/
|
||||
{
|
||||
return (CriteriaListHead != NULL);
|
||||
}
|
||||
|
||||
bool CCabinet::SetCompressionCodec(char* CodecName)
|
||||
/*
|
||||
* FUNCTION: Selects the codec to use for compression
|
||||
|
@ -821,19 +902,16 @@ void CCabinet::Close()
|
|||
}
|
||||
|
||||
|
||||
ULONG CCabinet::FindFirst(char* FileName,
|
||||
PCAB_SEARCH Search)
|
||||
ULONG CCabinet::FindFirst(PCAB_SEARCH Search)
|
||||
/*
|
||||
* FUNCTION: Finds the first file in the cabinet that matches a search criteria
|
||||
* ARGUMENTS:
|
||||
* FileName = Pointer to search criteria
|
||||
* Search = Pointer to search structure
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
RestartSearch = false;
|
||||
strncpy(Search->Search, FileName, MAX_PATH);
|
||||
Search->Next = FileListHead;
|
||||
return FindNext(Search);
|
||||
}
|
||||
|
@ -848,6 +926,8 @@ ULONG CCabinet::FindNext(PCAB_SEARCH Search)
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
bool bFound = false;
|
||||
PSEARCH_CRITERIA Criteria;
|
||||
ULONG Status;
|
||||
|
||||
if (RestartSearch)
|
||||
|
@ -867,7 +947,32 @@ ULONG CCabinet::FindNext(PCAB_SEARCH Search)
|
|||
RestartSearch = false;
|
||||
}
|
||||
|
||||
/* FIXME: Check search criteria */
|
||||
/* Check each search criteria against each file */
|
||||
while(Search->Next)
|
||||
{
|
||||
// Some features (like displaying cabinets) don't require search criteria, so we can just break here.
|
||||
// If a feature requires it, handle this in the ParseCmdline() function in "main.cxx".
|
||||
if(!CriteriaListHead)
|
||||
break;
|
||||
|
||||
Criteria = CriteriaListHead;
|
||||
|
||||
while(Criteria)
|
||||
{
|
||||
if(MatchFileNamePattern(Search->Next->FileName, Criteria->Search))
|
||||
{
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Criteria = Criteria->Next;
|
||||
}
|
||||
|
||||
if(bFound)
|
||||
break;
|
||||
|
||||
Search->Next = Search->Next->Next;
|
||||
}
|
||||
|
||||
if (!Search->Next)
|
||||
{
|
||||
|
@ -1960,6 +2065,151 @@ ULONG CCabinet::AddFile(char* FileName)
|
|||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool CCabinet::CreateSimpleCabinet()
|
||||
/*
|
||||
* FUNCTION: Create a simple cabinet based on the files in the criteria list
|
||||
*/
|
||||
{
|
||||
bool bRet = false;
|
||||
char* pszFile;
|
||||
char szFilePath[MAX_PATH];
|
||||
char szFile[MAX_PATH];
|
||||
PSEARCH_CRITERIA Criteria;
|
||||
ULONG Status;
|
||||
|
||||
#if defined(WIN32)
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
#else
|
||||
DIR* dirp;
|
||||
struct dirent* dp;
|
||||
struct stat stbuf;
|
||||
#endif
|
||||
|
||||
// Initialize a new cabinet
|
||||
Status = NewCabinet();
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Add each file in the criteria list
|
||||
Criteria = CriteriaListHead;
|
||||
|
||||
while(Criteria)
|
||||
{
|
||||
// Store the file path with a trailing slash in szFilePath
|
||||
pszFile = strrchr(Criteria->Search, '/');
|
||||
if(!pszFile)
|
||||
pszFile = strrchr(Criteria->Search, '\\');
|
||||
|
||||
if(pszFile)
|
||||
{
|
||||
strncpy(szFilePath, Criteria->Search, pszFile - Criteria->Search + 1);
|
||||
szFilePath[pszFile - Criteria->Search + 1] = 0;
|
||||
}
|
||||
else
|
||||
szFilePath[0] = 0;
|
||||
|
||||
#if defined(WIN32)
|
||||
// Windows: Use the easy FindFirstFile/FindNextFile API for getting all files and checking them against the pattern
|
||||
hFind = FindFirstFile(Criteria->Search, &FindFileData);
|
||||
|
||||
// Don't stop if a search criteria is not found
|
||||
if(hFind == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("FindFirstFile failed, Criteria: %s, error code is %u\n", Criteria->Search, (UINT)GetLastError()));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
strcpy(szFile, szFilePath);
|
||||
strcat(szFile, FindFileData.cFileName);
|
||||
|
||||
Status = AddFile(szFile);
|
||||
|
||||
if(Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(FindNextFile(hFind, &FindFileData));
|
||||
|
||||
FindClose(hFind);
|
||||
#else
|
||||
// Unix: Use opendir/readdir to loop through all entries, stat to check if it's a file and MatchFileNamePattern to match the file against the pattern
|
||||
if(szFilePath[0] == 0)
|
||||
strcpy(szFilePath, "./");
|
||||
|
||||
dirp = opendir(szFilePath);
|
||||
|
||||
if(dirp)
|
||||
{
|
||||
while( (dp = readdir(dirp)) )
|
||||
{
|
||||
strcpy(szFile, szFilePath);
|
||||
strcat(szFile, dp->d_name);
|
||||
|
||||
if(stat(szFile, &stbuf) == 0)
|
||||
{
|
||||
if(stbuf.st_mode != S_IFDIR)
|
||||
{
|
||||
// As we added "./" to szFilePath above, szFile might contain "./test.txt" now and Criteria->Search "test.txt".
|
||||
// Therefore they won't match using MatchFileNamePattern. By using pszFile here, we can avoid this problem.
|
||||
if(szFile[0] == '.' && szFile[1] == '/')
|
||||
pszFile = szFile + 2;
|
||||
else
|
||||
pszFile = szFile;
|
||||
|
||||
if(MatchFileNamePattern(pszFile, Criteria->Search))
|
||||
{
|
||||
Status = AddFile(szFile);
|
||||
|
||||
if(Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("stat failed, error code is %i\n", errno));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Criteria = Criteria->Next;
|
||||
}
|
||||
|
||||
Status = WriteDisk(false);
|
||||
if (Status == CAB_STATUS_SUCCESS)
|
||||
Status = CloseDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
CloseCabinet();
|
||||
bRet = true;
|
||||
|
||||
cleanup:
|
||||
DestroySearchCriteria();
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void CCabinet::SetMaxDiskSize(ULONG Size)
|
||||
/*
|
||||
|
@ -2509,8 +2759,6 @@ void CCabinet::DestroyDataNodes(PCFFOLDER_NODE FolderNode)
|
|||
void CCabinet::DestroyFileNodes()
|
||||
/*
|
||||
* FUNCTION: Destroys file nodes
|
||||
* ARGUMENTS:
|
||||
* FolderNode = Pointer to folder node
|
||||
*/
|
||||
{
|
||||
PCFFILE_NODE PrevNode;
|
||||
|
@ -2641,8 +2889,8 @@ void CCabinet::DestroyDeletedFolderNodes()
|
|||
|
||||
|
||||
ULONG CCabinet::ComputeChecksum(void* Buffer,
|
||||
ULONG Size,
|
||||
ULONG Seed)
|
||||
ULONG Size,
|
||||
ULONG Seed)
|
||||
/*
|
||||
* FUNCTION: Computes checksum for data block
|
||||
* ARGUMENTS:
|
||||
|
@ -2700,8 +2948,8 @@ ULONG CCabinet::ComputeChecksum(void* Buffer,
|
|||
|
||||
|
||||
ULONG CCabinet::ReadBlock(void* Buffer,
|
||||
ULONG Size,
|
||||
PULONG BytesRead)
|
||||
ULONG Size,
|
||||
PULONG BytesRead)
|
||||
/*
|
||||
* FUNCTION: Read a block of data from file
|
||||
* ARGUMENTS:
|
||||
|
@ -2718,6 +2966,67 @@ ULONG CCabinet::ReadBlock(void* Buffer,
|
|||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool CCabinet::MatchFileNamePattern(char* FileName, char* Pattern)
|
||||
/*
|
||||
* FUNCTION: Matches a wildcard character pattern against a file
|
||||
* ARGUMENTS:
|
||||
* FileName = The file name to check
|
||||
* Pattern = The pattern
|
||||
* RETURNS:
|
||||
* Whether the pattern matches the file
|
||||
*
|
||||
* COPYRIGHT:
|
||||
* This function is based on Busybox code, Copyright (C) 1998 by Erik Andersen, released under GPL2 or any later version.
|
||||
* Adapted from code written by Ingo Wilken.
|
||||
* Original location: http://www.busybox.net/cgi-bin/viewcvs.cgi/trunk/busybox/utility.c?rev=5&view=markup
|
||||
*/
|
||||
{
|
||||
char* retryPattern = NULL;
|
||||
char* retryFileName = NULL;
|
||||
char ch;
|
||||
|
||||
while (*FileName || *Pattern)
|
||||
{
|
||||
ch = *Pattern++;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '*':
|
||||
retryPattern = Pattern;
|
||||
retryFileName = FileName;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
if (*FileName++ == '\0')
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (*FileName == ch)
|
||||
{
|
||||
if (*FileName)
|
||||
FileName++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*FileName)
|
||||
{
|
||||
Pattern = retryPattern;
|
||||
FileName = ++retryFileName;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Pattern)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef CAB_READ_ONLY
|
||||
|
||||
ULONG CCabinet::InitCabinetHeader()
|
||||
|
|
|
@ -224,13 +224,18 @@ typedef struct _CFFILE_NODE
|
|||
PCFFOLDER_NODE FolderNode; // Folder this file belong to
|
||||
} CFFILE_NODE, *PCFFILE_NODE;
|
||||
|
||||
typedef struct _SEARCH_CRITERIA
|
||||
{
|
||||
struct _SEARCH_CRITERIA *Next; // Pointer to next search criteria
|
||||
struct _SEARCH_CRITERIA *Prev; // Pointer to previous search criteria
|
||||
char* Search; // The actual search criteria
|
||||
} SEARCH_CRITERIA, *PSEARCH_CRITERIA;
|
||||
|
||||
typedef struct _CAB_SEARCH
|
||||
{
|
||||
char Search[MAX_PATH]; // Search criteria
|
||||
PCFFILE_NODE Next; // Pointer to next node
|
||||
PCFFILE File; // Pointer to current CFFILE
|
||||
char* FileName; // Current filename
|
||||
PCFFILE_NODE Next; // Pointer to next node
|
||||
PCFFILE File; // Pointer to current CFFILE
|
||||
char* FileName; // Current filename
|
||||
} CAB_SEARCH, *PCAB_SEARCH;
|
||||
|
||||
|
||||
|
@ -345,16 +350,25 @@ public:
|
|||
/* Closes the current open cabinet file */
|
||||
void Close();
|
||||
/* Locates the first file in the current cabinet file that matches a search criteria */
|
||||
ULONG FindFirst(char* FileName, PCAB_SEARCH Search);
|
||||
ULONG FindFirst(PCAB_SEARCH Search);
|
||||
/* Locates the next file in the current cabinet file */
|
||||
ULONG FindNext(PCAB_SEARCH Search);
|
||||
/* Extracts a file from the current cabinet file */
|
||||
ULONG ExtractFile(char* FileName);
|
||||
/* Select codec engine to use */
|
||||
void SelectCodec(LONG Id);
|
||||
/* Returns if a codec engine is selected */
|
||||
/* Returns whether a codec engine is selected */
|
||||
bool IsCodecSelected();
|
||||
/* Adds a search criteria for adding files to a simple cabinet, displaying files in a cabinet or extracting them */
|
||||
ULONG AddSearchCriteria(char* SearchCriteria);
|
||||
/* Destroys the search criteria list */
|
||||
void DestroySearchCriteria();
|
||||
/* Returns whether we have search criteria */
|
||||
bool HasSearchCriteria();
|
||||
|
||||
#ifndef CAB_READ_ONLY
|
||||
/* Creates a simple cabinet based on the search criteria data */
|
||||
bool CreateSimpleCabinet();
|
||||
/* Sets the codec to use for compression (based on a string value) */
|
||||
bool SetCompressionCodec(char* CodecName);
|
||||
/* Creates a new cabinet file */
|
||||
|
@ -412,6 +426,7 @@ private:
|
|||
void DestroyDeletedFolderNodes();
|
||||
ULONG ComputeChecksum(void* Buffer, ULONG Size, ULONG Seed);
|
||||
ULONG ReadBlock(void* Buffer, ULONG Size, PULONG BytesRead);
|
||||
bool MatchFileNamePattern(char* FileName, char* Pattern);
|
||||
#ifndef CAB_READ_ONLY
|
||||
ULONG InitCabinetHeader();
|
||||
ULONG WriteCabinetHeader(bool MoreDisks);
|
||||
|
@ -455,6 +470,8 @@ private:
|
|||
PCFDATA_NODE CurrentDataNode;
|
||||
PCFFILE_NODE FileListHead;
|
||||
PCFFILE_NODE FileListTail;
|
||||
PSEARCH_CRITERIA CriteriaListHead;
|
||||
PSEARCH_CRITERIA CriteriaListTail;
|
||||
CCABCodec *Codec;
|
||||
LONG CodecId;
|
||||
bool CodecSelected;
|
||||
|
|
|
@ -27,7 +27,6 @@ public:
|
|||
private:
|
||||
void Usage();
|
||||
bool CreateCabinet();
|
||||
bool CreateSimpleCabinet();
|
||||
bool DisplayCabinet();
|
||||
bool ExtractFromCabinet();
|
||||
/* Event handlers */
|
||||
|
@ -39,7 +38,6 @@ private:
|
|||
bool ProcessAll;
|
||||
ULONG Mode;
|
||||
bool PromptOnOverwrite;
|
||||
char Location[MAX_PATH];
|
||||
char FileName[MAX_PATH];
|
||||
};
|
||||
|
||||
|
|
|
@ -391,7 +391,7 @@ ULONG CDFParser::Parse()
|
|||
|
||||
if (!InfFileOnly)
|
||||
{
|
||||
printf("\nWriting cabinet. This may take a while...\n\n");
|
||||
printf("\nWriting cabinet. This may take a while...\n\n");
|
||||
|
||||
if (DiskCreated)
|
||||
{
|
||||
|
|
|
@ -172,6 +172,7 @@ CCABManager::CCABManager()
|
|||
ProcessAll = false;
|
||||
InfFileOnly = false;
|
||||
Mode = CM_MODE_DISPLAY;
|
||||
FileName[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,8 +191,8 @@ void CCABManager::Usage()
|
|||
{
|
||||
printf("ReactOS Cabinet Manager\n\n");
|
||||
printf("CABMAN [-D | -E] [-A] [-L dir] cabinet [filename ...]\n");
|
||||
printf("CABMAN -C dirfile [-I] [-RC file] [-P dir]\n");
|
||||
printf("CABMAN -S cabinet filename\n");
|
||||
printf("CABMAN [-M mode] -C dirfile [-I] [-RC file] [-P dir]\n");
|
||||
printf("CABMAN [-M mode] -S cabinet filename ...\n");
|
||||
printf(" cabinet Cabinet file.\n");
|
||||
printf(" filename Name of the file to extract from the cabinet.\n");
|
||||
printf(" Wild cards and multiple filenames\n");
|
||||
|
@ -207,7 +208,7 @@ void CCABManager::Usage()
|
|||
printf(" -I Don't create the cabinet, only the .inf file.\n");
|
||||
printf(" -L dir Location to place extracted or generated files\n");
|
||||
printf(" (default is current directory).\n");
|
||||
printf(" -M Specify the compression method to use\n");
|
||||
printf(" -M mode Specify the compression method to use:\n");
|
||||
printf(" raw - No compression\n");
|
||||
printf(" mszip - MsZip compression (default)\n");
|
||||
printf(" -N Don't create the .inf file, only the cabinet.\n");
|
||||
|
@ -351,10 +352,23 @@ bool CCABManager::ParseCmdline(int argc, char* argv[])
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((FoundCabinet) || (Mode == CM_MODE_CREATE))
|
||||
if(Mode == CM_MODE_CREATE)
|
||||
{
|
||||
/* FIXME: There may be many of these if Mode != CM_MODE_CREATE */
|
||||
strcpy(FileName, argv[i]);
|
||||
if(FileName[0])
|
||||
{
|
||||
printf("You may only specify one directive file!\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For creating cabinets, this argument is the path to the directive file
|
||||
strcpy(FileName, argv[i]);
|
||||
}
|
||||
}
|
||||
else if(FoundCabinet)
|
||||
{
|
||||
// For creating simple cabinets, displaying or extracting them, add the argument as a search criteria
|
||||
AddSearchCriteria(argv[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -366,14 +380,21 @@ bool CCABManager::ParseCmdline(int argc, char* argv[])
|
|||
|
||||
if (ShowUsage)
|
||||
{
|
||||
Usage();
|
||||
return false;
|
||||
Usage();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Select MsZip by default for creating cabinets
|
||||
if( (Mode == CM_MODE_CREATE || Mode == CM_MODE_CREATE_SIMPLE) && !IsCodecSelected() )
|
||||
SelectCodec(CAB_CODEC_MSZIP);
|
||||
|
||||
// Search criteria (= the filename argument) is necessary for creating a simple cabinet
|
||||
if( Mode == CM_MODE_CREATE_SIMPLE && !HasSearchCriteria())
|
||||
{
|
||||
printf("You have to enter input file names!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -397,43 +418,6 @@ bool CCABManager::CreateCabinet()
|
|||
return (Status == CAB_STATUS_SUCCESS ? true : false);
|
||||
}
|
||||
|
||||
|
||||
bool CCABManager::CreateSimpleCabinet()
|
||||
/*
|
||||
* FUNCTION: Create cabinet
|
||||
*/
|
||||
{
|
||||
ULONG Status;
|
||||
|
||||
Status = NewCabinet();
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
Status = AddFile(FileName);
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
Status = WriteDisk(false);
|
||||
if (Status == CAB_STATUS_SUCCESS)
|
||||
Status = CloseDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
CloseCabinet();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CCABManager::DisplayCabinet()
|
||||
/*
|
||||
* FUNCTION: Display cabinet contents
|
||||
|
@ -448,7 +432,7 @@ bool CCABManager::DisplayCabinet()
|
|||
{
|
||||
printf("Cabinet %s\n\n", GetCabinetName());
|
||||
|
||||
if (FindFirst("", &Search) == CAB_STATUS_SUCCESS)
|
||||
if (FindFirst(&Search) == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -467,6 +451,8 @@ bool CCABManager::DisplayCabinet()
|
|||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
DestroySearchCriteria();
|
||||
|
||||
if (FileCount > 0) {
|
||||
if (FileCount == 1)
|
||||
printf(" 1 file ");
|
||||
|
@ -503,6 +489,7 @@ bool CCABManager::ExtractFromCabinet()
|
|||
* FUNCTION: Extract file(s) from cabinet
|
||||
*/
|
||||
{
|
||||
bool bRet = true;
|
||||
CAB_SEARCH Search;
|
||||
ULONG Status;
|
||||
|
||||
|
@ -510,34 +497,46 @@ bool CCABManager::ExtractFromCabinet()
|
|||
{
|
||||
printf("Cabinet %s\n\n", GetCabinetName());
|
||||
|
||||
if (FindFirst("", &Search) == CAB_STATUS_SUCCESS)
|
||||
if (FindFirst(&Search) == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (Status = ExtractFile(Search.FileName)) {
|
||||
switch (Status = ExtractFile(Search.FileName))
|
||||
{
|
||||
case CAB_STATUS_SUCCESS:
|
||||
break;
|
||||
|
||||
case CAB_STATUS_INVALID_CAB:
|
||||
printf("Cabinet contains errors.\n");
|
||||
return false;
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
case CAB_STATUS_UNSUPPCOMP:
|
||||
printf("Cabinet uses unsupported compression type.\n");
|
||||
return false;
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
case CAB_STATUS_CANNOT_WRITE:
|
||||
printf("You've run out of free space on the destination volume or the volume is damaged.\n");
|
||||
return false;
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unspecified error code (%u).\n", (UINT)Status);
|
||||
return false;
|
||||
bRet = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRet)
|
||||
break;
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
|
||||
DestroySearchCriteria();
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
|
||||
return bRet;
|
||||
}
|
||||
else
|
||||
printf("Cannot open file: %s.\n", GetCabinetName());
|
||||
|
||||
return false;
|
||||
|
@ -555,19 +554,15 @@ bool CCABManager::Run()
|
|||
{
|
||||
case CM_MODE_CREATE:
|
||||
return CreateCabinet();
|
||||
break;
|
||||
|
||||
case CM_MODE_DISPLAY:
|
||||
return DisplayCabinet();
|
||||
break;
|
||||
|
||||
case CM_MODE_EXTRACT:
|
||||
return ExtractFromCabinet();
|
||||
break;
|
||||
|
||||
case CM_MODE_CREATE_SIMPLE:
|
||||
return CreateSimpleCabinet();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue