#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#if defined(__FreeBSD__) || defined(__APPLE__)
+#if !defined(WIN32)
+# include <dirent.h>
# include <sys/stat.h>
-#endif // __FreeBSD__
+# include <sys/types.h>
+#endif
#include "cabinet.h"
#include "raw.h"
#include "mszip.h"
#ifndef CAB_READ_ONLY
#if 0
-#ifdef DBG
+#if DBG
void DumpBuffer(void* Buffer, ULONG Size)
{
NULL); // No attribute template
if (FileHandle == INVALID_HANDLE_VALUE)
{
- DPRINT(MID_TRACE, ("ERROR OPENING '%lu'.\n", (ULONG)GetLastError()));
+ DPRINT(MID_TRACE, ("ERROR OPENING '%u'.\n", (UINT)GetLastError()));
return;
}
if (!WriteFile(FileHandle, Buffer, Size, &BytesWritten, NULL))
{
- DPRINT(MID_TRACE, ("ERROR WRITING '%lu'.\n", (ULONG)GetLastError()));
+ DPRINT(MID_TRACE, ("ERROR WRITING '%u'.\n", (UINT)GetLastError()));
}
CloseFile(FileHandle);
}
-ULONG CCFDATAStorage::Create(char* FileName)
+ULONG CCFDATAStorage::Create(const char* FileName)
/*
* FUNCTION: Creates the file
* ARGUMENTS:
NULL); // No attribute template
if (FileHandle == INVALID_HANDLE_VALUE)
{
- DPRINT(MID_TRACE, ("ERROR '%lu'.\n", (ULONG)GetLastError()));
+ DPRINT(MID_TRACE, ("ERROR '%u'.\n", (UINT)GetLastError()));
return CAB_STATUS_CANNOT_CREATE;
}
#else /* !WIN32 */
/*
FileHandle = fopen(FullName, "w+b");
if (FileHandle == NULL) {
- DPRINT(MID_TRACE, ("ERROR '%lu'.\n", (ULONG)errno));
+ DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
return CAB_STATUS_CANNOT_CREATE;
}
*/
*/
{
#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;
FileHandle = tmpfile();
if (FileHandle == NULL)
{
- DPRINT(MID_TRACE, ("ERROR '%lu'.\n", (ULONG)errno));
+ DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
return CAB_STATUS_FAILURE;
}
#endif
*/
{
#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;
CabinetReservedFileBuffer = NULL;
CabinetReservedFileSize = 0;
- FolderListHead = NULL;
- FolderListTail = NULL;
- FileListHead = NULL;
- FileListTail = NULL;
+ FolderListHead = NULL;
+ FolderListTail = NULL;
+ FileListHead = NULL;
+ FileListTail = NULL;
+ CriteriaListHead = NULL;
+ CriteriaListTail = NULL;
Codec = NULL;
CodecId = -1;
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
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
if ((Status = ReadBlock(&CABHeader, sizeof(CFHEADER), &BytesRead))
!= CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
if ((Status = ReadBlock(&Size, sizeof(ULONG), &BytesRead))
!= CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ 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)
+ if (SetFilePointer(FileHandle, CabinetReserved, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
return CAB_STATUS_FAILURE;
}
#else
if ((Status = ReadBlock(&FolderNode->Folder,
sizeof(CFFOLDER), &BytesRead)) != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
}
Status = ReadFileTable();
if (Status != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("ReadFileTable() failed (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("ReadFileTable() failed (%u).\n", (UINT)Status));
return Status;
}
Status = ReadDataBlocks(FolderNode);
if (Status != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%u).\n", (UINT)Status));
return Status;
}
FolderNode = FolderNode->Next;
}
-ULONG CCabinet::FindFirst(char* FileName,
- PCAB_SEARCH Search)
+ULONG CCabinet::FindFirst(PCAB_SEARCH Search)
/*
* FUNCTION: Finds the first file in the cabinet that matches a search criteria
* ARGUMENTS:
- * FileName = Pointer to search criteria
* Search = Pointer to search structure
* RETURNS:
* Status of operation
*/
{
RestartSearch = false;
- strncpy(Search->Search, FileName, MAX_PATH);
Search->Next = FileListHead;
return FindNext(Search);
}
* Status of operation
*/
{
+ bool bFound = false;
+ PSEARCH_CRITERIA Criteria;
ULONG Status;
if (RestartSearch)
(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));
+ DPRINT(MAX_TRACE, ("Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n",
+ Search->Next->FileName, (UINT)Search->Next->File.FileOffset, (UINT)LastFileOffset));
Search->Next = Search->Next->Next;
}
RestartSearch = false;
}
- /* FIXME: Check search criteria */
+ /* Check each search criteria against each file */
+ while(Search->Next)
+ {
+ // Some features (like displaying cabinets) don't require search criteria, so we can just break here.
+ // If a feature requires it, handle this in the ParseCmdline() function in "main.cxx".
+ if(!CriteriaListHead)
+ break;
+
+ Criteria = CriteriaListHead;
+
+ while(Criteria)
+ {
+ if(MatchFileNamePattern(Search->Next->FileName, Criteria->Search))
+ {
+ bFound = true;
+ break;
+ }
+
+ Criteria = Criteria->Next;
+ }
+
+ if(bFound)
+ break;
+
+ Search->Next = Search->Next->Next;
+ }
if (!Search->Next)
{
ULONG BytesToWrite;
ULONG TotalBytesRead;
ULONG CurrentOffset;
- unsigned char* Buffer;
- unsigned char* CurrentBuffer;
+ PUCHAR Buffer;
+ PUCHAR CurrentBuffer;
FILEHANDLE DestFile;
PCFFILE_NODE File;
CFDATA CFData;
#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 (%lu).\n", (ULONG)Status));
+ DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
return Status;
}
return CAB_STATUS_UNSUPPCOMP;
}
- DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%lX) Size (%lu bytes) AO (0x%lX) UO (0x%lX).\n",
- (ULONG)File->File.FileOffset,
- (ULONG)File->File.FileSize,
- (ULONG)File->DataBlock->AbsoluteOffset,
- (ULONG)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);
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
+ Buffer = (PUCHAR)AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
if (!Buffer)
{
CloseFile(DestFile);
File->DataBlock->AbsoluteOffset,
NULL,
FILE_BEGIN);
- if (GetLastError() != NO_ERROR)
+ if (Offset == INVALID_SET_FILE_POINTER)
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
return CAB_STATUS_INVALID_CAB;
}
#else
{
do
{
- DPRINT(MAX_TRACE, ("CO (0x%lX) ReuseBlock (%lu) Offset (0x%lX) Size (%ld) BytesLeftInBlock (%ld)\n",
- File->DataBlock->UncompOffset, (ULONG)ReuseBlock, Offset, Size,
- BytesLeftInBlock));
+ 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 (%lu)\n", (ULONG)ReuseBlock));
+ DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
CurrentBuffer = Buffer;
TotalBytesRead = 0;
do
{
- DPRINT(MAX_TRACE, ("Size (%lu bytes).\n", Size));
+ DPRINT(MAX_TRACE, ("Size (%u bytes).\n", (UINT)Size));
if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
{
CloseFile(DestFile);
FreeMemory(Buffer);
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
- DPRINT(MAX_TRACE, ("Data block: Checksum (0x%lX) CompSize (%lu bytes) UncompSize (%lu bytes)\n",
- (ULONG)CFData.Checksum,
- (ULONG)CFData.CompSize,
- (ULONG)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",
- (_W64 unsigned long)CurrentBuffer, (_W64 unsigned long)Buffer));
+ (unsigned long)CurrentBuffer, (unsigned long)Buffer));
if (((Status = ReadBlock(CurrentBuffer, BytesToRead, &BytesRead)) !=
CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead))
{
CloseFile(DestFile);
FreeMemory(Buffer);
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
Status = LocateFile(TempName, &File);
if (Status == CAB_STATUS_NOFILE)
{
- DPRINT(MID_TRACE, ("Cannot locate file (%lu).\n", (ULONG)Status));
+ DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
return Status;
}
/* Search to start of file */
#if defined(WIN32)
- SetFilePointer(FileHandle,
- File->DataBlock->AbsoluteOffset,
- NULL,
- FILE_BEGIN);
- if (GetLastError() != NO_ERROR)
+ if( SetFilePointer(FileHandle,
+ File->DataBlock->AbsoluteOffset,
+ NULL,
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER )
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
return CAB_STATUS_INVALID_CAB;
}
#else
}
#endif
- DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%lX) Size (%lu bytes) AO (0x%lX) UO (0x%lX).\n",
- (ULONG)File->File.FileOffset,
- (ULONG)File->File.FileSize,
- (ULONG)File->DataBlock->AbsoluteOffset,
- (ULONG)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 (BytesToWrite != CFData.UncompSize)
{
- DPRINT(MID_TRACE, ("BytesToWrite (%lu) != CFData.UncompSize (%d)\n",
- BytesToWrite, CFData.UncompSize));
+ DPRINT(MID_TRACE, ("BytesToWrite (%u) != CFData.UncompSize (%d)\n",
+ (UINT)BytesToWrite, CFData.UncompSize));
return CAB_STATUS_INVALID_CAB;
}
}
else
{
- DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%lu)\n", (ULONG)ReuseBlock));
+ 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 (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
/* Go to next data block */
#if defined(WIN32)
- SetFilePointer(FileHandle,
- CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
- CurrentDataNode->Data.CompSize,
- NULL,
- FILE_BEGIN);
- if (GetLastError() != NO_ERROR)
+ if( SetFilePointer(FileHandle,
+ CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) +
+ CurrentDataNode->Data.CompSize,
+ NULL,
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER )
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
return CAB_STATUS_INVALID_CAB;
}
#else
if (Size < BytesToWrite)
BytesToWrite = Size;
- DPRINT(MAX_TRACE, ("Offset (0x%lX) CurrentOffset (0x%lX) ToWrite (%lu) Skipped (%lu)(%lu) Size (%lu).\n",
- (ULONG)Offset,
- (ULONG)CurrentOffset,
- (ULONG)BytesToWrite,
- (ULONG)BytesSkipped, (ULONG)Skip,
- (ULONG)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),
+ if (!WriteFile(DestFile, (void*)((PUCHAR)OutputBuffer + BytesSkipped),
BytesToWrite, (LPDWORD)&BytesWritten, NULL) ||
(BytesToWrite != BytesWritten))
{
- DPRINT(MIN_TRACE, ("Status 0x%lX.\n", GetLastError()));
+ DPRINT(MIN_TRACE, ("Status 0x%X.\n", (UINT)GetLastError()));
#else
BytesWritten = BytesToWrite;
- if (fwrite((void*)((unsigned long *)OutputBuffer + BytesSkipped),
+ if (fwrite((void*)((PUCHAR)OutputBuffer + BytesSkipped),
BytesToWrite, 1, DestFile) < 1)
{
#endif
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));
+ DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%u) BytesRead (%u) CurrentIBufferSize (%u).\n",
+ (UINT)BytesToRead, (UINT)BytesRead, (UINT)CurrentIBufferSize));
return CAB_STATUS_INVALID_CAB;
}
- *(unsigned char**)&CurrentIBuffer += BytesRead;
-
+ CurrentIBuffer = (unsigned char*)CurrentIBuffer + BytesRead;
CurrentIBufferSize += (USHORT)BytesRead;
if (CurrentIBufferSize == CAB_BLOCKSIZE)
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))
{
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;
+ }
+
+ 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)
/*
{
PCFDATA_NODE Node;
- DPRINT(MAX_TRACE, ("FileName '%s' FileOffset (0x%lX) FileSize (%lu).\n",
+ DPRINT(MAX_TRACE, ("FileName '%s' FileOffset (0x%X) FileSize (%u).\n",
File->FileName,
- (ULONG)File->File.FileOffset,
- (ULONG)File->File.FileSize));
+ (UINT)File->File.FileOffset,
+ (UINT)File->File.FileSize));
Node = CurrentFolderNode->DataListHead;
while (Node != NULL)
{
- DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%lX, 0x%lX) (%lu).\n",
- (ULONG)Node->UncompOffset,
- (ULONG)Node->UncompOffset + Node->Data.UncompSize,
- (ULONG)Node->Data.UncompSize));
+ 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) */
ULONG CCabinet::LocateFile(char* FileName,
- PCFFILE_NODE *File)
+ PCFFILE_NODE *File)
/*
* FUNCTION: Locates a file in the cabinet
* ARGUMENTS:
CurrentFolderNode = LocateFolderNode(Node->File.FileControlID);
if (!CurrentFolderNode)
{
- DPRINT(MID_TRACE, ("Folder with index number (%lu) not found.\n",
- (ULONG)Node->File.FileControlID));
+ DPRINT(MID_TRACE, ("Folder with index number (%u) not found.\n",
+ Node->File.FileControlID));
return CAB_STATUS_INVALID_CAB;
}
}
-ULONG CCabinet::ReadString(char* String, ULONG MaxLength)
+ULONG CCabinet::ReadString(char* String, LONG MaxLength)
/*
* FUNCTION: Reads a NULL-terminated string from the cabinet
* ARGUMENTS:
*/
{
ULONG BytesRead;
- ULONG Offset;
ULONG Status;
- ULONG Size;
+ 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 (%lu).\n", (ULONG)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++)
+ // Find the terminating NULL character
+ for (Size = 0; Size < MaxLength; Size++)
+ {
+ if (String[Size] == '\0')
{
- if (String[Size] == '\0')
- {
- Found = true;
- break;
- }
+ 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);
- (ULONG)SetFilePointer(FileHandle,
- -(LONG)Size,
- NULL,
- FILE_CURRENT);
- if (GetLastError() != NO_ERROR)
+ if( SetFilePointer(FileHandle,
+ (LONG)Size,
+ NULL,
+ FILE_CURRENT) == INVALID_SET_FILE_POINTER )
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ 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;
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);
- SetFilePointer(FileHandle,
- CABHeader.FileTableOffset,
- NULL,
- FILE_BEGIN);
- if (GetLastError() != NO_ERROR)
+ if( SetFilePointer(FileHandle,
+ CABHeader.FileTableOffset,
+ NULL,
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER )
{
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
- DPRINT(MIN_TRACE, ("Error: %lu\n", GetLastError()));
+ DPRINT(MIN_TRACE, ("SetFilePointer() failed, error code is %u.\n", (UINT)GetLastError()));
return CAB_STATUS_INVALID_CAB;
}
#else
if ((Status = ReadBlock(&File->File, sizeof(CFFILE),
&BytesRead)) != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
if (Status != CAB_STATUS_SUCCESS)
return Status;
- DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%lX). Size (%lu bytes) ControlId (0x%lX).\n",
+ DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X). Size (%u bytes) ControlId (0x%X).\n",
File->FileName,
- (ULONG)File->File.FileOffset,
- (ULONG)File->File.FileSize,
- (ULONG)File->File.FileControlID));
+ (UINT)File->File.FileOffset,
+ (UINT)File->File.FileSize,
+ File->File.FileControlID));
}
return CAB_STATUS_SUCCESS;
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;
/* Seek to data block */
#if defined(WIN32)
- SetLastError(NO_ERROR);
- SetFilePointer(FileHandle,
- AbsoluteOffset,
- NULL,
- FILE_BEGIN);
- if (GetLastError() != NO_ERROR)
- {
- DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n"));
+ 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 ((Status = ReadBlock(&Node->Data, sizeof(CFDATA),
&BytesRead)) != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
return CAB_STATUS_INVALID_CAB;
}
- DPRINT(MAX_TRACE, ("AbsOffset (0x%lX) UncompOffset (0x%lX) Checksum (0x%lX) CompSize (%lu) UncompSize (%lu).\n",
- (ULONG)AbsoluteOffset,
- (ULONG)UncompOffset,
- (ULONG)Node->Data.Checksum,
- (ULONG)Node->Data.CompSize,
- (ULONG)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;
void CCabinet::DestroyFileNodes()
/*
* FUNCTION: Destroys file nodes
- * ARGUMENTS:
- * FolderNode = Pointer to folder node
*/
{
PCFFILE_NODE PrevNode;
ULONG CCabinet::ComputeChecksum(void* Buffer,
- ULONG Size,
- ULONG Seed)
+ ULONG Size,
+ ULONG Seed)
/*
* FUNCTION: Computes checksum for data block
* ARGUMENTS:
/* FIXME: Doesn't seem to be correct. EXTRACT.EXE
won't accept checksums computed by this routine */
- DPRINT(MIN_TRACE, ("Checksumming buffer (0x%p) Size (%lu)\n", 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
ULONG CCabinet::ReadBlock(void* Buffer,
- ULONG Size,
- PULONG BytesRead)
+ ULONG Size,
+ PULONG BytesRead)
/*
* FUNCTION: Read a block of data from file
* ARGUMENTS:
return CAB_STATUS_SUCCESS;
}
+bool CCabinet::MatchFileNamePattern(char* FileName, char* Pattern)
+/*
+ * FUNCTION: Matches a wildcard character pattern against a file
+ * ARGUMENTS:
+ * FileName = The file name to check
+ * Pattern = The pattern
+ * RETURNS:
+ * Whether the pattern matches the file
+ *
+ * COPYRIGHT:
+ * This function is based on Busybox code, Copyright (C) 1998 by Erik Andersen, released under GPL2 or any later version.
+ * Adapted from code written by Ingo Wilken.
+ * Original location: http://www.busybox.net/cgi-bin/viewcvs.cgi/trunk/busybox/utility.c?rev=5&view=markup
+ */
+{
+ char* retryPattern = NULL;
+ char* retryFileName = NULL;
+ char ch;
+
+ while (*FileName || *Pattern)
+ {
+ ch = *Pattern++;
+
+ switch (ch)
+ {
+ case '*':
+ retryPattern = Pattern;
+ retryFileName = FileName;
+ break;
+
+ case '?':
+ if (*FileName++ == '\0')
+ return false;
+
+ break;
+
+ default:
+ if (*FileName == ch)
+ {
+ if (*FileName)
+ FileName++;
+ break;
+ }
+
+ if (*FileName)
+ {
+ Pattern = retryPattern;
+ FileName = ++retryFileName;
+ break;
+ }
+
+ return false;
+ }
+
+ if (!Pattern)
+ return false;
+ }
+
+ return true;
+}
+
#ifndef CAB_READ_ONLY
ULONG CCabinet::InitCabinetHeader()
{
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));
+ 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,
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,
while (DataNode != NULL)
{
- DPRINT(MAX_TRACE, ("Reading block at (0x%lX) CompSize (%d) UncompSize (%d).\n",
- DataNode->ScratchFilePosition,
+ DPRINT(MAX_TRACE, ("Reading block at (0x%X) CompSize (%u) UncompSize (%u).\n",
+ (UINT)DataNode->ScratchFilePosition,
DataNode->Data.CompSize,
DataNode->Data.UncompSize));
Status = ScratchFile->ReadBlock(&DataNode->Data, InputBuffer, &BytesRead);
if (Status != CAB_STATUS_SUCCESS)
{
- DPRINT(MIN_TRACE, ("Cannot read from scratch file (%lu).\n", (ULONG)Status));
+ DPRINT(MIN_TRACE, ("Cannot read from scratch file (%u).\n", (UINT)Status));
return Status;
}
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;
// 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%lX) CompSize (%lu) UncompSize (%lu).\n",
- (ULONG)DataNode->Data.Checksum,
- (ULONG)DataNode->Data.CompSize,
- (ULONG)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;
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 (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];
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);
}
}
-ULONG 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)
- ULONG 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