ReactOS  0.4.14-dev-815-ge410a12
CCabinet Class Reference

#include <cabinet.h>

Inheritance diagram for CCabinet:
Collaboration diagram for CCabinet:

Public Member Functions

 CCabinet ()
 
virtual ~CCabinet ()
 
bool IsSeparator (char Char)
 
charConvertPath (char *Path, bool Allocate)
 
charGetFileName (char *Path)
 
void RemoveFileName (char *Path)
 
bool NormalizePath (char *Path, ULONG Length)
 
charGetCabinetName ()
 
void SetCabinetName (char *FileName)
 
void SetDestinationPath (char *DestinationPath)
 
bool SetCabinetReservedFile (char *FileName)
 
charGetCabinetReservedFile ()
 
charGetDestinationPath ()
 
ULONG GetCurrentDiskNumber ()
 
ULONG Open ()
 
void Close ()
 
ULONG FindFirst (PCAB_SEARCH Search)
 
ULONG FindNext (PCAB_SEARCH Search)
 
ULONG ExtractFile (char *FileName)
 
void SelectCodec (LONG Id)
 
bool IsCodecSelected ()
 
ULONG AddSearchCriteria (char *SearchCriteria)
 
void DestroySearchCriteria ()
 
bool HasSearchCriteria ()
 
bool CreateSimpleCabinet ()
 
