* 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);
+ 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;
#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
0, // No sharing
NULL, // No security
CREATE_ALWAYS, // Create or overwrite
- FILE_ATTRIBUTE_NORMAL, // Normal file
+ 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);
}
-unsigned long CCFDATAStorage::Create(char* FileName)
+ULONG CCFDATAStorage::Create(const char* FileName)
/*
* FUNCTION: Creates the file
* ARGUMENTS:
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 (tmpnam(FullName) == NULL)*/
+ if ((FileHandle = tmpfile()) == NULL)
return CAB_STATUS_CANNOT_CREATE;
- FileHandle = fopen(FullName, "w+b");
+ /*
+ 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;
}
-unsigned long CCFDATAStorage::Destroy()
+ULONG CCFDATAStorage::Destroy()
/*
* FUNCTION: Destroys the file
* RETURNS:
}
-unsigned long CCFDATAStorage::Truncate()
+ULONG CCFDATAStorage::Truncate()
/*
* FUNCTION: Truncate the scratch file to zero bytes
* RETURNS:
*/
{
#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 = fopen(FullName, "w+b");
- if (FileHandle == NULL) {
- DPRINT(MID_TRACE, ("ERROR '%d'.\n", (unsigned int)errno));
+ FileHandle = tmpfile();
+ if (FileHandle == NULL)
+ {
+ DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
return CAB_STATUS_FAILURE;
}
#endif
}
-unsigned long CCFDATAStorage::Position()
+ULONG CCFDATAStorage::Position()
/*
* FUNCTION: Returns current position in file
* RETURNS:
#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:
*/
{
#if defined(WIN32)
- if (SetFilePointer(FileHandle,
- Position,
- NULL,
- FILE_BEGIN) == 0xFFFFFFFF)
+ if( SetFilePointer(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:
*/
{
#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:
*/
{
#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);
* FUNCTION: Default constructor
*/
{
+ *CabinetName = '\0';
+ *CabinetPrev = '\0';
+ *DiskPrev = '\0';
+ *CabinetNext = '\0';
+ *DiskNext = '\0';
+ *DestPath = '\0';
+ *CabinetReservedFile = '\0';
+
FileOpen = false;
- strcpy(DestPath, "");
- strcpy(CabinetReservedFile, "");
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;
* FUNCTION: Default destructor
*/
{
- if (CabinetReservedFileBuffer != NULL) {
+ if (CabinetReservedFileBuffer != NULL)
+ {
FreeMemory(CabinetReservedFileBuffer);
CabinetReservedFileBuffer = NULL;
CabinetReservedFileSize = 0;
* 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
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;
* 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;
}
*/
{
char* FileName;
- unsigned long i;
+ ULONG i;
i = (Path [0] ? (Path[1] == ':' ? 2 : 0) : 0);
FileName = GetFileName(Path + i);
bool CCabinet::NormalizePath(char* Path,
- unsigned long Length)
+ ULONG Length)
/*
* FUNCTION: Normalizes a path
* ARGUMENTS:
* 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;
}
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()
/*
*/
{
FILEHANDLE FileHandle;
- unsigned long BytesRead;
+ ULONG BytesRead;
#if defined(WIN32)
FileHandle = CreateFile(ConvertPath(FileName, true), // Open this file
- GENERIC_READ, // Open for reading
- FILE_SHARE_READ, // Share for reading
- NULL, // No security
- OPEN_EXISTING, // Existing file only
- FILE_ATTRIBUTE_NORMAL, // Normal file
- NULL); // No attribute template
- if (FileHandle == INVALID_HANDLE_VALUE) {
+ GENERIC_READ, // Open for reading
+ FILE_SHARE_READ, // Share for reading
+ NULL, // No security
+ OPEN_EXISTING, // Existing file only
+ FILE_ATTRIBUTE_NORMAL, // Normal file
+ NULL); // No attribute template
+ 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) {
+ FileHandle = fopen(ConvertPath(FileName, true), "rb");
+ 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;
}
}
-unsigned long CCabinet::GetCurrentDiskNumber()
+ULONG CCabinet::GetCurrentDiskNumber()
/*
* FUNCTION: Returns current disk number
* RETURNS:
}
-unsigned long CCabinet::Open()
+ULONG CCabinet::Open()
/*
* FUNCTION: Opens a cabinet file
* RETURNS:
*/
{
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)
#if defined(WIN32)
FileHandle = CreateFile(CabinetName, // Open this file
- GENERIC_READ, // Open for reading
- FILE_SHARE_READ, // Share for reading
- NULL, // No security
- OPEN_EXISTING, // Existing file only
- FILE_ATTRIBUTE_NORMAL, // Normal file
- NULL); // No attribute template
-
- if (FileHandle == INVALID_HANDLE_VALUE) {
+ GENERIC_READ, // Open for reading
+ FILE_SHARE_READ, // Share for reading
+ NULL, // No security
+ OPEN_EXISTING, // Existing file only
+ FILE_ATTRIBUTE_NORMAL, // Normal file
+ NULL); // No attribute template
+
+ 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) {
+ FileHandle = fopen(CabinetName, "rb");
+ if (FileHandle == NULL)
+ {
DPRINT(MID_TRACE, ("Cannot open file.\n"));
return CAB_STATUS_CANNOT_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;
}
(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;
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;
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)
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)
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;
}
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;
* 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:
* 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 (!Search->Next) {
- if (strlen(DiskNext) > 0) {
+ if(bFound)
+ break;
+
+ Search->Next = Search->Next->Next;
+ }
+
+ if (!Search->Next)
+ {
+ if (strlen(DiskNext) > 0)
+ {
CloseCabinet();
SetCabinetName(CabinetNext);
OnDiskChange(CabinetNext, DiskNext);
Status = Open();
- if (Status != CAB_STATUS_SUCCESS)
+ if (Status != CAB_STATUS_SUCCESS)
return Status;
Search->Next = FileListHead;
if (!Search->Next)
return CAB_STATUS_NOFILE;
- } else
+ }
+ else
return CAB_STATUS_NOFILE;
}
}
-unsigned long CCabinet::ExtractFile(char* FileName)
+ULONG CCabinet::ExtractFile(char* FileName)
/*
* FUNCTION: Extracts a file from the cabinet
* ARGUMENTS:
* 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);
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
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
}
}
#else /* !WIN32 */
- DestFile = fopen(DestName, "rb");
- if (DestFile != NULL) {
+ DestFile = fopen(DestName, "rb");
+ 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;
}
#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;
+ return CAB_STATUS_NOMEMORY;
}
/* 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;
}
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))) {
+ 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));
+ 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",
- (DWORD)CurrentBuffer, (DWORD)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)) {
+ if (((Status = ReadBlock(CurrentBuffer, 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",
CurrentBuffer += BytesRead;
- if (CFData.UncompSize == 0) {
+ if (CFData.UncompSize == 0)
+ {
if (strlen(DiskNext) == 0)
return CAB_STATUS_NOFILE;
OnDiskChange(CabinetNext, DiskNext);
Status = Open();
- if (Status != CAB_STATUS_SUCCESS)
+ if (Status != CAB_STATUS_SUCCESS)
return Status;
/* 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;
}
/* 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;
}
} 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"));
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;
}
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);
}
Size -= BytesToWrite;
- CurrentOffset += BytesToWrite;
+ CurrentOffset += BytesToWrite;
/* Don't skip any more bytes */
Skip = false;
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;
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;
/* 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;
+ return CAB_STATUS_NOMEMORY;
}
CurrentIBuffer = InputBuffer;
CurrentIBufferSize = 0;
// NextFolderNumber is 0-based
NextFolderNumber = 0;
- CurrentFolderNode = NULL;
+ CurrentFolderNode = NULL;
Status = NewFolder();
if (Status != CAB_STATUS_SUCCESS)
return Status;
CurrentFolderNode->Folder.DataOffset = DiskSize - TotalHeaderSize;
ScratchFile = new CCFDATAStorage;
- if (!ScratchFile) {
+ if (!ScratchFile)
+ {
DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
return CAB_STATUS_NOMEMORY;
}
}
-unsigned long CCabinet::NewDisk()
+ULONG CCabinet::NewDisk()
/*
* FUNCTION: Forces a new disk to be created
* RETURNS:
}
-unsigned long CCabinet::NewFolder()
+ULONG CCabinet::NewFolder()
/*
* FUNCTION: Forces a new folder to be created
* RETURNS:
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);
}
-unsigned long CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
+ULONG CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
/*
* FUNCTION: Writes a file to the scratch file
* ARGUMENTS:
* 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(
FILE_SHARE_READ, // Share for reading
NULL, // No security
OPEN_EXISTING, // File must exist
- FILE_ATTRIBUTE_NORMAL, // Normal file
+ 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) {
+ SourceFile = fopen(FileNode->FileName, "rb");
+ 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();
FileNode->File.FileOffset = CurrentFolderNode->UncompOffset;
CurrentFolderNode->UncompOffset += TotalBytesLeft;
- FileNode->File.FileControlID = 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;
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;
-
- CurrentIBufferSize += (unsigned short)BytesRead;
+ CurrentIBuffer = (unsigned char*)CurrentIBuffer + BytesRead;
+ CurrentIBufferSize += (USHORT)BytesRead;
- if (CurrentIBufferSize == CAB_BLOCKSIZE) {
+ if (CurrentIBufferSize == CAB_BLOCKSIZE)
+ {
Status = WriteDataBlock();
if (Status != CAB_STATUS_SUCCESS)
return Status;
} 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;
CreateNewFolder = true;
}
- } else {
+ }
+ else
+ {
if (FileNode->File.FileControlID <= CAB_FILE_MAX_FOLDER)
FileNode->File.FileControlID = CAB_FILE_SPLIT;
else
}
-unsigned long CCabinet::WriteDisk(unsigned long MoreDisks)
+ULONG CCabinet::WriteDisk(ULONG MoreDisks)
/*
* FUNCTION: Forces the current disk to be written
* ARGUMENTS:
*/
{
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();
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();
ASSERT(FileNode == FileListHead);
}
- if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) {
+ if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
+ {
Status = WriteDataBlock();
if (Status != CAB_STATUS_SUCCESS)
return Status;
}
-unsigned long CCabinet::CommitDisk(unsigned long MoreDisks)
+ULONG CCabinet::CommitDisk(ULONG MoreDisks)
/*
* FUNCTION: Commits the current disk
* ARGUMENTS:
*/
{
PCFFOLDER_NODE FolderNode;
- unsigned long Status;
+ ULONG Status;
OnCabinetName(CurrentDiskNumber, CabinetName);
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
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
}
}
#else /* !WIN32 */
- FileHandle = fopen(CabinetName, "rb");
- if (FileHandle != NULL) {
+ FileHandle = fopen(CabinetName, "rb");
+ 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
- WriteCabinetHeader(MoreDisks);
+ WriteCabinetHeader(MoreDisks != 0);
Status = WriteFolderEntries();
if (Status != CAB_STATUS_SUCCESS)
/* 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;
}
-unsigned long CCabinet::CloseDisk()
+ULONG CCabinet::CloseDisk()
/*
* FUNCTION: Closes the current disk
* RETURNS:
}
-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;
}
-unsigned long CCabinet::AddFile(char* FileName)
+ULONG CCabinet::AddFile(char* FileName)
/*
* FUNCTION: Adds a file to the current disk
* ARGUMENTS:
{
FILEHANDLE SrcFile;
PCFFILE_NODE FileNode;
+ char* NewFileName;
- FileNode = NewFileNode();
- if (!FileNode) {
+ NewFileName = (char*)AllocateMemory(strlen(FileName) + 1);
+ if (!NewFileName)
+ {
DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
return CAB_STATUS_NOMEMORY;
}
-
- FileNode->FolderNode = CurrentFolderNode;
-
- FileNode->FileName = (char*)AllocateMemory(strlen(FileName) + 1);
- strcpy(FileNode->FileName, FileName);
- ConvertPath(FileNode->FileName, false);
+ strcpy(NewFileName, FileName);
+ ConvertPath(NewFileName, false);
/* Try to open file */
#if defined(WIN32)
SrcFile = CreateFile(
- FileNode->FileName, // Open this file
+ NewFileName, // Open this file
GENERIC_READ, // Open for reading
FILE_SHARE_READ, // Share for reading
NULL, // No security
OPEN_EXISTING, // File must exist
- FILE_ATTRIBUTE_NORMAL, // Normal file
+ FILE_ATTRIBUTE_NORMAL, // Normal file
NULL); // No attribute template
- if (SrcFile == INVALID_HANDLE_VALUE) {
- DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName));
+ 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(FileNode->FileName, "rb");
- if (SrcFile == NULL) {
- DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName));
+ SrcFile = fopen(NewFileName, "rb");
+ if (SrcFile == NULL)
+ {
+ DPRINT(MID_TRACE, ("File not found (%s).\n", NewFileName));
+ FreeMemory(NewFileName);
return CAB_STATUS_CANNOT_OPEN;
}
#endif
+ FileNode = NewFileNode();
+ if (!FileNode)
+ {
+ DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
+ FreeMemory(NewFileName);
+ return CAB_STATUS_NOMEMORY;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
-void CCabinet::SetMaxDiskSize(unsigned long Size)
+ 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:
}
-bool CCabinet::OnDiskLabel(unsigned long Number, char* Label)
+bool CCabinet::OnDiskLabel(ULONG Number, char* Label)
/*
* FUNCTION: Called when a disk needs a label
* ARGUMENTS:
}
-bool CCabinet::OnCabinetName(unsigned long Number, char* Name)
+bool CCabinet::OnCabinetName(ULONG Number, char* Name)
/*
* FUNCTION: Called when a cabinet needs a name
* ARGUMENTS:
#endif /* CAB_READ_ONLY */
-PCFFOLDER_NODE CCabinet::LocateFolderNode(unsigned long Index)
+PCFFOLDER_NODE CCabinet::LocateFolderNode(ULONG Index)
/*
* FUNCTION: Locates a folder node
* ARGUMENTS:
{
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;
}
-unsigned long CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
+ULONG CCabinet::GetAbsoluteOffset(PCFFILE_NODE File)
/*
* FUNCTION: Returns the absolute offset of a file
* ARGUMENTS:
{
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;
}
}
-unsigned long CCabinet::LocateFile(char* FileName,
+ULONG CCabinet::LocateFile(char* FileName,
PCFFILE_NODE *File)
/*
* FUNCTION: Locates a file in the cabinet
*/
{
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;
}
}
-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:
* 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;
}
}
-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;
}
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:
* 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;
Node->Prev = FolderListTail;
- if (FolderListTail != NULL) {
+ if (FolderListTail != NULL)
FolderListTail->Next = Node;
- } else {
+ else
FolderListHead = Node;
- }
+
FolderListTail = Node;
return Node;
Node->Prev = FileListTail;
- if (FileListTail != NULL) {
+ if (FileListTail != NULL)
FileListTail->Next = Node;
- } else {
+ else
FileListHead = Node;
- }
+
FileListTail = Node;
return Node;
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;
PCFDATA_NODE NextNode;
NextNode = FolderNode->DataListHead;
- while (NextNode != NULL) {
+ while (NextNode != NULL)
+ {
PrevNode = NextNode->Next;
FreeMemory(NextNode);
NextNode = PrevNode;
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);
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;
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);
PCFFOLDER_NODE NextNode;
NextNode = FolderListHead;
- while (NextNode != NULL) {
+ while (NextNode != NULL)
+ {
PrevNode = NextNode->Next;
DestroyDataNodes(NextNode);
FreeMemory(NextNode);
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;
}
-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:
*/
{
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:
}
-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
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 = CurrentDiskNumber;
-
- if ((CurrentDiskNumber > 0) && (OnCabinetName(PrevCabinetNumber, CabinetPrev))) {
+ CABHeader.CabinetNumber = (USHORT)CurrentDiskNumber;
+
+ 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, "");
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;
}
-unsigned long CCabinet::WriteCabinetHeader(bool MoreDisks)
+ULONG CCabinet::WriteCabinetHeader(bool MoreDisks)
/*
* FUNCTION: Writes the cabinet header and optional fields
* ARGUMENTS:
{
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;
BytesWritten = Size + TotalFolderSize + TotalFileSize;
CABHeader.FolderCount = 0;
FolderNode = FolderListHead;
- while (FolderNode != NULL) {
+ while (FolderNode != NULL)
+ {
FolderNode->Folder.DataOffset = BytesWritten;
BytesWritten += FolderNode->TotalFolderSize;
/* 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;
/* 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;
}
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;
}
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;
}
}
-unsigned long CCabinet::WriteFolderEntries()
+ULONG CCabinet::WriteFolderEntries()
/*
* FUNCTION: Writes folder entries
* RETURNS:
*/
{
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;
}
}
-unsigned long CCabinet::WriteFileEntries()
+ULONG CCabinet::WriteFileEntries()
/*
* FUNCTION: Writes file entries for all files
* RETURNS:
*/
{
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;
/* The file could end in the last (split) block and should therefore
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;
}
#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;
}
}
-unsigned long CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
+ULONG CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode)
/*
* FUNCTION: Writes data blocks to the cabinet
* ARGUMENTS:
*/
{
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));
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;
}
-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;
}
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;
// 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);
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;
}
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:
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:
#if defined(WIN32)
FILETIME FileTime;
- if (GetFileTime(FileHandle, NULL, &FileTime, NULL))
+ if (GetFileTime(FileHandle, NULL, NULL, &FileTime))
FileTimeToDosDateTime(&FileTime,
&File->File.FileDate,
&File->File.FileTime);
// 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
}
-unsigned long CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
+ULONG CCabinet::GetAttributesOnFile(PCFFILE_NODE File)
/*
* FUNCTION: Returns attributes on a file
* ARGUMENTS:
*/
{
#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;
}
-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