ReactOS 0.4.15-dev-7704-gc07eb9f
CCabinet Class Reference

#include <cabinet.h>

Inheritance diagram for CCabinet:
Collaboration diagram for CCabinet:

Public Member Functions

 CCabinet ()
 
virtual ~CCabinet ()
 
bool IsSeparator (char Char)
 
void ConvertPath (std::string &Path)
 
std::string GetFileName (const std::string &Path)
 
void NormalizePath (std::string &Path)
 
charGetCabinetName ()
 
void SetCabinetName (const char *FileName)
 
void SetDestinationPath (const char *DestinationPath)
 
bool SetCabinetReservedFile (const char *FileName)
 
const charGetDestinationPath ()
 
ULONG GetCurrentDiskNumber ()
 
ULONG Open ()
 
void Close ()
 
ULONG FindFirst (PCAB_SEARCH Search)
 
ULONG FindNext (PCAB_SEARCH Search)
 
ULONG ExtractFile (const char *FileName)
 
void SelectCodec (LONG Id)
 
bool IsCodecSelected ()
 
ULONG AddSearchCriteria (const std::string &SearchCriteria, const std::string &TargetFolder)
 
void DestroySearchCriteria ()
 
bool HasSearchCriteria ()
 
std::string CreateCabFilename (PCFFILE_NODE Node)
 
bool CreateSimpleCabinet ()
 
bool SetCompressionCodec (const char *CodecName)
 
ULONG NewCabinet ()
 
ULONG NewDisk ()
 
ULONG NewFolder ()
 
ULONG WriteFileToScratchStorage (PCFFILE_NODE FileNode)
 
ULONG WriteDisk (ULONG MoreDisks)
 
ULONG CommitDisk (ULONG MoreDisks)
 
ULONG CloseDisk ()
 
ULONG CloseCabinet ()
 
ULONG AddFile (const std::string &FileName, const std::string &TargetFolder)
 
void SetMaxDiskSize (ULONG Size)
 
virtual bool OnOverwrite (PCFFILE Entry, const char *FileName)
 
virtual void OnExtract (PCFFILE Entry, const char *FileName)
 
virtual void OnDiskChange (const char *CabinetName, const char *DiskLabel)
 
virtual void OnVerboseMessage (const char *Message)
 
virtual void OnAdd (PCFFILE Entry, const char *FileName)
 
virtual bool OnCabinetName (ULONG Number, char *Name)
 
virtual bool OnDiskLabel (ULONG Number, char *Label)
 

Private Member Functions

PCFFOLDER_NODE LocateFolderNode (ULONG Index)
 
ULONG GetAbsoluteOffset (PCFFILE_NODE File)
 
ULONG LocateFile (const char *FileName, PCFFILE_NODE *File)
 
ULONG ReadString (char *String, LONG MaxLength)
 
ULONG ReadFileTable ()
 
ULONG ReadDataBlocks (PCFFOLDER_NODE FolderNode)
 
PCFFOLDER_NODE NewFolderNode ()
 
PCFFILE_NODE NewFileNode ()
 
PCFDATA_NODE NewDataNode (PCFFOLDER_NODE FolderNode)
 
void DestroyDataNodes (PCFFOLDER_NODE FolderNode)
 
void DestroyFileNodes ()
 
void DestroyDeletedFileNodes ()
 
void DestroyFolderNodes ()
 
void DestroyDeletedFolderNodes ()
 
ULONG ComputeChecksum (void *Buffer, ULONG Size, ULONG Seed)
 
ULONG ReadBlock (void *Buffer, ULONG Size, PULONG BytesRead)
 
bool MatchFileNamePattern (const char *FileName, const char *Pattern)
 
ULONG InitCabinetHeader ()
 
ULONG WriteCabinetHeader (bool MoreDisks)
 
ULONG WriteFolderEntries ()
 
ULONG WriteFileEntries ()
 
ULONG CommitDataBlocks (PCFFOLDER_NODE FolderNode)
 
ULONG WriteDataBlock ()
 
ULONG GetAttributesOnFile (PCFFILE_NODE File)
 
ULONG SetAttributesOnFile (char *FileName, USHORT FileAttributes)
 
ULONG GetFileTimes (FILE *FileHandle, PCFFILE_NODE File)
 
void ConvertDateAndTime (time_t *Time, PUSHORT DosDate, PUSHORT DosTime)
 

Private Attributes

ULONG CurrentDiskNumber
 
char CabinetName [256]
 
char CabinetPrev [256]
 
char DiskPrev [256]
 
char CabinetNext [256]
 
char DiskNext [256]
 
ULONG TotalHeaderSize
 
ULONG NextFieldsSize
 
ULONG TotalFolderSize
 
ULONG TotalFileSize
 
ULONG FolderUncompSize
 
ULONG BytesLeftInBlock
 
bool ReuseBlock
 
std::string DestPath
 
std::string CabinetReservedFile
 
voidCabinetReservedFileBuffer
 
ULONG CabinetReservedFileSize
 
FILEFileHandle
 
bool FileOpen
 
CFHEADER CABHeader
 
ULONG CabinetReserved
 
ULONG FolderReserved
 
ULONG DataReserved
 
std::list< PCFFOLDER_NODEFolderList
 
PCFFOLDER_NODE CurrentFolderNode
 
PCFDATA_NODE CurrentDataNode
 
std::list< PCFFILE_NODEFileList
 
std::list< PSEARCH_CRITERIACriteriaList
 
CCABCodecCodec
 
LONG CodecId
 
bool CodecSelected
 
voidInputBuffer
 
voidCurrentIBuffer
 
ULONG CurrentIBufferSize
 
voidOutputBuffer
 
ULONG TotalCompSize
 
voidCurrentOBuffer
 
ULONG CurrentOBufferSize
 
ULONG BytesLeftInCabinet
 
bool RestartSearch
 
ULONG LastFileOffset
 
ULONG LastBlockStart
 
ULONG MaxDiskSize
 
ULONG DiskSize
 
ULONG PrevCabinetNumber
 
bool CreateNewDisk
 
bool CreateNewFolder
 
class CCFDATAStorageScratchFile
 
FILESourceFile
 
bool ContinueFile
 
ULONG TotalBytesLeft
 
bool BlockIsSplit
 
ULONG NextFolderNumber
 

Detailed Description

Definition at line 305 of file cabinet.h.

Constructor & Destructor Documentation

◆ CCabinet()

CCabinet::CCabinet ( )

Definition at line 71 of file cabinet.cxx.

75{
76 *CabinetName = '\0';
77 *CabinetPrev = '\0';
78 *DiskPrev = '\0';
79 *CabinetNext = '\0';
80 *DiskNext = '\0';
81
82 FileOpen = false;
85
86 Codec = NULL;
87 CodecId = -1;
88 CodecSelected = false;
89
92 MaxDiskSize = 0;
93 BlockIsSplit = false;
95
98 ReuseBlock = false;
100}
bool FileOpen
Definition: cabinet.h:450
ULONG FolderUncompSize
Definition: cabinet.h:442
ULONG BytesLeftInBlock
Definition: cabinet.h:443
char DiskNext[256]
Definition: cabinet.h:437
class CCFDATAStorage * ScratchFile
Definition: cabinet.h:481
PCFDATA_NODE CurrentDataNode
Definition: cabinet.h:457
bool ReuseBlock
Definition: cabinet.h:444
bool CodecSelected
Definition: cabinet.h:462
char DiskPrev[256]
Definition: cabinet.h:435
char CabinetPrev[256]
Definition: cabinet.h:434
bool BlockIsSplit
Definition: cabinet.h:485
ULONG MaxDiskSize
Definition: cabinet.h:475
void * CabinetReservedFileBuffer
Definition: cabinet.h:447
ULONG CabinetReservedFileSize
Definition: cabinet.h:448
LONG CodecId
Definition: cabinet.h:461
char CabinetName[256]
Definition: cabinet.h:433
CCABCodec * Codec
Definition: cabinet.h:460
char CabinetNext[256]
Definition: cabinet.h:436
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

◆ ~CCabinet()

CCabinet::~CCabinet ( )
virtual

Definition at line 103 of file cabinet.cxx.

107{
109 {
113 }
114
115 if (CodecSelected)
116 delete Codec;
117}
#define free
Definition: debug_ros.c:5

Member Function Documentation

◆ AddFile()

ULONG CCabinet::AddFile ( const std::string &  FileName,
const std::string &  TargetFolder 
)

Definition at line 1515 of file cabinet.cxx.

1523{
1524 FILE* SrcFile;
1525 PCFFILE_NODE FileNode;
1526 std::string NewFileName;
1527
1528 NewFileName = FileName;
1529 ConvertPath(NewFileName);
1530
1531 /* Try to open file */
1532 SrcFile = fopen(NewFileName.c_str(), "rb");
1533 if (SrcFile == NULL)
1534 {
1535 DPRINT(MID_TRACE, ("File not found (%s).\n", NewFileName.c_str()));
1537 }
1538
1539 FileNode = NewFileNode();
1540 if (!FileNode)
1541 {
1542 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1543 fclose(SrcFile);
1544 return CAB_STATUS_NOMEMORY;
1545 }
1546
1547 FileNode->FolderNode = CurrentFolderNode;
1548 FileNode->FileName = NewFileName;
1549 FileNode->TargetFolder = TargetFolder;
1550 if (FileNode->TargetFolder.length() > 0 && FileNode->TargetFolder[FileNode->TargetFolder.length() - 1] != '\\')
1551 FileNode->TargetFolder += '\\';
1552
1553 /* FIXME: Check for and handle large files (>= 2GB) */
1554 FileNode->File.FileSize = GetSizeOfFile(SrcFile);
1555 if (FileNode->File.FileSize == (ULONG)-1)
1556 {
1557 DPRINT(MIN_TRACE, ("Cannot read from file.\n"));
1558 fclose(SrcFile);
1560 }
1561
1562 if (GetFileTimes(SrcFile, FileNode) != CAB_STATUS_SUCCESS)
1563 {
1564 DPRINT(MIN_TRACE, ("Cannot read file times.\n"));
1565 fclose(SrcFile);
1567 }
1568
1569 if (GetAttributesOnFile(FileNode) != CAB_STATUS_SUCCESS)
1570 {
1571 DPRINT(MIN_TRACE, ("Cannot read file attributes.\n"));
1572 fclose(SrcFile);
1574 }
1575
1576 fclose(SrcFile);
1577
1578 return CAB_STATUS_SUCCESS;
1579}
ULONG GetAttributesOnFile(PCFFILE_NODE File)
Definition: cabinet.cxx:2914
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:456
PCFFILE_NODE NewFileNode()
Definition: cabinet.cxx:2126
ULONG GetFileTimes(FILE *FileHandle, PCFFILE_NODE File)
Definition: cabinet.cxx:2872
void ConvertPath(std::string &Path)
Definition: cabinet.cxx:134
struct _FileName FileName
Definition: fatprocs.h:896
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:257
#define MIN_TRACE
Definition: cabinet.h:67
#define MID_TRACE
Definition: cabinet.h:68
#define CAB_STATUS_CANNOT_READ
Definition: cabinet.h:259
#define DPRINT(_t_, _x_)
Definition: cabinet.h:98
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:256
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:254
LONG GetSizeOfFile(FILE *handle)
Definition: cabinet.h:50
std::string TargetFolder
Definition: cabinet.h:230
std::string FileName
Definition: cabinet.h:229
CFFILE File
Definition: cabinet.h:228
PCFFOLDER_NODE FolderNode
Definition: cabinet.h:234
ULONG FileSize
Definition: cabinet.c:118
uint32_t ULONG
Definition: typedefs.h:59

Referenced by CreateSimpleCabinet(), and CDFParser::PerformFileCopy().

◆ AddSearchCriteria()

ULONG CCabinet::AddSearchCriteria ( const std::string &  SearchCriteria,
const std::string &  TargetFolder 
)

Definition at line 228 of file cabinet.cxx.

236{
237 PSEARCH_CRITERIA Criteria;
238
239 // Add the criteria to the list of search criteria
240 Criteria = new SEARCH_CRITERIA;
241 if(!Criteria)
242 {
243 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
244 return CAB_STATUS_NOMEMORY;
245 }
246
247 CriteriaList.push_back(Criteria);
248
249 // Set the actual criteria string
250 Criteria->Search = SearchCriteria;
251 Criteria->TargetFolder = TargetFolder;
252
253 return CAB_STATUS_SUCCESS;
254}
std::list< PSEARCH_CRITERIA > CriteriaList
Definition: cabinet.h:459
struct _SEARCH_CRITERIA SEARCH_CRITERIA
std::string TargetFolder
Definition: cabinet.h:240
std::string Search
Definition: cabinet.h:239

Referenced by CCABManager::ParseCmdline().

◆ Close()

void CCabinet::Close ( )

Definition at line 538 of file cabinet.cxx.

542{
543 if (FileOpen)
544 {
546 FileOpen = false;
547 }
548}
FILE * FileHandle
Definition: cabinet.h:449

Referenced by CloseCabinet().