bool SetCompressionCodec (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 (char *FileName)
 
void SetMaxDiskSize (ULONG Size)
 
virtual bool OnOverwrite (PCFFILE Entry, char *FileName)
 
virtual void OnExtract (PCFFILE Entry, char *FileName)
 
virtual void OnDiskChange (char *CabinetName, char *DiskLabel)
 
virtual void OnAdd (PCFFILE Entry, 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 (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 (char *FileName, 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
 
char DestPath [PATH_MAX]
 
char CabinetReservedFile [PATH_MAX]
 
voidCabinetReservedFileBuffer
 
ULONG CabinetReservedFileSize
 
FILEFileHandle
 
bool FileOpen
 
CFHEADER CABHeader
 
ULONG CabinetReserved
 
ULONG FolderReserved
 
ULONG DataReserved
 
PCFFOLDER_NODE FolderListHead
 
PCFFOLDER_NODE FolderListTail
 
PCFFOLDER_NODE CurrentFolderNode
 
PCFDATA_NODE CurrentDataNode
 
PCFFILE_NODE FileListHead
 
PCFFILE_NODE FileListTail
 
PSEARCH_CRITERIA CriteriaListHead
 
PSEARCH_CRITERIA CriteriaListTail
 
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
 
CCFDATAStorageScratchFile
 
FILESourceFile
 
bool ContinueFile
 
ULONG TotalBytesLeft
 
bool BlockIsSplit
 
ULONG NextFolderNumber
 

Detailed Description

Definition at line 321 of file cabinet.h.

Constructor & Destructor Documentation

◆ CCabinet()

CCabinet::CCabinet ( )

Definition at line 70 of file cabinet.cxx.

74 {
75  *CabinetName = '\0';
76  *CabinetPrev = '\0';
77  *DiskPrev = '\0';
78  *CabinetNext = '\0';
79  *DiskNext = '\0';
80  *DestPath = '\0';
81  *CabinetReservedFile = '\0';
82 
83  FileOpen = false;
86 
93 
94  Codec = NULL;
95  CodecId = -1;
96  CodecSelected = false;
97 
99  InputBuffer = NULL;
100  MaxDiskSize = 0;
101  BlockIsSplit = false;
102  ScratchFile = NULL;
103 
104  FolderUncompSize = 0;
105  BytesLeftInBlock = 0;
106  ReuseBlock = false;
108 }
PCFFILE_NODE FileListTail
Definition: cabinet.h:476
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
char CabinetReservedFile[PATH_MAX]
Definition: cabinet.h:462
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
CCABCodec * Codec
Definition: cabinet.h:479
PCFFOLDER_NODE FolderListTail
Definition: cabinet.h:472
void * OutputBuffer
Definition: cabinet.h:485
bool ReuseBlock
Definition: cabinet.h:460
PCFDATA_NODE CurrentDataNode
Definition: cabinet.h:474
ULONG MaxDiskSize
Definition: cabinet.h:494
bool CodecSelected
Definition: cabinet.h:481
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
char DiskPrev[256]
Definition: cabinet.h:451
smooth NULL
Definition: ftsmooth.c:416
char DiskNext[256]
Definition: cabinet.h:453
char CabinetPrev[256]
Definition: cabinet.h:450
LONG CodecId
Definition: cabinet.h:480
void * InputBuffer
Definition: cabinet.h:482
bool FileOpen
Definition: cabinet.h:466
bool BlockIsSplit
Definition: cabinet.h:504
ULONG BytesLeftInBlock
Definition: cabinet.h:459
ULONG FolderUncompSize
Definition: cabinet.h:458
char CabinetNext[256]
Definition: cabinet.h:452
char DestPath[PATH_MAX]
Definition: cabinet.h:461
ULONG CabinetReservedFileSize
Definition: cabinet.h:464
char CabinetName[256]
Definition: cabinet.h:449
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
void * CabinetReservedFileBuffer
Definition: cabinet.h:463
PSEARCH_CRITERIA CriteriaListTail
Definition: cabinet.h:478

◆ ~CCabinet()

CCabinet::~CCabinet ( )
virtual

Definition at line 111 of file cabinet.cxx.

115 {
117  {
121  }
122 
123  if (CodecSelected)
124  delete Codec;
125 }
#define free
Definition: debug_ros.c:5
CCABCodec * Codec
Definition: cabinet.h:479
bool CodecSelected
Definition: cabinet.h:481
smooth NULL
Definition: ftsmooth.c:416
ULONG CabinetReservedFileSize
Definition: cabinet.h:464
void * CabinetReservedFileBuffer
Definition: cabinet.h:463

Member Function Documentation

◆ AddFile()

ULONG CCabinet::AddFile ( char FileName)

Definition at line 1613 of file cabinet.cxx.

1621 {
1622  FILE* SrcFile;
1623  PCFFILE_NODE FileNode;
1624  char* NewFileName;
1625 
1626  NewFileName = (char*)malloc(strlen(FileName) + 1);
1627  if (!NewFileName)
1628  {
1629  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1630  return CAB_STATUS_NOMEMORY;
1631  }
1632  strcpy(NewFileName, FileName);
1633  ConvertPath(NewFileName, false);
1634 
1635  /* Try to open file */
1636  SrcFile = fopen(NewFileName, "rb");
1637  if (SrcFile == NULL)
1638  {
1639  DPRINT(MID_TRACE, ("File not found (%s).\n", NewFileName));
1640  free(NewFileName);
1641  return CAB_STATUS_CANNOT_OPEN;
1642  }
1643 
1644  FileNode = NewFileNode();
1645  if (!FileNode)
1646  {
1647  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1648  free(NewFileName);
1649  fclose(SrcFile);
1650  return CAB_STATUS_NOMEMORY;
1651  }
1652 
1653  FileNode->FolderNode = CurrentFolderNode;
1654  FileNode->FileName = NewFileName;
1655 
1656  /* FIXME: Check for and handle large files (>= 2GB) */
1657  FileNode->File.FileSize = GetSizeOfFile(SrcFile);
1658  if (FileNode->File.FileSize == (ULONG)-1)
1659  {
1660  DPRINT(MIN_TRACE, ("Cannot read from file.\n"));
1661  fclose(SrcFile);
1662  return CAB_STATUS_CANNOT_READ;
1663  }
1664 
1665  if (GetFileTimes(SrcFile, FileNode) != CAB_STATUS_SUCCESS)
1666  {
1667  DPRINT(MIN_TRACE, ("Cannot read file times.\n"));
1668  fclose(SrcFile);
1669  return CAB_STATUS_CANNOT_READ;
1670  }
1671 
1672  if (GetAttributesOnFile(FileNode) != CAB_STATUS_SUCCESS)
1673  {
1674  DPRINT(MIN_TRACE, ("Cannot read file attributes.\n"));
1675  fclose(SrcFile);
1676  return CAB_STATUS_CANNOT_READ;
1677  }
1678 
1679  fclose(SrcFile);
1680 
1681  return CAB_STATUS_SUCCESS;
1682 }
#define MID_TRACE
Definition: debug.h:15
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
CFFILE File
Definition: cabinet.h:221
ULONG GetAttributesOnFile(PCFFILE_NODE File)
Definition: cabinet.cxx:3141
#define CAB_STATUS_CANNOT_READ
Definition: cabinet.h:28
#define free
Definition: debug_ros.c:5
PCFFOLDER_NODE FolderNode
Definition: cabinet.h:226
char * FileName
Definition: cabinet.h:222
ULONG GetFileTimes(FILE *FileHandle, PCFFILE_NODE File)
Definition: cabinet.cxx:3099
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
PCFFILE_NODE NewFileNode()
Definition: cabinet.cxx:2258
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
char * ConvertPath(char *Path, bool Allocate)
Definition: cabinet.cxx:142
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:26
#define malloc
Definition: debug_ros.c:4
LONG GetSizeOfFile(FILE *handle)
Definition: cabinet.h:43

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

◆ AddSearchCriteria()

ULONG CCabinet::AddSearchCriteria ( char SearchCriteria)

Definition at line 285 of file cabinet.cxx.

293 {
294  PSEARCH_CRITERIA Criteria;
295 
296  // Add the criteria to the list of search criteria
297  Criteria = (PSEARCH_CRITERIA)malloc(sizeof(SEARCH_CRITERIA));
298  if(!Criteria)
299  {
300  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
301  return CAB_STATUS_NOMEMORY;
302  }
303 
304  Criteria->Prev = CriteriaListTail;
305  Criteria->Next = NULL;
306 
307  if(CriteriaListTail)
308  CriteriaListTail->Next = Criteria;
309  else
310  CriteriaListHead = Criteria;
311 
312  CriteriaListTail = Criteria;
313 
314  // Set the actual criteria string
315  Criteria->Search = (char*)malloc(strlen(SearchCriteria) + 1);
316  if (!Criteria->Search)
317  {
318  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
319  return CAB_STATUS_NOMEMORY;
320  }
321 
322  strcpy(Criteria->Search, SearchCriteria);
323 
324  return CAB_STATUS_SUCCESS;
325 }
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
struct _SEARCH_CRITERIA * Next
Definition: cabinet.h:231
struct _SEARCH_CRITERIA * PSEARCH_CRITERIA
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
char * Search
Definition: cabinet.h:233
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
struct _SEARCH_CRITERIA * Prev
Definition: cabinet.h:232
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define MIN_TRACE
Definition: debug.h:14
#define malloc
Definition: debug_ros.c:4
PSEARCH_CRITERIA CriteriaListTail
Definition: cabinet.h:478

Referenced by CCABManager::ParseCmdline().

◆ Close()

void CCabinet::Close ( void  )

Definition at line 625 of file cabinet.cxx.

629 {
630  if (FileOpen)
631  {
633  FileOpen = false;
634  }
635 }
FILE * FileHandle
Definition: cabinet.h:465
bool FileOpen
Definition: cabinet.h:466
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)

Referenced by CloseCabinet().

◆ CloseCabinet()

ULONG CCabinet::CloseCabinet ( )

Definition at line 1575 of file cabinet.cxx.

1581 {
1582  ULONG Status;
1583 
1584  DestroyFileNodes();
1585 
1587 
1588  if (InputBuffer)
1589  {
1590  free(InputBuffer);
1591  InputBuffer = NULL;
1592  }
1593 
1594  if (OutputBuffer)
1595  {
1596  free(OutputBuffer);
1597  OutputBuffer = NULL;
1598  }
1599 
1600  Close();
1601 
1602  if (ScratchFile)
1603  {
1604  Status = ScratchFile->Destroy();
1605  delete ScratchFile;
1606  return Status;
1607  }
1608 
1609  return CAB_STATUS_SUCCESS;
1610 }
#define free
Definition: debug_ros.c:5
void * OutputBuffer
Definition: cabinet.h:485
void DestroyFolderNodes()
Definition: cabinet.cxx:2408
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
smooth NULL
Definition: ftsmooth.c:416
void * InputBuffer
Definition: cabinet.h:482
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Status
Definition: gdiplustypes.h:24
void DestroyFileNodes()
Definition: cabinet.cxx:2340
unsigned int ULONG
Definition: retypes.h:1
void Close()
Definition: cabinet.cxx:625

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

◆ CloseDisk()

ULONG CCabinet::CloseDisk ( )

Definition at line 1557 of file cabinet.cxx.

1563 {
1565 
1566  /* Destroy folder nodes that are completely stored */
1568 
1570 
1571  return CAB_STATUS_SUCCESS;
1572 }
void DestroyDeletedFolderNodes()
Definition: cabinet.cxx:2429
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
void DestroyDeletedFileNodes()
Definition: cabinet.cxx:2362
ULONG CurrentDiskNumber
Definition: cabinet.h:448

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

◆ CommitDataBlocks()

ULONG CCabinet::CommitDataBlocks ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2926 of file cabinet.cxx.

2934 {
2935  PCFDATA_NODE DataNode;
2936  ULONG BytesRead;
2937  ULONG Status;
2938 
2939  DataNode = FolderNode->DataListHead;
2940  if (DataNode != NULL)
2942 
2943  while (DataNode != NULL)
2944  {
2945  DPRINT(MAX_TRACE, ("Reading block at (0x%X) CompSize (%u) UncompSize (%u).\n",
2946  (UINT)DataNode->ScratchFilePosition,
2947  DataNode->Data.CompSize,
2948  DataNode->Data.UncompSize));
2949 
2950  /* InputBuffer is free for us to use here, so we use it and avoid a
2951  memory allocation. OutputBuffer can't be used here because it may
2952  still contain valid data (if a data block spans two or more disks) */
2954  if (Status != CAB_STATUS_SUCCESS)
2955  {
2956  DPRINT(MIN_TRACE, ("Cannot read from scratch file (%u).\n", (UINT)Status));
2957  return Status;
2958  }
2959 
2960  if (fwrite(&DataNode->Data, sizeof(CFDATA), 1, FileHandle) < 1)
2961  {
2962  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2963  return CAB_STATUS_CANNOT_WRITE;
2964  }
2965 
2966  if (fwrite(InputBuffer, DataNode->Data.CompSize, 1, FileHandle) < 1)
2967  {
2968  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2969  return CAB_STATUS_CANNOT_WRITE;
2970  }
2971 
2972  DataNode = DataNode->Next;
2973  }
2974  return CAB_STATUS_SUCCESS;
2975 }
FILE * FileHandle
Definition: cabinet.h:465
ULONG ScratchFilePosition
Definition: cabinet.h:196
PCFDATA_NODE DataListHead
Definition: cabinet.h:209
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)
CFDATA Data
Definition: cabinet.h:199
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:29
Definition: fci.c:101
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
ULONG ReadBlock(PCFDATA Data, void *Buffer, PULONG BytesRead)
void * InputBuffer
Definition: cabinet.h:482
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Status
Definition: gdiplustypes.h:24
#define MAX_TRACE
Definition: debug.h:16
unsigned int UINT
Definition: ndis.h:50
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
struct _CFDATA_NODE * Next
Definition: cabinet.h:194

Referenced by CommitDisk().

◆ CommitDisk()

ULONG CCabinet::CommitDisk ( ULONG  MoreDisks)

Definition at line 1488 of file cabinet.cxx.

1496 {
1497  PCFFOLDER_NODE FolderNode;
1498  ULONG Status;
1499 
1501 
1502  /* Create file, fail if it already exists */
1503  FileHandle = fopen(CabinetName, "rb");
1504  if (FileHandle != NULL)
1505  {
1506  fclose(FileHandle);
1507  /* If file exists, ask to overwrite file */
1509  {
1510  FileHandle = fopen(CabinetName, "w+b");
1511  if (FileHandle == NULL)
1512  return CAB_STATUS_CANNOT_CREATE;
1513  }
1514  else
1515  return CAB_STATUS_FILE_EXISTS;
1516 
1517  }
1518  else
1519  {
1520  FileHandle = fopen(CabinetName, "w+b");
1521  if (FileHandle == NULL)
1522  return CAB_STATUS_CANNOT_CREATE;
1523  }
1524 
1525  WriteCabinetHeader(MoreDisks != 0);
1526 
1528  if (Status != CAB_STATUS_SUCCESS)
1529  return Status;
1530 
1531  /* Write file entries */
1532  WriteFileEntries();
1533 
1534  /* Write data blocks */
1535  FolderNode = FolderListHead;
1536  while (FolderNode != NULL)
1537  {
1538  if (FolderNode->Commit)
1539  {
1540  Status = CommitDataBlocks(FolderNode);
1541  if (Status != CAB_STATUS_SUCCESS)
1542  return Status;
1543  /* Remove data blocks for folder */
1544  DestroyDataNodes(FolderNode);
1545  }
1546  FolderNode = FolderNode->Next;
1547  }
1548 
1549  fclose(FileHandle);
1550 
1551  ScratchFile->Truncate();
1552 
1553  return CAB_STATUS_SUCCESS;
1554 }
void DestroyDataNodes(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2318
FILE * FileHandle
Definition: cabinet.h:465
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
ULONG WriteCabinetHeader(bool MoreDisks)
Definition: cabinet.cxx:2693
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
smooth NULL
Definition: ftsmooth.c:416
ULONG WriteFolderEntries()
Definition: cabinet.cxx:2834
#define CAB_STATUS_CANNOT_CREATE
Definition: cabinet.h:27
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
ULONG WriteFileEntries()
Definition: cabinet.cxx:2866
Status
Definition: gdiplustypes.h:24
ULONG CurrentDiskNumber
Definition: cabinet.h:448
char CabinetName[256]
Definition: cabinet.h:449
virtual bool OnOverwrite(PCFFILE Entry, char *FileName)
Definition: cabinet.cxx:1847
#define CAB_STATUS_FILE_EXISTS
Definition: cabinet.h:30
unsigned int ULONG
Definition: retypes.h:1
virtual bool OnCabinetName(ULONG Number, char *Name)
Definition: cabinet.cxx:1914
ULONG CommitDataBlocks(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2926

Referenced by WriteDisk().

◆ ComputeChecksum()

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

Definition at line 2472 of file cabinet.cxx.

2484 {
2485  int UlongCount; // Number of ULONGs in block
2486  ULONG Checksum; // Checksum accumulator
2487  unsigned char* pb;
2488  ULONG ul;
2489 
2490  /* FIXME: Doesn't seem to be correct. EXTRACT.EXE
2491  won't accept checksums computed by this routine */
2492 
2493  DPRINT(MIN_TRACE, ("Checksumming buffer (0x%p) Size (%u)\n", Buffer, (UINT)Size));
2494 
2495  UlongCount = Size / 4; // Number of ULONGs
2496  Checksum = Seed; // Init checksum
2497  pb = (unsigned char*)Buffer; // Start at front of data block
2498 
2499  /* Checksum integral multiple of ULONGs */
2500  while (UlongCount-- > 0)
2501  {
2502  /* NOTE: Build ULONG in big/little-endian independent manner */
2503  ul = *pb++; // Get low-order byte
2504  ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte
2505  ul |= (((ULONG)(*pb++)) << 16); // Add 3nd byte
2506  ul |= (((ULONG)(*pb++)) << 24); // Add 4th byte
2507 
2508  Checksum ^= ul; // Update checksum
2509  }
2510 
2511  /* Checksum remainder bytes */
2512  ul = 0;
2513  switch (Size % 4)
2514  {
2515  case 3:
2516  ul |= (((ULONG)(*pb++)) << 16); // Add 3rd byte
2517  case 2:
2518  ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte
2519  case 1:
2520  ul |= *pb++; // Get low-order byte
2521  default:
2522  break;
2523  }
2524  Checksum ^= ul; // Update checksum
2525 
2526  /* Return computed checksum */
2527  return Checksum;
2528 }
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
unsigned int UINT
Definition: ndis.h:50
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14

◆ ConvertDateAndTime()

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

Definition at line 3067 of file cabinet.cxx.

3078 {
3079  struct tm *timedef;
3080 
3081  timedef = localtime(Time);
3082 
3083  DPRINT(MAX_TRACE, ("day: %d, mon: %d, year:%d, hour: %d, min: %d, sec: %d\n",
3084  timedef->tm_mday, timedef->tm_mon, timedef->tm_year,
3085  timedef->tm_sec, timedef->tm_min, timedef->tm_hour));
3086 
3087  *DosDate = ((timedef->tm_mday + 1) << 0)
3088  | ((timedef->tm_mon + 1) << 5)
3089  | (((timedef->tm_year + 1900) - 1980) << 9);
3090 
3091  *DosTime = (timedef->tm_sec << 0)
3092  | (timedef->tm_min << 5)
3093  | (timedef->tm_hour << 11);
3094 }
int tm_min
Definition: time.h:78
int tm_mday
Definition: time.h:80
int tm_year
Definition: time.h:82
void DPRINT(...)
Definition: polytest.cpp:61
int tm_mon
Definition: time.h:81
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:424
#define MAX_TRACE
Definition: debug.h:16
int tm_sec
Definition: time.h:77
int tm_hour
Definition: time.h:79
static PLARGE_INTEGER Time
Definition: time.c:105

Referenced by GetFileTimes().

◆ ConvertPath()

char * CCabinet::ConvertPath ( char Path,
bool  Allocate 
)

Definition at line 142 of file cabinet.cxx.

152 {
153  char *newpath;
154  int i;
155 
156  if (Allocate)
157  newpath = strdup(Path);
158  else
159  newpath = Path;
160 
161  i = 0;
162  while (Path[i] != 0)
163  {
164 #if defined(_WIN32)
165  if (Path[i] == '/')
166  newpath[i] = '\\';
167  else
168 #else
169  if (Path[i] == '\\')
170  newpath[i] = '/';
171  else
172 #endif
173  newpath[i] = Path[i];
174 
175  i++;
176  }
177  newpath[i] = 0;
178 
179  return(newpath);
180 }
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:656
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
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
PRTL_UNICODE_STRING_BUFFER Path

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

◆ CreateSimpleCabinet()

bool CCabinet::CreateSimpleCabinet ( )

Definition at line 1684 of file cabinet.cxx.

1688 {
1689  bool bRet = false;
1690  char* pszFile;
1691  char szFilePath[PATH_MAX];
1692  char szFile[PATH_MAX];
1693  PSEARCH_CRITERIA Criteria;
1694  ULONG Status;
1695 
1696 #if defined(_WIN32)
1697  HANDLE hFind;
1698  WIN32_FIND_DATA FindFileData;
1699 #else
1700  DIR* dirp;
1701  struct dirent* dp;
1702  struct stat stbuf;
1703 #endif
1704 
1705  // Initialize a new cabinet
1706  Status = NewCabinet();
1707  if (Status != CAB_STATUS_SUCCESS)
1708  {
1709  DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
1710  goto cleanup2;
1711  }
1712 
1713  // Add each file in the criteria list
1714  Criteria = CriteriaListHead;
1715 
1716  while(Criteria)
1717  {
1718  // Store the file path with a trailing slash in szFilePath
1719  ConvertPath(Criteria->Search, false);
1720  pszFile = strrchr(Criteria->Search, DIR_SEPARATOR_CHAR);
1721 
1722  if(pszFile)
1723  {
1724  // Set the pointer to the start of the file name, not the slash
1725  pszFile++;
1726 
1727  strncpy(szFilePath, Criteria->Search, pszFile - Criteria->Search);
1728  szFilePath[pszFile - Criteria->Search] = 0;
1729  }
1730  else
1731  {
1732  pszFile = Criteria->Search;
1733 
1734 #if defined(_WIN32)
1735  szFilePath[0] = 0;
1736 #else
1737  // needed for opendir()
1738  strcpy(szFilePath, "./");
1739 #endif
1740  }
1741 
1742 #if defined(_WIN32)
1743  // Windows: Use the easy FindFirstFile/FindNextFile API for getting all files and checking them against the pattern
1744  hFind = FindFirstFile(Criteria->Search, &FindFileData);
1745 
1746  // Don't stop if a search criteria is not found
1748  {
1749  DPRINT(MIN_TRACE, ("FindFirstFile failed, Criteria: %s, error code is %u\n", Criteria->Search, (UINT)GetLastError()));
1750  goto cleanup;
1751  }
1752 
1753  do
1754  {
1755  if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
1756  {
1757  strcpy(szFile, szFilePath);
1758  strcat(szFile, FindFileData.cFileName);
1759 
1760  Status = AddFile(szFile);
1761 
1762  if(Status != CAB_STATUS_SUCCESS)
1763  {
1764  DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
1765  FindClose(hFind);
1766  goto cleanup;
1767  }
1768  }
1769  }
1770  while(FindNextFile(hFind, &FindFileData));
1771 
1772  FindClose(hFind);
1773 #else
1774  // 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
1775  dirp = opendir(szFilePath);
1776 
1777  if(dirp)
1778  {
1779  while( (dp = readdir(dirp)) )
1780  {
1781  strcpy(szFile, szFilePath);
1782  strcat(szFile, dp->d_name);
1783 
1784  if(stat(szFile, &stbuf) == 0)
1785  {
1786  if(stbuf.st_mode != S_IFDIR)
1787  {
1788  if(MatchFileNamePattern(dp->d_name, pszFile))
1789  {
1790  Status = AddFile(szFile);
1791 
1792  if(Status != CAB_STATUS_SUCCESS)
1793  {
1794  DPRINT(MIN_TRACE, ("Cannot add file to cabinet (%u).\n", (UINT)Status));
1795  goto cleanup;
1796  }
1797  }
1798  }
1799  }
1800  else
1801  {
1802  DPRINT(MIN_TRACE, ("stat failed, error code is %i\n", errno));
1803  goto cleanup;
1804  }
1805  }
1806 
1807  closedir(dirp);
1808  }
1809 #endif
1810 
1811  Criteria = Criteria->Next;
1812  }
1813 
1814  Status = WriteDisk(false);
1815  if (Status == CAB_STATUS_SUCCESS)
1816  Status = CloseDisk();
1817  if (Status != CAB_STATUS_SUCCESS)
1818  {
1819  DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
1820  goto cleanup;
1821  }
1822 
1823 cleanup:
1824  CloseCabinet();
1825  bRet = true;
1826 
1827 cleanup2:
1829  return bRet;
1830 }
static WCHAR szFilePath[]
Definition: qotd.c:14
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ULONG AddFile(char *FileName)
Definition: cabinet.cxx:1613
ULONG CloseCabinet()
Definition: cabinet.cxx:1575
ULONG NewCabinet()
Definition: cabinet.cxx:1148
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
Definition: fatfs.h:198
DIR *__cdecl opendir(const char *)
#define DIR_SEPARATOR_CHAR
Definition: config.h:5
struct _SEARCH_CRITERIA * Next
Definition: cabinet.h:231
Definition: dirent.h:39
void DPRINT(...)
Definition: polytest.cpp:61
#define FindFirstFile
Definition: winbase.h:3616
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define S_IFDIR
Definition: acwin.h:115
char * d_name
Definition: dirent.h:29
char * Search
Definition: cabinet.h:233
#define FindNextFile
Definition: winbase.h:3622
void DestroySearchCriteria()
Definition: cabinet.cxx:327
#define PATH_MAX
Definition: types.h:280
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Definition: stat.h:55
int __cdecl closedir(DIR *)
Status
Definition: gdiplustypes.h:24
struct dirent *__cdecl readdir(DIR *)
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
unsigned int UINT
Definition: ndis.h:50
char * ConvertPath(char *Path, bool Allocate)
Definition: cabinet.cxx:142
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
char * cleanup(char *str)
Definition: wpickclick.c:99
bool MatchFileNamePattern(char *FileName, char *Pattern)
Definition: cabinet.cxx:2551
ULONG CloseDisk()
Definition: cabinet.cxx:1557
ULONG WriteDisk(ULONG MoreDisks)
Definition: cabinet.cxx:1402
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by CCABManager::Run().

◆ DestroyDataNodes()

void CCabinet::DestroyDataNodes ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2318 of file cabinet.cxx.

2324 {
2325  PCFDATA_NODE PrevNode;
2326  PCFDATA_NODE NextNode;
2327 
2328  NextNode = FolderNode->DataListHead;
2329  while (NextNode != NULL)
2330  {
2331  PrevNode = NextNode->Next;
2332  free(NextNode);
2333  NextNode = PrevNode;
2334  }
2335  FolderNode->DataListHead = NULL;
2336  FolderNode->DataListTail = NULL;
2337 }
PCFDATA_NODE DataListTail
Definition: cabinet.h:210
PCFDATA_NODE DataListHead
Definition: cabinet.h:209
#define free
Definition: debug_ros.c:5
smooth NULL
Definition: ftsmooth.c:416
struct _CFDATA_NODE * Next
Definition: cabinet.h:194

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

◆ DestroyDeletedFileNodes()

void CCabinet::DestroyDeletedFileNodes ( )
private

Definition at line 2362 of file cabinet.cxx.

2366 {
2367  PCFFILE_NODE CurNode;
2368  PCFFILE_NODE NextNode;
2369 
2370  CurNode = FileListHead;
2371  while (CurNode != NULL)
2372  {
2373  NextNode = CurNode->Next;
2374 
2375  if (CurNode->Delete)
2376  {
2377  if (CurNode->Prev != NULL)
2378  CurNode->Prev->Next = CurNode->Next;
2379  else
2380  {
2381  FileListHead = CurNode->Next;
2382  if (FileListHead)
2383  FileListHead->Prev = NULL;
2384  }
2385 
2386  if (CurNode->Next != NULL)
2387  CurNode->Next->Prev = CurNode->Prev;
2388  else
2389  {
2390  FileListTail = CurNode->Prev;
2391  if (FileListTail)
2392  FileListTail->Next = NULL;
2393  }
2394 
2395  DPRINT(MAX_TRACE, ("Deleting file: '%s'\n", CurNode->FileName));
2396 
2397  TotalFileSize -= (sizeof(CFFILE) + (ULONG)strlen(GetFileName(CurNode->FileName)) + 1);
2398 
2399  if (CurNode->FileName)
2400  free(CurNode->FileName);
2401  free(CurNode);
2402  }
2403  CurNode = NextNode;
2404  }
2405 }
PCFFILE_NODE FileListTail
Definition: cabinet.h:476
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define free
Definition: debug_ros.c:5
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
struct _CFFILE CFFILE
char * FileName
Definition: cabinet.h:222
char * GetFileName(char *Path)
Definition: cabinet.cxx:183
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
#define MAX_TRACE
Definition: debug.h:16
bool Delete
Definition: cabinet.h:225
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
unsigned int ULONG
Definition: retypes.h:1
ULONG TotalFileSize
Definition: cabinet.h:457
struct _CFFILE_NODE * Prev
Definition: cabinet.h:220

Referenced by CloseDisk().

◆ DestroyDeletedFolderNodes()

void CCabinet::DestroyDeletedFolderNodes ( )
private

Definition at line 2429 of file cabinet.cxx.

2433 {
2434  PCFFOLDER_NODE CurNode;
2435  PCFFOLDER_NODE NextNode;
2436 
2437  CurNode = FolderListHead;
2438  while (CurNode != NULL)
2439  {
2440  NextNode = CurNode->Next;
2441 
2442  if (CurNode->Delete)
2443  {
2444  if (CurNode->Prev != NULL)
2445  CurNode->Prev->Next = CurNode->Next;
2446  else
2447  {
2448  FolderListHead = CurNode->Next;
2449  if (FolderListHead)
2451  }
2452 
2453  if (CurNode->Next != NULL)
2454  CurNode->Next->Prev = CurNode->Prev;
2455  else
2456  {
2457  FolderListTail = CurNode->Prev;
2458  if (FolderListTail)
2460  }
2461 
2462  DestroyDataNodes(CurNode);
2463  free(CurNode);
2464 
2465  TotalFolderSize -= sizeof(CFFOLDER);
2466  }
2467  CurNode = NextNode;
2468  }
2469 }
void DestroyDataNodes(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2318
struct _CFFOLDER_NODE * Prev
Definition: cabinet.h:205
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
#define free
Definition: debug_ros.c:5
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
PCFFOLDER_NODE FolderListTail
Definition: cabinet.h:472
struct _CFFOLDER CFFOLDER
smooth NULL
Definition: ftsmooth.c:416
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
ULONG TotalFolderSize
Definition: cabinet.h:456

Referenced by CloseDisk().

◆ DestroyFileNodes()

void CCabinet::DestroyFileNodes ( )
private

Definition at line 2340 of file cabinet.cxx.

2344 {
2345  PCFFILE_NODE PrevNode;
2346  PCFFILE_NODE NextNode;
2347 
2348  NextNode = FileListHead;
2349  while (NextNode != NULL)
2350  {
2351  PrevNode = NextNode->Next;
2352  if (NextNode->FileName)
2353  free(NextNode->FileName);
2354  free(NextNode);
2355  NextNode = PrevNode;
2356  }
2357  FileListHead = NULL;
2358  FileListTail = NULL;
2359 }
PCFFILE_NODE FileListTail
Definition: cabinet.h:476
#define free
Definition: debug_ros.c:5
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
char * FileName
Definition: cabinet.h:222
smooth NULL
Definition: ftsmooth.c:416
PCFFILE_NODE FileListHead
Definition: cabinet.h:475

Referenced by CloseCabinet().

◆ DestroyFolderNodes()

void CCabinet::DestroyFolderNodes ( )
private

Definition at line 2408 of file cabinet.cxx.

2412 {
2413  PCFFOLDER_NODE PrevNode;
2414  PCFFOLDER_NODE NextNode;
2415 
2416  NextNode = FolderListHead;
2417  while (NextNode != NULL)
2418  {
2419  PrevNode = NextNode->Next;
2420  DestroyDataNodes(NextNode);
2421  free(NextNode);
2422  NextNode = PrevNode;
2423  }
2424  FolderListHead = NULL;
2425  FolderListTail = NULL;
2426 }
void DestroyDataNodes(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2318
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
#define free
Definition: debug_ros.c:5
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
PCFFOLDER_NODE FolderListTail
Definition: cabinet.h:472
smooth NULL
Definition: ftsmooth.c:416

Referenced by CloseCabinet().

◆ DestroySearchCriteria()

void CCabinet::DestroySearchCriteria ( )

Definition at line 327 of file cabinet.cxx.

331 {
332  PSEARCH_CRITERIA Criteria;
333  PSEARCH_CRITERIA NextCriteria;
334 
335  Criteria = CriteriaListHead;
336 
337  while(Criteria)
338  {
339  NextCriteria = Criteria->Next;
340 
341  free(Criteria->Search);
342  free(Criteria);
343 
344  Criteria = NextCriteria;
345  }
346 
349 }
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
#define free
Definition: debug_ros.c:5
struct _SEARCH_CRITERIA * Next
Definition: cabinet.h:231
smooth NULL
Definition: ftsmooth.c:416
char * Search
Definition: cabinet.h:233
PSEARCH_CRITERIA CriteriaListTail
Definition: cabinet.h:478

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

◆ ExtractFile()

ULONG CCabinet::ExtractFile ( char FileName)

Definition at line 739 of file cabinet.cxx.

747 {
748  ULONG Size;
749  ULONG Offset;
751  ULONG BytesToRead;
753  ULONG BytesSkipped;
754  ULONG BytesToWrite;
755  ULONG TotalBytesRead;
756  ULONG CurrentOffset;
757  PUCHAR Buffer;
759  FILE* DestFile;
761  CFDATA CFData;
762  ULONG Status;
763  bool Skip;
764 #if defined(_WIN32)
765  FILETIME FileTime;
766 #endif
767  CHAR DestName[PATH_MAX];
768  CHAR TempName[PATH_MAX];
769 
771  if (Status != CAB_STATUS_SUCCESS)
772  {
773  DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
774  return Status;
775  }
776 
777  LastFileOffset = File->File.FileOffset;
778 
779  switch (CurrentFolderNode->Folder.CompressionType & CAB_COMP_MASK)
780  {
781  case CAB_COMP_NONE:
783  break;
784 
785  case CAB_COMP_MSZIP:
787  break;
788 
789  default:
790  return CAB_STATUS_UNSUPPCOMP;
791  }
792 
793  DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
794  (UINT)File->File.FileOffset,
795  (UINT)File->File.FileSize,
796  (UINT)File->DataBlock->AbsoluteOffset,
797  (UINT)File->DataBlock->UncompOffset));
798 
799  strcpy(DestName, DestPath);
800  strcat(DestName, FileName);
801 
802  /* Create destination file, fail if it already exists */
803  DestFile = fopen(DestName, "rb");
804  if (DestFile != NULL)
805  {
806  fclose(DestFile);
807  /* If file exists, ask to overwrite file */
808  if (OnOverwrite(&File->File, FileName))
809  {
810  DestFile = fopen(DestName, "w+b");
811  if (DestFile == NULL)
813  }
814  else
815  return CAB_STATUS_FILE_EXISTS;
816  }
817  else
818  {
819  DestFile = fopen(DestName, "w+b");
820  if (DestFile == NULL)
822  }
823 
824 #if defined(_WIN32)
825  if (!DosDateTimeToFileTime(File->File.FileDate, File->File.FileTime, &FileTime))
826  {
827  fclose(DestFile);
828  DPRINT(MIN_TRACE, ("DosDateTimeToFileTime() failed (%u).\n", (UINT)GetLastError()));
830  }
831 
832  SetFileTime(DestFile, NULL, &FileTime, NULL);
833 #else
834  //DPRINT(MIN_TRACE, ("FIXME: DosDateTimeToFileTime\n"));
835 #endif
836 
837  SetAttributesOnFile(DestName, File->File.Attributes);
838 
839  Buffer = (PUCHAR)malloc(CAB_BLOCKSIZE + 12); // This should be enough
840  if (!Buffer)
841  {
842  fclose(DestFile);
843  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
844  return CAB_STATUS_NOMEMORY;
845  }
846 
847  /* Call OnExtract event handler */
849 
850  /* Search to start of file */
851  if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
852  {
853  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
854  fclose(DestFile);
855  free(Buffer);
856  return CAB_STATUS_INVALID_CAB;
857  }
858 
859  Size = File->File.FileSize;
860  Offset = File->File.FileOffset;
861  CurrentOffset = File->DataBlock->UncompOffset;
862 
863  Skip = true;
864 
865  ReuseBlock = (CurrentDataNode == File->DataBlock);
866  if (Size > 0)
867  {
868  do
869  {
870  DPRINT(MAX_TRACE, ("CO (0x%X) ReuseBlock (%u) Offset (0x%X) Size (%d) BytesLeftInBlock (%d)\n",
871  (UINT)File->DataBlock->UncompOffset, (UINT)ReuseBlock, (UINT)Offset, (UINT)Size,
873 
874  if (/*(CurrentDataNode != File->DataBlock) &&*/ (!ReuseBlock) || (BytesLeftInBlock <= 0))
875  {
876  DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
877 
879  TotalBytesRead = 0;
880  do
881  {
882  DPRINT(MAX_TRACE, ("Size (%u bytes).\n", (UINT)Size));
883 
884  if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
885  CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
886  {
887  fclose(DestFile);
888  free(Buffer);
889  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
890  return CAB_STATUS_INVALID_CAB;
891  }
892 
893  DPRINT(MAX_TRACE, ("Data block: Checksum (0x%X) CompSize (%u bytes) UncompSize (%u bytes)\n",
894  (UINT)CFData.Checksum,
895  CFData.CompSize,
896  CFData.UncompSize));
897 
898  ASSERT(CFData.CompSize <= CAB_BLOCKSIZE + 12);
899 
900  BytesToRead = CFData.CompSize;
901 
902  DPRINT(MAX_TRACE, ("Read: (0x%lX,0x%lX).\n",
903  (unsigned long)CurrentBuffer, (unsigned long)Buffer));
904 
905  if (((Status = ReadBlock(CurrentBuffer, BytesToRead, &BytesRead)) !=
906  CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead))
907  {
908  fclose(DestFile);
909  free(Buffer);
910  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
911  return CAB_STATUS_INVALID_CAB;
912  }
913 
914  /* FIXME: Does not work with files generated by makecab.exe */
915 /*
916  if (CFData.Checksum != 0)
917  {
918  ULONG Checksum = ComputeChecksum(CurrentBuffer, BytesRead, 0);
919  if (Checksum != CFData.Checksum)
920  {
921  CloseFile(DestFile);
922  free(Buffer);
923  DPRINT(MIN_TRACE, ("Bad checksum (is 0x%X, should be 0x%X).\n",
924  Checksum, CFData.Checksum));
925  return CAB_STATUS_INVALID_CAB;
926  }
927  }
928 */
929  TotalBytesRead += BytesRead;
930 
932 
933  if (CFData.UncompSize == 0)
934  {
935  if (strlen(DiskNext) == 0)
936  {
937  fclose(DestFile);
938  free(Buffer);
939  return CAB_STATUS_NOFILE;
940  }
941 
942  /* CloseCabinet() will destroy all file entries so in case
943  FileName refers to the FileName field of a CFFOLDER_NODE
944  structure, we have to save a copy of the filename */
945  strcpy(TempName, FileName);
946 
947  CloseCabinet();
948 
950 
952 
953  Status = Open();
954  if (Status != CAB_STATUS_SUCCESS)
955  {
956  fclose(DestFile);
957  free(Buffer);
958  return Status;
959  }
960 
961  /* The first data block of the file will not be
962  found as it is located in the previous file */
963  Status = LocateFile(TempName, &File);
964  if (Status == CAB_STATUS_NOFILE)
965  {
966  DPRINT(MID_TRACE, ("Cannot locate file (%u).\n", (UINT)Status));
967  fclose(DestFile);
968  free(Buffer);
969  return Status;
970  }
971 
972  /* The file is continued in the first data block in the folder */
973  File->DataBlock = CurrentFolderNode->DataListHead;
974 
975  /* Search to start of file */
976  if (fseek(FileHandle, (off_t)File->DataBlock->AbsoluteOffset, SEEK_SET) != 0)
977  {
978  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
979  fclose(DestFile);
980  free(Buffer);
981  return CAB_STATUS_INVALID_CAB;
982  }
983 
984  DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
985  (UINT)File->File.FileOffset,
986  (UINT)File->File.FileSize,
987  (UINT)File->DataBlock->AbsoluteOffset,
988  (UINT)File->DataBlock->UncompOffset));
989 
990  CurrentDataNode = File->DataBlock;
991  ReuseBlock = true;
992 
993  RestartSearch = true;
994  }
995  } while (CFData.UncompSize == 0);
996 
997  DPRINT(MAX_TRACE, ("TotalBytesRead (%u).\n", (UINT)TotalBytesRead));
998 
999  Status = Codec->Uncompress(OutputBuffer, Buffer, TotalBytesRead, &BytesToWrite);
1000  if (Status != CS_SUCCESS)
1001  {
1002  fclose(DestFile);
1003  free(Buffer);
1004  DPRINT(MID_TRACE, ("Cannot uncompress block.\n"));
1005  if (Status == CS_NOMEMORY)
1006  return CAB_STATUS_NOMEMORY;
1007  return CAB_STATUS_INVALID_CAB;
1008  }
1009 
1010  if (BytesToWrite != CFData.UncompSize)
1011  {
1012  DPRINT(MID_TRACE, ("BytesToWrite (%u) != CFData.UncompSize (%d)\n",
1013  (UINT)BytesToWrite, CFData.UncompSize));
1014  fclose(DestFile);
1015  free(Buffer);
1016  return CAB_STATUS_INVALID_CAB;
1017  }
1018 
1019  BytesLeftInBlock = BytesToWrite;
1020  }
1021  else
1022  {
1023  DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%u)\n", (UINT)ReuseBlock));
1024 
1025  BytesToWrite = BytesLeftInBlock;
1026 
1027  DPRINT(MAX_TRACE, ("Seeking to absolute offset 0x%X.\n",
1028  (UINT)(CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) + CurrentDataNode->Data.CompSize)));
1029 
1030  if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) !=
1031  CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA)))
1032  {
1033  fclose(DestFile);
1034  free(Buffer);
1035  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
1036  return CAB_STATUS_INVALID_CAB;
1037  }
1038 
1039  DPRINT(MAX_TRACE, ("CFData.CompSize 0x%X CFData.UncompSize 0x%X.\n",
1040  CFData.CompSize, CFData.UncompSize));
1041 
1042  /* Go to next data block */
1044  CurrentDataNode->Data.CompSize, SEEK_SET) != 0)
1045  {
1046  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
1047  fclose(DestFile);
1048  free(Buffer);
1049  return CAB_STATUS_INVALID_CAB;
1050  }
1051 
1052  ReuseBlock = false;
1053  }
1054 
1055  if (Skip)
1056  BytesSkipped = (Offset - CurrentOffset);
1057  else
1058  BytesSkipped = 0;
1059 
1060  BytesToWrite -= BytesSkipped;
1061 
1062  if (Size < BytesToWrite)
1063  BytesToWrite = Size;
1064 
1065  DPRINT(MAX_TRACE, ("Offset (0x%X) CurrentOffset (0x%X) ToWrite (%u) Skipped (%u)(%u) Size (%u).\n",
1066  (UINT)Offset,
1067  (UINT)CurrentOffset,
1068  (UINT)BytesToWrite,
1069  (UINT)BytesSkipped, (UINT)Skip,
1070  (UINT)Size));
1071 
1072  BytesWritten = BytesToWrite;
1073  if (fwrite((void*)((PUCHAR)OutputBuffer + BytesSkipped),
1074  BytesToWrite, 1, DestFile) < 1)
1075  {
1076  fclose(DestFile);
1077  free(Buffer);
1078  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
1079 
1080  return CAB_STATUS_CANNOT_WRITE;
1081  }
1082 
1083  Size -= BytesToWrite;
1084 
1085  CurrentOffset += BytesToWrite;
1086 
1087  /* Don't skip any more bytes */
1088  Skip = false;
1089  } while (Size > 0);
1090  }
1091 
1092  fclose(DestFile);
1093 
1094  free(Buffer);
1095 
1096  return CAB_STATUS_SUCCESS;
1097 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
ULONG LocateFile(char *FileName, PCFFILE_NODE *File)
Definition: cabinet.cxx:2002
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
ULONG LastFileOffset
Definition: cabinet.h:491
#define MID_TRACE
Definition: debug.h:15
FILE * FileHandle
Definition: cabinet.h:465
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG CloseCabinet()
Definition: cabinet.cxx:1575
#define CAB_CODEC_RAW
Definition: cabinet.h:46
PCFDATA_NODE DataListHead
Definition: cabinet.h:209
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
#define free
Definition: debug_ros.c:5
__kernel_off_t off_t
Definition: linux.h:201
CCABCodec * Codec
Definition: cabinet.h:479
CFFOLDER Folder
Definition: cabinet.h:214
virtual void OnExtract(PCFFILE Entry, char *FileName)
Definition: cabinet.cxx:1862
ULONG SetAttributesOnFile(char *FileName, USHORT FileAttributes)
Definition: cabinet.cxx:3195
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void * OutputBuffer
Definition: cabinet.h:485
_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)
CFDATA Data
Definition: cabinet.h:199
bool ReuseBlock
Definition: cabinet.h:460
PCFDATA_NODE CurrentDataNode
Definition: cabinet.h:474
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1098
#define CAB_CODEC_MSZIP
Definition: cabinet.h:48
#define CAB_COMP_MSZIP
Definition: cabinet.c:53
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG Open()
Definition: cabinet.cxx:471
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:29
Definition: fci.c:101
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char DiskNext[256]
Definition: cabinet.h:453
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
#define CAB_BLOCKSIZE
Definition: cabinet.c:49
#define SEEK_SET
Definition: jmemansi.c:26
#define CAB_STATUS_UNSUPPCOMP
Definition: cabinet.h:33
File()
Definition: File.h:18
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2531
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
Definition: time.c:75
#define CAB_STATUS_CANNOT_CREATE
Definition: cabinet.h:27
#define PATH_MAX
Definition: types.h:280
ULONG BytesLeftInBlock
Definition: cabinet.h:459
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
char CabinetNext[256]
Definition: cabinet.h:452
void SelectCodec(LONG Id)
Definition: cabinet.cxx:1109
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define CS_NOMEMORY
Definition: cabinet.h:42
ULONG AbsoluteOffset
Definition: cabinet.h:197
bool RestartSearch
Definition: cabinet.h:490
char DestPath[PATH_MAX]
Definition: cabinet.h:461
#define MAX_TRACE
Definition: debug.h:16
#define CAB_COMP_MASK
Definition: cabinet.c:51
static PVOID CurrentBuffer
unsigned int UINT
Definition: ndis.h:50
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
virtual bool OnOverwrite(PCFFILE Entry, char *FileName)
Definition: cabinet.cxx:1847
virtual ULONG Uncompress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
#define CAB_STATUS_FILE_EXISTS
Definition: cabinet.h:30
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
virtual void OnDiskChange(char *CabinetName, char *DiskLabel)
Definition: cabinet.cxx:1874
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define malloc
Definition: debug_ros.c:4
Definition: File.h:15
#define CAB_COMP_NONE
Definition: cabinet.c:52
#define CS_SUCCESS
Definition: cabinet.h:41
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
void SetCabinetName(char *FileName)
Definition: cabinet.cxx:261
#define CAB_STATUS_NOFILE
Definition: cabinet.h:32
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

