[ros-diffs] [cfinck] 32127: - 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.

cfinck at svn.reactos.org cfinck at svn.reactos.org
Mon Feb 4 23:48:42 CET 2008


Author: cfinck
Date: Tue Feb  5 01:48:42 2008
New Revision: 32127

URL: http://svn.reactos.org/svn/reactos?rev=32127&view=rev
Log:
- 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.

Modified:
    trunk/reactos/tools/cabman/cabinet.cxx
    trunk/reactos/tools/cabman/cabinet.h
    trunk/reactos/tools/cabman/cabman.h
    trunk/reactos/tools/cabman/dfp.cxx
    trunk/reactos/tools/cabman/main.cxx

Modified: trunk/reactos/tools/cabman/cabinet.cxx
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/cabinet.cxx?rev=32127&r1=32126&r2=32127&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/cabinet.cxx (original)
+++ trunk/reactos/tools/cabman/cabinet.cxx Tue Feb  5 01:48:42 2008
@@ -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 @@
     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;
@@ -509,6 +514,82 @@
     ConvertPath(DestPath, false);
     if (strlen(DestPath) > 0)
         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)
@@ -821,19 +902,16 @@
 }
 
 
-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 @@
  *     Status of operation
  */
 {
+    bool bFound = false;
+    PSEARCH_CRITERIA Criteria;
     ULONG Status;
 
     if (RestartSearch)
@@ -867,7 +947,32 @@
         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 @@
     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::DestroyFileNodes()
 /*
  * FUNCTION: Destroys file nodes
- * ARGUMENTS:
- *     FolderNode = Pointer to folder node
  */
 {
     PCFFILE_NODE PrevNode;
@@ -2641,8 +2889,8 @@
 
 
 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::ReadBlock(void* Buffer,
-                             ULONG Size,
-                             PULONG BytesRead)
+                          ULONG Size,
+                          PULONG BytesRead)
 /*
  * FUNCTION: Read a block of data from file
  * ARGUMENTS:
@@ -2716,6 +2964,67 @@
     if (!ReadFileData(FileHandle, Buffer, Size, BytesRead))
         return CAB_STATUS_INVALID_CAB;
     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

Modified: trunk/reactos/tools/cabman/cabinet.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/cabinet.h?rev=32127&r1=32126&r2=32127&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/cabinet.h (original)
+++ trunk/reactos/tools/cabman/cabinet.h Tue Feb  5 01:48:42 2008
@@ -224,13 +224,18 @@
     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 @@
     /* 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 @@
     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 @@
     PCFDATA_NODE CurrentDataNode;
     PCFFILE_NODE FileListHead;
     PCFFILE_NODE FileListTail;
+    PSEARCH_CRITERIA CriteriaListHead;
+    PSEARCH_CRITERIA CriteriaListTail;
     CCABCodec *Codec;
     LONG CodecId;
     bool CodecSelected;

Modified: trunk/reactos/tools/cabman/cabman.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/cabman.h?rev=32127&r1=32126&r2=32127&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/cabman.h (original)
+++ trunk/reactos/tools/cabman/cabman.h Tue Feb  5 01:48:42 2008
@@ -27,7 +27,6 @@
 private:
     void Usage();
     bool CreateCabinet();
-    bool CreateSimpleCabinet();
     bool DisplayCabinet();
     bool ExtractFromCabinet();
     /* Event handlers */
@@ -39,7 +38,6 @@
     bool ProcessAll;
     ULONG Mode;
     bool PromptOnOverwrite;
-    char Location[MAX_PATH];
     char FileName[MAX_PATH];
 };
 

Modified: trunk/reactos/tools/cabman/dfp.cxx
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/dfp.cxx?rev=32127&r1=32126&r2=32127&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/dfp.cxx (original)
+++ trunk/reactos/tools/cabman/dfp.cxx Tue Feb  5 01:48:42 2008
@@ -391,7 +391,7 @@
 
     if (!InfFileOnly)
     {
-          printf("\nWriting cabinet. This may take a while...\n\n");
+        printf("\nWriting cabinet. This may take a while...\n\n");
 
         if (DiskCreated)
         {

Modified: trunk/reactos/tools/cabman/main.cxx
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/main.cxx?rev=32127&r1=32126&r2=32127&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/main.cxx (original)
+++ trunk/reactos/tools/cabman/main.cxx Tue Feb  5 01:48:42 2008
@@ -172,6 +172,7 @@
     ProcessAll = false;
     InfFileOnly = false;
     Mode = CM_MODE_DISPLAY;
+    FileName[0] = 0;
 }
 
 
@@ -190,8 +191,8 @@
 {
     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 @@
     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 @@
         }
         else
         {
-            if ((FoundCabinet) || (Mode == CM_MODE_CREATE))
-            {
-                /* FIXME: There may be many of these if Mode != CM_MODE_CREATE */
-                strcpy(FileName, argv[i]);
+            if(Mode == CM_MODE_CREATE)
+            {
+                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 @@
 
     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;
 }
 
@@ -396,43 +417,6 @@
 
     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()
 /*
@@ -448,7 +432,7 @@
     {
         printf("Cabinet %s\n\n", GetCabinetName());
 
-        if (FindFirst("", &Search) == CAB_STATUS_SUCCESS)
+        if (FindFirst(&Search) == CAB_STATUS_SUCCESS)
         {
             do
             {
@@ -466,6 +450,8 @@
                 }
             } while (FindNext(&Search) == CAB_STATUS_SUCCESS);
         }
+
+        DestroySearchCriteria();
 
         if (FileCount > 0) {
             if (FileCount == 1)
@@ -503,6 +489,7 @@
  * FUNCTION: Extract file(s) from cabinet
  */
 {
+    bool bRet = true;
     CAB_SEARCH Search;
     ULONG Status;
 
@@ -510,34 +497,46 @@
     {
         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 @@
     {
         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;




More information about the Ros-diffs mailing list