◆ CloseCabinet()

ULONG CCabinet::CloseCabinet ( )

Definition at line 1477 of file cabinet.cxx.

1483{
1484 ULONG Status;
1485
1487
1489
1490 if (InputBuffer)
1491 {
1493 InputBuffer = NULL;
1494 }
1495
1496 if (OutputBuffer)
1497 {
1500 }
1501
1502 Close();
1503
1504 if (ScratchFile)
1505 {
1507 delete ScratchFile;
1508 return Status;
1509 }
1510
1511 return CAB_STATUS_SUCCESS;
1512}
void Close()
Definition: cabinet.cxx:538
void DestroyFileNodes()
Definition: cabinet.cxx:2183
void DestroyFolderNodes()
Definition: cabinet.cxx:2223
Status
Definition: gdiplustypes.h:25

Referenced by CreateSimpleCabinet(), ExtractFile(), FindNext(), Open(), and CDFParser::Parse().

◆ CloseDisk()

ULONG CCabinet::CloseDisk ( )

Definition at line 1459 of file cabinet.cxx.

1465{
1467
1468 /* Destroy folder nodes that are completely stored */
1470
1472
1473 return CAB_STATUS_SUCCESS;
1474}
void DestroyDeletedFileNodes()
Definition: cabinet.cxx:2196
ULONG CurrentDiskNumber
Definition: cabinet.h:432
void DestroyDeletedFolderNodes()
Definition: cabinet.cxx:2237

Referenced by CreateSimpleCabinet(), CDFParser::Parse(), CDFParser::PerformNewCommand(), and WriteDisk().

◆ CommitDataBlocks()

ULONG CCabinet::CommitDataBlocks ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2703 of file cabinet.cxx.

2711{
2713 ULONG Status;
2714
2715 if (!FolderNode->DataList.empty())
2716 Status = ScratchFile->Seek(FolderNode->DataList.front()->ScratchFilePosition);
2717
2718 for (PCFDATA_NODE DataNode : FolderNode->DataList)
2719 {
2720 DPRINT(MAX_TRACE, ("Reading block at (0x%X) CompSize (%u) UncompSize (%u).\n",
2721 (UINT)DataNode->ScratchFilePosition,
2722 DataNode->Data.CompSize,
2723 DataNode->Data.UncompSize));
2724
2725 /* InputBuffer is free for us to use here, so we use it and avoid a
2726 memory allocation. OutputBuffer can't be used here because it may
2727 still contain valid data (if a data block spans two or more disks) */
2730 {
2731 DPRINT(MIN_TRACE, ("Cannot read from scratch file (%u).\n", (UINT)Status));
2732 return Status;
2733 }
2734
2735 if (fwrite(&DataNode->Data, sizeof(CFDATA), 1, FileHandle) < 1)
2736 {
2737 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2739 }
2740
2741 if (fwrite(InputBuffer, DataNode->Data.CompSize, 1, FileHandle) < 1)
2742 {
2743 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2745 }
2746 }
2747 return CAB_STATUS_SUCCESS;
2748}
ULONG ReadBlock(PCFDATA Data, void *Buffer, PULONG BytesRead)
ULONG Seek(LONG Position)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
unsigned int UINT
Definition: ndis.h:50
#define MAX_TRACE
Definition: cabinet.h:69
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:260
Definition: fci.c:101
ULONG ScratchFilePosition
Definition: cabinet.h:208
CFDATA Data
Definition: cabinet.h:211
USHORT CompSize
Definition: cabinet.c:131
USHORT UncompSize
Definition: cabinet.c:132
std::list< PCFDATA_NODE > DataList
Definition: cabinet.h:219
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870

Referenced by CommitDisk().

◆ CommitDisk()

ULONG CCabinet::CommitDisk ( ULONG  MoreDisks)

Definition at line 1393 of file cabinet.cxx.

