Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: cabinet.h
  8. //
  9. //--------------------------------------------------------------------------
  10. /*** cabinet.h - Definitions for Cabinet File structure
  11. *
  12. * Author:
  13. * Benjamin W. Slivka
  14. *
  15. * History:
  16. * 15-Aug-1993 bens Initial version
  17. * 05-Sep-1993 bens Added Overview section
  18. * 29-Nov-1993 chuckst Added disk names to folder first & next
  19. * Used "CF" consistently
  20. * Eliminated redundant cch fields
  21. * 09-Feb-1994 chuckst merged in some related global constants
  22. * 09-Mar-1994 bens Add RESERVE defintions (for encryption)
  23. * 17-Mar-1994 bens Improve comments about split CFDATA structures
  24. * 25-Mar-1994 bens Add cabinet set ID
  25. * 13-May-1994 bens Define bad value for iCabinet
  26. * 15-Jun-1997 pberkman added CABSignatureStruct_
  27. *
  28. * Overview:
  29. * This file contains definitions for the Diamond Cabinet File format.
  30. * A Cabinet File exists to store one or more files. Usually these
  31. * files have been compressed, but that is not required. It is also
  32. * possible for a cabinet file to contain only a portion of a larger
  33. * file.
  34. *
  35. * In designing this format, the following goals where achieved:
  36. * 1) Minimize overhead in the CF format
  37. * ==> Where ever possible BYTEs or USHORTs were used, rather
  38. * than using LONGs, even though the latter would be easier
  39. * to manipulate on certain RISC platforms.
  40. * 2) Support little-endian and big-endian byte ordering.
  41. * ==> For simplicity on x86 systems, multi-byte numbers are
  42. * stored in a little-endian form, but the code to read and
  43. * write these numbers operates correctly on either type of
  44. * computer.
  45. *
  46. * A cabinet file contains the following structures in the following
  47. * order:
  48. * Name Description
  49. * ----------- -------------------
  50. * CFHEADER Cabinet description
  51. * [CFRESERVE] Optional RESERVED control information in CFHEADER
  52. * CFFOLDER(s) Folder descriptions
  53. * [reserved] Optional RESERVED data per folder
  54. * CFFILE(s) File descriptions
  55. * CFDATA(s) Data blocks
  56. * [reserved] Optional RESERVED data per data block
  57. *
  58. * Data Integrity Strategy:
  59. * The Cabinet File has built-in data integrity checks, since it is
  60. * possible for customers to have damaged diskettes, or for accidental
  61. * or malicious damage to occur. Rather than doing an individual
  62. * checksum for the entire cabinet file (which would have a dramatic
  63. * impact on the speed of installation from floppy disk, since the
  64. * entire file would need to be read), we have per-component
  65. * checksums, and compute and check them as we read the various
  66. * components of the file.
  67. *
  68. * 1) Checksum CFHEADER
  69. * 2) Store cabinet file length in CFHEADER (to detect file truncation)
  70. * 3) Checksum entire set of CFFOLDER structures
  71. * 4) Checksum entire set of CFFILE structures
  72. * 5) Checksum each (compressed) data block independantly
  73. *
  74. * This approach allows us to avoid reading unnecessary parts of the
  75. * file cabinet (though reading all of CFFOLDER and CFFILE structures
  76. * would otherwise not be required in all cases), while still providing
  77. * adequate integrity checking.
  78. */
  79. #ifndef INCLUDED_CABINET
  80. #define INCLUDED_CABINET 1
  81. typedef unsigned long CHECKSUM;
  82. typedef unsigned long COFF;
  83. typedef unsigned long UOFF;
  84. //** Pack structures tightly in cabinet files!
  85. #pragma pack(1)
  86. /*** verCF - Cabinet File format version
  87. *
  88. * The low-order byte is interpreted as a decimal number for the minor
  89. * (1/100ths) portion of the version number.
  90. * The high-order byte is interpreted as a decimal number for the major
  91. * portion of the version number.
  92. *
  93. * Examples:
  94. * 0x0000 0.00
  95. * 0x010A 1.10
  96. * 0x0410 4.16
  97. *
  98. * History:
  99. * 1.01 Original
  100. * 1.02 Added flags field, changed signature
  101. * 1.03 Added setId,iCabinet so FDI can ensure correct cabinet
  102. * on continuation.
  103. */
  104. #define verCF 0x0103 // CF version 1.03
  105. /*** Various cabinet file limits
  106. *
  107. */
  108. #define cMAX_FOLDERS_PER_CABINET (ifoldMASK-1)
  109. #define cMAX_FILES_PER_CABINET 65535
  110. /*** cbRESERVE_XXX_MAX - Maximum size of RESERVE sections
  111. *
  112. * NOTE: cbRESERVE_HEADER_MAX is a fair bit less than 64K because in
  113. * the 16-bit version of this code, we want to have a USHORT
  114. * variable that holds the size of the CFHEADER structure +
  115. * the size of the CFRESERVE structure + the size of the per-header
  116. * reserved data.
  117. */
  118. #define cbRESERVE_HEADER_MAX 60000 // Fits in a USHORT
  119. #define cbRESERVE_FOLDER_MAX 255 // Fits in a BYTE
  120. #define cbRESERVE_DATA_MAX 255 // Fits in a BYTE
  121. /*** ifoldXXXX - Special values for CFFILE.iFolder
  122. *
  123. */
  124. #define ifoldMASK 0xFFFC // Low two bits zero
  125. #define ifoldCONTINUED_FROM_PREV 0xFFFD
  126. #define ifoldCONTINUED_TO_NEXT 0xFFFE
  127. #define ifoldCONTINUED_PREV_AND_NEXT 0xFFFF
  128. #define IS_CONTD_FORWARD(ifold) ((ifold & 0xfffe) == ifoldCONTINUED_TO_NEXT)
  129. #define IS_CONTD_BACK(ifold) ((ifold & 0xfffd) == ifoldCONTINUED_FROM_PREV)
  130. #ifndef MAKESIG
  131. /*** MAKESIG - Construct a 4 byte signature
  132. *
  133. * Entry:
  134. * ch1,ch2,ch3,ch4 - four characters
  135. *
  136. * Exit:
  137. * returns unsigned long
  138. */
  139. #define MAKESIG(ch1,ch2,ch3,ch4) \
  140. ( ((unsigned long)ch1) + \
  141. (((unsigned long)ch2)<< 8) + \
  142. (((unsigned long)ch3)<<16) + \
  143. (((unsigned long)ch4)<<24) )
  144. #endif // !MAKESIG
  145. #define sigCFHEADER MAKESIG('M','S','C','F') // CFHEADER signature
  146. /*** cfhdrXXX - bit flags for cfheader.flags field
  147. *
  148. */
  149. #define cfhdrPREV_CABINET 0x0001 // Set if previous cab/disk present
  150. #define cfhdrNEXT_CABINET 0x0002 // Set if next cab/disk present
  151. #define cfhdrRESERVE_PRESENT 0x0004 // Set if RESERVE_CONTROL is present
  152. /*** CFHEADER - Cabinet File Header
  153. *
  154. */
  155. typedef struct {
  156. //** LONGs are first, to ensure alignment
  157. long sig; // Cabinet File identification string
  158. CHECKSUM csumHeader; // Structure checksum (excluding csumHeader!)
  159. long cbCabinet; // Total length of file (consistency check)
  160. CHECKSUM csumFolders; // Checksum of CFFOLDER list
  161. COFF coffFiles; // Location in cabinet file of CFFILE list
  162. CHECKSUM csumFiles; // Checksum of CFFILE list
  163. //** SHORTs are next, to ensure alignment
  164. USHORT version; // Cabinet File version (verCF)
  165. USHORT cFolders; // Count of folders (CFIFOLDERs) in cabinet
  166. USHORT cFiles; // Count of files (CFIFILEs) in cabinet
  167. USHORT flags; // Flags to indicate optional data presence
  168. USHORT setID; // Cabinet set ID (identifies set of cabinets)
  169. USHORT iCabinet; // Cabinet number in set (0 based)
  170. #define iCABINET_BAD 0xFFFF // Illegal number for iCabinet
  171. //** If flags has the cfhdrRESERVE_PRESENT bit set, then a CFRESERVE
  172. // structure appears here, followed possibly by some CFHEADER reserved
  173. // space. The CFRESERVE structure has fields to define how much reserved
  174. // space is present in the CFHEADER, CFFOLDER, and CFDATA structures.
  175. // If CFRESERVE.cbCFHeader is non-zero, then abReserve[] immediately
  176. // follows the CFRESERVE structure. Note that all of these sizes are
  177. // multiples of 4 bytes, to ensure structure alignment!
  178. //
  179. // CFRESERVE cfres; // Reserve information
  180. // BYTE abReserve[]; // Reserved data space
  181. //
  182. //** The following fields presence depends upon the settings in the flags
  183. // field above. If cfhdrPREV_CABINET is set, then there are two ASCIIZ
  184. // strings to describe the previous disk and cabinet.
  185. //
  186. // NOTE: This "previous" cabinet is not necessarily the immediately
  187. // preceding cabinet! While it usually will be, if a file is
  188. // continued into the current cabinet, then the "previous"
  189. // cabinet identifies the cabinet where the folder that contains
  190. // this file *starts*! For example, if EXCEL.EXE starts in
  191. // cabinet excel.1 and is continued through excel.2 to excel.3,
  192. // then cabinet excel.3 will point back to *cabinet.1*, since
  193. // that is where you have to start in order to extract EXCEL.EXE.
  194. //
  195. // char szCabinetPrev[]; // Prev Cabinet filespec
  196. // char szDiskPrev[]; // Prev descriptive disk name
  197. //
  198. // Similarly, If cfhdrNEXT_CABINET is set, then there are two ASCIIZ
  199. // strings to describe the next disk and cabinet:
  200. //
  201. // char szCabinetNext[]; // Next Cabinet filespec
  202. // char szDiskNext[]; // Next descriptive disk name
  203. //
  204. } CFHEADER; /* cfheader */
  205. /*** CFRESERVE - Cabinet File Reserved data information
  206. *
  207. * This structure is present in the middle of the CFHEADER structure if
  208. * CFHEADER.flags has the cfhdrRESERVE_PRESENT bit set. This structure
  209. * defines the sizes of all the reserved data sections in the CFHEADER,
  210. * CFFOLDER, and CFDATA structures.
  211. *
  212. * These reserved sizes can be zero (although it would be strange to have
  213. * all of them be zero), but otherwise must be a multiple of 4, to ensure
  214. * structure alignment for RISC machines.
  215. */
  216. typedef struct {
  217. USHORT cbCFHeader; // Size of abReserve in CFHEADER structure
  218. BYTE cbCFFolder; // Size of abReserve in CFFOLDER structure
  219. BYTE cbCFData; // Size of abReserve in CFDATA structure
  220. } CFRESERVE; /* cfreserve */
  221. #define cbCF_HEADER_BAD 0xFFFF // Bad value for CFRESERVE.cbCFHeader
  222. //
  223. // the following struct identifies the content of the signature area
  224. // of abReserved for Athenticode version 2.
  225. //
  226. typedef struct CABSignatureStruct_
  227. {
  228. DWORD cbFileOffset;
  229. DWORD cbSig;
  230. BYTE Filler[8];
  231. } CABSignatureStruct_;
  232. /*** CFFOLDER - Cabinet Folder
  233. *
  234. * This structure describes a partial or complete "compression unit".
  235. * A folder is by definition a stream of compressed data. To retrieve
  236. * an uncompressed data from a folder, you *must* start decompressing
  237. * the data at the start of the folder, regardless of how far into the
  238. * folder the data you want actually starts.
  239. *
  240. * Folders may start in one cabinet, and continue on to one or more
  241. * succeeding cabinets. In general, if a folder has been continued over
  242. * a cabinet boundary, Diamond/FCI will terminate that folder as soon as
  243. * the current file has been completely compressed. Generally this means
  244. * that a folder would span at most two cabinets, but if the file is really
  245. * large, it could span more than two cabinets.
  246. *
  247. * Note: CFFOLDERs actually refer to folder *fragments*, not necessarily
  248. * complete folders. You know that a CFFOLDER is the beginning of a
  249. * folder (as opposed to a continuation in a subsequent cabinet file)
  250. * if a file starts in it (i.e., the CFFILE.uoffFolderStart field is
  251. * 0).
  252. */
  253. typedef struct {
  254. COFF coffCabStart; // Offset in cabinet file of first CFDATA
  255. // block for this folder.
  256. USHORT cCFData; // Count of CFDATAs for this folder that
  257. // are actually in this cabinet. Note that
  258. // a folder can continue into another cabinet
  259. // and have many more CFDATA blocks in that
  260. // cabinet, *and* a folder may have started
  261. // in a previous cabinet. This count is
  262. // only of CFDATAs for this folder that are
  263. // (at least partially) in this cabinet.
  264. short typeCompress; // Indicates compression type for all CFDATA
  265. // blocks for this folder. The valid values
  266. // are defined in the types.h built into
  267. // fci.h/fdi.h.
  268. //** If CFHEADER.flags has the cfhdrRESERVE_PRESENT bit set, and
  269. // CFRESERVE.cbCFFolder is non-zero, then abReserve[] appears here.
  270. //
  271. // BYTE abReserve[]; // Reserved data space
  272. //
  273. } CFFOLDER; /* cffolder */
  274. /*** CFFILE - Cabinet File structure describing a single file in the cabinet
  275. *
  276. * NOTE: iFolder is used to indicatate continuation cases, so we have to
  277. * calculate the real iFolder by examining the cabinet files:
  278. *
  279. * ifoldCONTINUED_FROM_PREV
  280. * This file ends in this cabinet, but is continued from a
  281. * previous cabinet. Therefore, the portion of the file contained
  282. * in *this* cabinet *must* start in the first folder.
  283. *
  284. * NOTE: szCabinetPrev is the name of the cabinet where this file
  285. * *starts*, which is not necessarily the immediately
  286. * preceeding cabinet! Since it only makes sense to
  287. * decompress a file from its start, the starting cabinet
  288. * is what is important!
  289. *
  290. * ifoldCONTINUED_TO_NEXT
  291. * This file starts in this cabinet, but is continued to the next
  292. * cabinet. Therfore, this file must start in the *last* folder
  293. * in this cabinet.
  294. *
  295. * ifoldCONTINUED_PREV_AND_NEXT
  296. * This file is the *middle* portion of a file that started in a
  297. * previous cabinet and is continued in the next cabinet. Since
  298. * this cabinet only contain this piece of a single file, there
  299. * is only a single folder fragment in this cabinet.
  300. */
  301. typedef struct {
  302. long cbFile; // Uncompressed size of file
  303. UOFF uoffFolderStart; // Offset in folder IN UNCOMPRESSED BYTES
  304. // of the start of this file
  305. USHORT iFolder; // Index of folder containing this file;
  306. // 0 is first folder in this cabinet.
  307. // See ifoldCONTINUED_XXXX values above
  308. // for treatment of continuation files.
  309. USHORT date; // Date stamp in FAT file system format
  310. USHORT time; // Time stamp in FAT file system format
  311. USHORT attribs; // Attribute in FAT file system format
  312. // char szName[]; // File name (may include path characters)
  313. } CFFILE; /* cffile */
  314. /*** CFDATA - Cabinet File structure describing a data block
  315. *
  316. */
  317. typedef struct {
  318. CHECKSUM csum; // Checksum (excluding this field itself!)
  319. // of this structure and the data that
  320. // follows. If this CFDATA structure is
  321. // continued to the next cabinet, then
  322. // the value of this field is ignored
  323. // (and set to zero).
  324. USHORT cbData; // Size of ab[] data that resides in the
  325. // current cabinet. A CFDATA may be split
  326. // across a cabinet boundary, so this
  327. // value indicates only the amount of data
  328. // store in this cabinet.
  329. USHORT cbUncomp; // Uncompressed size of ab[] data; if this
  330. // CFDATA block is continued to the next
  331. // cabinet, then this value is zero!
  332. // If this CFDATA block the remainder of
  333. // of a CFDATA block that started in the
  334. // previous cabinet, then this value is
  335. // the total size of the uncompressed data
  336. // represented by the two CFDATA blocks!
  337. //** If CFHEADER.flags has the cfhdrRESERVE_PRESENT bit set, and
  338. // CFRESERVE.cbCFData is non-zero, then abReserve[] appears here.
  339. //
  340. // BYTE abReserve[]; // Reserved data space
  341. //
  342. //** The actual data follows here, cbData bytes in length.
  343. //
  344. // BYTE ab[]; // Data
  345. //
  346. } CFDATA; /* cfdata */
  347. //** Attribute Bit to use for Run after extract
  348. #define RUNATTRIB 0x40
  349. //** Revert to default structure packing!
  350. #pragma pack()
  351. #endif // !INCLUDED_CABINET