Referenced by CCABManager::ExtractFromCabinet().

◆ FindFirst()

ULONG CCabinet::FindFirst ( PCAB_SEARCH  Search)

Definition at line 638 of file cabinet.cxx.

646 {
647  RestartSearch = false;
648  Search->Next = FileListHead;
649  return FindNext(Search);
650 }
PCFFILE_NODE Next
Definition: cabinet.h:238
ULONG FindNext(PCAB_SEARCH Search)
Definition: cabinet.cxx:653
bool RestartSearch
Definition: cabinet.h:490
PCFFILE_NODE FileListHead
Definition: cabinet.h:475

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

◆ FindNext()

ULONG CCabinet::FindNext ( PCAB_SEARCH  Search)

Definition at line 653 of file cabinet.cxx.

661 {
662  bool bFound = false;
663  PSEARCH_CRITERIA Criteria;
664  ULONG Status;
665 
666  if (RestartSearch)
667  {
668  Search->Next = FileListHead;
669 
670  /* Skip split files already extracted */
671  while ((Search->Next) &&
672  (Search->Next->File.FileControlID > CAB_FILE_MAX_FOLDER) &&
673  (Search->Next->File.FileOffset <= LastFileOffset))
674  {
675  DPRINT(MAX_TRACE, ("Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n",
676  Search->Next->FileName, (UINT)Search->Next->File.FileOffset, (UINT)LastFileOffset));
677  Search->Next = Search->Next->Next;
678  }
679 
680  RestartSearch = false;
681  }
682 
683  /* Check each search criteria against each file */
684  while(Search->Next)
685  {
686  // Some features (like displaying cabinets) don't require search criteria, so we can just break here.
687  // If a feature requires it, handle this in the ParseCmdline() function in "main.cxx".
688  if(!CriteriaListHead)
689  break;
690 
691  Criteria = CriteriaListHead;
692 
693  while(Criteria)
694  {
695  if(MatchFileNamePattern(Search->Next->FileName, Criteria->Search))
696  {
697  bFound = true;
698  break;
699  }
700 
701  Criteria = Criteria->Next;
702  }
703 
704  if(bFound)
705  break;
706 
707  Search->Next = Search->Next->Next;
708  }
709 
710  if (!Search->Next)
711  {
712  if (strlen(DiskNext) > 0)
713  {
714  CloseCabinet();
715 
717 
719 
720  Status = Open();
721  if (Status != CAB_STATUS_SUCCESS)
722  return Status;
723 
724  Search->Next = FileListHead;
725  if (!Search->Next)
726  return CAB_STATUS_NOFILE;
727  }
728  else
729  return CAB_STATUS_NOFILE;
730  }
731 
732  Search->File = &Search->Next->File;
733  Search->FileName = Search->Next->FileName;
734  Search->Next = Search->Next->Next;
735  return CAB_STATUS_SUCCESS;
736 }
ULONG LastFileOffset
Definition: cabinet.h:491
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG CloseCabinet()
Definition: cabinet.cxx:1575
CFFILE File
Definition: cabinet.h:221
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
char * FileName
Definition: cabinet.h:222
PCFFILE_NODE Next
Definition: cabinet.h:238
struct _SEARCH_CRITERIA * Next
Definition: cabinet.h:231
ULONG Open()
Definition: cabinet.cxx:471
char DiskNext[256]
Definition: cabinet.h:453
void DPRINT(...)
Definition: polytest.cpp:61
char * Search
Definition: cabinet.h:233
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
char CabinetNext[256]
Definition: cabinet.h:452
Status
Definition: gdiplustypes.h:24
#define CAB_FILE_MAX_FOLDER
Definition: cabinet.c:70
bool RestartSearch
Definition: cabinet.h:490
#define MAX_TRACE
Definition: debug.h:16
char * FileName
Definition: cabinet.h:240
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
unsigned int UINT
Definition: ndis.h:50
PCFFILE File
Definition: cabinet.h:76
virtual void OnDiskChange(char *CabinetName, char *DiskLabel)
Definition: cabinet.cxx:1874
unsigned int ULONG
Definition: retypes.h:1
bool MatchFileNamePattern(char *FileName, char *Pattern)
Definition: cabinet.cxx:2551
void SetCabinetName(char *FileName)
Definition: cabinet.cxx:261
#define CAB_STATUS_NOFILE
Definition: cabinet.h:32

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