1401{
1402 ULONG Status;
1403
1405
1406 /* Create file, fail if it already exists */
1407 FileHandle = fopen(CabinetName, "rb");
1408 if (FileHandle != NULL)
1409 {
1411 /* If file exists, ask to overwrite file */
1413 {
1414 FileHandle = fopen(CabinetName, "w+b");
1415 if (FileHandle == NULL)
1417 }
1418 else
1420
1421 }
1422 else
1423 {
1424 FileHandle = fopen(CabinetName, "w+b");
1425 if (FileHandle == NULL)
1427 }
1428
1429 WriteCabinetHeader(MoreDisks != 0);
1430
1433 return Status;
1434
1435 /* Write file entries */
1437
1438 /* Write data blocks */
1439 for (PCFFOLDER_NODE FolderNode : FolderList)
1440 {
1441 if (FolderNode->Commit)
1442 {
1443 Status = CommitDataBlocks(FolderNode);
1445 return Status;
1446 /* Remove data blocks for folder */
1447 DestroyDataNodes(FolderNode);
1448 }
1449 }
1450
1452
1454
1455 return CAB_STATUS_SUCCESS;
1456}
ULONG WriteFileEntries()
Definition: cabinet.cxx:2646
ULONG CommitDataBlocks(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2703
virtual bool OnOverwrite(PCFFILE Entry, const char *FileName)
Definition: cabinet.cxx:1735
void DestroyDataNodes(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2168
ULONG WriteCabinetHeader(bool MoreDisks)
Definition: cabinet.cxx:2484
virtual bool OnCabinetName(ULONG Number, char *Name)
Definition: cabinet.cxx:1806
ULONG WriteFolderEntries()
Definition: cabinet.cxx:2618
#define CAB_STATUS_FILE_EXISTS
Definition: cabinet.h:261
#define CAB_STATUS_CANNOT_CREATE
Definition: cabinet.h:258

Referenced by WriteDisk().

◆ ComputeChecksum()

ULONG CCabinet::ComputeChecksum ( void Buffer,
ULONG  Size,
ULONG  Seed 
)
private

Definition at line 2263 of file cabinet.cxx.

2275{
2276 int UlongCount; // Number of ULONGs in block
2277 ULONG Checksum; // Checksum accumulator
2278 unsigned char* pb;
2279 ULONG ul;
2280
2281 /* FIXME: Doesn't seem to be correct. EXTRACT.EXE
2282 won't accept checksums computed by this routine */
2283
2284 DPRINT(MIN_TRACE, ("Checksumming buffer (0x%p) Size (%u)\n", Buffer, (UINT)Size));
2285
2286 UlongCount = Size / 4; // Number of ULONGs
2287 Checksum = Seed; // Init checksum
2288 pb = (unsigned char*)Buffer; // Start at front of data block
2289
2290 /* Checksum integral multiple of ULONGs */
2291 while (UlongCount-- > 0)
2292 {
2293 /* NOTE: Build ULONG in big/little-endian independent manner */
2294 ul = *pb++; // Get low-order byte
2295 ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte
2296 ul |= (((ULONG)(*pb++)) << 16); // Add 3nd byte
2297 ul |= (((ULONG)(*pb++)) << 24); // Add 4th byte
2298
2299 Checksum ^= ul; // Update checksum
2300 }
2301
2302 /* Checksum remainder bytes */
2303 ul = 0;
2304 switch (Size % 4)
2305 {
2306 case 3:
2307 ul |= (((ULONG)(*pb++)) << 16); // Add 3rd byte
2308 case 2:
2309 ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte
2310 case 1:
2311 ul |= *pb++; // Get low-order byte
2312 default:
2313 break;
2314 }
2315 Checksum ^= ul; // Update checksum
2316
2317 /* Return computed checksum */
2318 return Checksum;
2319}
Definition: bufpool.h:45
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ ConvertDateAndTime()

void CCabinet::ConvertDateAndTime ( time_t Time,
PUSHORT  DosDate,
PUSHORT  DosTime 
)
private

Definition at line 2840 of file cabinet.cxx.

2851{
2852 struct tm *timedef;
2853
2854 timedef = localtime(Time);
2855
2856 DPRINT(MAX_TRACE, ("day: %d, mon: %d, year:%d, hour: %d, min: %d, sec: %d\n",
2857 timedef->tm_mday, timedef->tm_mon, timedef->tm_year,
2858 timedef->tm_sec, timedef->tm_min, timedef->tm_hour));
2859
2860 *DosDate = ((timedef->tm_mday + 1) << 0)
2861 | ((timedef->tm_mon + 1) << 5)
2862 | (((timedef->tm_year + 1900) - 1980) << 9);
2863
2864 *DosTime = (timedef->tm_sec << 0)
2865 | (timedef->tm_min << 5)
2866 | (timedef->tm_hour << 11);
2867}
static PLARGE_INTEGER Time
Definition: time.c:105
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
Definition: time.h:68
int tm_mon
Definition: time.h:73
int tm_year
Definition: time.h:74
int tm_hour
Definition: time.h:71
int tm_sec
Definition: time.h:69
int tm_mday
Definition: time.h:72
int tm_min
Definition: time.h:70

Referenced by GetFileTimes().

◆ ConvertPath()

void CCabinet::ConvertPath ( std::string &  Path)

Definition at line 134 of file cabinet.cxx.

144{
145 for (size_t i = 0; i < Path.size(); ++i)
146 {
147#if defined(_WIN32)
148 if (Path[i] == '/')
149 Path[i] = '\\';
150#else
151 if (Path[i] == '\\')
152 Path[i] = '/';
153#endif
154 }
155}
PRTL_UNICODE_STRING_BUFFER Path
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by AddFile(), CreateSimpleCabinet(), SetCabinetReservedFile(), SetDestinationPath(), and CDFParser::SetFileRelativePath().

◆ CreateCabFilename()

std::string CCabinet::CreateCabFilename ( PCFFILE_NODE  Node)

Definition at line 278 of file cabinet.cxx.

279{
280 std::string fname = GetFileName(Node->FileName);
281 if (!Node->TargetFolder.empty())
282 {
283 fname = Node->TargetFolder + fname;
284 }
285 return fname;
286}
std::string GetFileName(const std::string &Path)
Definition: cabinet.cxx:158
Definition: dlist.c:348

Referenced by DestroyDeletedFileNodes(), WriteFileEntries(), and WriteFileToScratchStorage().

◆ CreateSimpleCabinet()

bool CCabinet::CreateSimpleCabinet ( )

Definition at line 1581 of file cabinet.cxx.

1585{
1586 bool bRet = false;
1587 ULONG Status;
1588
1589#if defined(_WIN32)
1590 HANDLE hFind;
1591 WIN32_FIND_DATA FindFileData;
1592#else
1593 DIR* dirp;
1594 struct dirent* dp;
1595 struct stat stbuf;
1596#endif
1597
1598 // Initialize a new cabinet
1599 Status = NewCabinet();
1601 {
1602 DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
1603 goto cleanup2;
1604 }
1605
1606 // Add each file in the criteria list
1607 for (PSEARCH_CRITERIA Criteria : CriteriaList)
1608 {
1609 // Store the file path with a trailing slash in szFilePath
1610 std::string szSearchPath = Criteria->Search;
1611 ConvertPath(szSearchPath);
1612 auto sep = szSearchPath.find_last_of(DIR_SEPARATOR_CHAR);
1613 std::string szFilePath;
1614 std::string pszFile;
1615
1616 if (sep != std::string::npos)
1617 {
1618 pszFile = szSearchPath.substr(sep + 1); // We want the filename, not the dir separator!
1619
1620 szFilePath = szSearchPath.substr(0, sep + 1);
1621 }
1622 else
1623 {
1624 pszFile = Criteria->Search;
1625
1626#if !defined(_WIN32)
1627 // needed for opendir()
1628 szFilePath = "./";
1629#endif
1630 }
1631
1632#if defined(_WIN32)
1633 // Windows: Use the easy FindFirstFile/FindNextFile API for getting all files and checking them against the pattern
1634 hFind = FindFirstFile(Criteria->Search.c_str(), &FindFileData);
1635
1636 // Don't stop if a search criteria is not found
1638 {
1639 DPRINT(MIN_TRACE, ("FindFirstFile failed, Criteria: %s, error code is %u\n", Criteria->Search.c_str(), (UINT)GetLastError()));
1640 goto cleanup;
1641 }
1642
1643 do
1644 {
1645 if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
1646 {
1647 std::string szFile = szFilePath;
1648 szFile += FindFileData.cFileName;
1649
1650 Status = AddFile(szFile, Criteria->TargetFolder);
1651
1653 {
1654 DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
1655 FindClose(hFind);
1656 goto cleanup;
1657 }
1658 }
1659 }
1660 while(FindNextFile(hFind, &FindFileData));
1661
1662 FindClose(hFind);
1663#else
1664 // 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
1665 dirp = opendir(szFilePath.c_str());
1666
1667 if(dirp)
1668 {
1669 while( (dp = readdir(dirp)) )
1670 {
1671 std::string szFile = szFilePath;
1672 szFile += dp->d_name;
1673
1674 if(stat(szFile.c_str(), &stbuf) == 0)
1675 {
1676 if(stbuf.st_mode != S_IFDIR)
1677 {
1678 if(MatchFileNamePattern(dp->d_name, pszFile.c_str()))
1679 {
1680 Status = AddFile(szFile, Criteria->TargetFolder);
1681
1683 {
1684 DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
1685 goto cleanup;
1686 }
1687 }
1688 }
1689 }
1690 else
1691 {
1692 DPRINT(MIN_TRACE, ("stat failed, error code is %i\n", errno));
1693 goto cleanup;
1694 }
1695 }
1696
1697 closedir(dirp);
1698 }
1699#endif
1700 }
1701
1702 Status = WriteDisk(false);
1704 Status = CloseDisk();
1706 {
1707 DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
1708 goto cleanup;
1709 }
1710
1711cleanup:
1712 CloseCabinet();
1713 bRet = true;
1714
1715cleanup2:
1717 return bRet;
1718}
#define S_IFDIR
Definition: acwin.h:115
#define stat
Definition: acwin.h:99
ULONG AddFile(const std::string &FileName, const std::string &TargetFolder)
Definition: cabinet.cxx:1515
void DestroySearchCriteria()
Definition: cabinet.cxx:256
ULONG NewCabinet()
Definition: cabinet.cxx:1057
bool MatchFileNamePattern(const char *FileName, const char *Pattern)
Definition: cabinet.cxx:2342
ULONG CloseDisk()
Definition: cabinet.cxx:1459
ULONG CloseCabinet()
Definition: cabinet.cxx:1477
ULONG WriteDisk(ULONG MoreDisks)
Definition: cabinet.cxx:1311
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
int __cdecl closedir(DIR *)
DIR *__cdecl opendir(const char *)
struct dirent *__cdecl readdir(DIR *)
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static WCHAR szFilePath[]
Definition: qotd.c:14
#define errno
Definition: errno.h:18
#define DIR_SEPARATOR_CHAR
Definition: cabinet.h:46
Definition: dirent.h:40
Definition: fatfs.h:198
char * d_name
Definition: dirent.h:29
Definition: stat.h:55
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FindNextFile
Definition: winbase.h:3723
#define FindFirstFile
Definition: winbase.h:3717

Referenced by CCABManager::Run().

◆ DestroyDataNodes()

void CCabinet::DestroyDataNodes ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2168 of file cabinet.cxx.

2174{
2175 for (PCFDATA_NODE Node : FolderNode->DataList)
2176 {
2177 delete Node;
2178 }
2179 FolderNode->DataList.clear();
2180}
union node Node
Definition: types.h:1255

Referenced by CommitDisk(), DestroyDeletedFolderNodes(), and DestroyFolderNodes().

◆ DestroyDeletedFileNodes()

void CCabinet::DestroyDeletedFileNodes ( )
private

Definition at line 2196 of file cabinet.cxx.

2200{
2201 for (auto it = FileList.begin(); it != FileList.end(); )
2202 {
2203 PCFFILE_NODE CurNode = *it;
2204
2205 if (CurNode->Delete)
2206 {
2207 it = FileList.erase(it);
2208
2209 DPRINT(MAX_TRACE, ("Deleting file node: '%s'\n", CurNode->FileName.c_str()));
2210
2211 TotalFileSize -= (sizeof(CFFILE) + (ULONG)CreateCabFilename(CurNode).length() + 1);
2212
2213 delete CurNode;
2214 }
2215 else
2216 {
2217 it++;
2218 }
2219 }
2220}
vector< FileInfo > FileList
Definition: DriveVolume.h:63
ULONG TotalFileSize
Definition: cabinet.h:441
std::string CreateCabFilename(PCFFILE_NODE Node)
Definition: cabinet.cxx:278
struct _CFFILE CFFILE
bool Delete
Definition: cabinet.h:233

Referenced by CloseDisk().

◆ DestroyDeletedFolderNodes()

void CCabinet::DestroyDeletedFolderNodes ( )
private

Definition at line 2237 of file cabinet.cxx.

2241{
2242 for (auto it = FolderList.begin(); it != FolderList.end();)
2243 {
2244 PCFFOLDER_NODE CurNode = *it;
2245
2246 if (CurNode->Delete)
2247 {
2248 it = FolderList.erase(it);
2249
2250 DestroyDataNodes(CurNode);
2251 delete CurNode;
2252
2253 TotalFolderSize -= sizeof(CFFOLDER);
2254 }
2255 else
2256 {
2257 it++;
2258 }
2259 }
2260}
ULONG TotalFolderSize
Definition: cabinet.h:440
struct _CFFOLDER CFFOLDER

Referenced by CloseDisk().

◆ DestroyFileNodes()

void CCabinet::DestroyFileNodes ( )
private

Definition at line 2183 of file cabinet.cxx.

2187{
2188 for (PCFFILE_NODE Node : FileList)
2189 {
2190 delete Node;
2191 }
2192 FileList.clear();
2193}

Referenced by CloseCabinet().

◆ DestroyFolderNodes()

void CCabinet::DestroyFolderNodes ( )
private

Definition at line 2223 of file cabinet.cxx.

2227{
2229 {
2231 delete Node;
2232 }
2233 FolderList.clear();
2234}

Referenced by CloseCabinet().

◆ DestroySearchCriteria()

void CCabinet::DestroySearchCriteria ( )

Definition at line 256 of file cabinet.cxx.

260{
261 for (PSEARCH_CRITERIA Criteria : CriteriaList)
262 {
263 delete Criteria;
264 }
265 CriteriaList.clear();
266}

Referenced by CreateSimpleCabinet(), CCABManager::DisplayCabinet(), and CCABManager::ExtractFromCabinet().

◆ ExtractFile()

ULONG CCabinet::ExtractFile ( const char FileName)

Definition at line 648 of file cabinet.cxx.

656{
657 ULONG Size;
660 ULONG BytesToRead;
662 ULONG BytesSkipped;
663 ULONG BytesToWrite;
664 ULONG TotalBytesRead;
665 ULONG CurrentOffset;
668 FILE* DestFile;
670 CFDATA CFData;
672 bool Skip;
673#if defined(_WIN32)
674 FILETIME FileTime;
675#endif
676 CHAR DestName[PATH_MAX];
677 CHAR TempName[PATH_MAX];
678
681 {
682 DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
683 return Status;
684 }
685
686 LastFileOffset = File->File.FileOffset;
687
689 {
690 case CAB_COMP_NONE:
692 break;
693
694 case CAB_COMP_MSZIP:
696 break;
697
698 default:
700 }
701
702 DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
703 (UINT)File->File.FileOffset,
704 (UINT)File->File.FileSize,
705 (UINT)File->DataBlock->AbsoluteOffset,
706 (UINT)File->DataBlock->UncompOffset));
707
708 strcpy(DestName, DestPath.c_str());
709 strcat(DestName, FileName);
710
711 /* Create destination file, fail if it already exists */
712 DestFile = fopen(DestName, "rb");
713 if (DestFile != NULL)
714 {
715 fclose(DestFile);
716 /* If file exists, ask to overwrite file */
718 {
719 DestFile = fopen(DestName, "w+b");
720 if (DestFile == NULL)
722 }
723 else
725 }
726 else
727 {
728 DestFile = fopen(DestName, "w+b");
729 if (DestFile == NULL)
731 }
732
733#if defined(_WIN32)
734 if (!DosDateTimeToFileTime(File->File.FileDate, File->File.FileTime, &FileTime))
735 {
736 fclose(DestFile);
737 DPRINT(MIN_TRACE, ("DosDateTimeToFileTime() failed (%u).\n", (UINT)GetLastError()));
739 }
740
741 SetFileTime(DestFile, NULL, &FileTime, NULL);
742#else
743 //DPRINT(MIN_TRACE, ("FIXME: DosDateTimeToFileTime\n"));
744#endif
745
746 SetAttributesOnFile(DestName, File->File.Attributes);
747
748 Buffer = (PUCHAR)malloc(CAB_BLOCKSIZE + 12); // This should be enough
749 if (!Buffer)
750 {
751 fclose(DestFile);
752 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
753 return CAB_STATUS_NOMEMORY;
754 }
755
756 /* Call OnExtract event handler */
758
759 /* Search to start of file */
760 if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
761 {
762 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
763 fclose(DestFile);
764 free(Buffer);
766 }
767
768 Size = File->File.FileSize;
769 Offset = File->File.FileOffset;
770 CurrentOffset = File->DataBlock->UncompOffset;
771
772 Skip = true;
773
774 ReuseBlock = (CurrentDataNode == File->DataBlock);
775 if (Size > 0)
776 {
777 do
778 {
779 DPRINT(MAX_TRACE, ("CO (0x%X) ReuseBlock (%u) Offset (0x%X) Size (%d) BytesLeftInBlock (%d)\n",
780 (UINT)File->DataBlock->UncompOffset, (UINT)ReuseBlock, (UINT)Offset, (UINT)Size,
782
783 if (/*(CurrentDataNode != File->DataBlock) &&*/ (!ReuseBlock) || (BytesLeftInBlock <= 0))
784 {
785 DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
786
788 TotalBytesRead = 0;
789 do
790 {
791 DPRINT(MAX_TRACE, ("Size (%u bytes).\n", (UINT)Size));
792
793 if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
794 CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
795 {
796 fclose(DestFile);
797 free(Buffer);
798 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
800 }
801
802 DPRINT(MAX_TRACE, ("Data block: Checksum (0x%X) CompSize (%u bytes) UncompSize (%u bytes)\n",
803 (UINT)CFData.Checksum,
804 CFData.CompSize,
805 CFData.UncompSize));
806
807 ASSERT(CFData.CompSize <= CAB_BLOCKSIZE + 12);
808
809 BytesToRead = CFData.CompSize;
810
811 DPRINT(MAX_TRACE, ("Read: (0x%lX,0x%lX).\n",
812 (unsigned long)CurrentBuffer, (unsigned long)Buffer));
813
814 if (((Status = ReadBlock(CurrentBuffer, BytesToRead, &BytesRead)) !=
815 CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead))
816 {
817 fclose(DestFile);
818 free(Buffer);
819 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
821 }
822
823 /* FIXME: Does not work with files generated by makecab.exe */
824/*
825 if (CFData.Checksum != 0)
826 {
827 ULONG Checksum = ComputeChecksum(CurrentBuffer, BytesRead, 0);
828 if (Checksum != CFData.Checksum)
829 {
830 CloseFile(DestFile);
831 free(Buffer);
832 DPRINT(MIN_TRACE, ("Bad checksum (is 0x%X, should be 0x%X).\n",
833 Checksum, CFData.Checksum));
834 return CAB_STATUS_INVALID_CAB;
835 }
836 }
837*/
838 TotalBytesRead += BytesRead;
839
841
842 if (CFData.UncompSize == 0)
843 {
844 if (strlen(DiskNext) == 0)
845 {
846 fclose(DestFile);
847 free(Buffer);
848 return CAB_STATUS_NOFILE;
849 }
850
851 /* CloseCabinet() will destroy all file entries so in case
852 FileName refers to the FileName field of a CFFOLDER_NODE
853 structure, we have to save a copy of the filename */
854 strcpy(TempName, FileName);
855
856 CloseCabinet();
857
859
861
862 Status = Open();
864 {
865 fclose(DestFile);
866 free(Buffer);
867 return Status;
868 }
869
870 /* The first data block of the file will not be
871 found as it is located in the previous file */
872 Status = LocateFile(TempName, &File);
874 {
875 DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
876 fclose(DestFile);
877 free(Buffer);
878 return Status;
879 }
880
881 /* The file is continued in the first data block in the folder */
882 File->DataBlock = CurrentFolderNode->DataList.front();
883
884 /* Search to start of file */
885 if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
886 {
887 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
888 fclose(DestFile);
889 free(Buffer);
891 }
892
893 DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
894 (UINT)File->File.FileOffset,
895 (UINT)File->File.FileSize,
896 (UINT)File->DataBlock->AbsoluteOffset,
897 (UINT)File->DataBlock->UncompOffset));
898
899 CurrentDataNode = File->DataBlock;
900 ReuseBlock = true;
901
902 RestartSearch = true;
903 }
904 } while (CFData.UncompSize == 0);
905
906 DPRINT(MAX_TRACE, ("TotalBytesRead (%u).\n", (UINT)TotalBytesRead));
907
908 Status = Codec->Uncompress(OutputBuffer, Buffer, TotalBytesRead, &BytesToWrite);
909 if (Status != CS_SUCCESS)
910 {
911 fclose(DestFile);
912 free(Buffer);
913 DPRINT(MID_TRACE, ("Cannot uncompress block.\n"));
914 if (Status == CS_NOMEMORY)
915 return CAB_STATUS_NOMEMORY;
917 }
918
919 if (BytesToWrite != CFData.UncompSize)
920 {
921 DPRINT(MID_TRACE, ("BytesToWrite (%u) != CFData.UncompSize (%d)\n",
922 (UINT)BytesToWrite, CFData.UncompSize));
923 fclose(DestFile);
924 free(Buffer);
926 }
927
928 BytesLeftInBlock = BytesToWrite;
929 }
930 else
931 {
932 DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
933
934 BytesToWrite = BytesLeftInBlock;
935
936 DPRINT(MAX_TRACE, ("Seeking to absolute offset 0x%X.\n",
938
939 if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
940 CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
941 {
942 fclose(DestFile);
943 free(Buffer);
944 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
946 }
947
948 DPRINT(MAX_TRACE, ("CFData.CompSize 0x%X CFData.UncompSize 0x%X.\n",
949 CFData.CompSize, CFData.UncompSize));
950
951 /* Go to next data block */
954 {
955 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
956 fclose(DestFile);
957 free(Buffer);
959 }
960
961 ReuseBlock = false;
962 }
963
964 if (Skip)
965 BytesSkipped = (Offset - CurrentOffset);
966 else
967 BytesSkipped = 0;
968
969 BytesToWrite -= BytesSkipped;
970
971 if (Size < BytesToWrite)
972 BytesToWrite = Size;
973
974 DPRINT(MAX_TRACE, ("Offset (0x%X) CurrentOffset (0x%X) ToWrite (%u) Skipped (%u)(%u) Size (%u).\n",
975 (UINT)Offset,
976 (UINT)CurrentOffset,
977 (UINT)BytesToWrite,
978 (UINT)BytesSkipped, (UINT)Skip,
979 (UINT)Size));
980
981 BytesWritten = BytesToWrite;
982 if (fwrite((void*)((PUCHAR)OutputBuffer + BytesSkipped),
983 BytesToWrite, 1, DestFile) < 1)
984 {
985 fclose(DestFile);
986 free(Buffer);
987 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
988
990 }
991
992 Size -= BytesToWrite;
993
994 CurrentOffset += BytesToWrite;
995
996 /* Don't skip any more bytes */
997 Skip = false;
998 } while (Size > 0);
999 }
1000
1001 fclose(DestFile);
1002
1003 free(Buffer);
1004
1005 return CAB_STATUS_SUCCESS;
1006}
static ACPI_BUFFER CurrentBuffer
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
virtual ULONG Uncompress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
std::string DestPath
Definition: cabinet.h:445
bool RestartSearch
Definition: cabinet.h:471
virtual void OnDiskChange(const char *CabinetName, const char *DiskLabel)
Definition: cabinet.cxx:1762
void SetCabinetName(const char *FileName)
Definition: cabinet.cxx:205
virtual void OnExtract(PCFFILE Entry, const char *FileName)
Definition: cabinet.cxx:1750
ULONG Open()
Definition: cabinet.cxx:387
void SelectCodec(LONG Id)
Definition: cabinet.cxx:1018
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2322
ULONG LastFileOffset
Definition: cabinet.h:472
ULONG SetAttributesOnFile(char *FileName, USHORT FileAttributes)
Definition: cabinet.cxx:2968
ULONG LocateFile(const char *FileName, PCFFILE_NODE *File)
Definition: cabinet.cxx:1885
Definition: File.h:16
File()
Definition: File.h:18
#define malloc
Definition: debug_ros.c:4
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:948
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
Definition: time.c:75
__kernel_off_t off_t
Definition: linux.h:201
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
#define SEEK_SET
Definition: jmemansi.c:26
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define CAB_STATUS_NOFILE
Definition: cabinet.h:263
#define CAB_CODEC_MSZIP
Definition: cabinet.h:299
#define CAB_STATUS_UNSUPPCOMP
Definition: cabinet.h:264
#define CAB_COMP_MASK
Definition: cabinet.h:112
#define ASSERT(_x_)
Definition: cabinet.h:101
#define CS_NOMEMORY
Definition: cabinet.h:292
#define CS_SUCCESS
Definition: cabinet.h:291
#define CAB_COMP_NONE
Definition: cabinet.h:113
#define CAB_CODEC_RAW
Definition: cabinet.h:297
#define CAB_BLOCKSIZE
Definition: cabinet.h:110
#define CAB_COMP_MSZIP
Definition: cabinet.h:114
#define PATH_MAX
Definition: cabinet.h:32
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:262
ULONG AbsoluteOffset
Definition: cabinet.h:209
CFFOLDER Folder
Definition: cabinet.h:223
USHORT CompressionType
Definition: cabinet.c:110
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960
char CHAR
Definition: xmlstorage.h:175

Referenced by CCABManager::ExtractFromCabinet().

◆ FindFirst()

ULONG CCabinet::FindFirst ( PCAB_SEARCH  Search)

Definition at line 551 of file cabinet.cxx.

559{
560 RestartSearch = false;
561 Search->Next = FileList.begin();
562 return FindNext(Search);
563}
ULONG FindNext(PCAB_SEARCH Search)
Definition: cabinet.cxx:566
std::list< PCFFILE_NODE >::iterator Next
Definition: cabinet.h:245

Referenced by CCABManager::DisplayCabinet(), and CCABManager::ExtractFromCabinet().

◆ FindNext()

ULONG CCabinet::FindNext ( PCAB_SEARCH  Search)

Definition at line 566 of file cabinet.cxx.

574{
575 bool bFound = false;
577
578 if (RestartSearch)
579 {
580 Search->Next = FileList.begin();
581
582 /* Skip split files already extracted */
583 while ((Search->Next != FileList.end()) &&
584 ((*Search->Next)->File.FileControlID > CAB_FILE_MAX_FOLDER) &&
585 ((*Search->Next)->File.FileOffset <= LastFileOffset))
586 {
587 DPRINT(MAX_TRACE, ("Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n",
588 (*Search->Next)->FileName.c_str(), (UINT)(*Search->Next)->File.FileOffset, (UINT)LastFileOffset));
589 Search->Next++;
590 }
591
592 RestartSearch = false;
593 }
594
595 /* Check each search criteria against each file */
596 while(Search->Next != FileList.end())
597 {
598 // Some features (like displaying cabinets) don't require search criteria, so we can just break here.
599 // If a feature requires it, handle this in the ParseCmdline() function in "main.cxx".
600 if (CriteriaList.empty())
601 break;
602
603 for (PSEARCH_CRITERIA Criteria : CriteriaList)
604 {
605 // FIXME: We could handle path\filename here
606 if (MatchFileNamePattern((*Search->Next)->FileName.c_str(), Criteria->Search.c_str()))
607 {
608 bFound = true;
609 break;
610 }
611 }
612
613 if(bFound)
614 break;
615
616 Search->Next++;
617 }
618
619 if (Search->Next == FileList.end())
620 {
621 if (strlen(DiskNext) > 0)
622 {
623 CloseCabinet();
624
626
628
629 Status = Open();
631 return Status;
632
633 Search->Next = FileList.begin();
634 if (Search->Next == FileList.end())
635 return CAB_STATUS_NOFILE;
636 }
637 else
638 return CAB_STATUS_NOFILE;
639 }
640
641 Search->File = &(*Search->Next)->File;
642 Search->FileName = (*Search->Next)->FileName;
643 Search->Next++;
644 return CAB_STATUS_SUCCESS;
645}
#define CAB_FILE_MAX_FOLDER
Definition: cabinet.h:131
std::string FileName
Definition: cabinet.h:247
PCFFILE File
Definition: cabinet.h:79

Referenced by CCABManager::DisplayCabinet(), CCABManager::ExtractFromCabinet(), and FindFirst().

◆ GetAbsoluteOffset()

ULONG CCabinet::GetAbsoluteOffset ( PCFFILE_NODE  File)
private

Definition at line 1849 of file cabinet.cxx.

1857{
1858 DPRINT(MAX_TRACE, ("FileName '%s' FileOffset (0x%X) FileSize (%u).\n",
1859 File->FileName.c_str(),
1860 (UINT)File->File.FileOffset,
1861 (UINT)File->File.FileSize));
1862
1864 {
1865 DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%u).\n",
1866 (UINT)Node->UncompOffset,
1867 (UINT)(Node->UncompOffset + Node->Data.UncompSize),
1868 (UINT)Node->Data.UncompSize));
1869
1870 /* Node->Data.UncompSize will be 0 if the block is split
1871 (ie. it is the last block in this cabinet) */
1872 if ((Node->Data.UncompSize == 0) ||
1873 ((File->File.FileOffset >= Node->UncompOffset) &&
1874 (File->File.FileOffset < Node->UncompOffset +
1875 Node->Data.UncompSize)))
1876 {
1877 File->DataBlock = Node;
1878 return CAB_STATUS_SUCCESS;
1879 }
1880 }
1882}

