128 if ((Char ==
'\\') || (Char ==
'/'))
145 for (
size_t i = 0;
i <
Path.size(); ++
i)
169 j =
i = (
Path[0] ? (
Path[1] ==
':' ? 2 : 0) : 0);
175 return Path.c_str() +
j;
186 if (
Path.length() > 0)
250 Criteria->
Search = SearchCriteria;
281 if (!
Node->TargetFolder.empty())
283 fname =
Node->TargetFolder + fname;
301 printf(
"ERROR: Invalid codec specified!\n");
587 DPRINT(
MAX_TRACE, (
"Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n",
664 ULONG TotalBytesRead;
702 DPRINT(
MAX_TRACE, (
"Extracting file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
705 (
UINT)
File->DataBlock->AbsoluteOffset,
706 (
UINT)
File->DataBlock->UncompOffset));
712 DestFile =
fopen(DestName,
"rb");
713 if (DestFile !=
NULL)
719 DestFile =
fopen(DestName,
"w+b");
720 if (DestFile ==
NULL)
728 DestFile =
fopen(DestName,
"w+b");
729 if (DestFile ==
NULL)
770 CurrentOffset =
File->DataBlock->UncompOffset;
779 DPRINT(
MAX_TRACE, (
"CO (0x%X) ReuseBlock (%u) Offset (0x%X) Size (%d) BytesLeftInBlock (%d)\n",
802 DPRINT(
MAX_TRACE, (
"Data block: Checksum (0x%X) CompSize (%u bytes) UncompSize (%u bytes)\n",
803 (
UINT)CFData.Checksum,
809 BytesToRead = CFData.CompSize;
842 if (CFData.UncompSize == 0)
893 DPRINT(
MAX_TRACE, (
"Continuing extraction of file at uncompressed offset (0x%X) Size (%u bytes) AO (0x%X) UO (0x%X).\n",
896 (
UINT)
File->DataBlock->AbsoluteOffset,
897 (
UINT)
File->DataBlock->UncompOffset));
904 }
while (CFData.UncompSize == 0);
919 if (BytesToWrite != CFData.UncompSize)
922 (
UINT)BytesToWrite, CFData.UncompSize));
949 CFData.CompSize, CFData.UncompSize));
965 BytesSkipped = (
Offset - CurrentOffset);
969 BytesToWrite -= BytesSkipped;
971 if (
Size < BytesToWrite)
974 DPRINT(
MAX_TRACE, (
"Offset (0x%X) CurrentOffset (0x%X) ToWrite (%u) Skipped (%u)(%u) Size (%u).\n",
983 BytesToWrite, 1, DestFile) < 1)
992 Size -= BytesToWrite;
994 CurrentOffset += BytesToWrite;
1053 #ifndef CAB_READ_ONLY 1217 DPRINT(
MID_TRACE, (
"File not found (%s).\n", FileNode->FileNameOnDisk.c_str()));
1261 DPRINT(
MIN_TRACE, (
"Cannot read from file. BytesToRead (%u) BytesRead (%u) CurrentIBufferSize (%u).\n",
1343 DPRINT(
MAX_TRACE, (
"First on new disk. CurrentIBufferSize (%u) CurrentOBufferSize (%u).\n",
1441 if (FolderNode->Commit)
1532 SrcFile =
fopen(NewFileName.c_str(),
"rb");
1533 if (SrcFile ==
NULL)
1555 if (FileNode->
File.FileSize == (
ULONG)-1)
1618 pszFile = szSearchPath.substr(sep + 1);
1620 szFilePath = szSearchPath.substr(0, sep + 1);
1624 pszFile = Criteria->Search;
1626 #if !defined(_WIN32) 1634 hFind =
FindFirstFile(Criteria->Search.c_str(), &FindFileData);
1648 szFile += FindFileData.cFileName;
1674 if(
stat(szFile.c_str(), &stbuf) == 0)
1763 const char* DiskLabel)
1778 #ifndef CAB_READ_ONLY 1858 DPRINT(
MAX_TRACE, (
"FileName '%s' FileOffset (0x%X) FileSize (%u).\n",
1859 File->FileName.c_str(),
1865 DPRINT(
MAX_TRACE, (
"GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%u).\n",
1872 if ((
Node->Data.UncompSize == 0) ||
1875 Node->Data.UncompSize)))
1911 Node->File.FileControlID));
2027 File->FileName = Buf;
2029 DPRINT(
MAX_TRACE, (
"Found file '%s' at uncompressed offset (0x%X). Size (%u bytes) ControlId (0x%X).\n",
2030 File->FileName.c_str(),
2049 ULONG AbsoluteOffset;
2056 DPRINT(
MAX_TRACE, (
"Reading data blocks for folder (%u) at absolute offset (0x%X).\n",
2059 AbsoluteOffset = FolderNode->
Folder.DataOffset;
2062 for (
i = 0;
i < FolderNode->
Folder.DataBlockCount;
i++)
2085 DPRINT(
MAX_TRACE, (
"AbsOffset (0x%X) UncompOffset (0x%X) Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
2086 (
UINT)AbsoluteOffset,
2089 Node->Data.CompSize,
2090 Node->Data.UncompSize));
2092 Node->AbsoluteOffset = AbsoluteOffset;
2093 Node->UncompOffset = UncompOffset;
2095 AbsoluteOffset +=
sizeof(
CFDATA) +
Node->Data.CompSize;
2096 UncompOffset +=
Node->Data.UncompSize;
2286 UlongCount =
Size / 4;
2288 pb = (
unsigned char*)
Buffer;
2291 while (UlongCount-- > 0)
2295 ul |= (((
ULONG)(*pb++)) << 8);
2296 ul |= (((
ULONG)(*pb++)) << 16);
2297 ul |= (((
ULONG)(*pb++)) << 24);
2307 ul |= (((
ULONG)(*pb++)) << 16);
2309 ul |= (((
ULONG)(*pb++)) << 8);
2357 const char* retryPattern =
NULL;
2358 const char* retryFileName =
NULL;
2368 retryPattern = Pattern;
2388 Pattern = retryPattern;
2403 #ifndef CAB_READ_ONLY 2473 TotalSize +=
sizeof(
ULONG);
2527 if (FileNode->Commit)
2546 ReservedSize |= (0 << 16);
2547 ReservedSize |= (0 << 24);
2629 if (FolderNode->Commit)
2631 DPRINT(
MAX_TRACE, (
"Writing folder entry. CompressionType (0x%X) DataBlockCount (%d) DataOffset (0x%X).\n",
2632 FolderNode->Folder.CompressionType, FolderNode->Folder.DataBlockCount, (
UINT)FolderNode->Folder.DataOffset));
2653 bool SetCont =
false;
2663 File->Delete =
true;
2672 File->Delete =
false;
2676 DPRINT(
MAX_TRACE, (
"Writing file entry. FileControlID (0x%X) FileOffset (0x%X) FileSize (%u) FileName (%s).\n",
2720 DPRINT(
MAX_TRACE, (
"Reading block at (0x%X) CompSize (%u) UncompSize (%u).\n",
2722 DataNode->
Data.CompSize,
2723 DataNode->
Data.UncompSize));
2769 DPRINT(
MAX_TRACE, (
"Block compressed. CurrentIBufferSize (%u) TotalCompSize(%u).\n",
2794 DataNode->
Data.UncompSize = 0;
2803 DataNode->
Data.Checksum = 0;
2809 DPRINT(
MAX_TRACE, (
"Writing block. Checksum (0x%X) CompSize (%u) UncompSize (%u).\n",
2811 DataNode->
Data.CompSize,
2812 DataNode->
Data.UncompSize));
2838 #if !defined(_WIN32) 2856 DPRINT(
MAX_TRACE, (
"day: %d, mon: %d, year:%d, hour: %d, min: %d, sec: %d\n",
2860 *DosDate = ((timedef->
tm_mday + 1) << 0)
2861 | ((timedef->
tm_mon + 1) << 5)
2862 | (((timedef->
tm_year + 1900) - 1980) << 9);
2864 *DosTime = (timedef->
tm_sec << 0)
static ACPI_BUFFER CurrentBuffer
#define CAB_STATUS_INVALID_CAB
ULONG LocateFile(const char *FileName, PCFFILE_NODE *File)
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
struct _CFHEADER CFHEADER
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
ULONG FindFirst(PCAB_SEARCH Search)
void DestroyDataNodes(PCFFOLDER_NODE FolderNode)
virtual void OnVerboseMessage(const char *Message)
#define CAB_FILE_PREV_NEXT
static WCHAR szFilePath[]
char * strcat(char *DstString, const char *SrcString)
ACPI_SIZE strlen(const char *String)
IN BOOLEAN OUT PSTR Buffer
ULONG ScratchFilePosition
ULONG GetAttributesOnFile(PCFFILE_NODE File)
#define CAB_STATUS_CANNOT_READ
ULONG WriteFileToScratchStorage(PCFFILE_NODE FileNode)
vector< FileInfo > FileList
ULONG WriteCabinetHeader(bool MoreDisks)
virtual ULONG Compress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
ULONG Seek(LONG Position)
ULONG SetAttributesOnFile(char *FileName, USHORT FileAttributes)
#define INVALID_HANDLE_VALUE
IN PVOID IN PVOID IN USHORT IN USHORT Size
DWORD WINAPI GetLastError(VOID)
#define CAB_ATTRIB_SYSTEM
PCFFOLDER_NODE LocateFolderNode(ULONG Index)
#define CAB_ATTRIB_HIDDEN
std::list< PSEARCH_CRITERIA > CriteriaList
ULONG ComputeChecksum(void *Buffer, ULONG Size, ULONG Seed)
_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)
PCFFOLDER_NODE FolderNode
std::list< PCFFILE_NODE >::iterator Next
PCFDATA_NODE CurrentDataNode
std::string CreateCabFilename(PCFFILE_NODE Node)
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
#define CAB_FILE_CONTINUED
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
void DestroyFolderNodes()
DIR *__cdecl opendir(const char *)
GLenum GLuint GLenum GLsizei const GLchar * buf
struct _CFFOLDER CFFOLDER
PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode)
void NormalizePath(std::string &Path)
#define DIR_SEPARATOR_CHAR
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
_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)
ULONG GetFileTimes(FILE *FileHandle, PCFFILE_NODE File)
void SetCabinetName(const char *FileName)
const char * GetDestinationPath()
void SetMaxDiskSize(ULONG Size)
virtual void OnAdd(PCFFILE Entry, const char *FileName)
virtual bool OnDiskLabel(ULONG Number, char *Label)
#define CAB_STATUS_CANNOT_WRITE
ULONG CommitDisk(ULONG MoreDisks)
ULONG ExtractFile(const char *FileName)
#define CAB_STATUS_NOMEMORY
std::string CabinetReservedFile
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
#define CAB_ATTRIB_DIRECTORY
std::list< PCFDATA_NODE > DataList
#define CAB_ATTRIB_READONLY
PCFFOLDER_NODE NewFolderNode()
_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
#define ERROR_FILE_NOT_FOUND
class CCFDATAStorage * ScratchFile
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
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
#define FILE_ATTRIBUTE_DIRECTORY
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
#define CAB_STATUS_UNSUPPCOMP
ULONG ReadBlock(PCFDATA Data, void *Buffer, PULONG BytesRead)
#define SetFileAttributes
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
ULONG ReadBlock(void *Buffer, ULONG Size, PULONG BytesRead)
_In_ WDFCOLLECTION _In_ ULONG Index
#define UlongToHandle(ul)
ULONG WriteFolderEntries()
virtual void OnDiskChange(const char *CabinetName, const char *DiskLabel)
void DestroySearchCriteria()
#define CAB_STATUS_CANNOT_CREATE
#define CAB_STATUS_FAILURE
void ConvertDateAndTime(time_t *Time, PUSHORT DosDate, PUSHORT DosTime)
void DestroyDeletedFolderNodes()
void ConvertPath(std::string &Path)
#define CAB_STATUS_SUCCESS
ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode)
#define FILE_ATTRIBUTE_NORMAL
ULONG FindNext(PCAB_SEARCH Search)
void DestroyDeletedFileNodes()
void SelectCodec(LONG Id)
virtual bool OnOverwrite(PCFFILE Entry, const char *FileName)
_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 ReadString(char *String, LONG MaxLength)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
int __cdecl closedir(DIR *)
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
_Check_return_ _Ret_opt_z_ _CRTIMP char *__cdecl getcwd(_Out_writes_opt_(_SizeInBytes) char *_DstBuf, _In_ int _SizeInBytes)
#define GetFileAttributes
struct dirent *__cdecl readdir(DIR *)
virtual void OnExtract(PCFFILE Entry, const char *FileName)
_In_ ULONG _In_ ULONG Offset
#define CAB_FILE_MAX_FOLDER
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
struct _FileName FileName
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
PRTL_UNICODE_STRING_BUFFER Path
ULONG CabinetReservedFileSize
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
#define CAB_ATTRIB_ARCHIVE
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
ULONG WriteBlock(PCFDATA Data, void *Buffer, PULONG BytesWritten)
ULONG GetAbsoluteOffset(PCFFILE_NODE File)
bool SetCabinetReservedFile(const char *FileName)
void SetDestinationPath(const char *DestinationPath)
PCFFILE_NODE NewFileNode()
PCFFOLDER_NODE CurrentFolderNode
virtual ULONG Uncompress(void *OutputBuffer, void *InputBuffer, ULONG InputLength, PULONG OutputLength)=0
bool CreateSimpleCabinet()
#define CAB_STATUS_FILE_EXISTS
ULONG AddFile(const std::string &FileName, const std::string &TargetFolder)
void * CabinetReservedFileBuffer
bool IsSeparator(char Char)
char * strcpy(char *DstString, const char *SrcString)
ULONG AddSearchCriteria(const std::string &SearchCriteria, const std::string &TargetFolder)
char * cleanup(char *str)
#define CAB_STATUS_CANNOT_OPEN
#define DIR_SEPARATOR_STRING
std::string GetFileName(const std::string &Path)
virtual bool OnCabinetName(ULONG Number, char *Name)
bool MatchFileNamePattern(const char *FileName, const char *Pattern)
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
ULONG GetCurrentDiskNumber()
ULONG InitCabinetHeader()
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
#define CAB_STATUS_NOFILE
static PLARGE_INTEGER Time
bool SetCompressionCodec(const char *CodecName)
ULONG WriteDisk(ULONG MoreDisks)
ULONG CommitDataBlocks(PCFFOLDER_NODE FolderNode)
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
BOOL WINAPI FindClose(HANDLE hFindFile)