◆ GetAbsoluteOffset()

ULONG CCabinet::GetAbsoluteOffset ( PCFFILE_NODE  File)
private

Definition at line 1961 of file cabinet.cxx.

1969 {
1971 
1972  DPRINT(MAX_TRACE, ("FileName '%s' FileOffset (0x%X) FileSize (%u).\n",
1973  File->FileName,
1974  (UINT)File->File.FileOffset,
1975  (UINT)File->File.FileSize));
1976 
1978  while (Node != NULL)
1979  {
1980  DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%u).\n",
1981  (UINT)Node->UncompOffset,
1982  (UINT)(Node->UncompOffset + Node->Data.UncompSize),
1983  (UINT)Node->Data.UncompSize));
1984 
1985  /* Node->Data.UncompSize will be 0 if the block is split
1986  (ie. it is the last block in this cabinet) */
1987  if ((Node->Data.UncompSize == 0) ||
1988  ((File->File.FileOffset >= Node->UncompOffset) &&
1989  (File->File.FileOffset < Node->UncompOffset +
1990  Node->Data.UncompSize)))
1991  {
1992  File->DataBlock = Node;
1993  return CAB_STATUS_SUCCESS;
1994  }
1995 
1996  Node = Node->Next;
1997  }
1998  return CAB_STATUS_INVALID_CAB;
1999 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
PCFDATA_NODE DataListHead
Definition: cabinet.h:209
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
File()
Definition: File.h:18
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
#define MAX_TRACE
Definition: debug.h:16
unsigned int UINT
Definition: ndis.h:50
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
Definition: File.h:15
Definition: dlist.c:348

Referenced by LocateFile().

◆ GetAttributesOnFile()

ULONG CCabinet::GetAttributesOnFile ( PCFFILE_NODE  File)
private

Definition at line 3141 of file cabinet.cxx.

3149 {
3150 #if defined(_WIN32)
3151  LONG Attributes;
3152 
3153  Attributes = GetFileAttributes(File->FileName);
3154  if (Attributes == -1)
3155  return CAB_STATUS_CANNOT_READ;
3156 
3157  // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
3158  // The IDs for these attributes are the same in the CAB file and under Windows
3159  // If the file has any other attributes, strip them off by the logical AND.
3160  File->File.Attributes = (USHORT)(Attributes & 0x37);
3161 #else
3162  struct stat stbuf;
3163  char buf[PATH_MAX];
3164 
3165  // Check for an absolute path
3166  if (IsSeparator(File->FileName[0]))
3167  strcpy(buf, File->FileName);
3168  else
3169  {
3170  if (!getcwd(buf, sizeof(buf)))
3171  return CAB_STATUS_CANNOT_READ;
3173  strcat(buf, File->FileName);
3174  }
3175 
3176  if (stat(buf, &stbuf) == -1)
3177  return CAB_STATUS_CANNOT_READ;
3178 
3179 #if 0
3180  File->File.Attributes |= CAB_ATTRIB_READONLY;
3181  File->File.Attributes |= CAB_ATTRIB_HIDDEN;
3182  File->File.Attributes |= CAB_ATTRIB_SYSTEM;
3183 #endif
3184 
3185  if (stbuf.st_mode & S_IFDIR)
3186  File->File.Attributes |= CAB_ATTRIB_DIRECTORY;
3187 
3188  File->File.Attributes |= CAB_ATTRIB_ARCHIVE;
3189 
3190 #endif
3191  return CAB_STATUS_SUCCESS;
3192 }
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CAB_STATUS_CANNOT_READ
Definition: cabinet.h:28
#define CAB_ATTRIB_SYSTEM
Definition: cabinet.c:63
#define CAB_ATTRIB_HIDDEN
Definition: cabinet.c:62
long LONG
Definition: pedump.c:60
#define CAB_ATTRIB_DIRECTORY
Definition: cabinet.c:65
#define CAB_ATTRIB_READONLY
Definition: cabinet.c:61
#define S_IFDIR
Definition: acwin.h:115
File()
Definition: File.h:18
#define PATH_MAX
Definition: types.h:280
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Definition: stat.h:55
_Check_return_ _Ret_opt_z_ _CRTIMP char *__cdecl getcwd(_Out_writes_opt_(_SizeInBytes) char *_DstBuf, _In_ int _SizeInBytes)
#define GetFileAttributes
Definition: winbase.h:3649
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define CAB_ATTRIB_ARCHIVE
Definition: cabinet.c:66
unsigned short USHORT
Definition: pedump.c:61
bool IsSeparator(char Char)
Definition: cabinet.cxx:127
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define DIR_SEPARATOR_STRING
Definition: config.h:6
Definition: File.h:15

Referenced by AddFile().

◆ GetCabinetName()

char * CCabinet::GetCabinetName ( )

Definition at line 250 of file cabinet.cxx.

256 {
257  return CabinetName;
258 }
char CabinetName[256]
Definition: cabinet.h:449

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

◆ GetCabinetReservedFile()

char * CCabinet::GetCabinetReservedFile ( )

Definition at line 449 of file cabinet.cxx.

455 {
456  return CabinetReservedFile;
457 }
char CabinetReservedFile[PATH_MAX]
Definition: cabinet.h:462

◆ GetCurrentDiskNumber()

ULONG CCabinet::GetCurrentDiskNumber ( )

Definition at line 460 of file cabinet.cxx.

466 {
467  return CurrentDiskNumber;
468 }
ULONG CurrentDiskNumber
Definition: cabinet.h:448

Referenced by CDFParser::SetupNewDisk().

◆ GetDestinationPath()

char * CCabinet::GetDestinationPath ( )

Definition at line 381 of file cabinet.cxx.

387 {
388  return DestPath;
389 }
char DestPath[PATH_MAX]
Definition: cabinet.h:461

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

◆ GetFileName()

char * CCabinet::GetFileName ( char Path)

Definition at line 183 of file cabinet.cxx.

191 {
192  ULONG i, j;
193 
194  j = i = (Path[0] ? (Path[1] == ':' ? 2 : 0) : 0);
195 
196  while (Path [i++])
197  if (IsSeparator(Path [i - 1]))
198  j = i;
199 
200  return Path + j;
201 }
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
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
PRTL_UNICODE_STRING_BUFFER Path
bool IsSeparator(char Char)
Definition: cabinet.cxx:127
unsigned int ULONG
Definition: retypes.h:1

Referenced by DestroyDeletedFileNodes(), CCABManager::OnAdd(), CCABManager::OnExtract(), CDFParser::PerformFileCopy(), RemoveFileName(), WriteFileEntries(), and WriteFileToScratchStorage().

◆ GetFileTimes()

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

Definition at line 3099 of file cabinet.cxx.