Referenced by LocateFile().

◆ GetAttributesOnFile()

ULONG CCabinet::GetAttributesOnFile ( PCFFILE_NODE  File)
private

Definition at line 2914 of file cabinet.cxx.

2922{
2923#if defined(_WIN32)
2925
2926 Attributes = GetFileAttributes(File->FileName.c_str());
2927 if (Attributes == -1)
2929
2930 // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
2931 // The IDs for these attributes are the same in the CAB file and under Windows
2932 // If the file has any other attributes, strip them off by the logical AND.
2933 File->File.Attributes = (USHORT)(Attributes & 0x37);
2934#else
2935 struct stat stbuf;
2936 char buf[PATH_MAX];
2937
2938 // Check for an absolute path
2939 if (File->FileName.length() > 0 && IsSeparator(File->FileName[0]))
2940 strcpy(buf, File->FileName.c_str());
2941 else
2942 {
2943 if (!getcwd(buf, sizeof(buf)))
2946 strcat(buf, File->FileName.c_str());
2947 }
2948
2949 if (stat(buf, &stbuf) == -1)
2951
2952#if 0
2953 File->File.Attributes |= CAB_ATTRIB_READONLY;
2954 File->File.Attributes |= CAB_ATTRIB_HIDDEN;
2955 File->File.Attributes |= CAB_ATTRIB_SYSTEM;
2956#endif
2957
2958 if (stbuf.st_mode & S_IFDIR)
2959 File->File.Attributes |= CAB_ATTRIB_DIRECTORY;
2960
2961 File->File.Attributes |= CAB_ATTRIB_ARCHIVE;
2962
2963#endif
2964 return CAB_STATUS_SUCCESS;
2965}
bool IsSeparator(char Char)
Definition: cabinet.cxx:119
size_t length()
Definition: File.cpp:88
_Check_return_ _Ret_opt_z_ _CRTIMP char *__cdecl getcwd(_Out_writes_opt_(_SizeInBytes) char *_DstBuf, _In_ int _SizeInBytes)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define CAB_ATTRIB_HIDDEN
Definition: cabinet.h:123
#define DIR_SEPARATOR_STRING
Definition: cabinet.h:47
#define CAB_ATTRIB_READONLY
Definition: cabinet.h:122
#define CAB_ATTRIB_DIRECTORY
Definition: cabinet.h:126
#define CAB_ATTRIB_SYSTEM
Definition: cabinet.h:124
#define CAB_ATTRIB_ARCHIVE
Definition: cabinet.h:127
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define GetFileAttributes
Definition: winbase.h:3750

Referenced by AddFile().

◆ GetCabinetName()

char * CCabinet::GetCabinetName ( )

Definition at line 194 of file cabinet.cxx.

200{
201 return CabinetName;
202}

Referenced by CCABManager::DisplayCabinet(), and CCABManager::ExtractFromCabinet().

◆ GetCurrentDiskNumber()

ULONG CCabinet::GetCurrentDiskNumber ( )

Definition at line 376 of file cabinet.cxx.

382{
383 return CurrentDiskNumber;
384}

Referenced by CDFParser::SetupNewDisk().

◆ GetDestinationPath()

const char * CCabinet::GetDestinationPath ( )

Definition at line 308 of file cabinet.cxx.

314{
315 return DestPath.c_str();
316}

Referenced by CDFParser::OnCabinetName(), and CDFParser::WriteInfLine().

◆ GetFileName()

std::string CCabinet::GetFileName ( const std::string &  Path)

Definition at line 158 of file cabinet.cxx.

166{
167 ULONG i, j;
168
169 j = i = (Path[0] ? (Path[1] == ':' ? 2 : 0) : 0);
170
171 while (Path [i++])
172 if (IsSeparator(Path [i - 1]))
173 j = i;
174
175 return Path.c_str() + j;
176}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

Referenced by CreateCabFilename(), CCABManager::OnAdd(), CCABManager::OnExtract(), and CDFParser::PerformFileCopy().

◆ GetFileTimes()

ULONG CCabinet::GetFileTimes ( FILE FileHandle,
PCFFILE_NODE  File 
)
private

Definition at line 2872 of file cabinet.cxx.

2881{
2882#if defined(_WIN32)
2883 FILETIME FileTime;
2885
2886 if (GetFileTime(FileNo, NULL, NULL, &FileTime))
2887 FileTimeToDosDateTime(&FileTime,
2888 &File->File.FileDate,
2889 &File->File.FileTime);
2890#else
2891 struct stat stbuf;
2892 char buf[PATH_MAX];
2893
2894 // Check for an absolute path
2895 if (File->FileName.length() > 0 && IsSeparator(File->FileName[0]))
2896 strcpy(buf, File->FileName.c_str());
2897 else
2898 {
2899 if (!getcwd(buf, sizeof(buf)))
2902 strcat(buf, File->FileName.c_str());
2903 }
2904
2905 if (stat(buf, &stbuf) == -1)
2907
2908 ConvertDateAndTime(&stbuf.st_mtime, &File->File.FileDate, &File->File.FileTime);
2909#endif
2910 return CAB_STATUS_SUCCESS;
2911}
#define UlongToHandle(ul)
Definition: basetsd.h:97
void ConvertDateAndTime(time_t *Time, PUSHORT DosDate, PUSHORT DosTime)
Definition: cabinet.cxx:2840
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:896
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
Definition: time.c:37
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)

