ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cabinet.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.