3108 {
3109 #if defined(_WIN32)
3110  FILETIME FileTime;
3112 
3113  if (GetFileTime(FileNo, NULL, NULL, &FileTime))
3114  FileTimeToDosDateTime(&FileTime,
3115  &File->File.FileDate,
3116  &File->File.FileTime);
3117 #else
3118  struct stat stbuf;
3119  char buf[PATH_MAX];
3120 
3121  // Check for an absolute path
3122  if (IsSeparator(File->FileName[0]))
3123  strcpy(buf, File->FileName);
3124  else
3125  {
3126  if (!getcwd(buf, sizeof(buf)))
3127  return CAB_STATUS_CANNOT_READ;
3129  strcat(buf, File->FileName);
3130  }
3131 
3132  if (stat(buf, &stbuf) == -1)
3133  return CAB_STATUS_CANNOT_READ;
3134 
3135  ConvertDateAndTime(&stbuf.st_mtime, &File->File.FileDate, &File->File.FileTime);
3136 #endif
3137  return CAB_STATUS_SUCCESS;
3138 }
FILE * FileHandle
Definition: cabinet.h:465
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CAB_STATUS_CANNOT_READ
Definition: cabinet.h:28
smooth NULL
Definition: ftsmooth.c:416
File()
Definition: File.h:18
#define UlongToHandle(ul)
Definition: basetsd.h:97
void ConvertDateAndTime(time_t *Time, PUSHORT DosDate, PUSHORT DosTime)
Definition: cabinet.cxx:3067
#define PATH_MAX
Definition: types.h:280
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Definition: stat.h:55
_Check_return_ _Ret_opt_z_ _CRTIMP char *__cdecl getcwd(_Out_writes_opt_(_SizeInBytes) char *_DstBuf, _In_ int _SizeInBytes)
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
Definition: time.c:37
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
bool IsSeparator(char Char)
Definition: cabinet.cxx:127
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define DIR_SEPARATOR_STRING
Definition: config.h:6
Definition: File.h:15
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1046

Referenced by AddFile().

◆ HasSearchCriteria()

bool CCabinet::HasSearchCriteria ( )

Definition at line 351 of file cabinet.cxx.

357 {
358  return (CriteriaListHead != NULL);
359 }
PSEARCH_CRITERIA CriteriaListHead
Definition: cabinet.h:477
smooth NULL
Definition: ftsmooth.c:416

Referenced by CCABManager::ParseCmdline().

◆ InitCabinetHeader()

ULONG CCabinet::InitCabinetHeader ( )
private

Definition at line 2614 of file cabinet.cxx.

2620 {
2621  ULONG TotalSize;
2622  ULONG Size;
2623 
2624  CABHeader.FileTableOffset = 0; // Not known yet
2625  CABHeader.FolderCount = 0; // Not known yet
2626  CABHeader.FileCount = 0; // Not known yet
2627  CABHeader.Flags = 0; // Not known yet
2628 
2629  CABHeader.CabinetNumber = (USHORT)CurrentDiskNumber;
2630 
2632  {
2633  CABHeader.Flags |= CAB_FLAG_HASPREV;
2635  strcpy(CabinetPrev, "");
2636  }
2637 
2639  {
2640  CABHeader.Flags |= CAB_FLAG_HASNEXT;
2642  strcpy(DiskNext, "");
2643  }
2644 
2645  TotalSize = 0;
2646 
2647  if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
2648  {
2649 
2650  DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
2651 
2652  /* Calculate size of name of previous cabinet */
2653  TotalSize += (ULONG)strlen(CabinetPrev) + 1;
2654 
2655  /* Calculate size of label of previous disk */
2656  TotalSize += (ULONG)strlen(DiskPrev) + 1;
2657  }
2658 
2659  if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
2660  {
2661 
2662  DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
2663 
2664  /* Calculate size of name of next cabinet */
2665  Size = (ULONG)strlen(CabinetNext) + 1;
2666  TotalSize += Size;
2667  NextFieldsSize = Size;
2668 
2669  /* Calculate size of label of next disk */
2670  Size = (ULONG)strlen(DiskNext) + 1;
2671  TotalSize += Size;
2672  NextFieldsSize += Size;
2673  }
2674  else
2675  NextFieldsSize = 0;
2676 
2677  /* Add cabinet reserved area size if present */
2678  if (CabinetReservedFileSize > 0)
2679  {
2680  CABHeader.Flags |= CAB_FLAG_RESERVE;
2681  TotalSize += CabinetReservedFileSize;
2682  TotalSize += sizeof(ULONG); /* For CabinetResSize, FolderResSize, and FileResSize fields */
2683  }
2684 
2685  DiskSize += TotalSize;
2686 
2687  TotalHeaderSize = sizeof(CFHEADER) + TotalSize;
2688 
2689  return CAB_STATUS_SUCCESS;
2690 }
struct _CFHEADER CFHEADER
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG DiskSize
Definition: cabinet.h:495
ULONG NextFieldsSize
Definition: cabinet.h:455
#define CAB_FLAG_RESERVE
Definition: cabinet.c:59
virtual bool OnDiskLabel(ULONG Number, char *Label)
Definition: cabinet.cxx:1900
char DiskPrev[256]
Definition: cabinet.h:451
char DiskNext[256]
Definition: cabinet.h:453
char CabinetPrev[256]
Definition: cabinet.h:450
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_FLAG_HASPREV
Definition: cabinet.c:57
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
char CabinetNext[256]
Definition: cabinet.h:452
#define CAB_FLAG_HASNEXT
Definition: cabinet.c:58
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG CurrentDiskNumber
Definition: cabinet.h:448
ULONG CabinetReservedFileSize
Definition: cabinet.h:464
#define MAX_TRACE
Definition: debug.h:16
unsigned short USHORT
Definition: pedump.c:61
ULONG PrevCabinetNumber
Definition: cabinet.h:496
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
virtual bool OnCabinetName(ULONG Number, char *Name)
Definition: cabinet.cxx:1914
CFHEADER CABHeader
Definition: cabinet.h:467
ULONG TotalHeaderSize
Definition: cabinet.h:454

Referenced by NewCabinet(), and NewDisk().

◆ IsCodecSelected()

bool CCabinet::IsCodecSelected ( )

Definition at line 1099 of file cabinet.cxx.

1105 {
1106  return CodecSelected;
1107 }
bool CodecSelected
Definition: cabinet.h:481

Referenced by CCABManager::ParseCmdline().

◆ IsSeparator()

bool CCabinet::IsSeparator ( char  Char)

Definition at line 127 of file cabinet.cxx.

135 {
136  if ((Char == '\\') || (Char == '/'))
137  return true;
138  else
139  return false;
140 }

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

◆ LocateFile()

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

Definition at line 2002 of file cabinet.cxx.