Referenced by AddFile().

◆ HasSearchCriteria()

bool CCabinet::HasSearchCriteria ( )

Definition at line 268 of file cabinet.cxx.

274{
275 return !CriteriaList.empty();
276}

Referenced by CCABManager::ParseCmdline().

◆ InitCabinetHeader()

ULONG CCabinet::InitCabinetHeader ( )
private

Definition at line 2405 of file cabinet.cxx.

2411{
2412 ULONG TotalSize;
2413 ULONG Size;
2414
2415 CABHeader.FileTableOffset = 0; // Not known yet
2416 CABHeader.FolderCount = 0; // Not known yet
2417 CABHeader.FileCount = 0; // Not known yet
2418 CABHeader.Flags = 0; // Not known yet
2419
2421
2423 {
2426 strcpy(CabinetPrev, "");
2427 }
2428
2430 {
2433 strcpy(DiskNext, "");
2434 }
2435
2436 TotalSize = 0;
2437
2438 if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
2439 {
2440
2441 DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
2442
2443 /* Calculate size of name of previous cabinet */
2444 TotalSize += (ULONG)strlen(CabinetPrev) + 1;
2445
2446 /* Calculate size of label of previous disk */
2447 TotalSize += (ULONG)strlen(DiskPrev) + 1;
2448 }
2449
2450 if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
2451 {
2452
2453 DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
2454
2455 /* Calculate size of name of next cabinet */
2456 Size = (ULONG)strlen(CabinetNext) + 1;
2457 TotalSize += Size;
2459
2460 /* Calculate size of label of next disk */
2461 Size = (ULONG)strlen(DiskNext) + 1;
2462 TotalSize += Size;
2464 }
2465 else
2466 NextFieldsSize = 0;
2467
2468 /* Add cabinet reserved area size if present */
2470 {
2472 TotalSize += CabinetReservedFileSize;
2473 TotalSize += sizeof(ULONG); /* For CabinetResSize, FolderResSize, and FileResSize fields */
2474 }
2475
2476 DiskSize += TotalSize;
2477
2478 TotalHeaderSize = sizeof(CFHEADER) + TotalSize;
2479
2480 return CAB_STATUS_SUCCESS;
2481}
ULONG PrevCabinetNumber
Definition: cabinet.h:477
ULONG NextFieldsSize
Definition: cabinet.h:439
CFHEADER CABHeader
Definition: cabinet.h:451
ULONG TotalHeaderSize
Definition: cabinet.h:438
ULONG DiskSize
Definition: cabinet.h:476
virtual bool OnDiskLabel(ULONG Number, char *Label)
Definition: cabinet.cxx:1792
struct _CFHEADER CFHEADER
#define CAB_FLAG_HASNEXT
Definition: cabinet.h:119
#define CAB_FLAG_RESERVE
Definition: cabinet.h:120
#define CAB_FLAG_HASPREV
Definition: cabinet.h:118
ULONG FileTableOffset
Definition: cabinet.c:86
USHORT FileCount
Definition: cabinet.c:90
USHORT FolderCount
Definition: cabinet.c:89
USHORT Flags
Definition: cabinet.c:91
USHORT CabinetNumber
Definition: cabinet.c:93

Referenced by NewCabinet(), and NewDisk().

◆ IsCodecSelected()

bool CCabinet::IsCodecSelected ( )

Definition at line 1008 of file cabinet.cxx.

1014{
1015 return CodecSelected;
1016}

Referenced by CCABManager::ParseCmdline().

◆ IsSeparator()

bool CCabinet::IsSeparator ( char  Char)

Definition at line 119 of file cabinet.cxx.

127{
128 if ((Char == '\\') || (Char == '/'))
129 return true;
130 else
131 return false;
132}

Referenced by GetAttributesOnFile(), GetFileName(), GetFileTimes(), and NormalizePath().

◆ LocateFile()

ULONG CCabinet::LocateFile ( const char FileName,
PCFFILE_NODE File 
)
private

Definition at line 1885 of file cabinet.cxx.

1897{
1898 ULONG Status;
1899
1900 DPRINT(MAX_TRACE, ("FileName '%s'\n", FileName));
1901
1902 for (PCFFILE_NODE Node : FileList)
1903 {
1904 // FIXME: We could handle path\filename here
1905 if (strcasecmp(FileName, Node->FileName.c_str()) == 0)
1906 {
1907 CurrentFolderNode = LocateFolderNode(Node->File.FileControlID);
1908 if (!CurrentFolderNode)
1909 {
1910 DPRINT(MID_TRACE, ("Folder with index number (%u) not found.\n",
1911 Node->File.FileControlID));
1913 }
1914
1915 if (Node->DataBlock == NULL)
1917 else
1919
1920 *File = Node;
1921 return Status;
1922 }
1923 }
1924 return CAB_STATUS_NOFILE;
1925}
ULONG GetAbsoluteOffset(PCFFILE_NODE File)
Definition: cabinet.cxx:1849
PCFFOLDER_NODE LocateFolderNode(ULONG Index)
Definition: cabinet.cxx:1821
#define strcasecmp
Definition: fake.h:9

Referenced by ExtractFile().

◆ LocateFolderNode()

PCFFOLDER_NODE CCabinet::LocateFolderNode ( ULONG  Index)
private

Definition at line 1821 of file cabinet.cxx.

1829{
1830 switch (Index)
1831 {
1832 case CAB_FILE_SPLIT:
1833 return FolderList.back();
1834
1835 case CAB_FILE_CONTINUED:
1836 case CAB_FILE_PREV_NEXT:
1837 return FolderList.front();
1838 }
1839
1841 {
1842 if (Node->Index == Index)
1843 return Node;
1844 }
1845 return NULL;
1846}
#define CAB_FILE_SPLIT
Definition: cabinet.h:133
#define CAB_FILE_PREV_NEXT
Definition: cabinet.h:134
#define CAB_FILE_CONTINUED
Definition: cabinet.h:132
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by LocateFile().

◆ MatchFileNamePattern()

bool CCabinet::MatchFileNamePattern ( const char FileName,
const char Pattern 
)
private

Definition at line 2342 of file cabinet.cxx.

2356{
2357 const char* retryPattern = NULL;
2358 const char* retryFileName = NULL;
2359 char ch;
2360
2361 while (*FileName || *Pattern)
2362 {
2363 ch = *Pattern++;
2364
2365 switch (ch)
2366 {
2367 case '*':
2368 retryPattern = Pattern;
2369 retryFileName = FileName;
2370 break;
2371
2372 case '?':
2373 if (*FileName++ == '\0')
2374 return false;
2375
2376 break;
2377
2378 default:
2379 if (*FileName == ch)
2380 {
2381 if (*FileName)
2382 FileName++;
2383 break;
2384 }
2385
2386 if (*FileName)
2387 {
2388 Pattern = retryPattern;
2389 FileName = ++retryFileName;
2390 break;
2391 }
2392
2393 return false;
2394 }
2395
2396 if (!Pattern)
2397 return false;
2398 }
2399
2400 return true;
2401}

Referenced by CreateSimpleCabinet(), and FindNext().

◆ NewCabinet()

ULONG CCabinet::NewCabinet ( )

Definition at line 1057 of file cabinet.cxx.

1063{
1064 ULONG Status;
1065
1067
1068 OutputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
1069 InputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
1070 if ((!OutputBuffer) || (!InputBuffer))
1071 {
1072 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1073 return CAB_STATUS_NOMEMORY;
1074 }
1077
1079 CABHeader.Reserved1 = 0; // Not used
1080 CABHeader.CabinetSize = 0; // Not yet known
1081 CABHeader.Reserved2 = 0; // Not used
1082 CABHeader.Reserved3 = 0; // Not used
1084 CABHeader.FolderCount = 0; // Not yet known
1085 CABHeader.FileCount = 0; // Not yet known
1086 CABHeader.Flags = 0; // Not yet known
1087 // FIXME: Should be random
1088 CABHeader.SetID = 0x534F;
1090
1091
1092 TotalFolderSize = 0;
1093 TotalFileSize = 0;
1094
1095 DiskSize = sizeof(CFHEADER);
1096
1098
1099 // NextFolderNumber is 0-based
1100 NextFolderNumber = 0;
1101
1103 Status = NewFolder();
1105 return Status;
1106
1108
1110 if (!ScratchFile)
1111 {
1112 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1113 return CAB_STATUS_NOMEMORY;
1114 }
1115
1117
1118 CreateNewFolder = false;
1119
1120 CreateNewDisk = false;
1121
1123
1124 return Status;
1125}
ULONG NextFolderNumber
Definition: cabinet.h:486
ULONG CurrentIBufferSize
Definition: cabinet.h:465
bool CreateNewDisk
Definition: cabinet.h:478
bool CreateNewFolder
Definition: cabinet.h:479
ULONG InitCabinetHeader()
Definition: cabinet.cxx:2405
ULONG NewFolder()
Definition: cabinet.cxx:1152
void * CurrentIBuffer
Definition: cabinet.h:464
void * InputBuffer
Definition: cabinet.h:463
#define CAB_VERSION
Definition: cabinet.h:109
#define CAB_SIGNATURE
Definition: cabinet.h:108
ULONG DataOffset
Definition: cabinet.c:108
USHORT Version
Definition: cabinet.c:88
USHORT SetID
Definition: cabinet.c:92
ULONG Reserved3
Definition: cabinet.c:87
ULONG Reserved1
Definition: cabinet.c:83
ULONG CabinetSize
Definition: cabinet.c:84
ULONG Signature
Definition: cabinet.c:82
ULONG Reserved2
Definition: cabinet.c:85

Referenced by CreateSimpleCabinet(), CDFParser::PerformFileCopy(), and CDFParser::PerformNewCommand().

◆ NewDataNode()

PCFDATA_NODE CCabinet::NewDataNode ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2147 of file cabinet.cxx.

2155{
2157
2158 Node = new CFDATA_NODE;
2159 if (!Node)
2160 return NULL;
2161
2162 FolderNode->DataList.push_back(Node);
2163
2164 return Node;
2165}
struct _CFDATA_NODE CFDATA_NODE

Referenced by ReadDataBlocks(), and WriteDataBlock().

◆ NewDisk()

ULONG CCabinet::NewDisk ( )

Definition at line 1128 of file cabinet.cxx.

1134{
1135 // NextFolderNumber is 0-based
1136 NextFolderNumber = 1;
1137
1138 CreateNewDisk = false;
1139
1141
1143
1145
1147
1148 return CAB_STATUS_SUCCESS;
1149}
ULONG TotalFolderSize
Definition: cabinet.h:218
USHORT DataBlockCount
Definition: cabinet.c:109

Referenced by CDFParser::PerformFileCopy(), CDFParser::PerformNewCommand(), and WriteDisk().

◆ NewFileNode()

PCFFILE_NODE CCabinet::NewFileNode ( )
private

Definition at line 2126 of file cabinet.cxx.

2134{
2136
2137 Node = new CFFILE_NODE;
2138 if (!Node)
2139 return NULL;
2140
2141 FileList.push_back(Node);
2142
2143 return Node;
2144}
struct _CFFILE_NODE CFFILE_NODE

Referenced by AddFile(), and ReadFileTable().

◆ NewFolder()

ULONG CCabinet::NewFolder ( )

Definition at line 1152 of file cabinet.cxx.

1158{
1159 DPRINT(MAX_TRACE, ("Creating new folder.\n"));
1160
1162 if (!CurrentFolderNode)
1163 {
1164 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1165 return CAB_STATUS_NOMEMORY;
1166 }
1167
1168 switch (CodecId) {
1169 case CAB_CODEC_RAW:
1171 break;
1172
1173 case CAB_CODEC_MSZIP:
1175 break;
1176
1177 default:
1178 return CAB_STATUS_UNSUPPCOMP;
1179 }
1180
1181 /* FIXME: This won't work if no files are added to the new folder */
1182
1183 DiskSize += sizeof(CFFOLDER);
1184
1185 TotalFolderSize += sizeof(CFFOLDER);
1186
1188
1190
1191 LastBlockStart = 0;
1192
1193 return CAB_STATUS_SUCCESS;
1194}
PCFFOLDER_NODE NewFolderNode()
Definition: cabinet.cxx:2105
ULONG LastBlockStart
Definition: cabinet.h:474

Referenced by NewCabinet(), CDFParser::PerformNewCommand(), and WriteFileToScratchStorage().

◆ NewFolderNode()

