Fix building on newer Linux systems (particularly Fedora 13)
[reactos.git] / reactos / tools / cabman / cabinet.cxx
index aa17a00..5d834a9 100755 (executable)
@@ -4,10 +4,12 @@
  * FILE:        tools/cabman/cabinet.cpp
  * PURPOSE:     Cabinet routines
  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *              Colin Finck <mail@colinfinck.de>
  * NOTES:       Define CAB_READ_ONLY for read only version
  * REVISIONS:
  *   CSH 21/03-2001 Created
  *   CSH 15/08-2003 Made it portable
+ *   CF  04/05-2007 Made it compatible with 64-bit operating systems
  * TODO:
  *   - Checksum of datablocks should be calculated
  *   - EXTRACT.EXE complains if a disk is created manually
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if !defined(WIN32)
+# include <dirent.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+#endif
 #include "cabinet.h"
 #include "raw.h"
 #include "mszip.h"
 
 #if defined(WIN32)
 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
-static long _GetSizeOfFile(FILEHANDLE handle)
+static LONG _GetSizeOfFile(FILEHANDLE handle)
 {
-    unsigned long size = GetFileSize(handle, NULL);
+    ULONG size = GetFileSize(handle, NULL);
     if (size == INVALID_FILE_SIZE)
-      {
         return -1;
-      }
+
     return size;
 }
 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
-static bool _ReadFileData(FILEHANDLE handle, void* buffer, unsigned long size, unsigned long* bytesread)
+static bool _ReadFileData(FILEHANDLE handle, void* buffer, ULONG size, PULONG bytesread)
 {
-    return ReadFile(handle, buffer, size, bytesread, NULL) != 0;
+    return ReadFile(handle, buffer, size, (LPDWORD)bytesread, NULL) != 0;
 }
 #else
 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
-static long _GetSizeOfFile(FILEHANDLE handle)
+static LONG _GetSizeOfFile(FILEHANDLE handle)
 {
-    long size;
+    LONG size;
     fseek(handle, 0, SEEK_END);
     size = ftell(handle);
     fseek(handle, 0, SEEK_SET);
     return size;
 }
 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