2014 {
2016  ULONG Status;
2017 
2018  DPRINT(MAX_TRACE, ("FileName '%s'\n", FileName));
2019 
2020  Node = FileListHead;
2021  while (Node != NULL)
2022  {
2023  if (strcasecmp(FileName, Node->FileName) == 0)
2024  {
2025  CurrentFolderNode = LocateFolderNode(Node->File.FileControlID);
2026  if (!CurrentFolderNode)
2027  {
2028  DPRINT(MID_TRACE, ("Folder with index number (%u) not found.\n",
2029  Node->File.FileControlID));
2030  return CAB_STATUS_INVALID_CAB;
2031  }
2032 
2033  if (Node->DataBlock == NULL)
2035  else
2037 
2038  *File = Node;
2039  return Status;
2040  }
2041  Node = Node->Next;
2042  }
2043  return CAB_STATUS_NOFILE;
2044 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
#define MID_TRACE
Definition: debug.h:15
#define strcasecmp
Definition: fake.h:9
PCFFOLDER_NODE LocateFolderNode(ULONG Index)
Definition: cabinet.cxx:1929
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
Status
Definition: gdiplustypes.h:24
#define MAX_TRACE
Definition: debug.h:16
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
ULONG GetAbsoluteOffset(PCFFILE_NODE File)
Definition: cabinet.cxx:1961
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
unsigned int ULONG
Definition: retypes.h:1
Definition: File.h:15
#define CAB_STATUS_NOFILE
Definition: cabinet.h:32
Definition: dlist.c:348

Referenced by ExtractFile().

◆ LocateFolderNode()

PCFFOLDER_NODE CCabinet::LocateFolderNode ( ULONG  Index)
private

Definition at line 1929 of file cabinet.cxx.

1937 {
1939 
1940  switch (Index)
1941  {
1942  case CAB_FILE_SPLIT:
1943  return FolderListTail;
1944 
1945  case CAB_FILE_CONTINUED:
1946  case CAB_FILE_PREV_NEXT:
1947  return FolderListHead;
1948  }
1949 
1950  Node = FolderListHead;
1951  while (Node != NULL)
1952  {
1953  if (Node->Index == Index)
1954  return Node;
1955  Node = Node->Next;
1956  }
1957  return NULL;
1958 }
#define CAB_FILE_PREV_NEXT
Definition: cabinet.c:73
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
#define CAB_FILE_SPLIT
Definition: cabinet.c:72
PCFFOLDER_NODE FolderListTail
Definition: cabinet.h:472
#define CAB_FILE_CONTINUED
Definition: cabinet.c:71
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
static const UCHAR Index[8]
Definition: usbohci.c:18
Definition: dlist.c:348

Referenced by LocateFile().

◆ MatchFileNamePattern()

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

Definition at line 2551 of file cabinet.cxx.

2565 {
2566  char* retryPattern = NULL;
2567  char* retryFileName = NULL;
2568  char ch;
2569 
2570  while (*FileName || *Pattern)
2571  {
2572  ch = *Pattern++;
2573 
2574  switch (ch)
2575  {
2576  case '*':
2577  retryPattern = Pattern;
2578  retryFileName = FileName;
2579  break;
2580 
2581  case '?':
2582  if (*FileName++ == '\0')
2583  return false;
2584 
2585  break;
2586 
2587  default:
2588  if (*FileName == ch)
2589  {
2590  if (*FileName)
2591  FileName++;
2592  break;
2593  }
2594 
2595  if (*FileName)
2596  {
2597  Pattern = retryPattern;
2598  FileName = ++retryFileName;
2599  break;
2600  }
2601 
2602  return false;
2603  }
2604 
2605  if (!Pattern)
2606  return false;
2607  }
2608 
2609  return true;
2610 }
smooth NULL
Definition: ftsmooth.c:416
struct _FileName FileName
Definition: fatprocs.h:884

Referenced by CreateSimpleCabinet(), and FindNext().

◆ NewCabinet()

ULONG CCabinet::NewCabinet ( )

Definition at line 1148 of file cabinet.cxx.

1154 {
1155  ULONG Status;
1156 
1157  CurrentDiskNumber = 0;
1158 
1159  OutputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
1160  InputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
1161  if ((!OutputBuffer) || (!InputBuffer))
1162  {
1163  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1164  return CAB_STATUS_NOMEMORY;
1165  }
1167  CurrentIBufferSize = 0;
1168 
1169  CABHeader.Signature = CAB_SIGNATURE;
1170  CABHeader.Reserved1 = 0; // Not used
1171  CABHeader.CabinetSize = 0; // Not yet known
1172  CABHeader.Reserved2 = 0; // Not used
1173  CABHeader.Reserved3 = 0; // Not used
1174  CABHeader.Version = CAB_VERSION;
1175  CABHeader.FolderCount = 0; // Not yet known
1176  CABHeader.FileCount = 0; // Not yet known
1177  CABHeader.Flags = 0; // Not yet known
1178  // FIXME: Should be random
1179  CABHeader.SetID = 0x534F;
1180  CABHeader.CabinetNumber = 0;
1181 
1182 
1183  TotalFolderSize = 0;
1184  TotalFileSize = 0;
1185 
1186  DiskSize = sizeof(CFHEADER);
1187 
1189 
1190  // NextFolderNumber is 0-based
1191  NextFolderNumber = 0;
1192 
1194  Status = NewFolder();
1195  if (Status != CAB_STATUS_SUCCESS)
1196  return Status;
1197 
1199 
1201  if (!ScratchFile)
1202  {
1203  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1204  return CAB_STATUS_NOMEMORY;
1205  }
1206 
1207  Status = ScratchFile->Create();
1208 
1209  CreateNewFolder = false;
1210 
1211  CreateNewDisk = false;
1212 
1213  PrevCabinetNumber = 0;
1214 
1215  return Status;
1216 }
struct _CFHEADER CFHEADER
ULONG DiskSize
Definition: cabinet.h:495
CFFOLDER Folder
Definition: cabinet.h:214
bool CreateNewFolder
Definition: cabinet.h:498
void * OutputBuffer
Definition: cabinet.h:485
#define CAB_VERSION
Definition: cabinet.c:48
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_BLOCKSIZE
Definition: cabinet.c:49
void * InputBuffer
Definition: cabinet.h:482
ULONG NewFolder()
Definition: cabinet.cxx:1243
#define CAB_SIGNATURE
Definition: cabinet.c:47
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG CurrentIBufferSize
Definition: cabinet.h:484
ULONG TotalFolderSize
Definition: cabinet.h:456
Status
Definition: gdiplustypes.h:24
void * CurrentIBuffer
Definition: cabinet.h:483
ULONG NextFolderNumber
Definition: cabinet.h:505
ULONG CurrentDiskNumber
Definition: cabinet.h:448
ULONG PrevCabinetNumber
Definition: cabinet.h:496
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define malloc
Definition: debug_ros.c:4
bool CreateNewDisk
Definition: cabinet.h:497
ULONG TotalFileSize
Definition: cabinet.h:457
ULONG InitCabinetHeader()
Definition: cabinet.cxx:2614
CFHEADER CABHeader
Definition: cabinet.h:467
ULONG TotalHeaderSize
Definition: cabinet.h:454

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

◆ NewDataNode()

PCFDATA_NODE CCabinet::NewDataNode ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2288 of file cabinet.cxx.

2296 {
2298 
2299  Node = (PCFDATA_NODE)malloc(sizeof(CFDATA_NODE));
2300  if (!Node)
2301  return NULL;
2302 
2303  memset(Node, 0, sizeof(CFDATA_NODE));
2304 
2305  Node->Prev = FolderNode->DataListTail;
2306 
2307  if (FolderNode->DataListTail != NULL)
2308  FolderNode->DataListTail->Next = Node;
2309  else
2310  FolderNode->DataListHead = Node;
2311 
2312  FolderNode->DataListTail = Node;
2313 
2314  return Node;
2315 }
PCFDATA_NODE DataListTail
Definition: cabinet.h:210
PCFDATA_NODE DataListHead
Definition: cabinet.h:209
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
#define malloc
Definition: debug_ros.c:4
#define memset(x, y, z)
Definition: compat.h:39
struct _CFDATA_NODE * PCFDATA_NODE
struct _CFDATA_NODE * Next
Definition: cabinet.h:194
Definition: dlist.c:348

Referenced by ReadDataBlocks(), and WriteDataBlock().

◆ NewDisk()

ULONG CCabinet::NewDisk ( )

Definition at line 1219 of file cabinet.cxx.

1225 {
1226  // NextFolderNumber is 0-based
1227  NextFolderNumber = 1;
1228 
1229  CreateNewDisk = false;
1230 
1232 
1234 
1236 
1237  CurrentFolderNode->Folder.DataBlockCount = 0;
1238 
1239  return CAB_STATUS_SUCCESS;
1240 }
struct _CFHEADER CFHEADER
ULONG DiskSize
Definition: cabinet.h:495
CFFOLDER Folder
Definition: cabinet.h:214
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG TotalFolderSize
Definition: cabinet.h:456
ULONG NextFolderNumber
Definition: cabinet.h:505
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
ULONG TotalFolderSize
Definition: cabinet.h:208
bool CreateNewDisk
Definition: cabinet.h:497
ULONG TotalFileSize
Definition: cabinet.h:457
ULONG InitCabinetHeader()
Definition: cabinet.cxx:2614

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

◆ NewFileNode()

PCFFILE_NODE CCabinet::NewFileNode ( )
private

Definition at line 2258 of file cabinet.cxx.

2266 {
2268 
2269  Node = (PCFFILE_NODE)malloc(sizeof(CFFILE_NODE));
2270  if (!Node)
2271  return NULL;
2272 
2273  memset(Node, 0, sizeof(CFFILE_NODE));
2274 
2275  Node->Prev = FileListTail;
2276 
2277  if (FileListTail != NULL)
2278  FileListTail->Next = Node;
2279  else
2280  FileListHead = Node;
2281 
2282  FileListTail = Node;
2283 
2284  return Node;
2285 }
PCFFILE_NODE FileListTail
Definition: cabinet.h:476
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
struct _CFFILE_NODE * PCFFILE_NODE
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
#define malloc
Definition: debug_ros.c:4
#define memset(x, y, z)
Definition: compat.h:39
Definition: dlist.c:348

Referenced by AddFile(), and ReadFileTable().

◆ NewFolder()

ULONG CCabinet::NewFolder ( )

Definition at line 1243 of file cabinet.cxx.

1249 {
1250  DPRINT(MAX_TRACE, ("Creating new folder.\n"));
1251 
1253  if (!CurrentFolderNode)
1254  {
1255  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
1256  return CAB_STATUS_NOMEMORY;
1257  }
1258 
1259  switch (CodecId) {
1260  case CAB_CODEC_RAW:
1261  CurrentFolderNode->Folder.CompressionType = CAB_COMP_NONE;
1262  break;
1263 
1264  case CAB_CODEC_MSZIP:
1265  CurrentFolderNode->Folder.CompressionType = CAB_COMP_MSZIP;
1266  break;
1267 
1268  default:
1269  return CAB_STATUS_UNSUPPCOMP;
1270  }
1271 
1272  /* FIXME: This won't work if no files are added to the new folder */
1273 
1274  DiskSize += sizeof(CFFOLDER);
1275 
1276  TotalFolderSize += sizeof(CFFOLDER);
1277 
1278  NextFolderNumber++;
1279 
1280  CABHeader.FolderCount++;
1281 
1282  LastBlockStart = 0;
1283 
1284  return CAB_STATUS_SUCCESS;
1285 }
#define CAB_CODEC_RAW
Definition: cabinet.h:46
ULONG DiskSize
Definition: cabinet.h:495
CFFOLDER Folder
Definition: cabinet.h:214
ULONG LastBlockStart
Definition: cabinet.h:493
#define CAB_CODEC_MSZIP
Definition: cabinet.h:48
struct _CFFOLDER CFFOLDER
#define CAB_COMP_MSZIP
Definition: cabinet.c:53
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
void DPRINT(...)
Definition: polytest.cpp:61
PCFFOLDER_NODE NewFolderNode()
Definition: cabinet.cxx:2228
#define CAB_STATUS_UNSUPPCOMP
Definition: cabinet.h:33
LONG CodecId
Definition: cabinet.h:480
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG TotalFolderSize
Definition: cabinet.h:456
ULONG NextFolderNumber
Definition: cabinet.h:505
#define MAX_TRACE
Definition: debug.h:16
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
#define MIN_TRACE
Definition: debug.h:14
#define CAB_COMP_NONE
Definition: cabinet.c:52
CFHEADER CABHeader
Definition: cabinet.h:467

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

◆ NewFolderNode()

PCFFOLDER_NODE CCabinet::NewFolderNode ( )
private

Definition at line 2228 of file cabinet.cxx.

2234 {
2236 
2238  if (!Node)
2239  return NULL;
2240 
2241  memset(Node, 0, sizeof(CFFOLDER_NODE));
2242 
2243  Node->Folder.CompressionType = CAB_COMP_NONE;
2244 
2245  Node->Prev = FolderListTail;
2246 
2247  if (FolderListTail != NULL)
2249  else
2250  FolderListHead = Node;
2251 
2252  FolderListTail = Node;
2253 
2254  return Node;
2255 }
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
PCFFOLDER_NODE FolderListTail
Definition: cabinet.h:472
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
struct _CFFOLDER_NODE * PCFFOLDER_NODE
#define malloc
Definition: debug_ros.c:4
#define CAB_COMP_NONE
Definition: cabinet.c:52
#define memset(x, y, z)
Definition: compat.h:39
Definition: dlist.c:348

Referenced by NewFolder(), and Open().

◆ NormalizePath()

bool CCabinet::NormalizePath ( char Path,
ULONG  Length 
)

Definition at line 225 of file cabinet.cxx.

235 {
236  ULONG n;
237  bool OK = true;
238 
239  if ((n = (ULONG)strlen(Path)) &&
240  (!IsSeparator(Path[n - 1])) &&
241  (OK = ((n + 1) < Length)))
242  {
244  Path[n + 1] = 0;
245  }
246  return OK;
247 }
#define OK(condition, fail_message,...)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLdouble n
Definition: glext.h:7729
#define DIR_SEPARATOR_CHAR
Definition: config.h:5
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PRTL_UNICODE_STRING_BUFFER Path
bool IsSeparator(char Char)
Definition: cabinet.cxx:127
unsigned int ULONG
Definition: retypes.h:1

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

◆ OnAdd()

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

Reimplemented in CCABManager.

Definition at line 1888 of file cabinet.cxx.

1896 {
1897 }

Referenced by WriteFileToScratchStorage().

◆ OnCabinetName()

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

Reimplemented in CDFParser.

Definition at line 1914 of file cabinet.cxx.

1923 {
1924  return false;
1925 }

Referenced by CommitDisk(), and InitCabinetHeader().

◆ OnDiskChange()

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

Reimplemented in CCABManager.

Definition at line 1874 of file cabinet.cxx.

1882 {
1883 }

Referenced by ExtractFile(), and FindNext().

◆ OnDiskLabel()

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

Reimplemented in CDFParser.

Definition at line 1900 of file cabinet.cxx.

1909 {
1910  return false;
1911 }

Referenced by InitCabinetHeader().

◆ OnExtract()

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

Reimplemented in CCABManager.

Definition at line 1862 of file cabinet.cxx.

1870 {
1871 }

Referenced by ExtractFile().

◆ OnOverwrite()

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

Reimplemented in CCABManager.

Definition at line 1847 of file cabinet.cxx.

1857 {
1858  return false;
1859 }

Referenced by CommitDisk(), and ExtractFile().

◆ Open()

ULONG CCabinet::Open ( )

Definition at line 471 of file cabinet.cxx.

477 {
478  PCFFOLDER_NODE FolderNode;
479  ULONG Status;
480  ULONG Index;
481 
482  if (!FileOpen)
483  {
485  ULONG Size;
486 
487  OutputBuffer = malloc(CAB_BLOCKSIZE + 12); // This should be enough
488  if (!OutputBuffer)
489  return CAB_STATUS_NOMEMORY;
490 
491  FileHandle = fopen(CabinetName, "rb");
492  if (FileHandle == NULL)
493  {
494  DPRINT(MID_TRACE, ("Cannot open file.\n"));
495  return CAB_STATUS_CANNOT_OPEN;
496  }
497 
498  FileOpen = true;
499 
500  /* Load CAB header */
501  if ((Status = ReadBlock(&CABHeader, sizeof(CFHEADER), &BytesRead))
503  {
504  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
505  return CAB_STATUS_INVALID_CAB;
506  }
507 
508  /* Check header */
509  if ((BytesRead != sizeof(CFHEADER)) ||
510  (CABHeader.Signature != CAB_SIGNATURE ) ||
511  (CABHeader.Version != CAB_VERSION ) ||
512  (CABHeader.FolderCount == 0 ) ||
513  (CABHeader.FileCount == 0 ) ||
514  (CABHeader.FileTableOffset < sizeof(CFHEADER)))
515  {
516  CloseCabinet();
517  DPRINT(MID_TRACE, ("File has invalid header.\n"));
518  return CAB_STATUS_INVALID_CAB;
519  }
520 
521  Size = 0;
522 
523  /* Read/skip any reserved bytes */
524  if (CABHeader.Flags & CAB_FLAG_RESERVE)
525  {
526  if ((Status = ReadBlock(&Size, sizeof(ULONG), &BytesRead))
528  {
529  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
530  return CAB_STATUS_INVALID_CAB;
531  }
532  CabinetReserved = Size & 0xFFFF;
533  FolderReserved = (Size >> 16) & 0xFF;
534  DataReserved = (Size >> 24) & 0xFF;
535 
537  {
538  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
539  return CAB_STATUS_FAILURE;
540  }
541  }
542 
543  if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
544  {
545  /* Read name of previous cabinet */
546  Status = ReadString(CabinetPrev, 256);
547  if (Status != CAB_STATUS_SUCCESS)
548  return Status;
549  /* Read label of previous disk */
550  Status = ReadString(DiskPrev, 256);
551  if (Status != CAB_STATUS_SUCCESS)
552  return Status;
553  }
554  else
555  {
556  strcpy(CabinetPrev, "");
557  strcpy(DiskPrev, "");
558  }
559 
560  if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
561  {
562  /* Read name of next cabinet */
563  Status = ReadString(CabinetNext, 256);
564  if (Status != CAB_STATUS_SUCCESS)
565  return Status;
566  /* Read label of next disk */
567  Status = ReadString(DiskNext, 256);
568  if (Status != CAB_STATUS_SUCCESS)
569  return Status;
570  }
571  else
572  {
573  strcpy(CabinetNext, "");
574  strcpy(DiskNext, "");
575  }
576 
577  /* Read all folders */
578  for (Index = 0; Index < CABHeader.FolderCount; Index++)
579  {
580  FolderNode = NewFolderNode();
581  if (!FolderNode)
582  {
583  DPRINT(MIN_TRACE, ("Insufficient resources.\n"));
584  return CAB_STATUS_NOMEMORY;
585  }
586 
587  if (Index == 0)
588  FolderNode->UncompOffset = FolderUncompSize;
589 
590  FolderNode->Index = Index;
591 
592  if ((Status = ReadBlock(&FolderNode->Folder,
593  sizeof(CFFOLDER), &BytesRead)) != CAB_STATUS_SUCCESS)
594  {
595  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
596  return CAB_STATUS_INVALID_CAB;
597  }
598  }
599 
600  /* Read file entries */
601  Status = ReadFileTable();
602  if (Status != CAB_STATUS_SUCCESS)
603  {
604  DPRINT(MIN_TRACE, ("ReadFileTable() failed (%u).\n", (UINT)Status));
605  return Status;
606  }
607 
608  /* Read data blocks for all folders */
609  FolderNode = FolderListHead;
610  while (FolderNode != NULL)
611  {
612  Status = ReadDataBlocks(FolderNode);
613  if (Status != CAB_STATUS_SUCCESS)
614  {
615  DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%u).\n", (UINT)Status));
616  return Status;
617  }
618  FolderNode = FolderNode->Next;
619  }
620  }
621  return CAB_STATUS_SUCCESS;
622 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
#define SEEK_CUR
Definition: util.h:63
ULONG DataReserved
Definition: cabinet.h:470
#define MID_TRACE
Definition: debug.h:15
FILE * FileHandle
Definition: cabinet.h:465
ULONG Index
Definition: cabinet.h:211
ULONG CloseCabinet()
Definition: cabinet.cxx:1575
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
CFFOLDER Folder
Definition: cabinet.h:214
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
void * OutputBuffer
Definition: cabinet.h:485
ULONG ReadFileTable()
Definition: cabinet.cxx:2102
#define CAB_VERSION
Definition: cabinet.c:48
#define CAB_FLAG_RESERVE
Definition: cabinet.c:59
Definition: fci.c:82
char DiskPrev[256]
Definition: cabinet.h:451
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
ULONG CabinetReserved
Definition: cabinet.h:468
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char DiskNext[256]
Definition: cabinet.h:453
char CabinetPrev[256]
Definition: cabinet.h:450
void DPRINT(...)
Definition: polytest.cpp:61
PCFFOLDER_NODE NewFolderNode()
Definition: cabinet.cxx:2228
#define CAB_BLOCKSIZE
Definition: cabinet.c:49
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2531
bool FileOpen
Definition: cabinet.h:466
static const UCHAR Index[8]
Definition: usbohci.c:18
#define CAB_FLAG_HASPREV
Definition: cabinet.c:57
#define CAB_STATUS_FAILURE
Definition: cabinet.h:24
ULONG UncompOffset
Definition: cabinet.h:206
#define CAB_SIGNATURE
Definition: cabinet.c:47
ULONG FolderUncompSize
Definition: cabinet.h:458
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
char CabinetNext[256]
Definition: cabinet.h:452
ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2163
#define CAB_FLAG_HASNEXT
Definition: cabinet.c:58
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
ULONG ReadString(char *String, LONG MaxLength)
Definition: cabinet.cxx:2047
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG FolderReserved
Definition: cabinet.h:469
Status
Definition: gdiplustypes.h:24
char CabinetName[256]
Definition: cabinet.h:449
unsigned int UINT
Definition: ndis.h:50
Definition: fci.c:65
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:26
#define malloc
Definition: debug_ros.c:4
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
CFHEADER CABHeader
Definition: cabinet.h:467

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

◆ ReadBlock()

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

Definition at line 2531 of file cabinet.cxx.

2544 {
2546  if ( *BytesRead != Size )
2547  return CAB_STATUS_INVALID_CAB;
2548  return CAB_STATUS_SUCCESS;
2549 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
FILE * FileHandle
Definition: cabinet.h:465
_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)
Definition: bufpool.h:45
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

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

◆ ReadDataBlocks()

ULONG CCabinet::ReadDataBlocks ( PCFFOLDER_NODE  FolderNode)
private

Definition at line 2163 of file cabinet.cxx.

2171 {
2172  ULONG AbsoluteOffset;
2173  ULONG UncompOffset;
2175  ULONG BytesRead;
2176  ULONG Status;
2177  ULONG i;
2178 
2179  DPRINT(MAX_TRACE, ("Reading data blocks for folder (%u) at absolute offset (0x%X).\n",
2180  (UINT)FolderNode->Index, (UINT)FolderNode->Folder.DataOffset));
2181 
2182  AbsoluteOffset = FolderNode->Folder.DataOffset;
2183  UncompOffset = FolderNode->UncompOffset;
2184 
2185  for (i = 0; i < FolderNode->Folder.DataBlockCount; i++)
2186  {
2187  Node = NewDataNode(FolderNode);
2188  if (!Node)
2189  {
2190  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2191  return CAB_STATUS_NOMEMORY;
2192  }
2193 
2194  /* Seek to data block */
2195  if (fseek(FileHandle, (off_t)AbsoluteOffset, SEEK_SET) != 0)
2196  {
2197  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
2198  return CAB_STATUS_INVALID_CAB;
2199  }
2200 
2201  if ((Status = ReadBlock(&Node->Data, sizeof(CFDATA),
2203  {
2204  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
2205  return CAB_STATUS_INVALID_CAB;
2206  }
2207 
2208  DPRINT(MAX_TRACE, ("AbsOffset (0x%X) UncompOffset (0x%X) Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
2209  (UINT)AbsoluteOffset,
2210  (UINT)UncompOffset,
2211  (UINT)Node->Data.Checksum,
2212  Node->Data.CompSize,
2213  Node->Data.UncompSize));
2214 
2215  Node->AbsoluteOffset = AbsoluteOffset;
2216  Node->UncompOffset = UncompOffset;
2217 
2218  AbsoluteOffset += sizeof(CFDATA) + Node->Data.CompSize;
2219  UncompOffset += Node->Data.UncompSize;
2220  }
2221 
2222  FolderUncompSize = UncompOffset;
2223 
2224  return CAB_STATUS_SUCCESS;
2225 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
FILE * FileHandle
Definition: cabinet.h:465
ULONG Index
Definition: cabinet.h:211
__kernel_off_t off_t
Definition: linux.h:201
CFFOLDER Folder
Definition: cabinet.h:214
PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2288
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
union node Node
Definition: types.h:1255
Definition: fci.c:101
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
void DPRINT(...)
Definition: polytest.cpp:61
#define SEEK_SET
Definition: jmemansi.c:26
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2531
ULONG UncompOffset
Definition: cabinet.h:206
ULONG FolderUncompSize
Definition: cabinet.h:458
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
struct _CFDATA CFDATA
Status
Definition: gdiplustypes.h:24
#define MAX_TRACE
Definition: debug.h:16
unsigned int UINT
Definition: ndis.h:50
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
Definition: dlist.c:348

Referenced by Open().

◆ ReadFileTable()

ULONG CCabinet::ReadFileTable ( )
private

Definition at line 2102 of file cabinet.cxx.

2108 {
2109  ULONG i;
2110  ULONG Status;
2111  ULONG BytesRead;
2113 
2114  DPRINT(MAX_TRACE, ("Reading file table at absolute offset (0x%X).\n",
2115  (UINT)CABHeader.FileTableOffset));
2116 
2117  /* Seek to file table */
2118  if (fseek(FileHandle, (off_t)CABHeader.FileTableOffset, SEEK_SET) != 0)
2119  {
2120  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
2121  return CAB_STATUS_INVALID_CAB;
2122  }
2123 
2124  for (i = 0; i < CABHeader.FileCount; i++)
2125  {
2126  File = NewFileNode();
2127  if (!File)
2128  {
2129  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2130  return CAB_STATUS_NOMEMORY;
2131  }
2132 
2133  if ((Status = ReadBlock(&File->File, sizeof(CFFILE),
2135  {
2136  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
2137  return CAB_STATUS_INVALID_CAB;
2138  }
2139 
2140  File->FileName = (char*)malloc(PATH_MAX);
2141  if (!File->FileName)
2142  {
2143  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
2144  return CAB_STATUS_NOMEMORY;
2145  }
2146 
2147  /* Read file name */
2148  Status = ReadString(File->FileName, PATH_MAX);
2149  if (Status != CAB_STATUS_SUCCESS)
2150  return Status;
2151 
2152  DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X). Size (%u bytes) ControlId (0x%X).\n",
2153  File->FileName,
2154  (UINT)File->File.FileOffset,
2155  (UINT)File->File.FileSize,
2156  File->File.FileControlID));
2157 
2158  }
2159  return CAB_STATUS_SUCCESS;
2160 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
FILE * FileHandle
Definition: cabinet.h:465
__kernel_off_t off_t
Definition: linux.h:201
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
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
void DPRINT(...)
Definition: polytest.cpp:61
#define SEEK_SET
Definition: jmemansi.c:26
File()
Definition: File.h:18
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2531
Definition: fci.c:89
#define PATH_MAX
Definition: types.h:280
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG ReadString(char *String, LONG MaxLength)
Definition: cabinet.cxx:2047
Status
Definition: gdiplustypes.h:24
#define MAX_TRACE
Definition: debug.h:16
unsigned int UINT
Definition: ndis.h:50
PCFFILE_NODE NewFileNode()
Definition: cabinet.cxx:2258
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define malloc
Definition: debug_ros.c:4
Definition: File.h:15
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
CFHEADER CABHeader
Definition: cabinet.h:467

Referenced by Open().

◆ ReadString()

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

Definition at line 2047 of file cabinet.cxx.

2056 {
2057  ULONG BytesRead;
2058  ULONG Status;
2059  LONG Size;
2060  bool Found;
2061 
2062  Found = false;
2063 
2064  Status = ReadBlock(String, MaxLength, &BytesRead);
2065  if (Status != CAB_STATUS_SUCCESS)
2066  {
2067  DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
2068  return CAB_STATUS_INVALID_CAB;
2069  }
2070 
2071  // Find the terminating NULL character
2072  for (Size = 0; Size < MaxLength; Size++)
2073  {
2074  if (String[Size] == '\0')
2075  {
2076  Found = true;
2077  break;
2078  }
2079  }
2080 
2081  if (!Found)
2082  {
2083  DPRINT(MIN_TRACE, ("Filename in the cabinet file is too long.\n"));
2084  return CAB_STATUS_INVALID_CAB;
2085  }
2086 
2087  // Compute the offset of the next CFFILE.
2088  // 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.
2089  // + 1 to skip the terminating NULL character as well.
2090  Size = -(MaxLength - Size) + 1;
2091 
2092  if (fseek(FileHandle, (off_t)Size, SEEK_CUR) != 0)
2093  {
2094  DPRINT(MIN_TRACE, ("fseek() failed.\n"));
2095  return CAB_STATUS_INVALID_CAB;
2096  }
2097 
2098  return CAB_STATUS_SUCCESS;
2099 }
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
#define SEEK_CUR
Definition: util.h:63
FILE * FileHandle
Definition: cabinet.h:465
__kernel_off_t off_t
Definition: linux.h:201
static WCHAR String[]
Definition: stringtable.c:55
long LONG
Definition: pedump.c:60
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
void DPRINT(...)
Definition: polytest.cpp:61
return Found
Definition: dirsup.c:1270
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
Definition: cabinet.cxx:2531
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
unsigned int UINT
Definition: ndis.h:50
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

Referenced by Open(), and ReadFileTable().

◆ RemoveFileName()

void CCabinet::RemoveFileName ( char Path)

Definition at line 204 of file cabinet.cxx.

210 {
211  char* FileName;
212  ULONG i;
213 
214  i = (Path [0] ? (Path[1] == ':' ? 2 : 0) : 0);
215  FileName = GetFileName(Path + i);
216 
217  if ((FileName != (Path + i)) && (IsSeparator(FileName [-1])))
218  FileName--;
219  if ((FileName == (Path + i)) && (IsSeparator(FileName [0])))
220  FileName++;
221  FileName[0] = 0;
222 }
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
char * GetFileName(char *Path)
Definition: cabinet.cxx:183
struct _FileName FileName
Definition: fatprocs.h:884
PRTL_UNICODE_STRING_BUFFER Path
bool IsSeparator(char Char)
Definition: cabinet.cxx:127
unsigned int ULONG
Definition: retypes.h:1

◆ SelectCodec()

void CCabinet::SelectCodec ( LONG  Id)

Definition at line 1109 of file cabinet.cxx.

1115 {
1116  if (CodecSelected)
1117  {
1118  if (Id == CodecId)
1119  return;
1120 
1121  CodecSelected = false;
1122  delete Codec;
1123  }
1124 
1125  switch (Id)
1126  {
1127  case CAB_CODEC_RAW:
1128  Codec = new CRawCodec();
1129  break;
1130 
1131  case CAB_CODEC_MSZIP:
1132  Codec = new CMSZipCodec();
1133  break;
1134 
1135  default:
1136  return;
1137  }
1138 
1139  CodecId = Id;
1140  CodecSelected = true;
1141 }
#define CAB_CODEC_RAW
Definition: cabinet.h:46
CCABCodec * Codec
Definition: cabinet.h:479
DWORD Id
Definition: raw.h:15
#define CAB_CODEC_MSZIP
Definition: cabinet.h:48
bool CodecSelected
Definition: cabinet.h:481
LONG CodecId
Definition: cabinet.h:480

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

◆ SetAttributesOnFile()

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

Definition at line 3195 of file cabinet.cxx.

3204 {
3205 #if defined(_WIN32)
3206  // 0x37 = READONLY | HIDDEN | SYSTEM | DIRECTORY | ARCHIVE
3207  // The IDs for these attributes are the same in the CAB file and under Windows
3208  // If the file has any other attributes, strip them off by the logical AND.
3210 
3211  return CAB_STATUS_SUCCESS;
3212 #else
3213  //DPRINT(MIN_TRACE, ("FIXME: SetAttributesOnFile() is unimplemented\n"));
3214  return CAB_STATUS_SUCCESS;
3215 #endif
3216 }
_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:1230
#define SetFileAttributes
Definition: winbase.h:3743
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23

Referenced by ExtractFile().

◆ SetCabinetName()

void CCabinet::SetCabinetName ( char FileName)

Definition at line 261 of file cabinet.cxx.

267 {
269 }
char CabinetName[256]
Definition: cabinet.h:449
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388

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

◆ SetCabinetReservedFile()

bool CCabinet::SetCabinetReservedFile ( char FileName)

Definition at line 392 of file cabinet.cxx.

398 {
399  FILE* FileHandle;
401  char* ConvertedFileName;
402 
403  ConvertedFileName = ConvertPath(FileName, true);
404 
405  FileHandle = fopen(ConvertedFileName, "rb");
406  free(ConvertedFileName);
407  if (FileHandle == NULL)
408  {
409  DPRINT(MID_TRACE, ("Cannot open cabinet reserved file.\n"));
410  return false;
411  }
412 
414  if (CabinetReservedFileSize == (ULONG)-1)
415  {
416  DPRINT(MIN_TRACE, ("Cannot read from cabinet reserved file.\n"));
418  return false;
419  }
420 
421  if (CabinetReservedFileSize == 0)
422  {
424  return false;
425  }
426 
429  {
431  return false;
432  }
433 
436  {
438  return false;
439  }
440 
442 
444 
445  return true;
446 }
#define MID_TRACE
Definition: debug.h:15
FILE * FileHandle
Definition: cabinet.h:465
char CabinetReservedFile[PATH_MAX]
Definition: cabinet.h:462
#define free
Definition: debug_ros.c:5
_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)
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
ULONG CabinetReservedFileSize
Definition: cabinet.h:464
char * ConvertPath(char *Path, bool Allocate)
Definition: cabinet.cxx:142
void * CabinetReservedFileBuffer
Definition: cabinet.h:463
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define malloc
Definition: debug_ros.c:4
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
LONG GetSizeOfFile(FILE *handle)
Definition: cabinet.h:43

Referenced by CCABManager::ParseCmdline().

◆ SetCompressionCodec()

bool CCabinet::SetCompressionCodec ( char CodecName)

Definition at line 361 of file cabinet.cxx.

367 {
368  if( !strcasecmp(CodecName, "raw") )
370  else if( !strcasecmp(CodecName, "mszip") )
372  else
373  {
374  printf("ERROR: Invalid codec specified!\n");
375  return false;
376  }
377 
378  return true;
379 }
#define strcasecmp
Definition: fake.h:9
#define CAB_CODEC_RAW
Definition: cabinet.h:46
#define CAB_CODEC_MSZIP
Definition: cabinet.h:48
void SelectCodec(LONG Id)
Definition: cabinet.cxx:1109
#define printf
Definition: config.h:203

Referenced by CCABManager::ParseCmdline().

◆ SetDestinationPath()

void CCabinet::SetDestinationPath ( char DestinationPath)

Definition at line 272 of file cabinet.cxx.

278 {
279  strcpy(DestPath, DestinationPath);
280  ConvertPath(DestPath, false);
281  if (strlen(DestPath) > 0)
283 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define PATH_MAX
Definition: types.h:280
char DestPath[PATH_MAX]
Definition: cabinet.h:461
bool NormalizePath(char *Path, ULONG Length)
Definition: cabinet.cxx:225
char * ConvertPath(char *Path, bool Allocate)
Definition: cabinet.cxx:142
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388

Referenced by CCABManager::ParseCmdline().

◆ SetMaxDiskSize()

void CCabinet::SetMaxDiskSize ( ULONG  Size)

Definition at line 1832 of file cabinet.cxx.

1838 {
1839  MaxDiskSize = Size;
1840 }
ULONG MaxDiskSize
Definition: cabinet.h:494
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359

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

◆ WriteCabinetHeader()

ULONG CCabinet::WriteCabinetHeader ( bool  MoreDisks)
private

Definition at line 2693 of file cabinet.cxx.

2701 {
2702  PCFFOLDER_NODE FolderNode;
2703  PCFFILE_NODE FileNode;
2705  ULONG Size;
2706 
2707  if (MoreDisks)
2708  {
2709  CABHeader.Flags |= CAB_FLAG_HASNEXT;
2711  }
2712  else
2713  {
2714  CABHeader.Flags &= ~CAB_FLAG_HASNEXT;
2717  }
2718 
2719  /* Set absolute folder offsets */
2721  CABHeader.FolderCount = 0;
2722  FolderNode = FolderListHead;
2723  while (FolderNode != NULL)
2724  {
2725  FolderNode->Folder.DataOffset = BytesWritten;
2726 
2727  BytesWritten += FolderNode->TotalFolderSize;
2728 
2729  CABHeader.FolderCount++;
2730 
2731  FolderNode = FolderNode->Next;
2732  }
2733 
2734  /* Set absolute offset of file table */
2735  CABHeader.FileTableOffset = Size + TotalFolderSize;
2736 
2737  /* Count number of files to be committed */
2738  CABHeader.FileCount = 0;
2739  FileNode = FileListHead;
2740  while (FileNode != NULL)
2741  {
2742  if (FileNode->Commit)
2743  CABHeader.FileCount++;
2744  FileNode = FileNode->Next;
2745  }
2746 
2747  CABHeader.CabinetSize = DiskSize;
2748 
2749  /* Write header */
2750  if (fwrite(&CABHeader, sizeof(CFHEADER), 1, FileHandle) < 1)
2751  {
2752  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2753  return CAB_STATUS_CANNOT_WRITE;
2754  }
2755 
2756  /* Write per-cabinet reserved area if present */
2757  if (CABHeader.Flags & CAB_FLAG_RESERVE)
2758  {
2759  ULONG ReservedSize;
2760 
2761  ReservedSize = CabinetReservedFileSize & 0xffff;
2762  ReservedSize |= (0 << 16); /* Folder reserved area size */
2763  ReservedSize |= (0 << 24); /* Folder reserved area size */
2764 
2765  BytesWritten = sizeof(ULONG);
2766  if (fwrite(&ReservedSize, sizeof(ULONG), 1, FileHandle) < 1)
2767  {
2768  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2769  return CAB_STATUS_CANNOT_WRITE;
2770  }
2771 
2774  {
2775  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2776  return CAB_STATUS_CANNOT_WRITE;
2777  }
2778  }
2779 
2780  if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0)
2781  {
2782  DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev));
2783 
2784  /* Write name of previous cabinet */
2785  Size = (ULONG)strlen(CabinetPrev) + 1;
2786  BytesWritten = Size;
2787  if (fwrite(CabinetPrev, Size, 1, FileHandle) < 1)
2788  {
2789  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2790  return CAB_STATUS_CANNOT_WRITE;
2791  }
2792 
2793  DPRINT(MAX_TRACE, ("DiskPrev '%s'.\n", DiskPrev));
2794 
2795  /* Write label of previous disk */
2796  Size = (ULONG)strlen(DiskPrev) + 1;
2797  BytesWritten = Size;
2798  if (fwrite(DiskPrev, Size, 1, FileHandle) < 1)
2799  {
2800  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2801  return CAB_STATUS_CANNOT_WRITE;
2802  }
2803  }
2804 
2805  if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0)
2806  {
2807  DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext));
2808 
2809  /* Write name of next cabinet */
2810  Size = (ULONG)strlen(CabinetNext) + 1;
2811  BytesWritten = Size;
2812  if (fwrite(CabinetNext, Size, 1, FileHandle) < 1)
2813  {
2814  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2815  return CAB_STATUS_CANNOT_WRITE;
2816  }
2817 
2818  DPRINT(MAX_TRACE, ("DiskNext '%s'.\n", DiskNext));
2819 
2820  /* Write label of next disk */
2821  Size = (ULONG)strlen(DiskNext) + 1;
2822  BytesWritten = Size;
2823  if (fwrite(DiskNext, Size, 1, FileHandle) < 1)
2824  {
2825  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2826  return CAB_STATUS_CANNOT_WRITE;
2827  }
2828  }
2829 
2830  return CAB_STATUS_SUCCESS;
2831 }
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
FILE * FileHandle
Definition: cabinet.h:465
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG DiskSize
Definition: cabinet.h:495
PCFFOLDER_NODE FolderListHead
Definition: cabinet.h:471
CFFOLDER Folder
Definition: cabinet.h:214
ULONG NextFieldsSize
Definition: cabinet.h:455
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
struct _CFFOLDER_NODE * Next
Definition: cabinet.h:204
_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)
#define CAB_FLAG_RESERVE
Definition: cabinet.c:59
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:29
char DiskPrev[256]
Definition: cabinet.h:451
smooth NULL
Definition: ftsmooth.c:416
char DiskNext[256]
Definition: cabinet.h:453
bool Commit
Definition: cabinet.h:224
char CabinetPrev[256]
Definition: cabinet.h:450
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_FLAG_HASPREV
Definition: cabinet.c:57
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
char CabinetNext[256]
Definition: cabinet.h:452
ULONG TotalFolderSize
Definition: cabinet.h:456
#define CAB_FLAG_HASNEXT
Definition: cabinet.c:58
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG CabinetReservedFileSize
Definition: cabinet.h:464
#define MAX_TRACE
Definition: debug.h:16
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
Definition: fci.c:65
void * CabinetReservedFileBuffer
Definition: cabinet.h:463
unsigned int ULONG
Definition: retypes.h:1
ULONG TotalFolderSize
Definition: cabinet.h:208
#define MIN_TRACE
Definition: debug.h:14
ULONG TotalFileSize
Definition: cabinet.h:457
CFHEADER CABHeader
Definition: cabinet.h:467
ULONG TotalHeaderSize
Definition: cabinet.h:454

Referenced by CommitDisk().

◆ WriteDataBlock()

ULONG CCabinet::WriteDataBlock ( )
private

Definition at line 2978 of file cabinet.cxx.

2984 {
2985  ULONG Status;
2987  PCFDATA_NODE DataNode;
2988 
2989  if (!BlockIsSplit)
2990  {
2992  InputBuffer,
2994  &TotalCompSize);
2995 
2996  DPRINT(MAX_TRACE, ("Block compressed. CurrentIBufferSize (%u) TotalCompSize(%u).\n",
2998 
3001  }
3002 
3003  DataNode = NewDataNode(CurrentFolderNode);
3004  if (!DataNode)
3005  {
3006  DPRINT(MIN_TRACE, ("Insufficient memory.\n"));
3007  return CAB_STATUS_NOMEMORY;
3008  }
3009 
3010  DiskSize += sizeof(CFDATA);
3011 
3012  if (MaxDiskSize > 0)
3013  /* Disk size is limited */
3015  else
3016  BlockIsSplit = false;
3017 
3018  if (BlockIsSplit)
3019  {
3020  DataNode->Data.CompSize = (USHORT)(MaxDiskSize - DiskSize);
3021  DataNode->Data.UncompSize = 0;
3022  CreateNewDisk = true;
3023  }
3024  else
3025  {
3026  DataNode->Data.CompSize = (USHORT)CurrentOBufferSize;
3027  DataNode->Data.UncompSize = (USHORT)CurrentIBufferSize;
3028  }
3029 
3030  DataNode->Data.Checksum = 0;
3031  DataNode->ScratchFilePosition = ScratchFile->Position();
3032 
3033  // FIXME: MAKECAB.EXE does not like this checksum algorithm
3034  //DataNode->Data.Checksum = ComputeChecksum(CurrentOBuffer, DataNode->Data.CompSize, 0);
3035 
3036  DPRINT(MAX_TRACE, ("Writing block. Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
3037  (UINT)DataNode->Data.Checksum,
3038  DataNode->Data.CompSize,
3039  DataNode->Data.UncompSize));
3040 
3041  Status = ScratchFile->WriteBlock(&DataNode->Data,
3043  if (Status != CAB_STATUS_SUCCESS)
3044  return Status;
3045 
3047 
3049  CurrentFolderNode->Folder.DataBlockCount++;
3050 
3051  CurrentOBuffer = (unsigned char*)CurrentOBuffer + DataNode->Data.CompSize;
3052  CurrentOBufferSize -= DataNode->Data.CompSize;
3053 
3054  LastBlockStart += DataNode->Data.UncompSize;
3055 
3056  if (!BlockIsSplit)
3057  {
3058  CurrentIBufferSize = 0;
3060  }
3061 
3062  return CAB_STATUS_SUCCESS;
3063 }
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
ULONG ScratchFilePosition
Definition: cabinet.h:196
ULONG DiskSize
Definition: cabinet.h:495
virtual ULONG Compress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
CCABCodec * Codec
Definition: cabinet.h:479
CFFOLDER Folder
Definition: cabinet.h:214
void * OutputBuffer
Definition: cabinet.h:485
CFDATA Data
Definition: cabinet.h:199
ULONG MaxDiskSize
Definition: cabinet.h:494
ULONG CurrentOBufferSize
Definition: cabinet.h:488
ULONG LastBlockStart
Definition: cabinet.h:493
PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode)
Definition: cabinet.cxx:2288
CCFDATAStorage * ScratchFile
Definition: cabinet.h:500
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
void DPRINT(...)
Definition: polytest.cpp:61
void * InputBuffer
Definition: cabinet.h:482
if(!(yy_init))
Definition: macro.lex.yy.c:714
bool BlockIsSplit
Definition: cabinet.h:504
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG CurrentIBufferSize
Definition: cabinet.h:484
struct _CFDATA CFDATA
Status
Definition: gdiplustypes.h:24
void * CurrentOBuffer
Definition: cabinet.h:487
void * CurrentIBuffer
Definition: cabinet.h:483
ULONG TotalCompSize
Definition: cabinet.h:486
#define MAX_TRACE
Definition: debug.h:16
unsigned short USHORT
Definition: pedump.c:61
ULONG WriteBlock(PCFDATA Data, void *Buffer, PULONG BytesWritten)
unsigned int UINT
Definition: ndis.h:50
PCFFOLDER_NODE CurrentFolderNode
Definition: cabinet.h:473
unsigned int ULONG
Definition: retypes.h:1
ULONG TotalFolderSize
Definition: cabinet.h:208
#define MIN_TRACE
Definition: debug.h:14
bool CreateNewDisk
Definition: cabinet.h:497

Referenced by WriteDisk(), and WriteFileToScratchStorage().

◆ WriteDisk()

ULONG CCabinet::WriteDisk ( ULONG  MoreDisks)

Definition at line 1402 of file cabinet.cxx.

1410 {
1411  PCFFILE_NODE FileNode;
1412  ULONG Status;
1413 
1414  ContinueFile = false;
1415  FileNode = FileListHead;
1416  while (FileNode != NULL)
1417  {
1418  Status = WriteFileToScratchStorage(FileNode);
1419  if (Status != CAB_STATUS_SUCCESS)
1420  return Status;
1421 
1422  if (CreateNewDisk)
1423  {
1424  /* A data block could span more than two
1425  disks if MaxDiskSize is very small */
1426  while (CreateNewDisk)
1427  {
1428  DPRINT(MAX_TRACE, ("Creating new disk.\n"));
1429  CommitDisk(true);
1430  CloseDisk();
1431  NewDisk();
1432 
1433  ContinueFile = true;
1434  CreateNewDisk = false;
1435 
1436  DPRINT(MAX_TRACE, ("First on new disk. CurrentIBufferSize (%u) CurrentOBufferSize (%u).\n",
1438 
1439  if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1440  {
1441  Status = WriteDataBlock();
1442  if (Status != CAB_STATUS_SUCCESS)
1443  return Status;
1444  }
1445  }
1446  }
1447  else
1448  {
1449  ContinueFile = false;
1450  FileNode = FileNode->Next;
1451  }
1452  }
1453 
1454  if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1455  {
1456  /* A data block could span more than two
1457  disks if MaxDiskSize is very small */
1458 
1459  ASSERT(CreateNewDisk == false);
1460 
1461  do
1462  {
1463  if (CreateNewDisk)
1464  {
1465  DPRINT(MID_TRACE, ("Creating new disk 2.\n"));
1466  CommitDisk(true);
1467  CloseDisk();
1468  NewDisk();
1469  CreateNewDisk = false;
1470 
1471  ASSERT(FileNode == FileListHead);
1472  }
1473 
1474  if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0))
1475  {
1476  Status = WriteDataBlock();
1477  if (Status != CAB_STATUS_SUCCESS)
1478  return Status;
1479  }
1480  } while (CreateNewDisk);
1481  }
1482  CommitDisk(MoreDisks);
1483 
1484  return CAB_STATUS_SUCCESS;
1485 }
#define MID_TRACE
Definition: debug.h:15
bool ContinueFile
Definition: cabinet.h:502
ULONG WriteFileToScratchStorage(PCFFILE_NODE FileNode)
Definition: cabinet.cxx:1288
struct _CFFILE_NODE * Next
Definition: cabinet.h:219
ULONG CurrentOBufferSize
Definition: cabinet.h:488
ULONG CommitDisk(ULONG MoreDisks)
Definition: cabinet.cxx:1488
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG CurrentIBufferSize
Definition: cabinet.h:484
Status
Definition: gdiplustypes.h:24
#define MAX_TRACE
Definition: debug.h:16
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
unsigned int UINT
Definition: ndis.h:50
ULONG NewDisk()
Definition: cabinet.cxx:1219
unsigned int ULONG
Definition: retypes.h:1
ULONG WriteDataBlock()
Definition: cabinet.cxx:2978
bool CreateNewDisk
Definition: cabinet.h:497
ULONG CloseDisk()
Definition: cabinet.cxx:1557

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

◆ WriteFileEntries()

ULONG CCabinet::WriteFileEntries ( )
private

Definition at line 2866 of file cabinet.cxx.

2872 {
2874  bool SetCont = false;
2875 
2876  DPRINT(MAX_TRACE, ("Writing file table.\n"));
2877 
2878  File = FileListHead;
2879  while (File != NULL)
2880  {
2881  if (File->Commit)
2882  {
2883  /* Remove any continued files that ends in this disk */
2884  if (File->File.FileControlID == CAB_FILE_CONTINUED)
2885  File->Delete = true;
2886 
2887  /* The file could end in the last (split) block and should therefore
2888  appear in the next disk too */
2889 
2890  if ((File->File.FileOffset + File->File.FileSize >= LastBlockStart) &&
2891  (File->File.FileControlID <= CAB_FILE_MAX_FOLDER) && (BlockIsSplit))
2892  {
2893  File->File.FileControlID = CAB_FILE_SPLIT;
2894  File->Delete = false;
2895  SetCont = true;
2896  }
2897 
2898  DPRINT(MAX_TRACE, ("Writing file entry. FileControlID (0x%X) FileOffset (0x%X) FileSize (%u) FileName (%s).\n",
2899  File->File.FileControlID, (UINT)File->File.FileOffset, (UINT)File->File.FileSize, File->FileName));
2900 
2901  if (fwrite(&File->File, sizeof(CFFILE), 1, FileHandle) < 1)
2902  {
2903  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2904  return CAB_STATUS_CANNOT_WRITE;
2905  }
2906 
2907  if (fwrite(GetFileName(File->FileName), strlen(GetFileName(File->FileName)) + 1, 1, FileHandle) < 1)
2908  {
2909  DPRINT(MIN_TRACE, ("Cannot write to file.\n"));
2910  return CAB_STATUS_CANNOT_WRITE;
2911  }
2912 
2913  if (SetCont)
2914  {
2915  File->File.FileControlID = CAB_FILE_CONTINUED;
2916  SetCont = false;
2917  }
2918  }
2919 
2920  File = File->Next;
2921  }
2922  return CAB_STATUS_SUCCESS;
2923 }
FILE * FileHandle
Definition: cabinet.h:465
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CAB_FILE_SPLIT
Definition: cabinet.c:72
_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)
#define CAB_FILE_CONTINUED
Definition: cabinet.c:71
ULONG LastBlockStart
Definition: cabinet.h:493
char * GetFileName(char *Path)
Definition: cabinet.cxx:183
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:29
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
File()
Definition: File.h:18
Definition: fci.c:89
bool BlockIsSplit
Definition: cabinet.h:504
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
#define CAB_FILE_MAX_FOLDER
Definition: cabinet.c:70
#define MAX_TRACE
Definition: debug.h:16
PCFFILE_NODE FileListHead
Definition: cabinet.h:475
unsigned int UINT
Definition: ndis.h:50
#define MIN_TRACE
Definition: debug.h:14
Definition: File.h:15

Referenced by CommitDisk().

◆ WriteFileToScratchStorage()

ULONG CCabinet::WriteFileToScratchStorage ( PCFFILE_NODE  FileNode)

Definition at line 1288 of file cabinet.cxx.

1296 {
1297  ULONG BytesToRead;
1298  ULONG BytesRead;
1299  ULONG Status;
1300  ULONG Size;
1301 
1302  if (!ContinueFile)
1303  {
1304  /* Try to open file */
1305  SourceFile = fopen(FileNode->FileName, "rb");
1306  if (SourceFile == NULL)
1307  {
1308  DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName));
1309  return CAB_STATUS_NOFILE;
1310  }
1311 
1312  if (CreateNewFolder)
1313  {
1314  /* There is always a new folder after
1315  a split file is completely stored */
1316  Status = NewFolder();
1317  if (Status != CAB_STATUS_SUCCESS)
1318  return Status;
1319  CreateNewFolder = false;
1320  }
1321 
1322  /* Call OnAdd event handler */
1323  OnAdd(&FileNode->File, FileNode->FileName);
1324 
1325  TotalBytesLeft = FileNode->File.FileSize;
1326 
1327  FileNode->File.FileOffset = CurrentFolderNode->UncompOffset;
1329  FileNode->File.FileControlID = (USHORT)(NextFolderNumber - 1);
1330  CurrentFolderNode->Commit = true;
1332 
1333  Size = sizeof(CFFILE) + (ULONG)strlen(GetFileName(FileNode->FileName)) + 1;
1334  CABHeader.FileTableOffset += Size;
1335  TotalFileSize += Size;
1336  DiskSize += Size;
1337  }
1338 
1339  FileNode->Commit = true;
1340 
1341  if (TotalBytesLeft > 0)
1342  {
1343  do
1344  {
1346  BytesToRead = CAB_BLOCKSIZE - CurrentIBufferSize;
1347  else
1348  BytesToRead = TotalBytesLeft;
1349 
1350  if ( (BytesRead = fread(CurrentIBuffer, 1, BytesToRead, SourceFile)) != BytesToRead )
1351  {
1352  DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%u) BytesRead (%u) CurrentIBufferSize (%u).\n",
1353  (UINT)BytesToRead, (UINT)BytesRead, (UINT)CurrentIBufferSize));
1354  return CAB_STATUS_INVALID_CAB;
1355  }
1356 
1357