PCFFOLDER_NODE CCabinet::NewFolderNode ( )
private

Definition at line 2105 of file cabinet.cxx.

2111{
2113
2114 Node = new CFFOLDER_NODE;
2115 if (!Node)
2116 return NULL;
2117
2118 Node->Folder.CompressionType = CAB_COMP_NONE;
2119
2120 FolderList.push_back(Node);
2121
2122 return Node;
2123}
struct _CFFOLDER_NODE CFFOLDER_NODE

Referenced by NewFolder(), and Open().

◆ NormalizePath()

void CCabinet::NormalizePath ( std::string &  Path)

Definition at line 179 of file cabinet.cxx.

185{
186 if (Path.length() > 0)
187 {
188 if (!IsSeparator(Path[Path.length() - 1]))
190 }
191}

Referenced by SetDestinationPath(), and CDFParser::SetFileRelativePath().

◆ OnAdd()

void CCabinet::OnAdd ( PCFFILE  Entry,
const char FileName 
)
virtual

Reimplemented in CCABManager.

Definition at line 1780 of file cabinet.cxx.

1788{
1789}

Referenced by WriteFileToScratchStorage().

◆ OnCabinetName()

bool CCabinet::OnCabinetName ( ULONG  Number,
char Name 
)
virtual

Reimplemented in CDFParser.

Definition at line 1806 of file cabinet.cxx.

1815{
1816 return false;
1817}

Referenced by CommitDisk(), and InitCabinetHeader().

◆ OnDiskChange()

void CCabinet::OnDiskChange ( const char CabinetName,
const char DiskLabel 
)
virtual

Reimplemented in CCABManager.

Definition at line 1762 of file cabinet.cxx.

1770{
1771}

Referenced by ExtractFile(), and FindNext().

◆ OnDiskLabel()

bool CCabinet::OnDiskLabel ( ULONG  Number,
char Label 
)
virtual

Reimplemented in CDFParser.

Definition at line 1792 of file cabinet.cxx.

1801{
1802 return false;
1803}

Referenced by InitCabinetHeader().

◆ OnExtract()

void CCabinet::OnExtract ( PCFFILE  Entry,
const char FileName 
)
virtual

Reimplemented in CCABManager.

Definition at line 1750 of file cabinet.cxx.

1758{
1759}

Referenced by ExtractFile().

◆ OnOverwrite()

bool CCabinet::OnOverwrite ( PCFFILE  Entry,
const char FileName 
)
virtual

Reimplemented in CCABManager.

Definition at line 1735 of file cabinet.cxx.

1745{
1746 return false;
1747}

Referenced by CommitDisk(), and ExtractFile().

◆ OnVerboseMessage()

void CCabinet::OnVerboseMessage ( const char Message)
virtual

Reimplemented in CCABManager.

Definition at line 1773 of file cabinet.cxx.

1774{
1775
1776}

Referenced by CDFParser::Parse().

◆ Open()

ULONG CCabinet::Open ( )

Definition at line 387 of file cabinet.cxx.