-static bool _ReadFileData(FILEHANDLE handle, void* buffer, unsigned long size, unsigned long* bytesread)
+static bool _ReadFileData(FILEHANDLE handle, void* buffer, ULONG size, PULONG bytesread)
 {
     *bytesread = fread(buffer, 1, size, handle);
     return *bytesread == size;
@@ -57,12 +63,12 @@ static bool _ReadFileData(FILEHANDLE handle, void* buffer, unsigned long size, u
 #ifndef CAB_READ_ONLY
 
 #if 0
-#ifdef DBG
+#if DBG
 
-void DumpBuffer(void* Buffer, unsigned long Size)
+void DumpBuffer(void* Buffer, ULONG Size)
 {
     FILEHANDLE FileHandle;
-    unsigned long BytesWritten;
+    ULONG BytesWritten;
 
     /* Create file, overwrite if it already exists */
     FileHandle = CreateFile("dump.bin", // Create this file
@@ -72,13 +78,15 @@ void DumpBuffer(void* Buffer, unsigned long Size)
         CREATE_ALWAYS,                  // Create or overwrite
         FILE_ATTRIBUTE_NORMAL,          // Normal file
         NULL);                          // No attribute template
-    if (FileHandle == INVALID_HANDLE_VALUE) {
-        DPRINT(MID_TRACE, ("ERROR OPENING '%d'.\n", (unsigned int)GetLastError()));
+    if (FileHandle == INVALID_HANDLE_VALUE)
+    {
+        DPRINT(MID_TRACE, ("ERROR OPENING '%u'.\n", (UINT)GetLastError()));
         return;
     }
 
-    if (!WriteFile(FileHandle, Buffer, Size, &BytesWritten, NULL)) {
-        DPRINT(MID_TRACE, ("ERROR WRITING '%d'.\n", (unsigned int)GetLastError()));
+    if (!WriteFile(FileHandle, Buffer, Size, &BytesWritten, NULL))
+    {
+        DPRINT(MID_TRACE, ("ERROR WRITING '%u'.\n", (UINT)GetLastError()));
     }
 
     CloseFile(FileHandle);
@@ -107,7 +115,7 @@ CCFDATAStorage::~CCFDATAStorage()
 }
 
 
-unsigned long CCFDATAStorage::Create(char* FileName)
+ULONG CCFDATAStorage::Create(const char* FileName)
 /*
  * FUNCTION: Creates the file
  * ARGUMENTS:
@@ -134,21 +142,22 @@ unsigned long CCFDATAStorage::Create(char* FileName)
         FILE_FLAG_DELETE_ON_CLOSE |     // Delete file when closed
         FILE_ATTRIBUTE_TEMPORARY,       // Temporary file
         NULL);                          // No attribute template
-    if (FileHandle == INVALID_HANDLE_VALUE) {
-        DPRINT(MID_TRACE, ("ERROR '%d'.\n", (unsigned int)GetLastError()));
+    if (FileHandle == INVALID_HANDLE_VALUE)
+    {
+        DPRINT(MID_TRACE, ("ERROR '%u'.\n", (UINT)GetLastError()));
         return CAB_STATUS_CANNOT_CREATE;
     }
 #else /* !WIN32 */
     /*if (tmpnam(FullName) == NULL)*/
     if ((FileHandle = tmpfile()) == NULL)
         return CAB_STATUS_CANNOT_CREATE;
-               /*
+        /*
     FileHandle = fopen(FullName, "w+b");
     if (FileHandle == NULL) {
-        DPRINT(MID_TRACE, ("ERROR '%d'.\n", (unsigned int)errno));
+        DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
         return CAB_STATUS_CANNOT_CREATE;
     }
-               */
+        */
 #endif
 
     FileCreated = true;
@@ -157,7 +166,7 @@ unsigned long CCFDATAStorage::Create(char* FileName)
 }
 
 
-unsigned long CCFDATAStorage::Destroy()
+ULONG CCFDATAStorage::Destroy()
 /*
  * FUNCTION: Destroys the file
  * RETURNS:
@@ -174,7 +183,7 @@ unsigned long CCFDATAStorage::Destroy()
 }
 
 
-unsigned long CCFDATAStorage::Truncate()
+ULONG CCFDATAStorage::Truncate()
 /*
  * FUNCTION: Truncate the scratch file to zero bytes
  * RETURNS:
@@ -182,15 +191,16 @@ unsigned long CCFDATAStorage::Truncate()
  */
 {
 #if defined(WIN32)
-    if (!SetFilePointer(FileHandle, 0, NULL, FILE_BEGIN))
+    if( SetFilePointer(FileHandle, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER )
         return CAB_STATUS_FAILURE;
     if (!SetEndOfFile(FileHandle))
         return CAB_STATUS_FAILURE;
 #else /* !WIN32 */
     fclose(FileHandle);
     FileHandle = tmpfile();
-    if (FileHandle == NULL) {
-        DPRINT(MID_TRACE, ("ERROR '%d'.\n", (unsigned int)errno));
+    if (FileHandle == NULL)
+    {
+        DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
         return CAB_STATUS_FAILURE;
     }
 #endif
@@ -198,7 +208,7 @@ unsigned long CCFDATAStorage::Truncate()
 }
 
 
-unsigned long CCFDATAStorage::Position()
+ULONG CCFDATAStorage::Position()
 /*
  * FUNCTION: Returns current position in file
  * RETURNS:
@@ -208,12 +218,12 @@ unsigned long CCFDATAStorage::Position()
 #if defined(WIN32)
     return SetFilePointer(FileHandle, 0, NULL, FILE_CURRENT);
 #else
-    return (unsigned long)ftell(FileHandle);
+    return (ULONG)ftell(FileHandle);
 #endif
 }
 
 
-unsigned long CCFDATAStorage::Seek(long Position)
+ULONG CCFDATAStorage::Seek(LONG Position)
 /*
  * FUNCTION: Seeks to an absolute position
  * ARGUMENTS:
@@ -223,24 +233,23 @@ unsigned long CCFDATAStorage::Seek(long Position)
  */
 {
 #if defined(WIN32)
-    if (SetFilePointer(FileHandle,
-        Position,
-        NULL,
-        FILE_BEGIN) == 0xFFFFFFFF)
+    ifSetFilePointer(FileHandle,
+                       Position,
+                       NULL,
+                       FILE_BEGIN) == INVALID_SET_FILE_POINTER )
         return CAB_STATUS_FAILURE;
     else
         return CAB_STATUS_SUCCESS;
 #else
-    if (fseek(FileHandle, (off_t)Position, SEEK_SET) != 0) {
+    if (fseek(FileHandle, (off_t)Position, SEEK_SET) != 0)
         return CAB_STATUS_FAILURE;
-    } else {
+    else
         return CAB_STATUS_SUCCESS;
-    }
 #endif
 }
 
 
-unsigned long CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, unsigned long* BytesRead)
+ULONG CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, PULONG BytesRead)
 /*
  * FUNCTION: Reads a CFDATA block from the file
  * ARGUMENTS:
@@ -252,20 +261,19 @@ unsigned long CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, unsigned lon
  */
 {
 #if defined(WIN32)
-    if (!ReadFile(FileHandle, Buffer, Data->CompSize, BytesRead, NULL))
+    if (!ReadFile(FileHandle, Buffer, Data->CompSize, (LPDWORD)BytesRead, NULL))
         return CAB_STATUS_CANNOT_READ;
 #else
 
     *BytesRead = fread(Buffer, 1, Data->CompSize, FileHandle);
-    if (*BytesRead != Data->CompSize) {
+    if (*BytesRead != Data->CompSize)
         return CAB_STATUS_CANNOT_READ;
-  }
 #endif
     return CAB_STATUS_SUCCESS;
 }
 
 
-unsigned long CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, unsigned long* BytesWritten)
+ULONG CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, PULONG BytesWritten)
 /*
  * FUNCTION: Writes a CFDATA block to the file
  * ARGUMENTS:
@@ -277,7 +285,7 @@ unsigned long CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, unsigned lo
  */
 {
 #if defined(WIN32)
-    if (!WriteFile(FileHandle, Buffer, Data->CompSize, BytesWritten, NULL))
+    if (!WriteFile(FileHandle, Buffer, Data->CompSize, (LPDWORD)BytesWritten, NULL))
         return CAB_STATUS_CANNOT_WRITE;
 #else
     *BytesWritten = fwrite(Buffer, 1, Data->CompSize, FileHandle);
@@ -309,14 +317,16 @@ 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         = new CRawCodec();
-    CodecId       = CAB_CODEC_RAW;
-    CodecSelected = true;
+    Codec          = NULL;
+    CodecId        = -1;
+    CodecSelected  = false;
 
     OutputBuffer = NULL;
     InputBuffer  = NULL;
@@ -336,7 +346,8 @@ CCabinet::~CCabinet()
  * FUNCTION: Default destructor
  */
 {
-    if (CabinetReservedFileBuffer != NULL) {
+    if (CabinetReservedFileBuffer != NULL)
+    {
         FreeMemory(CabinetReservedFileBuffer);
         CabinetReservedFileBuffer = NULL;
         CabinetReservedFileSize = 0;
@@ -352,22 +363,21 @@ bool CCabinet::IsSeparator(char Char)
  * ARGUMENTS:
  *     Char = Character to check
  * RETURNS:
- *     Wether it is a separator
+ *     Whether it is a separator
  */
 {
-    if ((Char == '\\') || (Char == '/')) {
-      return true;
-    } else {
-      return false;
-    }
+    if ((Char == '\\') || (Char == '/'))
+        return true;
+    else
+        return false;
 }
 
 char* CCabinet::ConvertPath(char* Path, bool Allocate)
 /*
- * FUNCTION: Replaces \ or / with the one used be the host environment
+ * FUNCTION: Replaces \ or / with the one used by the host environment
  * ARGUMENTS:
  *     Path     = Pointer to string with pathname
- *     Allocate = Specifies wther to allocate memory for the new
+ *     Allocate = Specifies whether to allocate memory for the new
  *                string or to change the existing buffer
  * RETURNS:
  *     Pointer to new path
@@ -376,25 +386,25 @@ char* CCabinet::ConvertPath(char* Path, bool Allocate)
     char *newpath;
     int i;
 
-    if (Allocate) {
+    if (Allocate)
         newpath = strdup(Path);
-    } else {
+    else
         newpath = Path;
-    }
 
     i = 0;
-    while (Path[i] != 0) {
+    while (Path[i] != 0)
+    {
 #if defined(WIN32)
-       if (Path[i] == '/') {
-            newpath[i] = '\\';
-        } else {
+        if (Path[i] == '/')
+            newpath[i] = '\\';
+        else
 #else
-       if (Path[i] == '\\') {
-            newpath[i] = '/';
-        } else {
+        if (Path[i] == '\\')
+            newpath[i] = '/';
+        else
 #endif
-          newpath[i] = Path[i];
-        }
+            newpath[i] = Path[i];
+
         i++;
     }
     newpath[i] = 0;
@@ -412,13 +422,14 @@ char* CCabinet::GetFileName(char* Path)
  *     Pointer to filename
  */
 {
-    unsigned long i, j;
+    ULONG i, j;
 
     j = i = (Path[0] ? (Path[1] == ':' ? 2 : 0) : 0);
 
-    while (Path [i++]) {
-        if (IsSeparator(Path [i - 1])) j = i;
-    }
+    while (Path [i++])
+        if (IsSeparator(Path [i - 1]))
+            j = i;
+
     return Path + j;
 }
 
@@ -431,7 +442,7 @@ void CCabinet::RemoveFileName(char* Path)
  */
 {
     char* FileName;
-    unsigned long i;
+    ULONG i;
 
     i = (Path [0] ? (Path[1] == ':' ? 2 : 0) : 0);
     FileName = GetFileName(Path + i);
@@ -445,7 +456,7 @@ void CCabinet::RemoveFileName(char* Path)
 
 
 bool CCabinet::NormalizePath(char* Path,
-                             unsigned long Length)
+                             ULONG Length)
 /*
  * FUNCTION: Normalizes a path
  * ARGUMENTS:
@@ -455,12 +466,13 @@ bool CCabinet::NormalizePath(char* Path,
  *     true if there was enough room in Path, or false
  */
 {
-    unsigned long n;
+    ULONG n;
     bool OK = true;
 
-    if ((n = strlen(Path)) &&
+    if ((n = (ULONG)strlen(Path)) &&
         (!IsSeparator(Path[n - 1])) &&
-        (OK = ((n + 1) < Length))) {
+        (OK = ((n + 1) < Length)))
+    {
         Path[n]     = DIR_SEPARATOR_CHAR;
         Path[n + 1] = 0;
     }
@@ -503,6 +515,101 @@ 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
+ * ARGUMENTS:
+ *    CodecName = Pointer to a string with the name of the codec
+ */
+{
+    if( !strcasecmp(CodecName, "raw") )
+        SelectCodec(CAB_CODEC_RAW);
+    else if( !strcasecmp(CodecName, "mszip") )
+        SelectCodec(CAB_CODEC_MSZIP);
+    else
+    {
+        printf("Invalid codec specified!\n");
+        return false;
+    }
+
+    return true;
+}
 
 char* CCabinet::GetDestinationPath()
 /*
@@ -523,7 +630,7 @@ bool CCabinet::SetCabinetReservedFile(char* FileName)
  */
 {
     FILEHANDLE FileHandle;
-    unsigned long BytesRead;
+    ULONG BytesRead;
 
 #if defined(WIN32)
     FileHandle = CreateFile(ConvertPath(FileName, true),  // Open this file
@@ -533,38 +640,42 @@ bool CCabinet::SetCabinetReservedFile(char* FileName)
         OPEN_EXISTING,                   // Existing file only
         FILE_ATTRIBUTE_NORMAL,           // Normal file
         NULL);                           // No attribute template
-    if (FileHandle == INVALID_HANDLE_VALUE) {
+    if (FileHandle == INVALID_HANDLE_VALUE)
+    {
         DPRINT(MID_TRACE, ("Cannot open cabinet reserved file.\n"));
         return false;
     }
 #else /* !WIN32 */
-
     FileHandle = fopen(ConvertPath(FileName, true), "rb");
-    if (FileHandle == NULL) {
+    if (FileHandle == NULL)
+    {
         DPRINT(MID_TRACE, ("Cannot open cabinet reserved file.\n"));
         return false;
     }
 #endif
 
     CabinetReservedFileSize = GetSizeOfFile(FileHandle);
-    if (CabinetReservedFileSize == (unsigned long)-1) {
+    if (CabinetReservedFileSize == (ULONG)-1)
+    {
         DPRINT(MIN_TRACE, ("Cannot read from cabinet reserved file.\n"));
         return false;
     }
 
     if (CabinetReservedFileSize == 0)
-      {
+    {
         CloseFile(FileHandle);
         return false;
-      }
+    }
 
     CabinetReservedFileBuffer = AllocateMemory(CabinetReservedFileSize);
-    if (!CabinetReservedFileBuffer) {
+    if (!CabinetReservedFileBuffer)
+    {
         CloseFile(FileHandle);
         return false;
     }
 
-    if (!ReadFileData(FileHandle, CabinetReservedFileBuffer, CabinetReservedFileSize, &BytesRead)) {
+    if (!ReadFileData(FileHandle, CabinetReservedFileBuffer, CabinetReservedFileSize, &BytesRead))
+    {
         CloseFile(FileHandle);
         return false;
     }
@@ -588,7 +699,7 @@ char* CCabinet::GetCabinetReservedFile()
 }
 
 
-unsigned long CCabinet::GetCurrentDiskNumber()
+ULONG CCabinet::GetCurrentDiskNumber()
 /*
  * FUNCTION: Returns current disk number
  * RETURNS:
@@ -599,7 +710,7 @@ unsigned long CCabinet::GetCurrentDiskNumber()
 }
 
 
-unsigned long CCabinet::Open()
+ULONG CCabinet::Open()
 /*
  * FUNCTION: Opens a cabinet file
  * RETURNS:
@@ -607,12 +718,13 @@ unsigned long CCabinet::Open()
  */
 {
     PCFFOLDER_NODE FolderNode;
-    unsigned long Status;
-    unsigned long Index;
+    ULONG Status;
+    ULONG Index;
 
-    if (!FileOpen) {
-        unsigned long BytesRead;
-        unsigned long Size;
+    if (!FileOpen)
+    {
+        ULONG BytesRead;
+        ULONG Size;
 
         OutputBuffer = AllocateMemory(CAB_BLOCKSIZE + 12);    // This should be enough
         if (!OutputBuffer)
@@ -627,13 +739,15 @@ unsigned long CCabinet::Open()
             FILE_ATTRIBUTE_NORMAL,           // Normal file
             NULL);                           // No attribute template
 
-        if (FileHandle == INVALID_HANDLE_VALUE) {
+        if (FileHandle == INVALID_HANDLE_VALUE)
+        {
             DPRINT(MID_TRACE, ("Cannot open file.\n"));
             return CAB_STATUS_CANNOT_OPEN;
         }
 #else /* !WIN32 */
         FileHandle = fopen(CabinetName, "rb");
-        if (FileHandle == NULL) {
+        if (FileHandle == NULL)
+        {
             DPRINT(MID_TRACE, ("Cannot open file.\n"));
             return CAB_STATUS_CANNOT_OPEN;
         }
@@ -643,8 +757,9 @@ unsigned long CCabinet::Open()
 
         /* Load CAB header */
         if ((Status = ReadBlock(&CABHeader, sizeof(CFHEADER), &BytesRead))
-            != CAB_STATUS_SUCCESS) {
-            DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+            != CAB_STATUS_SUCCESS)
+        {
+            DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
             return CAB_STATUS_INVALID_CAB;
         }
 
@@ -654,7 +769,8 @@ unsigned long CCabinet::Open()
             (CABHeader.Version         != CAB_VERSION     ) ||
             (CABHeader.FolderCount     == 0               ) ||
             (CABHeader.FileCount       == 0               ) ||
-            (CABHeader.FileTableOffset < sizeof(CFHEADER))) {
+            (CABHeader.FileTableOffset < sizeof(CFHEADER)))
+        {
             CloseCabinet();
             DPRINT(MID_TRACE, ("File has invalid header.\n"));
             return CAB_STATUS_INVALID_CAB;
@@ -663,10 +779,12 @@ unsigned long CCabinet::Open()
         Size = 0;
 
         /* Read/skip any reserved bytes */
-        if (CABHeader.Flags & CAB_FLAG_RESERVE) {
-            if ((Status = ReadBlock(&Size, sizeof(unsigned long), &BytesRead))
-                != CAB_STATUS_SUCCESS) {
-                DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+        if (CABHeader.Flags & CAB_FLAG_RESERVE)
+        {
+            if ((Status = ReadBlock(&Size, sizeof(ULONG), &BytesRead))
+                != CAB_STATUS_SUCCESS)
+            {
+                DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
                 return CAB_STATUS_INVALID_CAB;
             }
             CabinetReserved = Size & 0xFFFF;
@@ -674,20 +792,22 @@ unsigned long CCabinet::Open()
             DataReserved    = (Size >> 24) & 0xFF;
 
 #if defined(WIN32)
-            SetFilePointer(FileHandle, CabinetReserved, NULL, FILE_CURRENT);
-            if (GetLastError() != NO_ERROR) {
-                DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+            if (SetFilePointer(FileHandle, CabinetReserved, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
+            {
+                DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
                 return CAB_STATUS_FAILURE;
             }
 #else
-            if (fseek(FileHandle, (off_t)CabinetReserved, SEEK_CUR) != 0) {
+            if (fseek(FileHandle, (off_t)CabinetReserved, SEEK_CUR) != 0)
+            {
                 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
                 return CAB_STATUS_FAILURE;
             }
 #endif
         }
 
-        if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) {
+        if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
+        {
             /* Read name of previous cabinet */
             Status = ReadString(CabinetPrev, 256);
             if (Status != CAB_STATUS_SUCCESS)
@@ -696,12 +816,15 @@ unsigned long CCabinet::Open()
             Status = ReadString(DiskPrev, 256);
             if (Status != CAB_STATUS_SUCCESS)
                 return Status;
-        } else {
+        }
+        else
+        {
             strcpy(CabinetPrev, "");
             strcpy(DiskPrev,    "");
         }
 
-        if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) {
+        if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
+        {
             /* Read name of next cabinet */
             Status = ReadString(CabinetNext, 256);
             if (Status != CAB_STATUS_SUCCESS)
@@ -710,15 +833,19 @@ unsigned long CCabinet::Open()
             Status = ReadString(DiskNext, 256);
             if (Status != CAB_STATUS_SUCCESS)
                 return Status;
-        } else {
+        }
+        else
+        {
             strcpy(CabinetNext, "");
             strcpy(DiskNext,    "");
         }
 
         /* Read all folders */
-        for (Index = 0; Index < CABHeader.FolderCount; Index++) {
+        for (Index = 0; Index < CABHeader.FolderCount; Index++)
+        {
             FolderNode = NewFolderNode();
-            if (!FolderNode) {
+            if (!FolderNode)
+            {
                 DPRINT(MIN_TRACE, ("Insufficient resources.\n"));
                 return CAB_STATUS_NOMEMORY;
             }
@@ -729,25 +856,29 @@ unsigned long CCabinet::Open()
             FolderNode->Index = Index;
 
             if ((Status = ReadBlock(&FolderNode->Folder,
-                sizeof(CFFOLDER), &BytesRead)) != CAB_STATUS_SUCCESS) {
-                DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+                sizeof(CFFOLDER), &BytesRead)) != CAB_STATUS_SUCCESS)
+            {
+                DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
                 return CAB_STATUS_INVALID_CAB;
             }
         }
 
         /* Read file entries */
         Status = ReadFileTable();
-        if (Status != CAB_STATUS_SUCCESS) {
-            DPRINT(MIN_TRACE, ("ReadFileTable() failed (%d).\n", (unsigned int)Status));
+        if (Status != CAB_STATUS_SUCCESS)
+        {
+            DPRINT(MIN_TRACE, ("ReadFileTable() failed (%u).\n", (UINT)Status));
             return Status;
         }
 
         /* Read data blocks for all folders */
         FolderNode = FolderListHead;
-        while (FolderNode != NULL) {
+        while (FolderNode != NULL)
+        {
             Status = ReadDataBlocks(FolderNode);
-            if (Status != CAB_STATUS_SUCCESS) {
-                DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%d).\n", (unsigned int)Status));
+            if (Status != CAB_STATUS_SUCCESS)
+            {
+                DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%u).\n", (UINT)Status));
                 return Status;
             }
             FolderNode = FolderNode->Next;
@@ -762,32 +893,30 @@ void CCabinet::Close()
  * FUNCTION: Closes the cabinet file
  */
 {
-    if (FileOpen) {
+    if (FileOpen)
+    {
         CloseFile(FileHandle);
         FileOpen = false;
     }
 }
 
 
-unsigned long 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);
 }
 
 
-unsigned long CCabinet::FindNext(PCAB_SEARCH Search)
+ULONG CCabinet::FindNext(PCAB_SEARCH Search)
 /*
  * FUNCTION: Finds next file in the cabinet that matches a search criteria
  * ARGUMENTS:
@@ -796,27 +925,58 @@ unsigned long CCabinet::FindNext(PCAB_SEARCH Search)
  *     Status of operation
  */
 {
-    unsigned long Status;
+    bool bFound = false;
+    PSEARCH_CRITERIA Criteria;
+    ULONG Status;
 
-    if (RestartSearch) {
+    if (RestartSearch)
+    {
         Search->Next  = FileListHead;
 
         /* Skip split files already extracted */
         while ((Search->Next) &&
             (Search->Next->File.FileControlID > CAB_FILE_MAX_FOLDER) &&
-            (Search->Next->File.FileOffset <= LastFileOffset)) {
-            DPRINT(MAX_TRACE, ("Skipping file (%s)  FileOffset (0x%lX)  LastFileOffset (0x%lX).\n",
-                Search->Next->FileName, Search->Next->File.FileOffset, LastFileOffset));
+            (Search->Next->File.FileOffset <= LastFileOffset))
+        {
+            DPRINT(MAX_TRACE, ("Skipping file (%s)  FileOffset (0x%X)  LastFileOffset (0x%X).\n",
+                Search->Next->FileName, (UINT)Search->Next->File.FileOffset, (UINT)LastFileOffset));
             Search->Next = Search->Next->Next;
         }
 
         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) {
-        if (strlen(DiskNext) > 0) {
+    if (!Search->Next)
+    {
+        if (strlen(DiskNext) > 0)
+        {
             CloseCabinet();
 
             SetCabinetName(CabinetNext);
@@ -830,7 +990,8 @@ unsigned long CCabinet::FindNext(PCAB_SEARCH Search)
             Search->Next = FileListHead;
             if (!Search->Next)
                 return CAB_STATUS_NOFILE;
-        } else
+        }
+        else
             return CAB_STATUS_NOFILE;
     }
 
@@ -841,7 +1002,7 @@ unsigned long CCabinet::FindNext(PCAB_SEARCH Search)
 }
 
 
-unsigned long CCabinet::ExtractFile(char* FileName)
+ULONG CCabinet::ExtractFile(char* FileName)
 /*
  * FUNCTION: Extracts a file from the cabinet
  * ARGUMENTS:
@@ -850,52 +1011,56 @@ unsigned long CCabinet::ExtractFile(char* FileName)
  *     Status of operation
  */
 {
-    unsigned long Size;
-    unsigned long Offset;
-    unsigned long BytesRead;
-    unsigned long BytesToRead;
-    unsigned long BytesWritten;
-    unsigned long BytesSkipped;
-    unsigned long BytesToWrite;
-    unsigned long TotalBytesRead;
-    unsigned long CurrentOffset;
-    unsigned char* Buffer;
-    unsigned char* CurrentBuffer;
+    ULONG Size;
+    ULONG Offset;
+    ULONG BytesRead;
+    ULONG BytesToRead;
+    ULONG BytesWritten;
+    ULONG BytesSkipped;
+    ULONG BytesToWrite;
+    ULONG TotalBytesRead;
+    ULONG CurrentOffset;
+    PUCHAR Buffer;
+    PUCHAR CurrentBuffer;
     FILEHANDLE DestFile;
     PCFFILE_NODE File;
     CFDATA CFData;
-    unsigned long Status;
+    ULONG Status;
     bool Skip;
 #if defined(WIN32)
     FILETIME FileTime;
 #endif
-    char DestName[MAX_PATH];
-    char TempName[MAX_PATH];
+    CHAR DestName[MAX_PATH];
+    CHAR TempName[MAX_PATH];
 
     Status = LocateFile(FileName, &File);
-    if (Status != CAB_STATUS_SUCCESS) {
-        DPRINT(MID_TRACE, ("Cannot locate file (%d).\n", (unsigned int)Status));
+    if (Status != CAB_STATUS_SUCCESS)
+    {
+        DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
         return Status;
     }
 
     LastFileOffset = File->File.FileOffset;
 
-    switch (CurrentFolderNode->Folder.CompressionType & CAB_COMP_MASK) {
-    case CAB_COMP_NONE:
-        SelectCodec(CAB_CODEC_RAW);
-        break;
-    case CAB_COMP_MSZIP:
-        SelectCodec(CAB_CODEC_MSZIP);
-        break;
-    default:
-        return CAB_STATUS_UNSUPPCOMP;
+    switch (CurrentFolderNode->Folder.CompressionType & CAB_COMP_MASK)
+    {
+        case CAB_COMP_NONE:
+            SelectCodec(CAB_CODEC_RAW);
+            break;
+
+        case CAB_COMP_MSZIP:
+            SelectCodec(CAB_CODEC_MSZIP);
+            break;
+
+        default:
+            return CAB_STATUS_UNSUPPCOMP;
     }
 
-    DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%X)  Size (%d bytes)  AO (0x%X)  UO (0x%X).\n",
-        (unsigned int)File->File.FileOffset,
-        (unsigned int)File->File.FileSize,
-        (unsigned int)File->DataBlock->AbsoluteOffset,
-        (unsigned int)File->DataBlock->UncompOffset));
+    DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%X)  Size (%u bytes)  AO (0x%X)  UO (0x%X).\n",
+        (UINT)File->File.FileOffset,
+        (UINT)File->File.FileSize,
+        (UINT)File->DataBlock->AbsoluteOffset,
+        (UINT)File->DataBlock->UncompOffset));
 
     strcpy(DestName, DestPath);
     strcat(DestName, FileName);
@@ -909,10 +1074,12 @@ unsigned long CCabinet::ExtractFile(char* FileName)
         CREATE_NEW,                      // New file only
         FILE_ATTRIBUTE_NORMAL,           // Normal file
         NULL);                           // No attribute template
-    if (DestFile == INVALID_HANDLE_VALUE) {
+    if (DestFile == INVALID_HANDLE_VALUE)
+    {
         /* If file exists, ask to overwrite file */
         if (((Status = GetLastError()) == ERROR_FILE_EXISTS) &&
-            (OnOverwrite(&File->File, FileName))) {
+            (OnOverwrite(&File->File, FileName)))
+        {
             /* Create destination file, overwrite if it already exists */
             DestFile = CreateFile(DestName, // Create this file
                 GENERIC_WRITE,              // Open for writing
@@ -923,7 +1090,9 @@ unsigned long CCabinet::ExtractFile(char* FileName)
                 NULL);                      // No attribute template
             if (DestFile == INVALID_HANDLE_VALUE)
                 return CAB_STATUS_CANNOT_CREATE;
-        } else {
+        }
+        else
+        {
             if (Status == ERROR_FILE_EXISTS)
                 return CAB_STATUS_FILE_EXISTS;
             else
@@ -932,28 +1101,31 @@ unsigned long CCabinet::ExtractFile(char* FileName)
     }
 #else /* !WIN32 */
     DestFile = fopen(DestName, "rb");
-    if (DestFile != NULL) {
+    if (DestFile != NULL)
+    {
         fclose(DestFile);
         /* If file exists, ask to overwrite file */
-        if (OnOverwrite(&File->File, FileName)) {
+        if (OnOverwrite(&File->File, FileName))
+        {
             DestFile = fopen(DestName, "w+b");
-            if (DestFile == NULL) {
+            if (DestFile == NULL)
                 return CAB_STATUS_CANNOT_CREATE;
-            }
-        } else {
-            return CAB_STATUS_FILE_EXISTS;
         }
-    } else {
+        else
+            return CAB_STATUS_FILE_EXISTS;
+    }
+    else
+    {
         DestFile = fopen(DestName, "w+b");
-        if (DestFile == NULL) {
+        if (DestFile == NULL)
             return CAB_STATUS_CANNOT_CREATE;
-        }
     }
 #endif
 #if defined(WIN32)
-    if (!DosDateTimeToFileTime(File->File.FileDate, File->File.FileTime, &FileTime)) {
+    if (!DosDateTimeToFileTime(File->File.FileDate, File->File.FileTime, &FileTime))
+    {
         CloseFile(DestFile);
-        DPRINT(MIN_TRACE, ("DosDateTimeToFileTime() failed (%lu).\n", GetLastError()));
+        DPRINT(MIN_TRACE, ("DosDateTimeToFileTime() failed (%u).\n", (UINT)GetLastError()));
         return CAB_STATUS_CANNOT_WRITE;
     }
 
@@ -961,10 +1133,11 @@ unsigned long CCabinet::ExtractFile(char* FileName)
 #else
     //DPRINT(MIN_TRACE, ("FIXME: DosDateTimeToFileTime\n"));
 #endif
-    SetAttributesOnFile(File);
+    SetAttributesOnFile(DestName, File->File.Attributes);
 
-    Buffer = (unsigned char*)AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
-    if (!Buffer) {
+    Buffer = (PUCHAR)AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
+    if (!Buffer)
+    {
         CloseFile(DestFile);
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
@@ -973,18 +1146,20 @@ unsigned long CCabinet::ExtractFile(char* FileName)
     /* Call OnExtract event handler */
     OnExtract(&File->File, FileName);
 
-       /* Search to start of file */
+    /* Search to start of file */
 #if defined(WIN32)
-       Offset = SetFilePointer(FileHandle,
-               File->DataBlock->AbsoluteOffset,
-               NULL,
-               FILE_BEGIN);
-       if (GetLastError() != NO_ERROR) {
-               DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-               return CAB_STATUS_INVALID_CAB;
-       }
+    Offset = SetFilePointer(FileHandle,
+        File->DataBlock->AbsoluteOffset,
+        NULL,
+        FILE_BEGIN);
+    if (Offset == INVALID_SET_FILE_POINTER)
+    {
+        DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+        return CAB_STATUS_INVALID_CAB;
+    }
 #else
-    if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0) {
+    if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
+    {
         DPRINT(MIN_TRACE, ("fseek() failed.\n"));
         return CAB_STATUS_FAILURE;
     }
@@ -997,55 +1172,62 @@ unsigned long CCabinet::ExtractFile(char* FileName)
 
     Skip = true;
 
-       ReuseBlock = (CurrentDataNode == File->DataBlock);
-    if (Size > 0) {
-               do {
-                       DPRINT(MAX_TRACE, ("CO (0x%lX)    ReuseBlock (%d)    Offset (0x%lX)   Size (%ld)  BytesLeftInBlock (%ld)\n",
-                               File->DataBlock->UncompOffset, (unsigned int)ReuseBlock, Offset, Size,
-                               BytesLeftInBlock));
+    ReuseBlock = (CurrentDataNode == File->DataBlock);
+    if (Size > 0)
+    {
+        do
+        {
+            DPRINT(MAX_TRACE, ("CO (0x%X)    ReuseBlock (%u)    Offset (0x%X)   Size (%d)  BytesLeftInBlock (%d)\n",
+                (UINT)File->DataBlock->UncompOffset, (UINT)ReuseBlock, (UINT)Offset, (UINT)Size,
+                (UINT)BytesLeftInBlock));
 
-                       if (/*(CurrentDataNode != File->DataBlock) &&*/ (!ReuseBlock) || (BytesLeftInBlock <= 0)) {
-
-                               DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%d)\n", (unsigned int)ReuseBlock));
+            if (/*(CurrentDataNode != File->DataBlock) &&*/ (!ReuseBlock) || (BytesLeftInBlock <= 0))
+            {
+                DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
 
                 CurrentBuffer  = Buffer;
                 TotalBytesRead = 0;
-                do {
-                    DPRINT(MAX_TRACE, ("Size (%lu bytes).\n", Size));
+                do
+                {
+                    DPRINT(MAX_TRACE, ("Size (%u bytes).\n", (UINT)Size));
 
                     if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
-                        CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA))) {
+                        CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
+                    {
                         CloseFile(DestFile);
                         FreeMemory(Buffer);
-                        DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+                        DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
                         return CAB_STATUS_INVALID_CAB;
                     }
 
-                    DPRINT(MAX_TRACE, ("Data block: Checksum (0x%X)  CompSize (%d bytes)  UncompSize (%d bytes)\n",
-                        (unsigned int)CFData.Checksum,
-                        (unsigned int)CFData.CompSize,
-                        (unsigned int)CFData.UncompSize));
+                    DPRINT(MAX_TRACE, ("Data block: Checksum (0x%X)  CompSize (%u bytes)  UncompSize (%u bytes)\n",
+                        (UINT)CFData.Checksum,
+                        CFData.CompSize,
+                        CFData.UncompSize));
 
                     ASSERT(CFData.CompSize <= CAB_BLOCKSIZE + 12);
 
                     BytesToRead = CFData.CompSize;
 
-                                       DPRINT(MAX_TRACE, ("Read: (0x%lX,0x%lX).\n",
-                                               (long unsigned int)CurrentBuffer, (long unsigned int)Buffer));
+                    DPRINT(MAX_TRACE, ("Read: (0x%lX,0x%lX).\n",
+                        (unsigned long)CurrentBuffer, (unsigned long)Buffer));
 
                     if (((Status = ReadBlock(CurrentBuffer, BytesToRead, &BytesRead)) !=
-                        CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead)) {
+                        CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead))
+                    {
                         CloseFile(DestFile);
                         FreeMemory(Buffer);
-                        DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+                        DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
                         return CAB_STATUS_INVALID_CAB;
                     }
 
                     /* FIXME: Does not work with files generated by makecab.exe */
 /*
-                    if (CFData.Checksum != 0) {
-                        unsigned long Checksum = ComputeChecksum(CurrentBuffer, BytesRead, 0);
-                        if (Checksum != CFData.Checksum) {
+                    if (CFData.Checksum != 0)
+                    {
+                        ULONG Checksum = ComputeChecksum(CurrentBuffer, BytesRead, 0);
+                        if (Checksum != CFData.Checksum)
+                        {
                             CloseFile(DestFile);
                             FreeMemory(Buffer);
                             DPRINT(MIN_TRACE, ("Bad checksum (is 0x%X, should be 0x%X).\n",
@@ -1058,7 +1240,8 @@ unsigned long CCabinet::ExtractFile(char* FileName)
 
                     CurrentBuffer += BytesRead;
 
-                    if (CFData.UncompSize == 0) {
+                    if (CFData.UncompSize == 0)
+                    {
                         if (strlen(DiskNext) == 0)
                             return CAB_STATUS_NOFILE;
 
@@ -1080,8 +1263,9 @@ unsigned long CCabinet::ExtractFile(char* FileName)
                         /* The first data block of the file will not be
                            found as it is located in the previous file */
                         Status = LocateFile(TempName, &File);
-                        if (Status == CAB_STATUS_NOFILE) {
-                            DPRINT(MID_TRACE, ("Cannot locate file (%d).\n", (unsigned int)Status));
+                        if (Status == CAB_STATUS_NOFILE)
+                        {
+                            DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
                             return Status;
                         }
 
@@ -1090,26 +1274,27 @@ unsigned long CCabinet::ExtractFile(char* FileName)
 
                         /* Search to start of file */
 #if defined(WIN32)
-                       (unsigned int)SetFilePointer(FileHandle,
-                               File->DataBlock->AbsoluteOffset,
-                               NULL,
-                               FILE_BEGIN);
-                       if (GetLastError() != NO_ERROR) {
-                               DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-                               return CAB_STATUS_INVALID_CAB;
-                       }
+                        if( SetFilePointer(FileHandle,
+                                           File->DataBlock->AbsoluteOffset,
+                                           NULL,
+                                           FILE_BEGIN) == INVALID_SET_FILE_POINTER )
+                        {
+                            DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+                            return CAB_STATUS_INVALID_CAB;
+                        }
 #else
-                        if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0) {
+                        if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
+                        {
                             DPRINT(MIN_TRACE, ("fseek() failed.\n"));
                             return CAB_STATUS_INVALID_CAB;
                         }
 #endif
 
-                        DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%X)  Size (%d bytes)  AO (0x%X)  UO (0x%X).\n",
-                            (unsigned int)File->File.FileOffset,
-                            (unsigned int)File->File.FileSize,
-                            (unsigned int)File->DataBlock->AbsoluteOffset,
-                            (unsigned int)File->DataBlock->UncompOffset));
+                        DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%X)  Size (%u bytes)  AO (0x%X)  UO (0x%X).\n",
+                            (UINT)File->File.FileOffset,
+                            (UINT)File->File.FileSize,
+                            (UINT)File->DataBlock->AbsoluteOffset,
+                            (UINT)File->DataBlock->UncompOffset));
 
                         CurrentDataNode = File->DataBlock;
                         ReuseBlock = true;
@@ -1118,10 +1303,11 @@ unsigned long CCabinet::ExtractFile(char* FileName)
                     }
                 } while (CFData.UncompSize == 0);
 
-                DPRINT(MAX_TRACE, ("TotalBytesRead (%lu).\n", TotalBytesRead));
+                DPRINT(MAX_TRACE, ("TotalBytesRead (%u).\n", (UINT)TotalBytesRead));
 
                 Status = Codec->Uncompress(OutputBuffer, Buffer, TotalBytesRead, &BytesToWrite);
-                if (Status != CS_SUCCESS) {
+                if (Status != CS_SUCCESS)
+                {
                     CloseFile(DestFile);
                     FreeMemory(Buffer);
                     DPRINT(MID_TRACE, ("Cannot uncompress block.\n"));
@@ -1130,47 +1316,51 @@ unsigned long CCabinet::ExtractFile(char* FileName)
                     return CAB_STATUS_INVALID_CAB;
                 }
 
-                if (BytesToWrite != CFData.UncompSize) {
-                    DPRINT(MID_TRACE, ("BytesToWrite (%lu) != CFData.UncompSize (%d)\n",
-                        BytesToWrite, CFData.UncompSize));
+                if (BytesToWrite != CFData.UncompSize)
+                {
+                    DPRINT(MID_TRACE, ("BytesToWrite (%u) != CFData.UncompSize (%d)\n",
+                        (UINT)BytesToWrite, CFData.UncompSize));
                     return CAB_STATUS_INVALID_CAB;
                 }
 
                 BytesLeftInBlock = BytesToWrite;
-            } else {
-                DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%d)\n", (unsigned int)ReuseBlock));
+            }
+            else
+            {
+                DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
 
                 BytesToWrite = BytesLeftInBlock;
 
-                               DPRINT(MAX_TRACE, ("Seeking to absolute offset 0x%lX.\n",
-                                       CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
-                    CurrentDataNode->Data.CompSize));
+                DPRINT(MAX_TRACE, ("Seeking to absolute offset 0x%X.\n",
+                    (UINT)(CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) + CurrentDataNode->Data.CompSize)));
 
-                               if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
-                                       CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA))) {
-                                       CloseFile(DestFile);
-                                       FreeMemory(Buffer);
-                                       DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
-                                       return CAB_STATUS_INVALID_CAB;
-                               }
+                if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
+                    CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
+                {
+                    CloseFile(DestFile);
+                    FreeMemory(Buffer);
+                    DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
+                    return CAB_STATUS_INVALID_CAB;
+                }
 
-                               DPRINT(MAX_TRACE, ("CFData.CompSize 0x%X  CFData.UncompSize 0x%X.\n",
-                                       CFData.CompSize, CFData.UncompSize));
+                DPRINT(MAX_TRACE, ("CFData.CompSize 0x%X  CFData.UncompSize 0x%X.\n",
+                    CFData.CompSize, CFData.UncompSize));
 
                 /* Go to next data block */
 #if defined(WIN32)
-               (unsigned int)SetFilePointer(FileHandle,
-                       CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
-                    CurrentDataNode->Data.CompSize,
-                       NULL,
-                       FILE_BEGIN);
-               if (GetLastError() != NO_ERROR) {
-                       DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-                       return CAB_STATUS_INVALID_CAB;
-               }
+                if( SetFilePointer(FileHandle,
+                                   CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
+                                   CurrentDataNode->Data.CompSize,
+                                   NULL,
+                                   FILE_BEGIN) == INVALID_SET_FILE_POINTER )
+                {
+                    DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+                    return CAB_STATUS_INVALID_CAB;
+                }
 #else
                 if (fseek(FileHandle, (off_t)CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
-                    CurrentDataNode->Data.CompSize, SEEK_SET) != 0) {
+                    CurrentDataNode->Data.CompSize, SEEK_SET) != 0)
+                {
                     DPRINT(MIN_TRACE, ("fseek() failed.\n"));
                     return CAB_STATUS_INVALID_CAB;
                 }
@@ -1184,27 +1374,29 @@ unsigned long CCabinet::ExtractFile(char* FileName)
             else
                 BytesSkipped = 0;
 
-                       BytesToWrite -= BytesSkipped;
+            BytesToWrite -= BytesSkipped;
 
-                       if (Size < BytesToWrite)
+            if (Size < BytesToWrite)
                 BytesToWrite = Size;
 
-            DPRINT(MAX_TRACE, ("Offset (0x%X)  CurrentOffset (0x%X)  ToWrite (%d)  Skipped (%d)(%d)  Size (%d).\n",
-                (unsigned int)Offset,
-                (unsigned int)CurrentOffset,
-                (unsigned int)BytesToWrite,
-                (unsigned int)BytesSkipped, (unsigned int)Skip,
-                (unsigned int)Size));
+            DPRINT(MAX_TRACE, ("Offset (0x%X)  CurrentOffset (0x%X)  ToWrite (%u)  Skipped (%u)(%u)  Size (%u).\n",
+                (UINT)Offset,
+                (UINT)CurrentOffset,
+                (UINT)BytesToWrite,
+                (UINT)BytesSkipped, (UINT)Skip,
+                (UINT)Size));
 
 #if defined(WIN32)
-            if (!WriteFile(DestFile, (void*)((unsigned long)OutputBuffer + BytesSkipped),
-                BytesToWrite, &BytesWritten, NULL) ||
-                (BytesToWrite != BytesWritten)) {
-                                       DPRINT(MIN_TRACE, ("Status 0x%lX.\n", GetLastError()));
+            if (!WriteFile(DestFile, (void*)((PUCHAR)OutputBuffer + BytesSkipped),
+                BytesToWrite, (LPDWORD)&BytesWritten, NULL) ||
+                (BytesToWrite != BytesWritten))
+            {
+                        DPRINT(MIN_TRACE, ("Status 0x%X.\n", (UINT)GetLastError()));
 #else
             BytesWritten = BytesToWrite;
-            if (fwrite((void*)((unsigned long)OutputBuffer + BytesSkipped),
-                BytesToWrite, 1, DestFile) < 1) {
+            if (fwrite((void*)((PUCHAR)OutputBuffer + BytesSkipped),
+                BytesToWrite, 1, DestFile) < 1)
+            {
 #endif
                 CloseFile(DestFile);
                 FreeMemory(Buffer);
@@ -1213,7 +1405,7 @@ unsigned long CCabinet::ExtractFile(char* FileName)
             }
             Size -= BytesToWrite;
 
-                       CurrentOffset += BytesToWrite;
+            CurrentOffset += BytesToWrite;
 
             /* Don't skip any more bytes */
             Skip = false;
@@ -1227,15 +1419,25 @@ unsigned long CCabinet::ExtractFile(char* FileName)
     return CAB_STATUS_SUCCESS;
 }
 
+bool CCabinet::IsCodecSelected()
+/*
+ * FUNCTION: Returns the value of CodecSelected
+ * RETURNS:
+ *     Whether a codec is selected
+ */
+{
+    return CodecSelected;
+}
 
-void CCabinet::SelectCodec(unsigned long Id)
+void CCabinet::SelectCodec(LONG Id)
 /*
  * FUNCTION: Selects codec engine to use
  * ARGUMENTS:
  *     Id = Codec identifier
  */
 {
-    if (CodecSelected) {
+    if (CodecSelected)
+    {
         if (Id == CodecId)
             return;
 
@@ -1243,17 +1445,18 @@ void CCabinet::SelectCodec(unsigned long Id)
         delete Codec;
     }
 
-    switch (Id) {
-    case CAB_CODEC_RAW:
-#if 0
-        Codec = new CRawCodec();
-#endif
-        break;
-    case CAB_CODEC_MSZIP:
-        Codec = new CMSZipCodec();
-        break;
-    default:
-        return;
+    switch (Id)
+    {
+        case CAB_CODEC_RAW:
+            Codec = new CRawCodec();
+            break;
+
+        case CAB_CODEC_MSZIP:
+            Codec = new CMSZipCodec();
+            break;
+
+        default:
+            return;
     }
 
     CodecId       = Id;
@@ -1265,20 +1468,21 @@ void CCabinet::SelectCodec(unsigned long Id)
 
 /* CAB write methods */
 
-unsigned long CCabinet::NewCabinet()
+ULONG CCabinet::NewCabinet()
 /*
  * FUNCTION: Creates a new cabinet
  * RETURNS:
  *     Status of operation
  */
 {
-    unsigned long Status;
+    ULONG Status;
 
     CurrentDiskNumber = 0;
 
     OutputBuffer = AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
     InputBuffer  = AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
-    if ((!OutputBuffer) || (!InputBuffer)) {
+    if ((!OutputBuffer) || (!InputBuffer))
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
     }
@@ -1309,7 +1513,7 @@ unsigned long CCabinet::NewCabinet()
     // NextFolderNumber is 0-based
     NextFolderNumber = 0;
 
-       CurrentFolderNode = NULL;
+    CurrentFolderNode = NULL;
     Status = NewFolder();
     if (Status != CAB_STATUS_SUCCESS)
         return Status;
@@ -1317,7 +1521,8 @@ unsigned long CCabinet::NewCabinet()
     CurrentFolderNode->Folder.DataOffset = DiskSize - TotalHeaderSize;
 
     ScratchFile = new CCFDATAStorage;
-    if (!ScratchFile) {
+    if (!ScratchFile)
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
     }
@@ -1334,7 +1539,7 @@ unsigned long CCabinet::NewCabinet()
 }
 
 
-unsigned long CCabinet::NewDisk()
+ULONG CCabinet::NewDisk()
 /*
  * FUNCTION: Forces a new disk to be created
  * RETURNS:
@@ -1358,7 +1563,7 @@ unsigned long CCabinet::NewDisk()
 }
 
 
-unsigned long CCabinet::NewFolder()
+ULONG CCabinet::NewFolder()
 /*
  * FUNCTION: Forces a new folder to be created
  * RETURNS:
@@ -1368,23 +1573,26 @@ unsigned long CCabinet::NewFolder()
     DPRINT(MAX_TRACE, ("Creating new folder.\n"));
 
     CurrentFolderNode = NewFolderNode();
-    if (!CurrentFolderNode) {
+    if (!CurrentFolderNode)
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
     }
 
     switch (CodecId) {
-    case CAB_CODEC_RAW:
-        CurrentFolderNode->Folder.CompressionType = CAB_COMP_NONE;
-        break;
-    case CAB_CODEC_MSZIP:
-        CurrentFolderNode->Folder.CompressionType = CAB_COMP_MSZIP;
-        break;
-    default:
-        return CAB_STATUS_UNSUPPCOMP;
+        case CAB_CODEC_RAW:
+            CurrentFolderNode->Folder.CompressionType = CAB_COMP_NONE;
+            break;
+
+        case CAB_CODEC_MSZIP:
+            CurrentFolderNode->Folder.CompressionType = CAB_COMP_MSZIP;
+            break;
+
+        default:
+            return CAB_STATUS_UNSUPPCOMP;
     }
 
-       /* FIXME: This won't work if no files are added to the new folder */
+    /* FIXME: This won't work if no files are added to the new folder */
 
     DiskSize += sizeof(CFFOLDER);
 
@@ -1400,7 +1608,7 @@ unsigned long CCabinet::NewFolder()
 }
 
 
-unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
+ULONG CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
 /*
  * FUNCTION: Writes a file to the scratch file
  * ARGUMENTS:
@@ -1409,12 +1617,13 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
  *     Status of operation
  */
 {
-    unsigned long BytesToRead;
-    unsigned long BytesRead;
-    unsigned long Status;
-    unsigned long Size;
+    ULONG BytesToRead;
+    ULONG BytesRead;
+    ULONG Status;
+    ULONG Size;
 
-    if (!ContinueFile) {
+    if (!ContinueFile)
+    {
         /* Try to open file */
 #if defined(WIN32)
         SourceFile = CreateFile(
@@ -1425,19 +1634,22 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
             OPEN_EXISTING,           // File must exist
             FILE_ATTRIBUTE_NORMAL,   // Normal file
             NULL);                   // No attribute template
-        if (SourceFile == INVALID_HANDLE_VALUE) {
+        if (SourceFile == INVALID_HANDLE_VALUE)
+        {
             DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName));
             return CAB_STATUS_NOFILE;
         }
 #else /* !WIN32 */
         SourceFile = fopen(FileNode->FileName, "rb");
-        if (SourceFile == NULL) {
+        if (SourceFile == NULL)
+        {
             DPRINT(MID_TRACE, ("Cannot open cabinet reserved file.\n"));
             return CAB_STATUS_NOFILE;
         }
 #endif
 
-        if (CreateNewFolder) {
+        if (CreateNewFolder)
+        {
             /* There is always a new folder after
                a split file is completely stored */
             Status = NewFolder();
@@ -1453,11 +1665,11 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
 
         FileNode->File.FileOffset        = CurrentFolderNode->UncompOffset;
         CurrentFolderNode->UncompOffset += TotalBytesLeft;
-        FileNode->File.FileControlID     = (unsigned short)(NextFolderNumber - 1);
+        FileNode->File.FileControlID     = (USHORT)(NextFolderNumber - 1);
         CurrentFolderNode->Commit        = true;
         PrevCabinetNumber                               = CurrentDiskNumber;
 
-        Size = sizeof(CFFILE) + strlen(GetFileName(FileNode->FileName)) + 1;
+        Size = sizeof(CFFILE) + (ULONG)strlen(GetFileName(FileNode->FileName)) + 1;
         CABHeader.FileTableOffset += Size;
         TotalFileSize += Size;
         DiskSize += Size;
@@ -1465,24 +1677,27 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
 
     FileNode->Commit = true;
 
-    if (TotalBytesLeft > 0) {
-        do {
-            if (TotalBytesLeft > (unsigned long)CAB_BLOCKSIZE - CurrentIBufferSize)
+    if (TotalBytesLeft > 0)
+    {
+        do
+        {
+            if (TotalBytesLeft > (ULONG)CAB_BLOCKSIZE - CurrentIBufferSize)
                 BytesToRead = CAB_BLOCKSIZE - CurrentIBufferSize;
             else
                 BytesToRead = TotalBytesLeft;
 
-            if (!ReadFileData(SourceFile, CurrentIBuffer, BytesToRead, &BytesRead) || (BytesToRead != BytesRead)) {
-                DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%lu)  BytesRead (%lu)  CurrentIBufferSize (%lu).\n",
-                    BytesToRead, BytesRead, CurrentIBufferSize));
+            if (!ReadFileData(SourceFile, CurrentIBuffer, BytesToRead, &BytesRead) || (BytesToRead != BytesRead))
+            {
+                DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%u)  BytesRead (%u)  CurrentIBufferSize (%u).\n",
+                    (UINT)BytesToRead, (UINT)BytesRead, (UINT)CurrentIBufferSize));
                 return CAB_STATUS_INVALID_CAB;
             }
 
-            *(unsigned char**)&CurrentIBuffer += BytesRead;
+            CurrentIBuffer = (unsigned char*)CurrentIBuffer + BytesRead;
+            CurrentIBufferSize += (USHORT)BytesRead;
 
-            CurrentIBufferSize += (unsigned short)BytesRead;
-
-            if (CurrentIBufferSize == CAB_BLOCKSIZE) {
+            if (CurrentIBufferSize == CAB_BLOCKSIZE)
+            {
                 Status = WriteDataBlock();
                 if (Status != CAB_STATUS_SUCCESS)
                     return Status;
@@ -1491,15 +1706,18 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
         } while ((TotalBytesLeft > 0) && (!CreateNewDisk));
     }
 
-    if (TotalBytesLeft == 0) {
+    if (TotalBytesLeft == 0)
+    {
         CloseFile(SourceFile);
         FileNode->Delete = true;
 
-        if (FileNode->File.FileControlID > CAB_FILE_MAX_FOLDER) {
+        if (FileNode->File.FileControlID > CAB_FILE_MAX_FOLDER)
+        {
             FileNode->File.FileControlID = CAB_FILE_CONTINUED;
             CurrentFolderNode->Delete = true;
 
-            if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) {
+            if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
+            {
                 Status = WriteDataBlock();
                 if (Status != CAB_STATUS_SUCCESS)
                     return Status;
@@ -1507,7 +1725,9 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
 
             CreateNewFolder = true;
         }
-    } else {
+    }
+    else
+    {
         if (FileNode->File.FileControlID <= CAB_FILE_MAX_FOLDER)
             FileNode->File.FileControlID = CAB_FILE_SPLIT;
         else
@@ -1518,7 +1738,7 @@ unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
 }
 
 
-unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
+ULONG CCabinet::WriteDisk(ULONG MoreDisks)
 /*
  * FUNCTION: Forces the current disk to be written
  * ARGUMENTS:
@@ -1528,19 +1748,22 @@ unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
  */
 {
     PCFFILE_NODE FileNode;
-    unsigned long Status;
+    ULONG Status;
 
     ContinueFile = false;
     FileNode = FileListHead;
-    while (FileNode != NULL) {
-
+    while (FileNode != NULL)
+    {
         Status = WriteFileToScratchStorage(FileNode);
         if (Status != CAB_STATUS_SUCCESS)
             return Status;
-        if (CreateNewDisk) {
+
+        if (CreateNewDisk)
+        {
             /* A data block could span more than two
                disks if MaxDiskSize is very small */
-            while (CreateNewDisk) {
+            while (CreateNewDisk)
+            {
                 DPRINT(MAX_TRACE, ("Creating new disk.\n"));
                 CommitDisk(true);
                 CloseDisk();
@@ -1549,29 +1772,35 @@ unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
                 ContinueFile = true;
                 CreateNewDisk = false;
 
-                DPRINT(MAX_TRACE, ("First on new disk. CurrentIBufferSize (%lu)  CurrentOBufferSize (%lu).\n",
-                    CurrentIBufferSize, CurrentOBufferSize));
+                DPRINT(MAX_TRACE, ("First on new disk. CurrentIBufferSize (%u)  CurrentOBufferSize (%u).\n",
+                    (UINT)CurrentIBufferSize, (UINT)CurrentOBufferSize));
 
-                if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) {
+                if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
+                {
                     Status = WriteDataBlock();
                     if (Status != CAB_STATUS_SUCCESS)
                         return Status;
                 }
             }
-        } else {
+        }
+        else
+        {
             ContinueFile = false;
             FileNode = FileNode->Next;
         }
     }
 
-    if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) {
+    if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
+    {
         /* A data block could span more than two
            disks if MaxDiskSize is very small */
 
         ASSERT(CreateNewDisk == false);
 
-        do {
-            if (CreateNewDisk) {
+        do
+        {
+            if (CreateNewDisk)
+            {
                 DPRINT(MID_TRACE, ("Creating new disk 2.\n"));
                 CommitDisk(true);
                 CloseDisk();
@@ -1581,7 +1810,8 @@ unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
                 ASSERT(FileNode == FileListHead);
             }
 
-            if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) {
+            if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
+            {
                 Status = WriteDataBlock();
                 if (Status != CAB_STATUS_SUCCESS)
                     return Status;
@@ -1594,7 +1824,7 @@ unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
 }
 
 
-unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
+ULONG CCabinet::CommitDisk(ULONG MoreDisks)
 /*
  * FUNCTION: Commits the current disk
  * ARGUMENTS:
@@ -1604,7 +1834,7 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
  */
 {
     PCFFOLDER_NODE FolderNode;
-    unsigned long Status;
+    ULONG Status;
 
     OnCabinetName(CurrentDiskNumber, CabinetName);
 
@@ -1617,11 +1847,13 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
         CREATE_NEW,                      // New file only
         FILE_ATTRIBUTE_NORMAL,           // Normal file
         NULL);                           // No attribute template
-    if (FileHandle == INVALID_HANDLE_VALUE) {
-        unsigned long Status;
+    if (FileHandle == INVALID_HANDLE_VALUE)
+    {
+        ULONG Status;
         /* If file exists, ask to overwrite file */
         if (((Status = GetLastError()) == ERROR_FILE_EXISTS) &&
-            (OnOverwrite(NULL, CabinetName))) {
+            (OnOverwrite(NULL, CabinetName)))
+        {
 
             /* Create cabinet file, overwrite if it already exists */
             FileHandle = CreateFile(CabinetName, // Create this file
@@ -1633,7 +1865,9 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
                 NULL);                           // No attribute template
             if (FileHandle == INVALID_HANDLE_VALUE)
                 return CAB_STATUS_CANNOT_CREATE;
-        } else {
+        }
+        else
+        {
             if (Status == ERROR_FILE_EXISTS)
                 return CAB_STATUS_FILE_EXISTS;
             else
@@ -1642,22 +1876,25 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
     }
 #else /* !WIN32 */
     FileHandle = fopen(CabinetName, "rb");
-    if (FileHandle != NULL) {
+    if (FileHandle != NULL)
+    {
         fclose(FileHandle);
         /* If file exists, ask to overwrite file */
-        if (OnOverwrite(NULL, CabinetName)) {
+        if (OnOverwrite(NULL, CabinetName))
+        {
             FileHandle = fopen(CabinetName, "w+b");
-            if (FileHandle == NULL) {
+            if (FileHandle == NULL)
                 return CAB_STATUS_CANNOT_CREATE;
-            }
-        } else {
-            return CAB_STATUS_FILE_EXISTS;
         }
-    } else {
+        else
+            return CAB_STATUS_FILE_EXISTS;
+
+    }
+    else
+    {
         FileHandle = fopen(CabinetName, "w+b");
-        if (FileHandle == NULL) {
+        if (FileHandle == NULL)
             return CAB_STATUS_CANNOT_CREATE;
-        }
     }
 #endif
 
@@ -1672,8 +1909,10 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
 
     /* Write data blocks */
     FolderNode = FolderListHead;
-    while (FolderNode != NULL) {
-        if (FolderNode->Commit) {
+    while (FolderNode != NULL)
+    {
+        if (FolderNode->Commit)
+        {
             Status = CommitDataBlocks(FolderNode);
             if (Status != CAB_STATUS_SUCCESS)
                 return Status;
@@ -1691,7 +1930,7 @@ unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
 }
 
 
-unsigned long CCabinet::CloseDisk()
+ULONG CCabinet::CloseDisk()
 /*
  * FUNCTION: Closes the current disk
  * RETURNS:
@@ -1709,32 +1948,35 @@ unsigned long CCabinet::CloseDisk()
 }
 
 
-unsigned long CCabinet::CloseCabinet()
+ULONG CCabinet::CloseCabinet()
 /*
  * FUNCTION: Closes the current cabinet
  * RETURNS:
  *     Status of operation
  */
 {
-    unsigned long Status;
+    ULONG Status;
 
     DestroyFileNodes();
 
     DestroyFolderNodes();
 
-    if (InputBuffer) {
+    if (InputBuffer)
+    {
         FreeMemory(InputBuffer);
         InputBuffer = NULL;
     }
 
-    if (OutputBuffer) {
+    if (OutputBuffer)
+    {
         FreeMemory(OutputBuffer);
         OutputBuffer = NULL;
     }
 
     Close();
 
-    if (ScratchFile) {
+    if (ScratchFile)
+    {
         Status = ScratchFile->Destroy();
         delete ScratchFile;
         return Status;
@@ -1744,7 +1986,7 @@ unsigned long CCabinet::CloseCabinet()
 }
 
 
-unsigned long CCabinet::AddFile(char* FileName)
+ULONG CCabinet::AddFile(char* FileName)
 /*
  * FUNCTION: Adds a file to the current disk
  * ARGUMENTS:
@@ -1758,7 +2000,8 @@ unsigned long CCabinet::AddFile(char* FileName)
     char* NewFileName;
 
     NewFileName = (char*)AllocateMemory(strlen(FileName) + 1);
-    if (!NewFileName) {
+    if (!NewFileName)
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
     }
@@ -1775,14 +2018,16 @@ unsigned long CCabinet::AddFile(char* FileName)
         OPEN_EXISTING,           // File must exist
         FILE_ATTRIBUTE_NORMAL,   // Normal file
         NULL);                   // No attribute template
-    if (SrcFile == INVALID_HANDLE_VALUE) {
+    if (SrcFile == INVALID_HANDLE_VALUE)
+    {
         DPRINT(MID_TRACE, ("File not found (%s).\n", NewFileName));
         FreeMemory(NewFileName);
         return CAB_STATUS_CANNOT_OPEN;
     }
 #else /* !WIN32 */
     SrcFile = fopen(NewFileName, "rb");
-    if (SrcFile == NULL) {
+    if (SrcFile == NULL)
+    {
         DPRINT(MID_TRACE, ("File not found (%s).\n", NewFileName));
         FreeMemory(NewFileName);
         return CAB_STATUS_CANNOT_OPEN;
@@ -1790,34 +2035,191 @@ unsigned long CCabinet::AddFile(char* FileName)
 #endif
 
     FileNode = NewFileNode();
-    if (!FileNode) {
+    if (!FileNode)
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         FreeMemory(NewFileName);
         return CAB_STATUS_NOMEMORY;
     }
 
-       FileNode->FolderNode = CurrentFolderNode;
+    FileNode->FolderNode = CurrentFolderNode;
     FileNode->FileName = NewFileName;
 
     /* FIXME: Check for and handle large files (>= 2GB) */
     FileNode->File.FileSize = GetSizeOfFile(SrcFile);
-    if (FileNode->File.FileSize == (unsigned long)-1) {
+    if (FileNode->File.FileSize == (ULONG)-1)
+    {
         DPRINT(MIN_TRACE, ("Cannot read from file.\n"));
         FreeMemory(NewFileName);
         return CAB_STATUS_CANNOT_READ;
     }
 
-    GetFileTimes(SrcFile, FileNode);
+    if (GetFileTimes(SrcFile, FileNode) != CAB_STATUS_SUCCESS)
+    {
+        DPRINT(MIN_TRACE, ("Cannot read file times.\n"));
+        FreeMemory(NewFileName);
+        return CAB_STATUS_CANNOT_READ;
+    }
 
-    GetAttributesOnFile(FileNode);
+    if (GetAttributesOnFile(FileNode) != CAB_STATUS_SUCCESS)
+    {
+        DPRINT(MIN_TRACE, ("Cannot read file attributes.\n"));
+        FreeMemory(NewFileName);
+        return CAB_STATUS_CANNOT_READ;
+    }
 
     CloseFile(SrcFile);
 
     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
+        ConvertPath(Criteria->Search, false);
+        pszFile = strrchr(Criteria->Search, DIR_SEPARATOR_CHAR);
+
+        if(pszFile)
+        {
+            // Set the pointer to the start of the file name, not the slash
+            pszFile++;
+
+            strncpy(szFilePath, Criteria->Search, pszFile - Criteria->Search);
+            szFilePath[pszFile - Criteria->Search] = 0;
+        }
+        else
+        {
+            pszFile = Criteria->Search;
+
+#if defined(WIN32)
+            szFilePath[0] = 0;
+#else
+            // needed for opendir()
+            strcpy(szFilePath, "./");
+#endif
+        }
+
+#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;
+        }
 
-void CCabinet::SetMaxDiskSize(unsigned long Size)
+        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
+        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)
+                    {
+                        if(MatchFileNamePattern(dp->d_name, pszFile))
+                        {
+                            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)
 /*
  * FUNCTION: Sets the maximum size of the current disk
  * ARGUMENTS:
@@ -1885,7 +2287,7 @@ void CCabinet::OnAdd(PCFFILE File,
 }
 
 
-bool CCabinet::OnDiskLabel(unsigned long Number, char* Label)
+bool CCabinet::OnDiskLabel(ULONG Number, char* Label)
 /*
  * FUNCTION: Called when a disk needs a label
  * ARGUMENTS:
@@ -1899,7 +2301,7 @@ bool CCabinet::OnDiskLabel(unsigned long Number, char* Label)
 }
 
 
-bool CCabinet::OnCabinetName(unsigned long Number, char* Name)
+bool CCabinet::OnCabinetName(ULONG Number, char* Name)
 /*
  * FUNCTION: Called when a cabinet needs a name
  * ARGUMENTS:
@@ -1914,7 +2316,7 @@ bool CCabinet::OnCabinetName(unsigned long Number, char* Name)
 
 #endif /* CAB_READ_ONLY */
 
-PCFFOLDER_NODE CCabinet::LocateFolderNode(unsigned long Index)
+PCFFOLDER_NODE CCabinet::LocateFolderNode(ULONG Index)
 /*
  * FUNCTION: Locates a folder node
  * ARGUMENTS:
@@ -1925,17 +2327,19 @@ PCFFOLDER_NODE CCabinet::LocateFolderNode(unsigned long Index)
 {
     PCFFOLDER_NODE Node;
 
-    switch (Index) {
-    case CAB_FILE_SPLIT:
-        return FolderListTail;
+    switch (Index)
+    {
+        case CAB_FILE_SPLIT:
+            return FolderListTail;
 
-    case CAB_FILE_CONTINUED:
-    case CAB_FILE_PREV_NEXT:
-        return FolderListHead;
+        case CAB_FILE_CONTINUED:
+        case CAB_FILE_PREV_NEXT:
+            return FolderListHead;
     }
 
     Node = FolderListHead;
-    while (Node != NULL) {
+    while (Node != NULL)
+    {
         if (Node->Index == Index)
             return Node;
         Node = Node->Next;
@@ -1944,7 +2348,7 @@ PCFFOLDER_NODE CCabinet::LocateFolderNode(unsigned long Index)
 }
 
 
-unsigned long CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
+ULONG CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
 /*
  * FUNCTION: Returns the absolute offset of a file
  * ARGUMENTS:
@@ -1955,25 +2359,26 @@ unsigned long CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
 {
     PCFDATA_NODE Node;
 
-    DPRINT(MAX_TRACE, ("FileName '%s'  FileOffset (0x%X)  FileSize (%d).\n",
-        (char*)File->FileName,
-        (unsigned int)File->File.FileOffset,
-        (unsigned int)File->File.FileSize));
+    DPRINT(MAX_TRACE, ("FileName '%s'  FileOffset (0x%X)  FileSize (%u).\n",
+        File->FileName,
+        (UINT)File->File.FileOffset,
+        (UINT)File->File.FileSize));
 
     Node = CurrentFolderNode->DataListHead;
-    while (Node != NULL) {
-
-        DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%d).\n",
-            (unsigned int)Node->UncompOffset,
-            (unsigned int)Node->UncompOffset + Node->Data.UncompSize,
-            (unsigned int)Node->Data.UncompSize));
+    while (Node != NULL)
+    {
+        DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%u).\n",
+            (UINT)Node->UncompOffset,
+            (UINT)(Node->UncompOffset + Node->Data.UncompSize),
+            (UINT)Node->Data.UncompSize));
 
         /* Node->Data.UncompSize will be 0 if the block is split
            (ie. it is the last block in this cabinet) */
         if ((Node->Data.UncompSize == 0) ||
             ((File->File.FileOffset >= Node->UncompOffset) &&
             (File->File.FileOffset < Node->UncompOffset +
-            Node->Data.UncompSize))) {
+            Node->Data.UncompSize)))
+        {
                 File->DataBlock = Node;
                 return CAB_STATUS_SUCCESS;
         }
@@ -1984,7 +2389,7 @@ unsigned long CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
 }
 
 
-unsigned long CCabinet::LocateFile(char* FileName,
+ULONG CCabinet::LocateFile(char* FileName,
                            PCFFILE_NODE *File)
 /*
  * FUNCTION: Locates a file in the cabinet
@@ -1998,25 +2403,28 @@ unsigned long CCabinet::LocateFile(char* FileName,
  */
 {
     PCFFILE_NODE Node;
-    unsigned long Status;
+    ULONG Status;
 
     DPRINT(MAX_TRACE, ("FileName '%s'\n", FileName));
 
     Node = FileListHead;
-    while (Node != NULL) {
-        if (strcasecmp(FileName, Node->FileName) == 0) {
-
+    while (Node != NULL)
+    {
+        if (strcasecmp(FileName, Node->FileName) == 0)
+        {
             CurrentFolderNode = LocateFolderNode(Node->File.FileControlID);
-            if (!CurrentFolderNode) {
-                DPRINT(MID_TRACE, ("Folder with index number (%d) not found.\n",
-                    (unsigned int)Node->File.FileControlID));
+            if (!CurrentFolderNode)
+            {
+                DPRINT(MID_TRACE, ("Folder with index number (%u) not found.\n",
+                    Node->File.FileControlID));
                 return CAB_STATUS_INVALID_CAB;
             }
 
-            if (Node->DataBlock == NULL) {
+            if (Node->DataBlock == NULL)
                 Status = GetAbsoluteOffset(Node);
-            else
+            else
                 Status = CAB_STATUS_SUCCESS;
+
             *File = Node;
             return Status;
         }
@@ -2026,7 +2434,7 @@ unsigned long CCabinet::LocateFile(char* FileName,
 }
 
 
-unsigned long CCabinet::ReadString(char* String, unsigned long MaxLength)
+ULONG CCabinet::ReadString(char* String, LONG MaxLength)
 /*
  * FUNCTION: Reads a NULL-terminated string from the cabinet
  * ARGUMENTS:
@@ -2036,53 +2444,53 @@ unsigned long CCabinet::ReadString(char* String, unsigned long MaxLength)
  *     Status of operation
  */
 {
-    unsigned long BytesRead;
-    unsigned long Offset;
-    unsigned long Status;
-    unsigned long Size;
+    ULONG BytesRead;
+    ULONG Status;
+    LONG Size;
     bool Found;
 
-    Offset = 0;
     Found  = false;
-    do {
-        Size = ((Offset + 32) <= MaxLength)? 32 : MaxLength - Offset;
 
-        if (Size == 0) {
-            DPRINT(MIN_TRACE, ("Too long a filename.\n"));
-            return CAB_STATUS_INVALID_CAB;
-        }
-
-        Status = ReadBlock(&String[Offset], Size, &BytesRead);
-        if ((Status != CAB_STATUS_SUCCESS) || (BytesRead != Size)) {
-            DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
-            return CAB_STATUS_INVALID_CAB;
-        }
+    Status = ReadBlock(String, MaxLength, &BytesRead);
+    if (Status != CAB_STATUS_SUCCESS)
+    {
+        DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
+        return CAB_STATUS_INVALID_CAB;
+    }
 
-        for (Size = Offset; Size < Offset + BytesRead; Size++) {
-            if (String[Size] == '\0') {
-                Found = true;
-                break;
-            }
+    // Find the terminating NULL character
+    for (Size = 0; Size < MaxLength; Size++)
+    {
+        if (String[Size] == '\0')
+        {
+            Found = true;
+            break;
         }
+    }
 
-        Offset += BytesRead;
+    if (!Found)
+    {
+        DPRINT(MIN_TRACE, ("Filename in the cabinet file is too long.\n"));
+        return CAB_STATUS_INVALID_CAB;
+    }
 
-    } while (!Found);
+    // Compute the offset of the next CFFILE.
+    // We have to subtract from the current offset here, because we read MaxLength characters above and most-probably the file name isn't MaxLength characters long.
+    // + 1 to skip the terminating NULL character as well.
+    Size = -(MaxLength - Size) + 1;
 
-    /* Back up some bytes */
-    Size = (BytesRead - Size) - 1;
 #if defined(WIN32)
-       SetLastError(NO_ERROR);
-       (unsigned int)SetFilePointer(FileHandle,
-               -(long)Size,
-               NULL,
-               FILE_CURRENT);
-       if (GetLastError() != NO_ERROR) {
-               DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-               return CAB_STATUS_INVALID_CAB;
-       }
+    if( SetFilePointer(FileHandle,
+                       (LONG)Size,
+                       NULL,
+                       FILE_CURRENT) == INVALID_SET_FILE_POINTER )
+    {
+        DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+        return CAB_STATUS_INVALID_CAB;
+    }
 #else
-    if (fseek(FileHandle, (off_t)(-(long)Size), SEEK_CUR) != 0) {
+    if (fseek(FileHandle, (off_t)Size, SEEK_CUR) != 0)
+    {
         DPRINT(MIN_TRACE, ("fseek() failed.\n"));
         return CAB_STATUS_INVALID_CAB;
     }
@@ -2091,55 +2499,58 @@ unsigned long CCabinet::ReadString(char* String, unsigned long MaxLength)
 }
 
 
-unsigned long CCabinet::ReadFileTable()
+ULONG CCabinet::ReadFileTable()
 /*
  * FUNCTION: Reads the file table from the cabinet file
  * RETURNS:
  *     Status of operation
  */
 {
-    unsigned long i;
-    unsigned long Status;
-    unsigned long BytesRead;
+    ULONG i;
+    ULONG Status;
+    ULONG BytesRead;
     PCFFILE_NODE File;
 
-    DPRINT(MAX_TRACE, ("Reading file table at absolute offset (0x%lX).\n",
-        CABHeader.FileTableOffset));
+    DPRINT(MAX_TRACE, ("Reading file table at absolute offset (0x%X).\n",
+        (UINT)CABHeader.FileTableOffset));
 
     /* Seek to file table */
 #if defined(WIN32)
-       SetLastError(NO_ERROR);
-       (unsigned int)SetFilePointer(FileHandle,
-               CABHeader.FileTableOffset,
-               NULL,
-               FILE_BEGIN);
-       if (GetLastError() != NO_ERROR) {
-               DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-               DPRINT(MIN_TRACE, ("Error: %lu\n", GetLastError()));
-               return CAB_STATUS_INVALID_CAB;
-       }
+    if( SetFilePointer(FileHandle,
+                       CABHeader.FileTableOffset,
+                       NULL,
+                       FILE_BEGIN) == INVALID_SET_FILE_POINTER )
+    {
+        DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+        return CAB_STATUS_INVALID_CAB;
+    }
 #else
-    if (fseek(FileHandle, (off_t)CABHeader.FileTableOffset, SEEK_SET) != 0) {
+    if (fseek(FileHandle, (off_t)CABHeader.FileTableOffset, SEEK_SET) != 0)
+    {
         DPRINT(MIN_TRACE, ("fseek() failed.\n"));
         return CAB_STATUS_INVALID_CAB;
     }
 #endif
 
-    for (i = 0; i < CABHeader.FileCount; i++) {
+    for (i = 0; i < CABHeader.FileCount; i++)
+    {
         File = NewFileNode();
-        if (!File) {
+        if (!File)
+        {
             DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
             return CAB_STATUS_NOMEMORY;
         }
 
         if ((Status = ReadBlock(&File->File, sizeof(CFFILE),
-            &BytesRead)) != CAB_STATUS_SUCCESS) {
-            DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+            &BytesRead)) != CAB_STATUS_SUCCESS)
+        {
+            DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
             return CAB_STATUS_INVALID_CAB;
         }
 
         File->FileName = (char*)AllocateMemory(MAX_PATH);
-        if (!File->FileName) {
+        if (!File->FileName)
+        {
             DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
             return CAB_STATUS_NOMEMORY;
         }
@@ -2149,18 +2560,18 @@ unsigned long CCabinet::ReadFileTable()
         if (Status != CAB_STATUS_SUCCESS)
             return Status;
 
-        DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X).  Size (%d bytes)  ControlId (0x%X).\n",
-            (char*)File->FileName,
-            (unsigned int)File->File.FileOffset,
-            (unsigned int)File->File.FileSize,
-            (unsigned int)File->File.FileControlID));
+        DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X).  Size (%u bytes)  ControlId (0x%X).\n",
+            File->FileName,
+            (UINT)File->File.FileOffset,
+            (UINT)File->File.FileSize,
+            File->File.FileControlID));
 
     }
     return CAB_STATUS_SUCCESS;
 }
 
 
-unsigned long CCabinet::ReadDataBlocks(PCFFOLDER_NODE FolderNode)
+ULONG CCabinet::ReadDataBlocks(PCFFOLDER_NODE FolderNode)
 /*
  * FUNCTION: Reads all CFDATA blocks for a folder from the cabinet file
  * ARGUMENTS:
@@ -2169,56 +2580,59 @@ unsigned long CCabinet::ReadDataBlocks(PCFFOLDER_NODE FolderNode)
  *     Status of operation
  */
 {
-    unsigned long AbsoluteOffset;
-    unsigned long UncompOffset;
+    ULONG AbsoluteOffset;
+    ULONG UncompOffset;
     PCFDATA_NODE Node;
-    unsigned long BytesRead;
-    unsigned long Status;
-    unsigned long i;
+    ULONG BytesRead;
+    ULONG Status;
+    ULONG i;
 
-    DPRINT(MAX_TRACE, ("Reading data blocks for folder (%lu)  at absolute offset (0x%lX).\n",
-        FolderNode->Index, FolderNode->Folder.DataOffset));
+    DPRINT(MAX_TRACE, ("Reading data blocks for folder (%u)  at absolute offset (0x%X).\n",
+        (UINT)FolderNode->Index, (UINT)FolderNode->Folder.DataOffset));
 
     AbsoluteOffset = FolderNode->Folder.DataOffset;
     UncompOffset   = FolderNode->UncompOffset;
 
-    for (i = 0; i < FolderNode->Folder.DataBlockCount; i++) {
+    for (i = 0; i < FolderNode->Folder.DataBlockCount; i++)
+    {
         Node = NewDataNode(FolderNode);
-        if (!Node) {
+        if (!Node)
+        {
             DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
             return CAB_STATUS_NOMEMORY;
         }
 
         /* Seek to data block */
 #if defined(WIN32)
-       SetLastError(NO_ERROR);
-       (unsigned int)SetFilePointer(FileHandle,
-               AbsoluteOffset,
-               NULL,
-               FILE_BEGIN);
-       if (GetLastError() != NO_ERROR) {
-               DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
-               return CAB_STATUS_INVALID_CAB;
-       }
+        if( SetFilePointer(FileHandle,
+                           AbsoluteOffset,
+                           NULL,
+                           FILE_BEGIN) == INVALID_SET_FILE_POINTER )
+        {
+            DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
+            return CAB_STATUS_INVALID_CAB;
+        }
 #else
-        if (fseek(FileHandle, (off_t)AbsoluteOffset, SEEK_SET) != 0) {
+        if (fseek(FileHandle, (off_t)AbsoluteOffset, SEEK_SET) != 0)
+        {
             DPRINT(MIN_TRACE, ("fseek() failed.\n"));
             return CAB_STATUS_INVALID_CAB;
         }
 #endif
 
         if ((Status = ReadBlock(&Node->Data, sizeof(CFDATA),
-            &BytesRead)) != CAB_STATUS_SUCCESS) {
-            DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (unsigned int)Status));
+            &BytesRead)) != CAB_STATUS_SUCCESS)
+        {
+            DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
             return CAB_STATUS_INVALID_CAB;
         }
 
-        DPRINT(MAX_TRACE, ("AbsOffset (0x%X)  UncompOffset (0x%X)  Checksum (0x%X)  CompSize (%d)  UncompSize (%d).\n",
-            (unsigned int)AbsoluteOffset,
-            (unsigned int)UncompOffset,
-            (unsigned int)Node->Data.Checksum,
-            (unsigned int)Node->Data.CompSize,
-            (unsigned int)Node->Data.UncompSize));
+        DPRINT(MAX_TRACE, ("AbsOffset (0x%X)  UncompOffset (0x%X)  Checksum (0x%X)  CompSize (%u)  UncompSize (%u).\n",
+            (UINT)AbsoluteOffset,
+            (UINT)UncompOffset,
+            (UINT)Node->Data.Checksum,
+            Node->Data.CompSize,
+            Node->Data.UncompSize));
 
         Node->AbsoluteOffset = AbsoluteOffset;
         Node->UncompOffset   = UncompOffset;
@@ -2252,11 +2666,11 @@ PCFFOLDER_NODE CCabinet::NewFolderNode()
 
     Node->Prev = FolderListTail;
 
-    if (FolderListTail != NULL) {
+    if (FolderListTail != NULL)
         FolderListTail->Next = Node;
-    } else {
+    else
         FolderListHead = Node;
-    }
+
     FolderListTail = Node;
 
     return Node;
@@ -2282,11 +2696,11 @@ PCFFILE_NODE CCabinet::NewFileNode()
 
     Node->Prev = FileListTail;
 
-    if (FileListTail != NULL) {
+    if (FileListTail != NULL)
         FileListTail->Next = Node;
-    } else {
+    else
         FileListHead = Node;
-    }
+
     FileListTail = Node;
 
     return Node;
@@ -2312,11 +2726,11 @@ PCFDATA_NODE CCabinet::NewDataNode(PCFFOLDER_NODE FolderNode)
 
     Node->Prev = FolderNode->DataListTail;
 
-    if (FolderNode->DataListTail != NULL) {
+    if (FolderNode->DataListTail != NULL)
         FolderNode->DataListTail->Next = Node;
-    } else {
+    else
         FolderNode->DataListHead = Node;
-    }
+
     FolderNode->DataListTail = Node;
 
     return Node;
@@ -2334,7 +2748,8 @@ void CCabinet::DestroyDataNodes(PCFFOLDER_NODE FolderNode)
     PCFDATA_NODE NextNode;
 
     NextNode = FolderNode->DataListHead;
-    while (NextNode != NULL) {
+    while (NextNode != NULL)
+    {
         PrevNode = NextNode->Next;
         FreeMemory(NextNode);
         NextNode = PrevNode;
@@ -2347,15 +2762,14 @@ void CCabinet::DestroyDataNodes(PCFFOLDER_NODE FolderNode)
 void CCabinet::DestroyFileNodes()
 /*
  * FUNCTION: Destroys file nodes
- * ARGUMENTS:
- *     FolderNode = Pointer to folder node
  */
 {
     PCFFILE_NODE PrevNode;
     PCFFILE_NODE NextNode;
 
     NextNode = FileListHead;
-    while (NextNode != NULL) {
+    while (NextNode != NULL)
+    {
         PrevNode = NextNode->Next;
         if (NextNode->FileName)
             FreeMemory(NextNode->FileName);
@@ -2376,21 +2790,25 @@ void CCabinet::DestroyDeletedFileNodes()
     PCFFILE_NODE NextNode;
 
     CurNode = FileListHead;
-    while (CurNode != NULL) {
+    while (CurNode != NULL)
+    {
         NextNode = CurNode->Next;
 
-        if (CurNode->Delete) {
-            if (CurNode->Prev != NULL) {
+        if (CurNode->Delete)
+        {
+            if (CurNode->Prev != NULL)
                 CurNode->Prev->Next = CurNode->Next;
-            } else {
+            else
+            {
                 FileListHead = CurNode->Next;
                 if (FileListHead)
                     FileListHead->Prev = NULL;
             }
 
-            if (CurNode->Next != NULL) {
+            if (CurNode->Next != NULL)
                 CurNode->Next->Prev = CurNode->Prev;
-            } else {
+            else
+            {
                 FileListTail = CurNode->Prev;
                 if (FileListTail)
                     FileListTail->Next = NULL;
@@ -2398,7 +2816,7 @@ void CCabinet::DestroyDeletedFileNodes()
 
             DPRINT(MAX_TRACE, ("Deleting file: '%s'\n", CurNode->FileName));
 
-            TotalFileSize -= (sizeof(CFFILE) + strlen(GetFileName(CurNode->FileName)) + 1);
+            TotalFileSize -= (sizeof(CFFILE) + (ULONG)strlen(GetFileName(CurNode->FileName)) + 1);
 
             if (CurNode->FileName)
                 FreeMemory(CurNode->FileName);
@@ -2418,7 +2836,8 @@ void CCabinet::DestroyFolderNodes()
     PCFFOLDER_NODE NextNode;
 
     NextNode = FolderListHead;
-    while (NextNode != NULL) {
+    while (NextNode != NULL)
+    {
         PrevNode = NextNode->Next;
         DestroyDataNodes(NextNode);
         FreeMemory(NextNode);
@@ -2438,21 +2857,25 @@ void CCabinet::DestroyDeletedFolderNodes()
     PCFFOLDER_NODE NextNode;
 
     CurNode = FolderListHead;
-    while (CurNode != NULL) {
+    while (CurNode != NULL)
+    {
         NextNode = CurNode->Next;
 
-        if (CurNode->Delete) {
-            if (CurNode->Prev != NULL) {
+        if (CurNode->Delete)
+        {
+            if (CurNode->Prev != NULL)
                 CurNode->Prev->Next = CurNode->Next;
-            } else {
+            else
+            {
                 FolderListHead = CurNode->Next;
                 if (FolderListHead)
                     FolderListHead->Prev = NULL;
             }
 
-            if (CurNode->Next != NULL) {
+            if (CurNode->Next != NULL)
                 CurNode->Next->Prev = CurNode->Prev;
-            } else {
+            else
+            {
                 FolderListTail = CurNode->Prev;
                 if (FolderListTail)
                     FolderListTail->Next = NULL;
@@ -2468,9 +2891,9 @@ void CCabinet::DestroyDeletedFolderNodes()
 }
 
 
-unsigned long CCabinet::ComputeChecksum(void* Buffer,
-                                unsigned int Size,
-                                unsigned long Seed)
+ULONG CCabinet::ComputeChecksum(void* Buffer,
+                                ULONG Size,
+                                ULONG Seed)
 /*
  * FUNCTION: Computes checksum for data block
  * ARGUMENTS:
@@ -2482,37 +2905,39 @@ unsigned long CCabinet::ComputeChecksum(void* Buffer,
  */
 {
     int UlongCount; // Number of ULONGs in block
-    unsigned long Checksum; // Checksum accumulator
+    ULONG Checksum; // Checksum accumulator
     unsigned char* pb;
-    unsigned long ul;
+    ULONG ul;
 
     /* FIXME: Doesn't seem to be correct. EXTRACT.EXE
        won't accept checksums computed by this routine */
 
-    DPRINT(MIN_TRACE, ("Checksumming buffer (0x%X)  Size (%d)\n", (unsigned int)Buffer, Size));
+    DPRINT(MIN_TRACE, ("Checksumming buffer (0x%p)  Size (%u)\n", Buffer, (UINT)Size));
 
     UlongCount = Size / 4;              // Number of ULONGs
     Checksum   = Seed;                  // Init checksum
     pb         = (unsigned char*)Buffer;         // Start at front of data block
 
     /* Checksum integral multiple of ULONGs */
-    while (UlongCount-- > 0) {
-        /* NOTE: Build unsigned long in big/little-endian independent manner */
+    while (UlongCount-- > 0)
+    {
+        /* NOTE: Build ULONG in big/little-endian independent manner */
         ul = *pb++;                     // Get low-order byte
-        ul |= (((unsigned long)(*pb++)) <<  8); // Add 2nd byte
-        ul |= (((unsigned long)(*pb++)) << 16); // Add 3nd byte
-        ul |= (((unsigned long)(*pb++)) << 24); // Add 4th byte
+        ul |= (((ULONG)(*pb++)) <<  8); // Add 2nd byte
+        ul |= (((ULONG)(*pb++)) << 16); // Add 3nd byte
+        ul |= (((ULONG)(*pb++)) << 24); // Add 4th byte
 
         Checksum ^= ul;                 // Update checksum
     }
 
     /* Checksum remainder bytes */
     ul = 0;
-    switch (Size % 4) {
+    switch (Size % 4)
+    {
         case 3:
-            ul |= (((unsigned long)(*pb++)) << 16); // Add 3rd byte
+            ul |= (((ULONG)(*pb++)) << 16); // Add 3rd byte
         case 2:
-            ul |= (((unsigned long)(*pb++)) <<  8); // Add 2nd byte
+            ul |= (((ULONG)(*pb++)) <<  8); // Add 2nd byte
         case 1:
             ul |= *pb++;                    // Get low-order byte
         default:
@@ -2525,15 +2950,15 @@ unsigned long CCabinet::ComputeChecksum(void* Buffer,
 }
 
 
-unsigned long CCabinet::ReadBlock(void* Buffer,
-                          unsigned long Size,
-                          unsigned long* BytesRead)
+ULONG CCabinet::ReadBlock(void* Buffer,
+                          ULONG Size,
+                          PULONG BytesRead)
 /*
  * FUNCTION: Read a block of data from file
  * ARGUMENTS:
  *     Buffer    = Pointer to data buffer
  *     Size      = Length of data buffer
- *     BytesRead = Pointer to unsigned long that on return will contain
+ *     BytesRead = Pointer to ULONG that on return will contain
  *                 number of bytes read
  * RETURNS:
  *     Status of operation
@@ -2544,32 +2969,95 @@ unsigned long 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
 
-unsigned long CCabinet::InitCabinetHeader()
+ULONG CCabinet::InitCabinetHeader()
 /*
  * FUNCTION: Initializes cabinet header and optional fields
  * RETURNS:
  *     Status of operation
  */
 {
-    unsigned long TotalSize;
-    unsigned long Size;
+    ULONG TotalSize;
+    ULONG Size;
 
     CABHeader.FileTableOffset = 0;    // Not known yet
     CABHeader.FolderCount     = 0;    // Not known yet
     CABHeader.FileCount       = 0;    // Not known yet
     CABHeader.Flags           = 0;    // Not known yet
 
-    CABHeader.CabinetNumber = (unsigned short)CurrentDiskNumber;
+    CABHeader.CabinetNumber = (USHORT)CurrentDiskNumber;
 
-    if ((CurrentDiskNumber > 0) && (OnCabinetName(PrevCabinetNumber, CabinetPrev))) {
+    if ((CurrentDiskNumber > 0) && (OnCabinetName(PrevCabinetNumber, CabinetPrev)))
+    {
         CABHeader.Flags |= CAB_FLAG_HASPREV;
         if (!OnDiskLabel(PrevCabinetNumber, DiskPrev))
             strcpy(CabinetPrev, "");
     }
 
-    if (OnCabinetName(CurrentDiskNumber + 1, CabinetNext)) {
+    if (OnCabinetName(CurrentDiskNumber + 1, CabinetNext))
+    {
         CABHeader.Flags |= CAB_FLAG_HASNEXT;
         if (!OnDiskLabel(CurrentDiskNumber + 1, DiskNext))
             strcpy(DiskNext, "");
@@ -2577,40 +3065,43 @@ unsigned long CCabinet::InitCabinetHeader()
 
     TotalSize = 0;
 
-    if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) {
+    if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
+    {
 
         DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
 
         /* Calculate size of name of previous cabinet */
-        TotalSize += strlen(CabinetPrev) + 1;
+        TotalSize += (ULONG)strlen(CabinetPrev) + 1;
 
         /* Calculate size of label of previous disk */
-        TotalSize += strlen(DiskPrev) + 1;
+        TotalSize += (ULONG)strlen(DiskPrev) + 1;
     }
 
-    if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) {
+    if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
+    {
 
         DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
 
         /* Calculate size of name of next cabinet */
-        Size = strlen(CabinetNext) + 1;
+        Size = (ULONG)strlen(CabinetNext) + 1;
         TotalSize += Size;
         NextFieldsSize = Size;
 
         /* Calculate size of label of next disk */
-        Size = strlen(DiskNext) + 1;
+        Size = (ULONG)strlen(DiskNext) + 1;
         TotalSize += Size;
         NextFieldsSize += Size;
-    } else
+    }
+    else
         NextFieldsSize = 0;
 
     /* Add cabinet reserved area size if present */
     if (CabinetReservedFileSize > 0)
-      {
+    {
         CABHeader.Flags |= CAB_FLAG_RESERVE;
         TotalSize += CabinetReservedFileSize;
-        TotalSize += sizeof(unsigned long); /* For CabinetResSize, FolderResSize, and FileResSize fields */
-      }
+        TotalSize += sizeof(ULONG); /* For CabinetResSize, FolderResSize, and FileResSize fields */
+    }
 
     DiskSize += TotalSize;
 
@@ -2620,7 +3111,7 @@ unsigned long CCabinet::InitCabinetHeader()
 }
 
 
-unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
+ULONG CCabinet::WriteCabinetHeader(bool MoreDisks)
 /*
  * FUNCTION: Writes the cabinet header and optional fields
  * ARGUMENTS:
@@ -2631,13 +3122,16 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
 {
     PCFFOLDER_NODE FolderNode;
     PCFFILE_NODE FileNode;
-    unsigned long BytesWritten;
-    unsigned long Size;
+    ULONG BytesWritten;
+    ULONG Size;
 
-    if (MoreDisks) {
+    if (MoreDisks)
+    {
         CABHeader.Flags |= CAB_FLAG_HASNEXT;
         Size = TotalHeaderSize;
-    } else {
+    }
+    else
+    {
         CABHeader.Flags &= ~CAB_FLAG_HASNEXT;
         DiskSize -= NextFieldsSize;
         Size = TotalHeaderSize - NextFieldsSize;
@@ -2647,7 +3141,8 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
     BytesWritten = Size + TotalFolderSize + TotalFileSize;
     CABHeader.FolderCount = 0;
     FolderNode = FolderListHead;
-    while (FolderNode != NULL) {
+    while (FolderNode != NULL)
+    {
         FolderNode->Folder.DataOffset = BytesWritten;
 
         BytesWritten += FolderNode->TotalFolderSize;
@@ -2663,7 +3158,8 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
     /* Count number of files to be committed */
     CABHeader.FileCount = 0;
     FileNode = FileListHead;
-    while (FileNode != NULL) {
+    while (FileNode != NULL)
+    {
         if (FileNode->Commit)
             CABHeader.FileCount++;
         FileNode = FileNode->Next;
@@ -2673,66 +3169,75 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
 
     /* Write header */
 #if defined(WIN32)
-    if (!WriteFile(FileHandle, &CABHeader, sizeof(CFHEADER), &BytesWritten, NULL)) {
+    if (!WriteFile(FileHandle, &CABHeader, sizeof(CFHEADER), (LPDWORD)&BytesWritten, NULL))
+    {
         DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
         return CAB_STATUS_CANNOT_WRITE;
     }
 #else
     BytesWritten = sizeof(CFHEADER);
-    if (fwrite(&CABHeader, sizeof(CFHEADER), 1, FileHandle) < 1) {
+    if (fwrite(&CABHeader, sizeof(CFHEADER), 1, FileHandle) < 1)
+    {
         DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
         return CAB_STATUS_CANNOT_WRITE;
     }
 #endif
 
     /* Write per-cabinet reserved area if present */
-    if (CABHeader.Flags & CAB_FLAG_RESERVE) {
-        unsigned long ReservedSize;
+    if (CABHeader.Flags & CAB_FLAG_RESERVE)
+    {
+        ULONG ReservedSize;
 
         ReservedSize = CabinetReservedFileSize & 0xffff;
         ReservedSize |= (0 << 16); /* Folder reserved area size */
         ReservedSize |= (0 << 24); /* Folder reserved area size */
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, &ReservedSize, sizeof(unsigned long), &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, &ReservedSize, sizeof(ULONG), (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
-        BytesWritten = sizeof(unsigned long);
-        if (fwrite(&ReservedSize, sizeof(unsigned long), 1, FileHandle) < 1) {
+        BytesWritten = sizeof(ULONG);
+        if (fwrite(&ReservedSize, sizeof(ULONG), 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #endif
 
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, CabinetReservedFileBuffer, CabinetReservedFileSize, &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, CabinetReservedFileBuffer, CabinetReservedFileSize, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
         BytesWritten = CabinetReservedFileSize;
-        if (fwrite(CabinetReservedFileBuffer, CabinetReservedFileSize, 1, FileHandle) < 1) {
+        if (fwrite(CabinetReservedFileBuffer, CabinetReservedFileSize, 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #endif
     }
 
-    if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) {
-
+    if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
+    {
         DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
 
         /* Write name of previous cabinet */
-        Size = strlen(CabinetPrev) + 1;
+        Size = (ULONG)strlen(CabinetPrev) + 1;
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, CabinetPrev, Size, &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, CabinetPrev, Size, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
         BytesWritten = Size;
-        if (fwrite(CabinetPrev, Size, 1, FileHandle) < 1) {
+        if (fwrite(CabinetPrev, Size, 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
@@ -2741,35 +3246,39 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
         DPRINT(MAX_TRACE, ("DiskPrev '%s'.\n", DiskPrev));
 
         /* Write label of previous disk */
-        Size = strlen(DiskPrev) + 1;
+        Size = (ULONG)strlen(DiskPrev) + 1;
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, DiskPrev, Size, &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, DiskPrev, Size, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
         BytesWritten = Size;
-        if (fwrite(DiskPrev, Size, 1, FileHandle) < 1) {
+        if (fwrite(DiskPrev, Size, 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #endif
     }
 
-    if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) {
-
+    if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
+    {
         DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
 
         /* Write name of next cabinet */
-        Size = strlen(CabinetNext) + 1;
+        Size = (ULONG)strlen(CabinetNext) + 1;
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, CabinetNext, Size, &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, CabinetNext, Size, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
         BytesWritten = Size;
-        if (fwrite(CabinetNext, Size, 1, FileHandle) < 1) {
+        if (fwrite(CabinetNext, Size, 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
@@ -2778,15 +3287,17 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
         DPRINT(MAX_TRACE, ("DiskNext '%s'.\n", DiskNext));
 
         /* Write label of next disk */
-        Size = strlen(DiskNext) + 1;
+        Size = (ULONG)strlen(DiskNext) + 1;
 #if defined(WIN32)
-        if (!WriteFile(FileHandle, DiskNext, Size, &BytesWritten, NULL)) {
+        if (!WriteFile(FileHandle, DiskNext, Size, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
         BytesWritten = Size;
-        if (fwrite(DiskNext, Size, 1, FileHandle) < 1) {
+        if (fwrite(DiskNext, Size, 1, FileHandle) < 1)
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
@@ -2797,7 +3308,7 @@ unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
 }
 
 
-unsigned long CCabinet::WriteFolderEntries()
+ULONG CCabinet::WriteFolderEntries()
 /*
  * FUNCTION: Writes folder entries
  * RETURNS:
@@ -2805,29 +3316,32 @@ unsigned long CCabinet::WriteFolderEntries()
  */
 {
     PCFFOLDER_NODE FolderNode;
-    unsigned long BytesWritten;
+    ULONG BytesWritten;
 
     DPRINT(MAX_TRACE, ("Writing folder table.\n"));
 
     FolderNode = FolderListHead;
-    while (FolderNode != NULL) {
-        if (FolderNode->Commit) {
-
-            DPRINT(MAX_TRACE, ("Writing folder entry. CompressionType (0x%X)  DataBlockCount (%d)  DataOffset (0x%lX).\n",
-                FolderNode->Folder.CompressionType, FolderNode->Folder.DataBlockCount, FolderNode->Folder.DataOffset));
+    while (FolderNode != NULL)
+    {
+        if (FolderNode->Commit)
+        {
+            DPRINT(MAX_TRACE, ("Writing folder entry. CompressionType (0x%X)  DataBlockCount (%d)  DataOffset (0x%X).\n",
+                FolderNode->Folder.CompressionType, FolderNode->Folder.DataBlockCount, (UINT)FolderNode->Folder.DataOffset));
 
 #if defined(WIN32)
             if (!WriteFile(FileHandle,
-                           &FolderNode->Folder,
-                           sizeof(CFFOLDER),
-                           &BytesWritten,
-                           NULL)) {
+                        &FolderNode->Folder,
+                        sizeof(CFFOLDER),
+                        (LPDWORD)&BytesWritten,
+                        NULL))
+            {
                 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
                 return CAB_STATUS_CANNOT_WRITE;
             }
 #else
             BytesWritten = sizeof(CFFOLDER);
-            if (fwrite(&FolderNode->Folder, sizeof(CFFOLDER), 1, FileHandle) < 1) {
+            if (fwrite(&FolderNode->Folder, sizeof(CFFOLDER), 1, FileHandle) < 1)
+            {
                 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
                 return CAB_STATUS_CANNOT_WRITE;
             }
@@ -2840,7 +3354,7 @@ unsigned long CCabinet::WriteFolderEntries()
 }
 
 
-unsigned long CCabinet::WriteFileEntries()
+ULONG CCabinet::WriteFileEntries()
 /*
  * FUNCTION: Writes file entries for all files
  * RETURNS:
@@ -2848,14 +3362,16 @@ unsigned long CCabinet::WriteFileEntries()
  */
 {
     PCFFILE_NODE File;
-    unsigned long BytesWritten;
-    bool SetCont;
+    ULONG BytesWritten;
+    bool SetCont = false;
 
     DPRINT(MAX_TRACE, ("Writing file table.\n"));
 
     File = FileListHead;
-    while (File != NULL) {
-        if (File->Commit) {
+    while (File != NULL)
+    {
+        if (File->Commit)
+        {
             /* Remove any continued files that ends in this disk */
             if (File->File.FileControlID == CAB_FILE_CONTINUED)
                 File->Delete = true;
@@ -2864,25 +3380,27 @@ unsigned long CCabinet::WriteFileEntries()
                appear in the next disk too */
 
             if ((File->File.FileOffset + File->File.FileSize >= LastBlockStart) &&
-                (File->File.FileControlID <= CAB_FILE_MAX_FOLDER) && (BlockIsSplit)) {
+                (File->File.FileControlID <= CAB_FILE_MAX_FOLDER) && (BlockIsSplit))
+            {
                 File->File.FileControlID = CAB_FILE_SPLIT;
                 File->Delete = false;
                 SetCont = true;
             }
 
-            DPRINT(MAX_TRACE, ("Writing file entry. FileControlID (0x%X)  FileOffset (0x%lX)  FileSize (%lu)  FileName (%s).\n",
-                File->File.FileControlID, File->File.FileOffset, File->File.FileSize, File->FileName));
+            DPRINT(MAX_TRACE, ("Writing file entry. FileControlID (0x%X)  FileOffset (0x%X)  FileSize (%u)  FileName (%s).\n",
+                File->File.FileControlID, (UINT)File->File.FileOffset, (UINT)File->File.FileSize, File->FileName));
 
 #if defined(WIN32)
             if (!WriteFile(FileHandle,
                 &File->File,
                 sizeof(CFFILE),
-                &BytesWritten,
+                (LPDWORD)&BytesWritten,
                 NULL))
                 return CAB_STATUS_CANNOT_WRITE;
 #else
             BytesWritten = sizeof(CFFILE);
-            if (fwrite(&File->File, sizeof(CFFILE), 1, FileHandle) < 1) {
+            if (fwrite(&File->File, sizeof(CFFILE), 1, FileHandle) < 1)
+            {
                 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
                 return CAB_STATUS_CANNOT_WRITE;
             }
@@ -2891,17 +3409,21 @@ unsigned long CCabinet::WriteFileEntries()
 #if defined(WIN32)
             if (!WriteFile(FileHandle,
                 GetFileName(File->FileName),
-                strlen(GetFileName(File->FileName)) + 1, &BytesWritten, NULL))
+                (DWORD)strlen(GetFileName(File->FileName)) + 1,
+                (LPDWORD)&BytesWritten,
+                NULL))
                 return CAB_STATUS_CANNOT_WRITE;
 #else
             BytesWritten = strlen(GetFileName(File->FileName)) + 1;
-            if (fwrite(GetFileName(File->FileName), strlen(GetFileName(File->FileName)) + 1, 1, FileHandle) < 1) {
+            if (fwrite(GetFileName(File->FileName), strlen(GetFileName(File->FileName)) + 1, 1, FileHandle) < 1)
+            {
                 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
                 return CAB_STATUS_CANNOT_WRITE;
             }
 #endif
 
-            if (SetCont) {
+            if (SetCont)
+            {
                 File->File.FileControlID = CAB_FILE_CONTINUED;
                 SetCont = false;
             }
@@ -2913,7 +3435,7 @@ unsigned long CCabinet::WriteFileEntries()
 }
 
 
-unsigned long CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
+ULONG CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
 /*
  * FUNCTION: Writes data blocks to the cabinet
  * ARGUMENTS:
@@ -2923,17 +3445,18 @@ unsigned long CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
  */
 {
     PCFDATA_NODE DataNode;
-    unsigned long BytesWritten;
-    unsigned long BytesRead;
-    unsigned long Status;
+    ULONG BytesWritten;
+    ULONG BytesRead;
+    ULONG Status;
 
     DataNode = FolderNode->DataListHead;
     if (DataNode != NULL)
         Status = ScratchFile->Seek(DataNode->ScratchFilePosition);
 
-    while (DataNode != NULL) {
-        DPRINT(MAX_TRACE, ("Reading block at (0x%lX)  CompSize (%d)  UncompSize (%d).\n",
-            DataNode->ScratchFilePosition,
+    while (DataNode != NULL)
+    {
+        DPRINT(MAX_TRACE, ("Reading block at (0x%X)  CompSize (%u)  UncompSize (%u).\n",
+            (UINT)DataNode->ScratchFilePosition,
             DataNode->Data.CompSize,
             DataNode->Data.UncompSize));
 
@@ -2941,37 +3464,42 @@ unsigned long CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
            memory allocation. OutputBuffer can't be used here because it may
            still contain valid data (if a data block spans two or more disks) */
         Status = ScratchFile->ReadBlock(&DataNode->Data, InputBuffer, &BytesRead);
-        if (Status != CAB_STATUS_SUCCESS) {
-            DPRINT(MIN_TRACE, ("Cannot read from scratch file (%d).\n", (unsigned int)Status));
+        if (Status != CAB_STATUS_SUCCESS)
+        {
+            DPRINT(MIN_TRACE, ("Cannot read from scratch file (%u).\n", (UINT)Status));
             return Status;
         }
 
 #if defined(WIN32)
         if (!WriteFile(FileHandle, &DataNode->Data,
-            sizeof(CFDATA), &BytesWritten, NULL)) {
+            sizeof(CFDATA), (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
-          BytesWritten = sizeof(CFDATA);
-          if (fwrite(&DataNode->Data, sizeof(CFDATA), 1, FileHandle) < 1) {
-              DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
-              return CAB_STATUS_CANNOT_WRITE;
-          }
+        BytesWritten = sizeof(CFDATA);
+        if (fwrite(&DataNode->Data, sizeof(CFDATA), 1, FileHandle) < 1)
+        {
+            DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
+            return CAB_STATUS_CANNOT_WRITE;
+        }
 #endif
 
 #if defined(WIN32)
         if (!WriteFile(FileHandle, InputBuffer,
-            DataNode->Data.CompSize, &BytesWritten, NULL)) {
+            DataNode->Data.CompSize, (LPDWORD)&BytesWritten, NULL))
+        {
             DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
             return CAB_STATUS_CANNOT_WRITE;
         }
 #else
-          BytesWritten = DataNode->Data.CompSize;
-          if (fwrite(InputBuffer, DataNode->Data.CompSize, 1, FileHandle) < 1) {
-              DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
-              return CAB_STATUS_CANNOT_WRITE;
-          }
+        BytesWritten = DataNode->Data.CompSize;
+        if (fwrite(InputBuffer, DataNode->Data.CompSize, 1, FileHandle) < 1)
+        {
+            DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
+            return CAB_STATUS_CANNOT_WRITE;
+        }
 #endif
 
         DataNode = DataNode->Next;
@@ -2980,32 +3508,34 @@ unsigned long CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
 }
 
 
-unsigned long CCabinet::WriteDataBlock()
+ULONG CCabinet::WriteDataBlock()
 /*
  * FUNCTION: Writes the current data block to the scratch file
  * RETURNS:
  *     Status of operation
  */
 {
-    unsigned long Status;
-    unsigned long BytesWritten;
+    ULONG Status;
+    ULONG BytesWritten;
     PCFDATA_NODE DataNode;
 
-    if (!BlockIsSplit) {
+    if (!BlockIsSplit)
+    {
         Status = Codec->Compress(OutputBuffer,
             InputBuffer,
             CurrentIBufferSize,
             &TotalCompSize);
 
-        DPRINT(MAX_TRACE, ("Block compressed. CurrentIBufferSize (%lu)  TotalCompSize(%lu).\n",
-            CurrentIBufferSize, TotalCompSize));
+        DPRINT(MAX_TRACE, ("Block compressed. CurrentIBufferSize (%u)  TotalCompSize(%u).\n",
+            (UINT)CurrentIBufferSize, (UINT)TotalCompSize));
 
         CurrentOBuffer     = OutputBuffer;
         CurrentOBufferSize = TotalCompSize;
     }
 
     DataNode = NewDataNode(CurrentFolderNode);
-    if (!DataNode) {
+    if (!DataNode)
+    {
         DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
         return CAB_STATUS_NOMEMORY;
     }
@@ -3018,13 +3548,16 @@ unsigned long CCabinet::WriteDataBlock()
     else
         BlockIsSplit = false;
 
-    if (BlockIsSplit) {
-        DataNode->Data.CompSize   = (unsigned short)(MaxDiskSize - DiskSize);
+    if (BlockIsSplit)
+    {
+        DataNode->Data.CompSize   = (USHORT)(MaxDiskSize - DiskSize);
         DataNode->Data.UncompSize = 0;
         CreateNewDisk = true;
-    } else {
-        DataNode->Data.CompSize   = (unsigned short)CurrentOBufferSize;
-        DataNode->Data.UncompSize = (unsigned short)CurrentIBufferSize;
+    }
+    else
+    {
+        DataNode->Data.CompSize   = (USHORT)CurrentOBufferSize;
+        DataNode->Data.UncompSize = (USHORT)CurrentIBufferSize;
     }
 
     DataNode->Data.Checksum = 0;
@@ -3033,10 +3566,10 @@ unsigned long CCabinet::WriteDataBlock()
     // FIXME: MAKECAB.EXE does not like this checksum algorithm
     //DataNode->Data.Checksum = ComputeChecksum(CurrentOBuffer, DataNode->Data.CompSize, 0);
 
-    DPRINT(MAX_TRACE, ("Writing block. Checksum (0x%X)  CompSize (%d)  UncompSize (%d).\n",
-        (unsigned int)DataNode->Data.Checksum,
-        (unsigned int)DataNode->Data.CompSize,
-        (unsigned int)DataNode->Data.UncompSize));
+    DPRINT(MAX_TRACE, ("Writing block. Checksum (0x%X)  CompSize (%u)  UncompSize (%u).\n",
+        (UINT)DataNode->Data.Checksum,
+        DataNode->Data.CompSize,
+        DataNode->Data.UncompSize));
 
     Status = ScratchFile->WriteBlock(&DataNode->Data,
         CurrentOBuffer, &BytesWritten);
@@ -3048,12 +3581,13 @@ unsigned long CCabinet::WriteDataBlock()
     CurrentFolderNode->TotalFolderSize += (BytesWritten + sizeof(CFDATA));
     CurrentFolderNode->Folder.DataBlockCount++;
 
-    *(unsigned char**)&CurrentOBuffer += DataNode->Data.CompSize;
-    CurrentOBufferSize     -= DataNode->Data.CompSize;
+    CurrentOBuffer = (unsigned char*)CurrentOBuffer + DataNode->Data.CompSize;
+    CurrentOBufferSize -= DataNode->Data.CompSize;
 
     LastBlockStart += DataNode->Data.UncompSize;
 
-    if (!BlockIsSplit) {
+    if (!BlockIsSplit)
+    {
         CurrentIBufferSize = 0;
         CurrentIBuffer     = InputBuffer;
     }
@@ -3061,12 +3595,11 @@ unsigned long CCabinet::WriteDataBlock()
     return CAB_STATUS_SUCCESS;
 }
 
-
 #if !defined(WIN32)
 
 void CCabinet::ConvertDateAndTime(time_t* Time,
-  unsigned short* DosDate,
-  unsigned short* DosTime)
+                                  PUSHORT DosDate,
+                                  PUSHORT DosTime)
 /*
  * FUNCTION: Returns file times of a file
  * ARGUMENTS:
@@ -3081,22 +3614,22 @@ void CCabinet::ConvertDateAndTime(time_t* Time,
     timedef = localtime(Time);
 
     DPRINT(MAX_TRACE, ("day: %d, mon: %d, year:%d, hour: %d, min: %d, sec: %d\n",
-      timedef->tm_mday, timedef->tm_mon, timedef->tm_year,
-      timedef->tm_sec, timedef->tm_min, timedef->tm_hour));
+        timedef->tm_mday, timedef->tm_mon, timedef->tm_year,
+        timedef->tm_sec, timedef->tm_min, timedef->tm_hour));
 
     *DosDate = ((timedef->tm_mday + 1) << 0)
-      | ((timedef->tm_mon + 1) << 5)
-      | (((timedef->tm_year + 1900) - 1980) << 9);
+        | ((timedef->tm_mon + 1) << 5)
+        | (((timedef->tm_year + 1900) - 1980) << 9);
 
     *DosTime = (timedef->tm_sec << 0)
-      | (timedef->tm_min << 5)
-      | (timedef->tm_hour << 11);
+        | (timedef->tm_min << 5)
+        | (timedef->tm_hour << 11);
 }
 
 #endif // !WIN32
 
 
-unsigned long CCabinet::GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File)
+ULONG CCabinet::GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File)
 /*
  * FUNCTION: Returns file times of a file
  * ARGUMENTS:
@@ -3119,20 +3652,17 @@ unsigned long CCabinet::GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File)
 
     // Check for an absolute path
     if (IsSeparator(File->FileName[0]))
-      {
         strcpy(buf, File->FileName);
-      }
     else
-      {
-        getcwd(buf, sizeof(buf));
+    {
+        if (!getcwd(buf, sizeof(buf)))
+            return CAB_STATUS_CANNOT_READ;
         strcat(buf, DIR_SEPARATOR_STRING);
         strcat(buf, File->FileName);
-      }
+    }
 
     if (stat(buf, &stbuf) == -1)
-      {
         return CAB_STATUS_CANNOT_READ;
-      }
 
     ConvertDateAndTime(&stbuf.st_mtime, &File->File.FileDate, &File->File.FileTime);
 #endif
@@ -3140,7 +3670,7 @@ unsigned long CCabinet::GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File)
 }
 
 
-unsigned long CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
+ULONG CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
 /*
  * FUNCTION: Returns attributes on a file
  * ARGUMENTS:
@@ -3150,46 +3680,33 @@ unsigned long CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
  */
 {
 #if defined(WIN32)
-    long Attributes;
+    LONG Attributes;
 
     Attributes = GetFileAttributes(File->FileName);
     if (Attributes == -1)
         return CAB_STATUS_CANNOT_READ;
 
-    if (Attributes & FILE_ATTRIBUTE_READONLY)
-        File->File.Attributes |= CAB_ATTRIB_READONLY;
-
-    if (Attributes & FILE_ATTRIBUTE_HIDDEN)
-        File->File.Attributes |= CAB_ATTRIB_HIDDEN;
-
-    if (Attributes & FILE_ATTRIBUTE_SYSTEM)
-        File->File.Attributes |= CAB_ATTRIB_SYSTEM;
-
-    if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
-        File->File.Attributes |= CAB_ATTRIB_DIRECTORY;
-
-    if (Attributes & FILE_ATTRIBUTE_ARCHIVE)
-        File->File.Attributes |= CAB_ATTRIB_ARCHIVE;
+    // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
+    // The IDs for these attributes are the same in the CAB file and under Windows
+    // If the file has any other attributes, strip them off by the logical AND.
+    File->File.Attributes = (USHORT)(Attributes & 0x37);
 #else
     struct stat stbuf;
     char buf[MAX_PATH];
 
     // Check for an absolute path
     if (IsSeparator(File->FileName[0]))
-      {
         strcpy(buf, File->FileName);
-      }
     else
-      {
-        getcwd(buf, sizeof(buf));
+    {
+        if (!getcwd(buf, sizeof(buf)))
+            return CAB_STATUS_CANNOT_READ;
         strcat(buf, DIR_SEPARATOR_STRING);
         strcat(buf, File->FileName);
-      }
+    }
 
     if (stat(buf, &stbuf) == -1)
-      {
         return CAB_STATUS_CANNOT_READ;
-      }
 
 #if 0
     File->File.Attributes |= CAB_ATTRIB_READONLY;
@@ -3207,34 +3724,21 @@ unsigned long CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
 }
 
 
-unsigned long CCabinet::SetAttributesOnFile(PCFFILE_NODE File)
+ULONG CCabinet::SetAttributesOnFile(char* FileName, USHORT FileAttributes)
 /*
  * FUNCTION: Sets attributes on a file
  * ARGUMENTS:
- *      File = Pointer to CFFILE node for file
+ *      FileName       = File name with path
+ *      FileAttributes = Attributes of that file
  * RETURNS:
  *     Status of operation
  */
 {
 #if defined(WIN32)
-    unsigned long Attributes = 0;
-
-    if (File->File.Attributes & CAB_ATTRIB_READONLY)
-        Attributes |= FILE_ATTRIBUTE_READONLY;
-
-    if (File->File.Attributes & CAB_ATTRIB_HIDDEN)
-        Attributes |= FILE_ATTRIBUTE_HIDDEN;
-
-    if (File->File.Attributes & CAB_ATTRIB_SYSTEM)
-        Attributes |= FILE_ATTRIBUTE_SYSTEM;
-
-    if (File->File.Attributes & CAB_ATTRIB_DIRECTORY)
-        Attributes |= FILE_ATTRIBUTE_DIRECTORY;
-
-    if (File->File.Attributes & CAB_ATTRIB_ARCHIVE)
-        Attributes |= FILE_ATTRIBUTE_ARCHIVE;
-
-    SetFileAttributes(File->FileName, Attributes);
+    // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
+    // The IDs for these attributes are the same in the CAB file and under Windows
+    // If the file has any other attributes, strip them off by the logical AND.
+    SetFileAttributes(FileName, (DWORD)(FileAttributes & 0x37));
 
     return CAB_STATUS_SUCCESS;
 #else