Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencabinet.h
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS cabinet manager 00004 * FILE: tools/cabman/cabinet.h 00005 * PURPOSE: Cabinet definitions 00006 */ 00007 00008 #pragma once 00009 00010 #if defined(_WIN32) 00011 #include <windows.h> 00012 #else 00013 #include <errno.h> 00014 #include <fcntl.h> 00015 #include <sys/types.h> 00016 #include <time.h> 00017 #include <typedefs.h> 00018 #include <unistd.h> 00019 #endif 00020 00021 #include <stdlib.h> 00022 #include <stdio.h> 00023 #include <string.h> 00024 #include <limits.h> 00025 00026 #ifndef PATH_MAX 00027 #define PATH_MAX MAX_PATH 00028 #endif 00029 00030 #if defined(_WIN32) 00031 #define DIR_SEPARATOR_CHAR '\\' 00032 #define DIR_SEPARATOR_STRING "\\" 00033 00034 #define strcasecmp _stricmp 00035 #define strdup _strdup 00036 00037 #define AllocateMemory(size) HeapAlloc(GetProcessHeap(), 0, size) 00038 #define FreeMemory(buffer) HeapFree(GetProcessHeap(), 0, buffer) 00039 #define FILEHANDLE HANDLE 00040 #define CloseFile(handle) CloseHandle(handle) 00041 #else 00042 #define DIR_SEPARATOR_CHAR '/' 00043 #define DIR_SEPARATOR_STRING "/" 00044 00045 #define AllocateMemory(size) malloc(size) 00046 #define FreeMemory(buffer) free(buffer) 00047 #define CloseFile(handle) fclose(handle) 00048 #define FILEHANDLE FILE* 00049 #endif 00050 00051 /* Debugging */ 00052 00053 #define NORMAL_MASK 0x000000FF 00054 #define SPECIAL_MASK 0xFFFFFF00 00055 #define MIN_TRACE 0x00000001 00056 #define MID_TRACE 0x00000002 00057 #define MAX_TRACE 0x00000003 00058 00059 #define DEBUG_MEMORY 0x00000100 00060 00061 #if DBG 00062 00063 extern ULONG DebugTraceLevel; 00064 00065 #undef DPRINT 00066 #define DPRINT(_t_, _x_) \ 00067 if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \ 00068 ((DebugTraceLevel & _t_) > NORMAL_MASK)) { \ 00069 printf("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \ 00070 printf _x_ ; \ 00071 } 00072 00073 #undef ASSERT 00074 #define ASSERT(_b_) { \ 00075 if (!(_b_)) { \ 00076 printf("(%s:%d)(%s) ASSERTION: ", __FILE__, __LINE__, __FUNCTION__); \ 00077 printf(#_b_); \ 00078 exit(0); \ 00079 } \ 00080 } 00081 00082 #else /* DBG */ 00083 00084 #undef DPRINT 00085 #define DPRINT(_t_, _x_) do { } while(0) 00086 00087 #undef ASSERT 00088 #define ASSERT(_x_) 00089 00090 #endif /* DBG */ 00091 00092 00093 /* Cabinet constants */ 00094 00095 #define CAB_SIGNATURE 0x4643534D // "MSCF" 00096 #define CAB_VERSION 0x0103 00097 #define CAB_BLOCKSIZE 32768 00098 00099 #define CAB_COMP_MASK 0x00FF 00100 #define CAB_COMP_NONE 0x0000 00101 #define CAB_COMP_MSZIP 0x0001 00102 #define CAB_COMP_QUANTUM 0x0002 00103 #define CAB_COMP_LZX 0x0003 00104 00105 #define CAB_FLAG_HASPREV 0x0001 00106 #define CAB_FLAG_HASNEXT 0x0002 00107 #define CAB_FLAG_RESERVE 0x0004 00108 00109 #define CAB_ATTRIB_READONLY 0x0001 00110 #define CAB_ATTRIB_HIDDEN 0x0002 00111 #define CAB_ATTRIB_SYSTEM 0x0004 00112 #define CAB_ATTRIB_VOLUME 0x0008 00113 #define CAB_ATTRIB_DIRECTORY 0x0010 00114 #define CAB_ATTRIB_ARCHIVE 0x0020 00115 #define CAB_ATTRIB_EXECUTE 0x0040 00116 #define CAB_ATTRIB_UTF_NAME 0x0080 00117 00118 #define CAB_FILE_MAX_FOLDER 0xFFFC 00119 #define CAB_FILE_CONTINUED 0xFFFD 00120 #define CAB_FILE_SPLIT 0xFFFE 00121 #define CAB_FILE_PREV_NEXT 0xFFFF 00122 00123 00124 /* Cabinet structures */ 00125 00126 typedef struct _CFHEADER 00127 { 00128 ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE) 00129 ULONG Reserved1; // Reserved field 00130 ULONG CabinetSize; // Cabinet file size 00131 ULONG Reserved2; // Reserved field 00132 ULONG FileTableOffset; // Offset of first CFFILE 00133 ULONG Reserved3; // Reserved field 00134 USHORT Version; // Cabinet version (CAB_VERSION) 00135 USHORT FolderCount; // Number of folders 00136 USHORT FileCount; // Number of files 00137 USHORT Flags; // Cabinet flags (CAB_FLAG_*) 00138 USHORT SetID; // Cabinet set id 00139 USHORT CabinetNumber; // Zero-based cabinet number 00140 /* Optional fields (depends on Flags) 00141 USHORT CabinetResSize // Per-cabinet reserved area size 00142 char FolderResSize // Per-folder reserved area size 00143 char FileResSize // Per-file reserved area size 00144 char CabinetReserved[] // Per-cabinet reserved area 00145 char CabinetPrev[] // Name of previous cabinet file 00146 char DiskPrev[] // Name of previous disk 00147 char CabinetNext[] // Name of next cabinet file 00148 char DiskNext[] // Name of next disk 00149 */ 00150 } CFHEADER, *PCFHEADER; 00151 00152 00153 typedef struct _CFFOLDER 00154 { 00155 ULONG DataOffset; // Absolute offset of first CFDATA block in this folder 00156 USHORT DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet 00157 USHORT CompressionType; // Type of compression used for all CFDATA blocks in this folder 00158 /* Optional fields (depends on Flags) 00159 char FolderReserved[] // Per-folder reserved area 00160 */ 00161 } CFFOLDER, *PCFFOLDER; 00162 00163 00164 typedef struct _CFFILE 00165 { 00166 ULONG FileSize; // Uncompressed file size in bytes 00167 ULONG FileOffset; // Uncompressed offset of file in the folder 00168 USHORT FileControlID; // File control ID (CAB_FILE_*) 00169 USHORT FileDate; // File date stamp, as used by DOS 00170 USHORT FileTime; // File time stamp, as used by DOS 00171 USHORT Attributes; // File attributes (CAB_ATTRIB_*) 00172 /* After this is the NULL terminated filename */ 00173 } CFFILE, *PCFFILE; 00174 00175 00176 typedef struct _CFDATA 00177 { 00178 ULONG Checksum; // Checksum of CFDATA entry 00179 USHORT CompSize; // Number of compressed bytes in this block 00180 USHORT UncompSize; // Number of uncompressed bytes in this block 00181 /* Optional fields (depends on Flags) 00182 char DataReserved[] // Per-datablock reserved area 00183 */ 00184 } CFDATA, *PCFDATA; 00185 00186 typedef struct _CFDATA_NODE 00187 { 00188 struct _CFDATA_NODE *Next; 00189 struct _CFDATA_NODE *Prev; 00190 ULONG ScratchFilePosition; // Absolute offset in scratch file 00191 ULONG AbsoluteOffset; // Absolute offset in cabinet 00192 ULONG UncompOffset; // Uncompressed offset in folder 00193 CFDATA Data; 00194 } CFDATA_NODE, *PCFDATA_NODE; 00195 00196 typedef struct _CFFOLDER_NODE 00197 { 00198 struct _CFFOLDER_NODE *Next; 00199 struct _CFFOLDER_NODE *Prev; 00200 ULONG UncompOffset; // File size accumulator 00201 ULONG AbsoluteOffset; 00202 ULONG TotalFolderSize; // Total size of folder in current disk 00203 PCFDATA_NODE DataListHead; 00204 PCFDATA_NODE DataListTail; 00205 ULONG Index; 00206 bool Commit; // true if the folder should be committed 00207 bool Delete; // true if marked for deletion 00208 CFFOLDER Folder; 00209 } CFFOLDER_NODE, *PCFFOLDER_NODE; 00210 00211 typedef struct _CFFILE_NODE 00212 { 00213 struct _CFFILE_NODE *Next; 00214 struct _CFFILE_NODE *Prev; 00215 CFFILE File; 00216 char* FileName; 00217 PCFDATA_NODE DataBlock; // First data block of file. NULL if not known 00218 bool Commit; // true if the file data should be committed 00219 bool Delete; // true if marked for deletion 00220 PCFFOLDER_NODE FolderNode; // Folder this file belong to 00221 } CFFILE_NODE, *PCFFILE_NODE; 00222 00223 typedef struct _SEARCH_CRITERIA 00224 { 00225 struct _SEARCH_CRITERIA *Next; // Pointer to next search criteria 00226 struct _SEARCH_CRITERIA *Prev; // Pointer to previous search criteria 00227 char* Search; // The actual search criteria 00228 } SEARCH_CRITERIA, *PSEARCH_CRITERIA; 00229 00230 typedef struct _CAB_SEARCH 00231 { 00232 PCFFILE_NODE Next; // Pointer to next node 00233 PCFFILE File; // Pointer to current CFFILE 00234 char* FileName; // Current filename 00235 } CAB_SEARCH, *PCAB_SEARCH; 00236 00237 00238 /* Constants */ 00239 00240 /* Status codes */ 00241 #define CAB_STATUS_SUCCESS 0x00000000 00242 #define CAB_STATUS_FAILURE 0x00000001 00243 #define CAB_STATUS_NOMEMORY 0x00000002 00244 #define CAB_STATUS_CANNOT_OPEN 0x00000003 00245 #define CAB_STATUS_CANNOT_CREATE 0x00000004 00246 #define CAB_STATUS_CANNOT_READ 0x00000005 00247 #define CAB_STATUS_CANNOT_WRITE 0x00000006 00248 #define CAB_STATUS_FILE_EXISTS 0x00000007 00249 #define CAB_STATUS_INVALID_CAB 0x00000008 00250 #define CAB_STATUS_NOFILE 0x00000009 00251 #define CAB_STATUS_UNSUPPCOMP 0x0000000A 00252 00253 00254 00255 /* Codecs */ 00256 00257 class CCABCodec { 00258 public: 00259 /* Default constructor */ 00260 CCABCodec() {}; 00261 /* Default destructor */ 00262 virtual ~CCABCodec() {}; 00263 /* Compresses a data block */ 00264 virtual ULONG Compress(void* OutputBuffer, 00265 void* InputBuffer, 00266 ULONG InputLength, 00267 PULONG OutputLength) = 0; 00268 /* Uncompresses a data block */ 00269 virtual ULONG Uncompress(void* OutputBuffer, 00270 void* InputBuffer, 00271 ULONG InputLength, 00272 PULONG OutputLength) = 0; 00273 }; 00274 00275 00276 /* Codec status codes */ 00277 #define CS_SUCCESS 0x0000 /* All data consumed */ 00278 #define CS_NOMEMORY 0x0001 /* Not enough free memory */ 00279 #define CS_BADSTREAM 0x0002 /* Bad data stream */ 00280 00281 00282 /* Codec indentifiers */ 00283 #define CAB_CODEC_RAW 0x00 00284 #define CAB_CODEC_LZX 0x01 00285 #define CAB_CODEC_MSZIP 0x02 00286 00287 00288 00289 /* Classes */ 00290 00291 #ifndef CAB_READ_ONLY 00292 00293 class CCFDATAStorage { 00294 public: 00295 /* Default constructor */ 00296 CCFDATAStorage(); 00297 /* Default destructor */ 00298 virtual ~CCFDATAStorage(); 00299 ULONG Create(); 00300 ULONG Destroy(); 00301 ULONG Truncate(); 00302 ULONG Position(); 00303 ULONG Seek(LONG Position); 00304 ULONG ReadBlock(PCFDATA Data, void* Buffer, PULONG BytesRead); 00305 ULONG WriteBlock(PCFDATA Data, void* Buffer, PULONG BytesWritten); 00306 private: 00307 char FullName[PATH_MAX]; 00308 bool FileCreated; 00309 FILEHANDLE FileHandle; 00310 }; 00311 00312 #endif /* CAB_READ_ONLY */ 00313 00314 class CCabinet { 00315 public: 00316 /* Default constructor */ 00317 CCabinet(); 00318 /* Default destructor */ 00319 virtual ~CCabinet(); 00320 /* Determines if a character is a separator */ 00321 bool IsSeparator(char Char); 00322 /* Replaces \ or / with the one used be the host environment */ 00323 char* ConvertPath(char* Path, bool Allocate); 00324 /* Returns a pointer to the filename part of a fully qualified filename */ 00325 char* GetFileName(char* Path); 00326 /* Removes a filename from a fully qualified filename */ 00327 void RemoveFileName(char* Path); 00328 /* Normalizes a path */ 00329 bool NormalizePath(char* Path, ULONG Length); 00330 /* Returns name of cabinet file */ 00331 char* GetCabinetName(); 00332 /* Sets the name of the cabinet file */ 00333 void SetCabinetName(char* FileName); 00334 /* Sets destination path for extracted files */ 00335 void SetDestinationPath(char* DestinationPath); 00336 /* Sets cabinet reserved file */ 00337 bool SetCabinetReservedFile(char* FileName); 00338 /* Returns cabinet reserved file */ 00339 char* GetCabinetReservedFile(); 00340 /* Returns destination path */ 00341 char* GetDestinationPath(); 00342 /* Returns zero-based current disk number */ 00343 ULONG GetCurrentDiskNumber(); 00344 /* Opens the current cabinet file */ 00345 ULONG Open(); 00346 /* Closes the current open cabinet file */ 00347 void Close(); 00348 /* Locates the first file in the current cabinet file that matches a search criteria */ 00349 ULONG FindFirst(PCAB_SEARCH Search); 00350 /* Locates the next file in the current cabinet file */ 00351 ULONG FindNext(PCAB_SEARCH Search); 00352 /* Extracts a file from the current cabinet file */ 00353 ULONG ExtractFile(char* FileName); 00354 /* Select codec engine to use */ 00355 void SelectCodec(LONG Id); 00356 /* Returns whether a codec engine is selected */ 00357 bool IsCodecSelected(); 00358 /* Adds a search criteria for adding files to a simple cabinet, displaying files in a cabinet or extracting them */ 00359 ULONG AddSearchCriteria(char* SearchCriteria); 00360 /* Destroys the search criteria list */ 00361 void DestroySearchCriteria(); 00362 /* Returns whether we have search criteria */ 00363 bool HasSearchCriteria(); 00364 00365 #ifndef CAB_READ_ONLY 00366 /* Creates a simple cabinet based on the search criteria data */ 00367 bool CreateSimpleCabinet(); 00368 /* Sets the codec to use for compression (based on a string value) */ 00369 bool SetCompressionCodec(char* CodecName); 00370 /* Creates a new cabinet file */ 00371 ULONG NewCabinet(); 00372 /* Forces a new disk to be created */ 00373 ULONG NewDisk(); 00374 /* Forces a new folder to be created */ 00375 ULONG NewFolder(); 00376 /* Writes a file to scratch storage */ 00377 ULONG WriteFileToScratchStorage(PCFFILE_NODE FileNode); 00378 /* Forces the current disk to be written */ 00379 ULONG WriteDisk(ULONG MoreDisks); 00380 /* Commits the current disk */ 00381 ULONG CommitDisk(ULONG MoreDisks); 00382 /* Closes the current disk */ 00383 ULONG CloseDisk(); 00384 /* Closes the current cabinet */ 00385 ULONG CloseCabinet(); 00386 /* Adds a file to the current disk */ 00387 ULONG AddFile(char* FileName); 00388 /* Sets the maximum size of the current disk */ 00389 void SetMaxDiskSize(ULONG Size); 00390 #endif /* CAB_READ_ONLY */ 00391 00392 /* Default event handlers */ 00393 00394 /* Handler called when a file is about to be overridden */ 00395 virtual bool OnOverwrite(PCFFILE Entry, char* FileName); 00396 /* Handler called when a file is about to be extracted */ 00397 virtual void OnExtract(PCFFILE Entry, char* FileName); 00398 /* Handler called when a new disk is to be processed */ 00399 virtual void OnDiskChange(char* CabinetName, char* DiskLabel); 00400 #ifndef CAB_READ_ONLY 00401 /* Handler called when a file is about to be added */ 00402 virtual void OnAdd(PCFFILE Entry, char* FileName); 00403 /* Handler called when a cabinet need a name */ 00404 virtual bool OnCabinetName(ULONG Number, char* Name); 00405 /* Handler called when a disk needs a label */ 00406 virtual bool OnDiskLabel(ULONG Number, char* Label); 00407 #endif /* CAB_READ_ONLY */ 00408 private: 00409 PCFFOLDER_NODE LocateFolderNode(ULONG Index); 00410 ULONG GetAbsoluteOffset(PCFFILE_NODE File); 00411 ULONG LocateFile(char* FileName, PCFFILE_NODE *File); 00412 ULONG ReadString(char* String, LONG MaxLength); 00413 ULONG ReadFileTable(); 00414 ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode); 00415 PCFFOLDER_NODE NewFolderNode(); 00416 PCFFILE_NODE NewFileNode(); 00417 PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode); 00418 void DestroyDataNodes(PCFFOLDER_NODE FolderNode); 00419 void DestroyFileNodes(); 00420 void DestroyDeletedFileNodes(); 00421 void DestroyFolderNodes(); 00422 void DestroyDeletedFolderNodes(); 00423 ULONG ComputeChecksum(void* Buffer, ULONG Size, ULONG Seed); 00424 ULONG ReadBlock(void* Buffer, ULONG Size, PULONG BytesRead); 00425 bool MatchFileNamePattern(char* FileName, char* Pattern); 00426 #ifndef CAB_READ_ONLY 00427 ULONG InitCabinetHeader(); 00428 ULONG WriteCabinetHeader(bool MoreDisks); 00429 ULONG WriteFolderEntries(); 00430 ULONG WriteFileEntries(); 00431 ULONG CommitDataBlocks(PCFFOLDER_NODE FolderNode); 00432 ULONG WriteDataBlock(); 00433 ULONG GetAttributesOnFile(PCFFILE_NODE File); 00434 ULONG SetAttributesOnFile(char* FileName, USHORT FileAttributes); 00435 ULONG GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File); 00436 #if !defined(_WIN32) 00437 void ConvertDateAndTime(time_t* Time, PUSHORT DosDate, PUSHORT DosTime); 00438 #endif 00439 #endif /* CAB_READ_ONLY */ 00440 ULONG CurrentDiskNumber; // Zero based disk number 00441 char CabinetName[256]; // Filename of current cabinet 00442 char CabinetPrev[256]; // Filename of previous cabinet 00443 char DiskPrev[256]; // Label of cabinet in file CabinetPrev 00444 char CabinetNext[256]; // Filename of next cabinet 00445 char DiskNext[256]; // Label of cabinet in file CabinetNext 00446 ULONG TotalHeaderSize; // Size of header and optional fields 00447 ULONG NextFieldsSize; // Size of next cabinet name and next disk label 00448 ULONG TotalFolderSize; // Size of all folder entries 00449 ULONG TotalFileSize; // Size of all file entries 00450 ULONG FolderUncompSize; // Uncompressed size of folder 00451 ULONG BytesLeftInBlock; // Number of bytes left in current block 00452 bool ReuseBlock; 00453 char DestPath[PATH_MAX]; 00454 char CabinetReservedFile[PATH_MAX]; 00455 void* CabinetReservedFileBuffer; 00456 ULONG CabinetReservedFileSize; 00457 FILEHANDLE FileHandle; 00458 bool FileOpen; 00459 CFHEADER CABHeader; 00460 ULONG CabinetReserved; 00461 ULONG FolderReserved; 00462 ULONG DataReserved; 00463 PCFFOLDER_NODE FolderListHead; 00464 PCFFOLDER_NODE FolderListTail; 00465 PCFFOLDER_NODE CurrentFolderNode; 00466 PCFDATA_NODE CurrentDataNode; 00467 PCFFILE_NODE FileListHead; 00468 PCFFILE_NODE FileListTail; 00469 PSEARCH_CRITERIA CriteriaListHead; 00470 PSEARCH_CRITERIA CriteriaListTail; 00471 CCABCodec *Codec; 00472 LONG CodecId; 00473 bool CodecSelected; 00474 void* InputBuffer; 00475 void* CurrentIBuffer; // Current offset in input buffer 00476 ULONG CurrentIBufferSize; // Bytes left in input buffer 00477 void* OutputBuffer; 00478 ULONG TotalCompSize; // Total size of current CFDATA block 00479 void* CurrentOBuffer; // Current offset in output buffer 00480 ULONG CurrentOBufferSize; // Bytes left in output buffer 00481 ULONG BytesLeftInCabinet; 00482 bool RestartSearch; 00483 ULONG LastFileOffset; // Uncompressed offset of last extracted file 00484 #ifndef CAB_READ_ONLY 00485 ULONG LastBlockStart; // Uncompressed offset of last block in folder 00486 ULONG MaxDiskSize; 00487 ULONG DiskSize; 00488 ULONG PrevCabinetNumber; // Previous cabinet number (where split file starts) 00489 bool CreateNewDisk; 00490 bool CreateNewFolder; 00491 00492 CCFDATAStorage *ScratchFile; 00493 FILEHANDLE SourceFile; 00494 bool ContinueFile; 00495 ULONG TotalBytesLeft; 00496 bool BlockIsSplit; // true if current data block is split 00497 ULONG NextFolderNumber; // Zero based folder number 00498 #endif /* CAB_READ_ONLY */ 00499 }; 00500 00501 /* EOF */ Generated on Sat May 26 2012 04:16:52 for ReactOS by
1.7.6.1
|