393{
395 ULONG Index;
396
397 if (!FileOpen)
398 {
400 ULONG Size;
401
402 OutputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
403 if (!OutputBuffer)
404 return CAB_STATUS_NOMEMORY;
405
407 if (FileHandle == NULL)
408 {
409 DPRINT(MID_TRACE, ("Cannot open file.\n"));
411 }
412
413 FileOpen = true;
414
415 /* Load CAB header */
416 if ((Status = ReadBlock(&CABHeader, sizeof(CFHEADER), &BytesRead))
418 {
419 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
421 }
422
423 /* Check header */
424 if ((BytesRead != sizeof(CFHEADER)) ||
427 (CABHeader.FolderCount == 0 ) ||
428 (CABHeader.FileCount == 0 ) ||
430 {
431 CloseCabinet();
432 DPRINT(MID_TRACE, ("File has invalid header.\n"));
434 }
435
436 Size = 0;
437
438 /* Read/skip any reserved bytes */
440 {
441 if ((Status = ReadBlock(&Size, sizeof(ULONG), &BytesRead))
443 {
444 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
446 }
447 CabinetReserved = Size & 0xFFFF;
448 FolderReserved = (Size >> 16) & 0xFF;
449 DataReserved = (Size >> 24) & 0xFF;
450
452 {
453 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
454 return CAB_STATUS_FAILURE;
455 }
456 }
457
458 if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
459 {
460 /* Read name of previous cabinet */
463 return Status;
464 /* Read label of previous disk */
465 Status = ReadString(DiskPrev, 256);
467 return Status;
468 }
469 else
470 {
471 strcpy(CabinetPrev, "");
472 strcpy(DiskPrev, "");
473 }
474
475 if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
476 {
477 /* Read name of next cabinet */
480 return Status;
481 /* Read label of next disk */
482 Status = ReadString(DiskNext, 256);
484 return Status;
485 }
486 else
487 {
488 strcpy(CabinetNext, "");
489 strcpy(DiskNext, "");
490 }
491
492 /* Read all folders */
493 for (Index = 0; Index < CABHeader.FolderCount; Index++)
494 {
495 PCFFOLDER_NODE FolderNode = NewFolderNode();
496 if (!FolderNode)
497 {
498 DPRINT(MIN_TRACE, ("Insufficient resources.\n"));
499 return CAB_STATUS_NOMEMORY;
500 }
501
502 if (Index == 0)
503 FolderNode->UncompOffset = FolderUncompSize;
504
505 FolderNode->Index = Index;
506
507 if ((Status = ReadBlock(&FolderNode->Folder,
509 {
510 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
512 }
513 }
514
515 /* Read file entries */
518 {
519 DPRINT(MIN_TRACE, ("ReadFileTable() failed (%u).\n", (UINT)Status));
520 return Status;
521 }
522
523 /* Read data blocks for all folders */
525 {
528 {
529 DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%u).\n", (UINT)Status));
530 return Status;
531 }
532 }
533 }
534 return CAB_STATUS_SUCCESS;
535}
ULONG ReadFileTable()
Definition: cabinet.cxx:1983
ULONG CabinetReserved
Definition: cabinet.h:452
ULONG DataReserved
Definition: cabinet.h:454
ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2040
ULONG ReadString(char *String, LONG MaxLength)
Definition: cabinet.cxx:1928
ULONG FolderReserved
Definition: cabinet.h:453
#define SEEK_CUR
Definition: util.h:63
#define CAB_STATUS_FAILURE
Definition: cabinet.h:255
Definition: fci.c:82
Definition: fci.c:65
ULONG UncompOffset
Definition: cabinet.h:216
ULONG Index
Definition: cabinet.h:220

Referenced by CCABManager::DisplayCabinet(), ExtractFile(), CCABManager::ExtractFromCabinet(), and FindNext().

◆ ReadBlock()

ULONG CCabinet::ReadBlock ( void Buffer,
ULONG  Size,
PULONG  BytesRead 
)
private

Definition at line 2322 of file cabinet.cxx.

2335{
2337 if ( *BytesRead != Size )
2339 return CAB_STATUS_SUCCESS;
2340}
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)

Referenced by ExtractFile(), Open(), ReadDataBlocks(), ReadFileTable(), and ReadString().

◆ ReadDataBlocks()

ULONG CCabinet::ReadDataBlocks ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2040 of file cabinet.cxx.

2048{
2049 ULONG AbsoluteOffset;
2050 ULONG UncompOffset;
2053 ULONG Status;
2054 ULONG i;
2055
2056 DPRINT(MAX_TRACE, ("Reading data blocks for folder (%u) at absolute offset (0x%X).\n",
2057 (UINT)FolderNode->Index, (UINT)FolderNode->Folder.DataOffset));
2058
2059 AbsoluteOffset = FolderNode->Folder.DataOffset;
2060 UncompOffset = FolderNode->UncompOffset;
2061
2062 for (i = 0; i < FolderNode->Folder.DataBlockCount; i++)
2063 {
2064 Node = NewDataNode(FolderNode);
2065 if (!Node)
2066 {
2067 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2068 return CAB_STATUS_NOMEMORY;
2069 }
2070
2071 /* Seek to data block */
2072 if (fseek(FileHandle, (off_t)AbsoluteOffset, SEEK_SET) != 0)
2073 {
2074 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
2076 }
2077
2078 if ((Status = ReadBlock(&Node->Data, sizeof(CFDATA),
2080 {
2081 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
2083 }
2084
2085 DPRINT(MAX_TRACE, ("AbsOffset (0x%X) UncompOffset (0x%X) Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
2086 (UINT)AbsoluteOffset,
2087 (UINT)UncompOffset,
2088 (UINT)Node->Data.Checksum,
2089 Node->Data.CompSize,
2090 Node->Data.UncompSize));
2091
2092 Node->AbsoluteOffset = AbsoluteOffset;
2093 Node->UncompOffset = UncompOffset;
2094
2095 AbsoluteOffset += sizeof(CFDATA) + Node->Data.CompSize;
2096 UncompOffset += Node->Data.UncompSize;
2097 }
2098
2099 FolderUncompSize = UncompOffset;
2100
2101 return CAB_STATUS_SUCCESS;
2102}
PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2147
struct _CFDATA CFDATA

Referenced by Open().

◆ ReadFileTable()

ULONG CCabinet::ReadFileTable ( )
private

Definition at line 1983 of file cabinet.cxx.

1989{
1990 ULONG i;
1991 ULONG Status;
1994
1995 DPRINT(MAX_TRACE, ("Reading file table at absolute offset (0x%X).\n",
1997
1998 /* Seek to file table */
2000 {
2001 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
2003 }
2004
2005 for (i = 0; i < CABHeader.FileCount; i++)
2006 {
2007 File = NewFileNode();
2008 if (!File)
2009 {
2010 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2011 return CAB_STATUS_NOMEMORY;
2012 }
2013
2014 if ((Status = ReadBlock(&File->File, sizeof(CFFILE),
2016 {
2017 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
2019 }
2020
2021 /* Read file name */
2022 char Buf[PATH_MAX];
2023 Status = ReadString(Buf, PATH_MAX);
2025 return Status;
2026 // FIXME: We could split up folder\file.txt here
2027 File->FileName = Buf;
2028
2029 DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X). Size (%u bytes) ControlId (0x%X).\n",
2030 File->FileName.c_str(),
2031 (UINT)File->File.FileOffset,
2032 (UINT)File->File.FileSize,
2033 File->File.FileControlID));
2034
2035 }
2036 return CAB_STATUS_SUCCESS;
2037}
Definition: fci.c:89

Referenced by Open().

◆ ReadString()

ULONG CCabinet::ReadString ( char String,
LONG  MaxLength 
)
private

Definition at line 1928 of file cabinet.cxx.

1937{
1939 ULONG Status;
1940 LONG Size;
1941 bool Found;
1942
1943 Found = false;
1944
1945 Status = ReadBlock(String, MaxLength, &BytesRead);
1947 {
1948 DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
1950 }
1951
1952 // Find the terminating NULL character
1953 for (Size = 0; Size < MaxLength; Size++)
1954 {
1955 if (String[Size] == '\0')
1956 {
1957 Found = true;
1958 break;
1959 }
1960 }
1961
1962 if (!Found)
1963 {
1964 DPRINT(MIN_TRACE, ("Filename in the cabinet file is too long.\n"));
1966 }
1967
1968 // Compute the offset of the next CFFILE.
1969 // 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.
1970 // + 1 to skip the terminating NULL character as well.
1971 Size = -(MaxLength - Size) + 1;
1972
1973 if (fseek(FileHandle, (off_t)Size, SEEK_CUR) != 0)
1974 {
1975 DPRINT(MIN_TRACE, ("fseek() failed.\n"));
1977 }
1978
1979 return CAB_STATUS_SUCCESS;
1980}
return Found
Definition: dirsup.c:1270
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

Referenced by Open(), and ReadFileTable().

◆ SelectCodec()

void CCabinet::SelectCodec ( LONG  Id)

Definition at line 1018 of file cabinet.cxx.

1024{
1025 if (CodecSelected)
1026 {
1027 if (Id == CodecId)
1028 return;
1029
1030 CodecSelected = false;
1031 delete Codec;
1032 }
1033
1034 switch (Id)
1035 {
1036 case CAB_CODEC_RAW:
1037 Codec = new CRawCodec();
1038 break;
1039
1040 case CAB_CODEC_MSZIP:
1041 Codec = new CMSZipCodec();
1042 break;
1043
1044 default:
1045 return;
1046 }
1047
1048 CodecId = Id;
1049 CodecSelected = true;
1050}
DWORD Id
Definition: raw.h:16

Referenced by ExtractFile(), CCABManager::ParseCmdline(), and SetCompressionCodec().

◆ SetAttributesOnFile()

ULONG CCabinet::SetAttributesOnFile ( char FileName,
USHORT  FileAttributes 
)
private

Definition at line 2968 of file cabinet.cxx.

2977{
2978#if defined(_WIN32)
2979 // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
2980 // The IDs for these attributes are the same in the CAB file and under Windows
2981 // If the file has any other attributes, strip them off by the logical AND.
2983
2984 return CAB_STATUS_SUCCESS;
2985#else
2986 //DPRINT(MIN_TRACE, ("FIXME: SetAttributesOnFile() is unimplemented\n"));
2987 return CAB_STATUS_SUCCESS;
2988#endif
2989}
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
#define SetFileAttributes
Definition: winbase.h:3844

Referenced by ExtractFile().

◆ SetCabinetName()

void CCabinet::SetCabinetName ( const char FileName)

Definition at line 205 of file cabinet.cxx.

211{
213}

Referenced by ExtractFile(), FindNext(), and CCABManager::ParseCmdline().

◆ SetCabinetReservedFile()

bool CCabinet::SetCabinetReservedFile ( const char FileName)

Definition at line 319 of file cabinet.cxx.

325{
328 std::string ConvertedFileName;
329
330 ConvertedFileName = FileName;
331 ConvertPath(ConvertedFileName);
332
333 FileHandle = fopen(ConvertedFileName.c_str(), "rb");
334 if (FileHandle == NULL)
335 {
336 DPRINT(MID_TRACE, ("Cannot open cabinet reserved file.\n"));
337 return false;
338 }
339
342 {
343 DPRINT(MIN_TRACE, ("Cannot read from cabinet reserved file.\n"));
345 return false;
346 }
347
349 {
351 return false;
352 }
353
356 {
358 return false;
359 }
360
363 {
365 return false;
366 }
367
369
371
372 return true;
373}
std::string CabinetReservedFile
Definition: cabinet.h:446

Referenced by CCABManager::ParseCmdline().

◆ SetCompressionCodec()

bool CCabinet::SetCompressionCodec ( const char CodecName)

Definition at line 288 of file cabinet.cxx.

294{
295 if( !strcasecmp(CodecName, "raw") )
297 else if( !strcasecmp(CodecName, "mszip") )
299 else
300 {
301 printf("ERROR: Invalid codec specified!\n");
302 return false;
303 }
304
305 return true;
306}
#define printf
Definition: freeldr.h:94

Referenced by CCABManager::ParseCmdline().

◆ SetDestinationPath()

void CCabinet::SetDestinationPath ( const char DestinationPath)

Definition at line 216 of file cabinet.cxx.

222{
223 DestPath = DestinationPath;
226}
void NormalizePath(std::string &Path)
Definition: cabinet.cxx:179

Referenced by CCABManager::ParseCmdline().

◆ SetMaxDiskSize()

void CCabinet::SetMaxDiskSize ( ULONG  Size)

Definition at line 1720 of file cabinet.cxx.

1726{
1727 MaxDiskSize = Size;
1728}

Referenced by CDFParser::DoMaxDiskSize(), and CDFParser::SetupNewDisk().

◆ WriteCabinetHeader()

ULONG CCabinet::WriteCabinetHeader ( bool  MoreDisks)
private

Definition at line 2484 of file cabinet.cxx.

2492{
2494 ULONG Size;
2495
2496 if (MoreDisks)
2497 {
2500 }
2501 else
2502 {
2503 CABHeader.Flags &= ~CAB_FLAG_HASNEXT;
2506 }
2507
2508 /* Set absolute folder offsets */
2511 for (PCFFOLDER_NODE FolderNode : FolderList)
2512 {
2513 FolderNode->Folder.DataOffset = BytesWritten;
2514
2515 BytesWritten += FolderNode->TotalFolderSize;
2516
2518 }
2519
2520 /* Set absolute offset of file table */
2522
2523 /* Count number of files to be committed */
2524 CABHeader.FileCount = 0;
2525 for (PCFFILE_NODE FileNode : FileList)
2526 {
2527 if (FileNode->Commit)
2529 }
2530
2532
2533 /* Write header */
2534 if (fwrite(&CABHeader, sizeof(CFHEADER), 1, FileHandle) < 1)
2535 {
2536 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2538 }
2539
2540 /* Write per-cabinet reserved area if present */
2542 {
2543 ULONG ReservedSize;
2544
2545 ReservedSize = CabinetReservedFileSize & 0xffff;
2546 ReservedSize |= (0 << 16); /* Folder reserved area size */
2547 ReservedSize |= (0 << 24); /* Folder reserved area size */
2548
2549 BytesWritten = sizeof(ULONG);
2550 if (fwrite(&ReservedSize, sizeof(ULONG), 1, FileHandle) < 1)
2551 {
2552 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2554 }
2555
2558 {
2559 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2561 }
2562 }
2563
2564 if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
2565 {
2566 DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
2567
2568 /* Write name of previous cabinet */
2569 Size = (ULONG)strlen(CabinetPrev) + 1;
2571 if (fwrite(CabinetPrev, Size, 1, FileHandle) < 1)
2572 {
2573 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2575 }
2576
2577 DPRINT(MAX_TRACE, ("DiskPrev '%s'.\n", DiskPrev));
2578
2579 /* Write label of previous disk */
2580 Size = (ULONG)strlen(DiskPrev) + 1;
2582 if (fwrite(DiskPrev, Size, 1, FileHandle) < 1)
2583 {
2584 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2586 }
2587 }
2588
2589 if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
2590 {
2591 DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
2592
2593 /* Write name of next cabinet */
2594 Size = (ULONG)strlen(CabinetNext) + 1;
2596 if (fwrite(CabinetNext, Size, 1, FileHandle) < 1)
2597 {
2598 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2600 }
2601
2602 DPRINT(MAX_TRACE, ("DiskNext '%s'.\n", DiskNext));
2603
2604 /* Write label of next disk */
2605 Size = (ULONG)strlen(DiskNext) + 1;
2607 if (fwrite(DiskNext, Size, 1, FileHandle) < 1)
2608 {
2609 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2611 }
2612 }
2613
2614 return CAB_STATUS_SUCCESS;
2615}

Referenced by CommitDisk().

◆ WriteDataBlock()

ULONG CCabinet::WriteDataBlock ( )
private

Definition at line 2751 of file cabinet.cxx.

2757{
2758 ULONG Status;
2760 PCFDATA_NODE DataNode;
2761
2762 if (!BlockIsSplit)
2763 {
2767 &TotalCompSize);
2768
2769 DPRINT(MAX_TRACE, ("Block compressed. CurrentIBufferSize (%u) TotalCompSize(%u).\n",
2771
2774 }
2775
2776 DataNode = NewDataNode(CurrentFolderNode);
2777 if (!DataNode)
2778 {
2779 DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2780 return CAB_STATUS_NOMEMORY;
2781 }
2782
2783 DiskSize += sizeof(CFDATA);
2784
2785 if (MaxDiskSize > 0)
2786 /* Disk size is limited */
2788 else
2789 BlockIsSplit = false;
2790
2791 if (BlockIsSplit)
2792 {
2793 DataNode->Data.CompSize = (USHORT)(MaxDiskSize - DiskSize);
2794 DataNode->Data.UncompSize = 0;
2795 CreateNewDisk = true;
2796 }
2797 else
2798 {
2801 }
2802
2803 DataNode->Data.Checksum = 0;
2805
2806 // FIXME: MAKECAB.EXE does not like this checksum algorithm
2807 //DataNode->Data.Checksum = ComputeChecksum(CurrentOBuffer, DataNode->Data.CompSize, 0);
2808
2809 DPRINT(MAX_TRACE, ("Writing block. Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
2810 (UINT)DataNode->Data.Checksum,
2811 DataNode->Data.CompSize,
2812 DataNode->Data.UncompSize));
2813
2814 Status = ScratchFile->WriteBlock(&DataNode->Data,
2817 return Status;
2818
2820
2823
2824 CurrentOBuffer = (unsigned char*)CurrentOBuffer + DataNode->Data.CompSize;
2825 CurrentOBufferSize -= DataNode->Data.CompSize;
2826
2827 LastBlockStart += DataNode->Data.UncompSize;
2828
2829 if (!BlockIsSplit)
2830 {
2833 }
2834
2835 return CAB_STATUS_SUCCESS;
2836}
virtual ULONG Compress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
ULONG WriteBlock(PCFDATA Data, void *Buffer, PULONG BytesWritten)
void * OutputBuffer
Definition: cabinet.h:466
ULONG TotalCompSize
Definition: cabinet.h:467
ULONG CurrentOBufferSize
Definition: cabinet.h:469
void * CurrentOBuffer
Definition: cabinet.h:468
if(dx< 0)
Definition: linetemp.h:194
ULONG Checksum
Definition: cabinet.c:130

Referenced by WriteDisk(), and WriteFileToScratchStorage().

◆ WriteDisk()

ULONG CCabinet::WriteDisk ( ULONG  MoreDisks)

Definition at line 1311 of file cabinet.cxx.

1319{
1320 ULONG Status;
1321
1322 ContinueFile = false;
1323 for (auto it = FileList.begin(); it != FileList.end();)
1324 {
1327 return Status;
1328
1329 if (CreateNewDisk)
1330 {
1331 /* A data block could span more than two
1332 disks if MaxDiskSize is very small */
1333 while (CreateNewDisk)
1334 {
1335 DPRINT(MAX_TRACE, ("Creating new disk.\n"));
1336 CommitDisk(true);
1337 CloseDisk();
1338 NewDisk();
1339
1340 ContinueFile = true;
1341 CreateNewDisk = false;
1342
1343 DPRINT(MAX_TRACE, ("First on new disk. CurrentIBufferSize (%u) CurrentOBufferSize (%u).\n",
1345
1346 if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1347 {
1350 return Status;
1351 }
1352 }
1353 }
1354 else
1355 {
1356 ContinueFile = false;
1357 it++;
1358 }
1359 }
1360
1361 if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1362 {
1363 /* A data block could span more than two
1364 disks if MaxDiskSize is very small */
1365
1366 ASSERT(CreateNewDisk == false);
1367
1368 do
1369 {
1370 if (CreateNewDisk)
1371 {
1372 DPRINT(MID_TRACE, ("Creating new disk 2.\n"));
1373 CommitDisk(true);
1374 CloseDisk();
1375 NewDisk();
1376 CreateNewDisk = false;
1377 }
1378
1379 if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1380 {
1383 return Status;
1384 }
1385 } while (CreateNewDisk);
1386 }
1387 CommitDisk(MoreDisks);
1388
1389 return CAB_STATUS_SUCCESS;
1390}
bool ContinueFile
Definition: cabinet.h:483
ULONG WriteDataBlock()
Definition: cabinet.cxx:2751
ULONG NewDisk()
Definition: cabinet.cxx:1128
ULONG CommitDisk(ULONG MoreDisks)
Definition: cabinet.cxx:1393
ULONG WriteFileToScratchStorage(PCFFILE_NODE FileNode)
Definition: cabinet.cxx:1197

Referenced by CreateSimpleCabinet(), CDFParser::Parse(), and CDFParser::PerformNewCommand().

◆ WriteFileEntries()

ULONG CCabinet::WriteFileEntries ( )
private

Definition at line 2646 of file cabinet.cxx.

2652{
2653 bool SetCont = false;
2654
2655 DPRINT(MAX_TRACE, ("Writing file table.\n"));
2656
2657 for (PCFFILE_NODE File : FileList)
2658 {
2659 if (File->Commit)
2660 {
2661 /* Remove any continued files that ends in this disk */
2662 if (File->File.FileControlID == CAB_FILE_CONTINUED)
2663 File->Delete = true;
2664
2665 /* The file could end in the last (split) block and should therefore
2666 appear in the next disk too */
2667
2668 if ((File->File.FileOffset + File->File.FileSize >= LastBlockStart) &&
2669 (File->File.FileControlID <= CAB_FILE_MAX_FOLDER) && (BlockIsSplit))
2670 {
2671 File->File.FileControlID = CAB_FILE_SPLIT;
2672 File->Delete = false;
2673 SetCont = true;
2674 }
2675
2676 DPRINT(MAX_TRACE, ("Writing file entry. FileControlID (0x%X) FileOffset (0x%X) FileSize (%u) FileName (%s).\n",
2677 File->File.FileControlID, (UINT)File->File.FileOffset, (UINT)File->File.FileSize, File->FileName.c_str()));
2678
2679 if (fwrite(&File->File, sizeof(CFFILE), 1, FileHandle) < 1)
2680 {
2681 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2683 }
2684
2685 std::string fname = CreateCabFilename(File);
2686 if (fwrite(fname.c_str(), fname.length() + 1, 1, FileHandle) < 1)
2687 {
2688 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2690 }
2691
2692 if (SetCont)
2693 {
2694 File->File.FileControlID = CAB_FILE_CONTINUED;
2695 SetCont = false;
2696 }
2697 }
2698 }
2699 return CAB_STATUS_SUCCESS;
2700}

Referenced by CommitDisk().

◆ WriteFileToScratchStorage()

ULONG CCabinet::WriteFileToScratchStorage ( PCFFILE_NODE  FileNode)

Definition at line 1197 of file cabinet.cxx.

1205{
1206 ULONG BytesToRead;
1208 ULONG Status;
1209 ULONG Size;
1210
1211 if (!ContinueFile)
1212 {
1213 /* Try to open file */
1214 SourceFile = fopen(FileNode->FileName.c_str(), "rb");
1215 if (SourceFile == NULL)
1216 {
1217 DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileNameOnDisk.c_str()));
1218 return CAB_STATUS_NOFILE;
1219 }
1220
1221 if (CreateNewFolder)
1222 {
1223 /* There is always a new folder after
1224 a split file is completely stored */
1225 Status = NewFolder();
1227 return Status;
1228 CreateNewFolder = false;
1229 }
1230
1231 /* Call OnAdd event handler */
1232 OnAdd(&FileNode->File, FileNode->FileName.c_str());
1233
1234 TotalBytesLeft = FileNode->File.FileSize;
1235
1238 FileNode->File.FileControlID = (USHORT)(NextFolderNumber - 1);
1239 CurrentFolderNode->Commit = true;
1241
1242 Size = sizeof(CFFILE) + (ULONG)CreateCabFilename(FileNode).length() + 1;
1245 DiskSize += Size;
1246 }
1247
1248 FileNode->Commit = true;
1249
1250 if (TotalBytesLeft > 0)
1251 {
1252 do
1253 {
1255 BytesToRead = CAB_BLOCKSIZE - CurrentIBufferSize;
1256 else
1257 BytesToRead = TotalBytesLeft;
1258
1259 if ( (BytesRead = fread(CurrentIBuffer, 1, BytesToRead, SourceFile)) != BytesToRead )
1260 {
1261 DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%u) BytesRead (%u) CurrentIBufferSize (%u).\n",
1262 (UINT)BytesToRead, (UINT)BytesRead, (UINT)CurrentIBufferSize));
1264 }
1265
1266 CurrentIBuffer = (unsigned char*)CurrentIBuffer + BytesRead;
1268
1270 {
1273 return Status;
1274 }
1276 } while ((TotalBytesLeft > 0) && (!CreateNewDisk));
1277 }
1278
1279 if (TotalBytesLeft == 0)
1280 {
1282 FileNode->Delete = true;
1283
1284 if (FileNode->File.FileControlID > CAB_FILE_MAX_FOLDER)
1285 {
1287 CurrentFolderNode->Delete = true;
1288
1289 if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1290 {
1293 return Status;
1294 }
1295
1296 CreateNewFolder = true;
1297 }
1298 }
1299 else
1300 {
1301 if (FileNode->File.FileControlID <= CAB_FILE_MAX_FOLDER)
1302 FileNode->File.FileControlID = CAB_FILE_SPLIT;
1303 else
1305 }
1306
1307 return CAB_STATUS_SUCCESS;
1308}
virtual void OnAdd(PCFFILE Entry, const char *FileName)
Definition: cabinet.cxx:1780
ULONG TotalBytesLeft
Definition: cabinet.h:484
FILE * SourceFile
Definition: cabinet.h:482
bool Commit
Definition: cabinet.h:232
USHORT FileControlID
Definition: cabinet.h:183
ULONG FileOffset
Definition: cabinet.c:119

Referenced by WriteDisk().

◆ WriteFolderEntries()

ULONG CCabinet::WriteFolderEntries ( )
private

Definition at line 2618 of file cabinet.cxx.

2624{
2625 DPRINT(MAX_TRACE, ("Writing folder table.\n"));
2626
2627 for (PCFFOLDER_NODE FolderNode : FolderList)
2628 {
2629 if (FolderNode->Commit)
2630 {
2631 DPRINT(MAX_TRACE, ("Writing folder entry. CompressionType (0x%X) DataBlockCount (%d) DataOffset (0x%X).\n",
2632 FolderNode->Folder.CompressionType, FolderNode->Folder.DataBlockCount, (UINT)FolderNode->Folder.DataOffset));
2633
2634 if (fwrite(&FolderNode->Folder, sizeof(CFFOLDER), 1, FileHandle) < 1)
2635 {
2636 DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2638 }
2639 }
2640 }
2641
2642 return CAB_STATUS_SUCCESS;
2643}

Referenced by CommitDisk().

Member Data Documentation

◆ BlockIsSplit

bool CCabinet::BlockIsSplit
private

Definition at line 485 of file cabinet.h.

Referenced by CCabinet(), WriteDataBlock(), and WriteFileEntries().

◆ BytesLeftInBlock

ULONG CCabinet::BytesLeftInBlock
private

Definition at line 443 of file cabinet.h.

Referenced by CCabinet(), and ExtractFile().

◆ BytesLeftInCabinet

ULONG CCabinet::BytesLeftInCabinet
private

Definition at line 470 of file cabinet.h.

◆ CABHeader

CFHEADER CCabinet::CABHeader
private

◆ CabinetName

char CCabinet::CabinetName[256]
private

Definition at line 433 of file cabinet.h.

Referenced by CCabinet(), CommitDisk(), GetCabinetName(), Open(), and SetCabinetName().

◆ CabinetNext

char CCabinet::CabinetNext[256]
private

Definition at line 436 of file cabinet.h.

Referenced by CCabinet(), ExtractFile(), FindNext(), InitCabinetHeader(), Open(), and WriteCabinetHeader().

◆ CabinetPrev

char CCabinet::CabinetPrev[256]
private

Definition at line 434 of file cabinet.h.

Referenced by CCabinet(), InitCabinetHeader(), Open(), and WriteCabinetHeader().

◆ CabinetReserved

ULONG CCabinet::CabinetReserved
private

Definition at line 452 of file cabinet.h.

Referenced by Open().

◆ CabinetReservedFile

std::string CCabinet::CabinetReservedFile
private

Definition at line 446 of file cabinet.h.

Referenced by SetCabinetReservedFile().

◆ CabinetReservedFileBuffer

void* CCabinet::CabinetReservedFileBuffer
private

Definition at line 447 of file cabinet.h.

Referenced by CCabinet(), SetCabinetReservedFile(), WriteCabinetHeader(), and ~CCabinet().

◆ CabinetReservedFileSize

ULONG CCabinet::CabinetReservedFileSize
private

◆ Codec

CCABCodec* CCabinet::Codec
private

Definition at line 460 of file cabinet.h.

Referenced by CCabinet(), ExtractFile(), SelectCodec(), WriteDataBlock(), and ~CCabinet().

◆ CodecId

LONG CCabinet::CodecId
private

Definition at line 461 of file cabinet.h.

Referenced by CCabinet(), NewFolder(), and SelectCodec().

◆ CodecSelected

bool CCabinet::CodecSelected
private

Definition at line 462 of file cabinet.h.

Referenced by CCabinet(), IsCodecSelected(), SelectCodec(), and ~CCabinet().

◆ ContinueFile

bool CCabinet::ContinueFile
private

Definition at line 483 of file cabinet.h.

Referenced by WriteDisk(), and WriteFileToScratchStorage().

◆ CreateNewDisk

bool CCabinet::CreateNewDisk
private

Definition at line 478 of file cabinet.h.

Referenced by NewCabinet(), NewDisk(), WriteDataBlock(), WriteDisk(), and WriteFileToScratchStorage().

◆ CreateNewFolder

bool CCabinet::CreateNewFolder
private

Definition at line 479 of file cabinet.h.

Referenced by NewCabinet(), and WriteFileToScratchStorage().

◆ CriteriaList

std::list<PSEARCH_CRITERIA> CCabinet::CriteriaList
private

◆ CurrentDataNode

PCFDATA_NODE CCabinet::CurrentDataNode
private

Definition at line 457 of file cabinet.h.

Referenced by CCabinet(), and ExtractFile().

◆ CurrentDiskNumber

ULONG CCabinet::CurrentDiskNumber
private

◆ CurrentFolderNode

PCFFOLDER_NODE CCabinet::CurrentFolderNode
private

◆ CurrentIBuffer

void* CCabinet::CurrentIBuffer
private

Definition at line 464 of file cabinet.h.

Referenced by NewCabinet(), WriteDataBlock(), and WriteFileToScratchStorage().

◆ CurrentIBufferSize

ULONG CCabinet::CurrentIBufferSize
private

Definition at line 465 of file cabinet.h.

Referenced by NewCabinet(), WriteDataBlock(), WriteDisk(), and WriteFileToScratchStorage().

◆ CurrentOBuffer

void* CCabinet::CurrentOBuffer
private

Definition at line 468 of file cabinet.h.

Referenced by WriteDataBlock().

◆ CurrentOBufferSize

ULONG CCabinet::CurrentOBufferSize
private

Definition at line 469 of file cabinet.h.

Referenced by WriteDataBlock(), WriteDisk(), and WriteFileToScratchStorage().

◆ DataReserved

ULONG CCabinet::DataReserved
private

Definition at line 454 of file cabinet.h.

Referenced by Open().

◆ DestPath

std::string CCabinet::DestPath
private

Definition at line 445 of file cabinet.h.

Referenced by ExtractFile(), GetDestinationPath(), and SetDestinationPath().

◆ DiskNext

char CCabinet::DiskNext[256]
private

Definition at line 437 of file cabinet.h.

Referenced by CCabinet(), ExtractFile(), FindNext(), InitCabinetHeader(), Open(), and WriteCabinetHeader().

◆ DiskPrev

char CCabinet::DiskPrev[256]
private

Definition at line 435 of file cabinet.h.

Referenced by CCabinet(), InitCabinetHeader(), Open(), and WriteCabinetHeader().

◆ DiskSize

ULONG CCabinet::DiskSize
private

◆ FileHandle

◆ FileList

std::list<PCFFILE_NODE> CCabinet::FileList
private

Definition at line 458 of file cabinet.h.

◆ FileOpen

bool CCabinet::FileOpen
private

Definition at line 450 of file cabinet.h.

Referenced by CCabinet(), Close(), and Open().

◆ FolderList

std::list<PCFFOLDER_NODE> CCabinet::FolderList
private

Definition at line 455 of file cabinet.h.

◆ FolderReserved

ULONG CCabinet::FolderReserved
private

Definition at line 453 of file cabinet.h.

Referenced by Open().

◆ FolderUncompSize

ULONG CCabinet::FolderUncompSize
private

Definition at line 442 of file cabinet.h.

Referenced by CCabinet(), Open(), and ReadDataBlocks().

◆ InputBuffer

void* CCabinet::InputBuffer
private

Definition at line 463 of file cabinet.h.

Referenced by NewCabinet(), and WriteDataBlock().

◆ LastBlockStart

ULONG CCabinet::LastBlockStart
private

Definition at line 474 of file cabinet.h.

Referenced by NewFolder(), WriteDataBlock(), and WriteFileEntries().

◆ LastFileOffset

ULONG CCabinet::LastFileOffset
private

Definition at line 472 of file cabinet.h.

Referenced by ExtractFile(), and FindNext().

◆ MaxDiskSize

ULONG CCabinet::MaxDiskSize
private

Definition at line 475 of file cabinet.h.

Referenced by CCabinet(), SetMaxDiskSize(), and WriteDataBlock().

◆ NextFieldsSize

ULONG CCabinet::NextFieldsSize
private

Definition at line 439 of file cabinet.h.

Referenced by InitCabinetHeader(), and WriteCabinetHeader().

◆ NextFolderNumber

ULONG CCabinet::NextFolderNumber
private

Definition at line 486 of file cabinet.h.

Referenced by NewCabinet(), NewDisk(), NewFolder(), and WriteFileToScratchStorage().

◆ OutputBuffer

void* CCabinet::OutputBuffer
private

Definition at line 466 of file cabinet.h.

Referenced by WriteDataBlock().

◆ PrevCabinetNumber

ULONG CCabinet::PrevCabinetNumber
private

Definition at line 477 of file cabinet.h.

Referenced by InitCabinetHeader(), NewCabinet(), and WriteFileToScratchStorage().

◆ RestartSearch

bool CCabinet::RestartSearch
private

Definition at line 471 of file cabinet.h.

Referenced by ExtractFile(), FindFirst(), and FindNext().

◆ ReuseBlock

bool CCabinet::ReuseBlock
private

Definition at line 444 of file cabinet.h.

Referenced by CCabinet(), and ExtractFile().

◆ ScratchFile

class CCFDATAStorage* CCabinet::ScratchFile
private

◆ SourceFile

FILE* CCabinet::SourceFile
private

Definition at line 482 of file cabinet.h.

Referenced by WriteFileToScratchStorage().

◆ TotalBytesLeft

ULONG CCabinet::TotalBytesLeft
private

Definition at line 484 of file cabinet.h.

Referenced by WriteFileToScratchStorage().

◆ TotalCompSize

ULONG CCabinet::TotalCompSize
private

Definition at line 467 of file cabinet.h.

Referenced by WriteDataBlock().

◆ TotalFileSize

ULONG CCabinet::TotalFileSize
private

◆ TotalFolderSize

ULONG CCabinet::TotalFolderSize
private

◆ TotalHeaderSize

ULONG CCabinet::TotalHeaderSize
private

Definition at line 438 of file cabinet.h.

Referenced by InitCabinetHeader(), NewCabinet(), and WriteCabinetHeader().


The documentation for this class was generated from the following files: