Source code of Windows XP (NT5)
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.

1243 lines
52 KiB

  1. /*** types.h - Common defines for FCI/FDI stuff -- goes into FCI/FDI.H
  2. *
  3. * Microsoft Confidential
  4. * Copyright (C) Microsoft Corporation 1993-1994
  5. * All Rights Reserved.
  6. *
  7. * History:
  8. * 03-Mar-1993 chuckst Merged from other files
  9. * 08-Mar-1994 bens Changed symbol to control recursive include
  10. * 09-Mar-1994 bens Cleanups for RESERVE modifications
  11. * 16-Mar-1994 bens Nuke padlong()
  12. * 21-Mar-1994 bens Spruce up comments
  13. * 22-Mar-1994 bens Add BIT16 test so we can build 16 or 32 bit!
  14. * 26-May-1994 bens Added Quantum compression definitions
  15. * 30-Jul-1997 msliger Correct CB_MAX_DISK from 7FFFFFF to 7FFFFFFF.
  16. */
  17. #ifndef INCLUDED_TYPES_FCI_FDI
  18. #define INCLUDED_TYPES_FCI_FDI 1
  19. #ifdef __cplusplus
  20. extern "C" { /* Assume C declarations for C++ */
  21. #endif /* __cplusplus */
  22. //** Define away for 32-bit (NT/Chicago) build
  23. #ifndef HUGE
  24. #define HUGE
  25. #endif
  26. #ifndef FAR
  27. #define FAR
  28. #endif
  29. #ifndef DIAMONDAPI
  30. #define DIAMONDAPI __cdecl
  31. #endif
  32. //** Specify structure packing explicitly for clients of FDI
  33. #ifndef _WIN64
  34. #include <pshpack4.h>
  35. #endif
  36. //** Don't redefine types defined in Win16 WINDOWS.H (_INC_WINDOWS)
  37. // or Win32 WINDOWS.H (_WINDOWS_)
  38. //
  39. #if !defined(_INC_WINDOWS) && !defined(_WINDOWS_)
  40. typedef int BOOL; /* f */
  41. typedef unsigned char BYTE; /* b */
  42. typedef unsigned int UINT; /* ui */
  43. typedef unsigned short USHORT; /* us */
  44. typedef unsigned long ULONG; /* ul */
  45. #endif // _INC_WINDOWS
  46. typedef unsigned long CHECKSUM; /* csum */
  47. typedef unsigned long UOFF; /* uoff - uncompressed offset */
  48. typedef unsigned long COFF; /* coff - cabinet file offset */
  49. #ifndef TRUE
  50. #define TRUE 1
  51. #endif
  52. #ifndef FALSE
  53. #define FALSE 0
  54. #endif
  55. #ifndef NULL
  56. #define NULL 0
  57. #endif
  58. /*** ERF - Error structure
  59. *
  60. * This structure returns error information from FCI/FDI. The caller should
  61. * not modify this structure.
  62. */
  63. typedef struct {
  64. int erfOper; // FCI/FDI error code -- see FDIERROR_XXX
  65. // and FCIERR_XXX equates for details.
  66. int erfType; // Optional error value filled in by FCI/FDI.
  67. // For FCI, this is usually the C run-time
  68. // *errno* value.
  69. BOOL fError; // TRUE => error present
  70. } ERF; /* erf */
  71. typedef ERF FAR *PERF; /* perf */
  72. #ifdef _DEBUG
  73. // don't hide statics from map during debugging
  74. #define STATIC
  75. #else // !DEBUG
  76. #define STATIC static
  77. #endif // !DEBUG
  78. #define CB_MAX_CHUNK 32768U
  79. #define CB_MAX_DISK 0x7fffffffL
  80. #define CB_MAX_FILENAME 256
  81. #define CB_MAX_CABINET_NAME 256
  82. #define CB_MAX_CAB_PATH 256
  83. #define CB_MAX_DISK_NAME 256
  84. /*** tcompXXX - Diamond compression types
  85. *
  86. * These are passed to FCIAddFile(), and are also stored in the CFFOLDER
  87. * structures in cabinet files.
  88. *
  89. * NOTE: We reserve bits for the TYPE, QUANTUM_LEVEL, and QUANTUM_MEM
  90. * to provide room for future expansion. Since this value is stored
  91. * in the CFDATA records in the cabinet file, we don't want to
  92. * have to change the format for existing compression configurations
  93. * if we add new ones in the future. This will allows us to read
  94. * old cabinet files in the future.
  95. */
  96. typedef unsigned short TCOMP; /* tcomp */
  97. #define tcompMASK_TYPE 0x000F // Mask for compression type
  98. #define tcompTYPE_NONE 0x0000 // No compression
  99. #define tcompTYPE_MSZIP 0x0001 // MSZIP
  100. #define tcompTYPE_QUANTUM 0x0002 // Quantum
  101. #define tcompTYPE_LZX 0x0003 // LZX
  102. #define tcompBAD 0x000F // Unspecified compression type
  103. #define tcompMASK_LZX_WINDOW 0x1F00 // Mask for LZX Compression Memory
  104. #define tcompLZX_WINDOW_LO 0x0F00 // Lowest LZX Memory (15)
  105. #define tcompLZX_WINDOW_HI 0x1500 // Highest LZX Memory (21)
  106. #define tcompSHIFT_LZX_WINDOW 8 // Amount to shift over to get int
  107. #define tcompMASK_QUANTUM_LEVEL 0x00F0 // Mask for Quantum Compression Level
  108. #define tcompQUANTUM_LEVEL_LO 0x0010 // Lowest Quantum Level (1)
  109. #define tcompQUANTUM_LEVEL_HI 0x0070 // Highest Quantum Level (7)
  110. #define tcompSHIFT_QUANTUM_LEVEL 4 // Amount to shift over to get int
  111. #define tcompMASK_QUANTUM_MEM 0x1F00 // Mask for Quantum Compression Memory
  112. #define tcompQUANTUM_MEM_LO 0x0A00 // Lowest Quantum Memory (10)
  113. #define tcompQUANTUM_MEM_HI 0x1500 // Highest Quantum Memory (21)
  114. #define tcompSHIFT_QUANTUM_MEM 8 // Amount to shift over to get int
  115. #define tcompMASK_RESERVED 0xE000 // Reserved bits (high 3 bits)
  116. #define CompressionTypeFromTCOMP(tc) \
  117. ((tc) & tcompMASK_TYPE)
  118. #define CompressionLevelFromTCOMP(tc) \
  119. (((tc) & tcompMASK_QUANTUM_LEVEL) >> tcompSHIFT_QUANTUM_LEVEL)
  120. #define CompressionMemoryFromTCOMP(tc) \
  121. (((tc) & tcompMASK_QUANTUM_MEM) >> tcompSHIFT_QUANTUM_MEM)
  122. #define TCOMPfromTypeLevelMemory(t,l,m) \
  123. (((m) << tcompSHIFT_QUANTUM_MEM ) | \
  124. ((l) << tcompSHIFT_QUANTUM_LEVEL) | \
  125. ( t ))
  126. #define LZXCompressionWindowFromTCOMP(tc) \
  127. (((tc) & tcompMASK_LZX_WINDOW) >> tcompSHIFT_LZX_WINDOW)
  128. #define TCOMPfromLZXWindow(w) \
  129. (((w) << tcompSHIFT_LZX_WINDOW ) | \
  130. ( tcompTYPE_LZX ))
  131. //** Revert to default structure packing
  132. #ifndef _WIN64
  133. #include <poppack.h>
  134. #endif
  135. #ifdef __cplusplus
  136. }
  137. #endif /* __cplusplus */
  138. #endif // !INCLUDED_TYPES_FCI_FDI
  139. /*** fdi_int.h - Diamond File Decompression Interface definitions
  140. *
  141. * Microsoft Confidential
  142. * Copyright (C) Microsoft Corporation 1993-1997
  143. * All Rights Reserved.
  144. *
  145. * Author:
  146. * Chuck Strouss, Benjamin W. Slivka
  147. *
  148. * History:
  149. * 30-Nov-1993 chuckst Created
  150. * 21-Dec-1993 bens Updated with comments from 12/21/93 design review
  151. * 09-Mar-1994 bens Add new error code
  152. * 17-Mar-1994 bens Specify structure packing explicitly
  153. * 21-Mar-1994 bens Spruce up comments
  154. * 25-Mar-1994 bens Add fdintCABINET_INFO notification
  155. * 31-Mar-1994 bens Clarify handling of open files when errors occur
  156. * 01-Apr-1994 bens Add FDIIsCabinet() function.
  157. * 07-Apr-1994 bens Add Decryption interfaces; remove fdintPROGRESS
  158. * 11-Apr-1994 bens Add more guidance on how to respond to FDI errors.
  159. * 13-Apr-1994 bens Add date & time & attribs to fdintCOPY_FILE
  160. * 18-Apr-1994 bens Changed CDECL to DIAMONDAPI
  161. * 05-May-1994 bens Clarified error handling (billhu/alanr/migueldc)
  162. * 11-May-1994 bens Added setId/iCabinet to fdintNEXT_CABINET
  163. * 07-Jul-1994 bens Support Quantum virtual file -- PLEASE note the
  164. * comments about PFNOPEN/PFNCLOSE changes, and
  165. * about reserving memory, if necessary, before
  166. * calling FDICreate()!
  167. * 19-Aug-1994 bens Add cpuType parameter to FDICreate().
  168. * 03-Apr-1995 jeffwe Added chaining indicators to FDICABINETINFO
  169. * 22-Nov-1996 msliger Backed out fdintNEXT_FOLDER, added iFolder to
  170. * FDINOTIFICATION for fdintCOPY_FILE calls.
  171. * 20-Feb-1997 msliger Added fdintENUMERATE message.
  172. *
  173. *
  174. * ATTENTION:
  175. * This is the only documentation on the Diamond File Decompression
  176. * Interface (FDI). Please read it carefully, as there are some subtle
  177. * points in FDI that are carefully explained below.
  178. *
  179. * Concepts:
  180. * A *cabinet* file contains one or more *folders*. A folder contains
  181. * one or more (pieces of) *files*. A folder is by definition a
  182. * decompression unit, i.e., to extract a file from a folder, all of
  183. * the data from the start of the folder up through and including the
  184. * desired file must be read and decompressed.
  185. *
  186. * A folder can span one (or more) cabinet boundaries, and by implication
  187. * a file can also span one (or more) cabinet boundaries. Indeed, more
  188. * than one file can span a cabinet boundary, since Diamond concatenates
  189. * files together into a single data stream before compressing (actually,
  190. * at most one file will span any one cabinet boundary, but Diamond does
  191. * not know which file this is, since the mapping from uncompressed bytes
  192. * to compressed bytes is pretty obscure. Also, since Diamond compresses
  193. * in blocks of 32K (at present), any files with data in a 32K block that
  194. * spans a cabinet boundary require Diamond to read both cabinet files
  195. * to get the two halves of the compressed block).
  196. *
  197. * Overview:
  198. * The File Decompression Interface is used to simplify the reading of
  199. * Diamond cabinet files. A setup program will proceed in a manner very
  200. * similar to the pseudo code below. An FDI context is created, the
  201. * setup program calls FDICopy() for each cabinet to be processed. For
  202. * each file in the cabinet, FDICopy() calls a notification callback
  203. * routine, asking the setup program if the file should be copied.
  204. * This call-back approach is great because it allows the cabinet file
  205. * to be read and decompressed in an optimal manner, and also makes FDI
  206. * independent of the run-time environment -- FDI makes *no* C run-time
  207. * calls whatsoever. All memory allocation and file I/O functions are
  208. * passed into FDI by the client.
  209. *
  210. * main(...)
  211. * {
  212. * // Read INF file to construct list of desired files.
  213. * // Ideally, these would be sorted in the same order as the
  214. * // files appear in the cabinets, so that you can just walk
  215. * // down the list in response to fdintCOPY_FILE notifications.
  216. *
  217. * // Construct list of required cabinets.
  218. *
  219. * hfdi = FDICreate(...); // Create FDI context
  220. * For (cabinet in List of Cabinets) {
  221. * FDICopy(hfdi,cabinet,fdiNotify,...); // Process each cabinet
  222. * }
  223. * FDIDestroy(hfdi);
  224. * ...
  225. * }
  226. *
  227. * // Notification callback function
  228. * fdiNotify(fdint,...)
  229. * {
  230. * If (User Aborted) // Permit cancellation
  231. * if (fdint == fdintCLOSE_FILE_INFO)
  232. * close open file
  233. * return -1;
  234. * switch (fdint) {
  235. * case fdintCOPY_FILE: // File to copy, maybe
  236. * // Check file against list of desired files
  237. * if want to copy file
  238. * open destination file and return handle
  239. * else
  240. * return NULL; // Skip file
  241. * case fdintCLOSE_FILE_INFO:
  242. * close file
  243. * set date, time, and attributes
  244. *
  245. * case fdintNEXT_CABINET:
  246. * if not an error callback
  247. * Tell FDI to use suggested directory name
  248. * else
  249. * Tell user what the problem was, and prompt
  250. * for a new disk and/or path.
  251. * if user aborts
  252. * Tell FDI to abort
  253. * else
  254. * return to FDI to try another cabinet
  255. * //NOTE: Be sure to see the (sample) code in EXTRACT.C
  256. * // for an example of how to do this!
  257. * default:
  258. * return 0; // more messages may be defined
  259. * ...
  260. * }
  261. *
  262. * Error Handling Suggestions:
  263. * Since you the client have passed in *all* of the functions that
  264. * FDI uses to interact with the "outside" world, you are in prime
  265. * position to understand and deal with errors.
  266. *
  267. * The general philosophy of FDI is to pass all errors back up to
  268. * the client. FDI returns fairly generic error codes in the case
  269. * where one of the callback functions (PFNOPEN, PFNREAD, etc.) fail,
  270. * since it assumes that the callback function will save enough
  271. * information in a static/global so that when FDICopy() returns
  272. * fail, the client can examine this information and report enough
  273. * detail about the problem that the user can take corrective action.
  274. *
  275. * For very specific errors (CORRUPT_CABINET, for example), FDI returns
  276. * very specific error codes.
  277. *
  278. * THE BEST POLICY IS FOR YOUR CALLBACK ROUTINES TO AVOID RETURNING
  279. * ERRORS TO FDI!
  280. *
  281. * Examples:
  282. * (1) If the disk is getting full, instead of returning an error
  283. * from your PFNWRITE function, you should -- inside your
  284. * PFNWRITE function -- put up a dialog telling the user to free
  285. * some disk space.
  286. * (2) When you get the fdintNEXT_CABINET notification, you should
  287. * verify that the cabinet you return is the correct one (call
  288. * FDIIsCabinet(), and make sure the setID matches the one for
  289. * the current cabinet specified in the fdintCABINET_INFO, and
  290. * that the disk number is one greater.
  291. *
  292. * NOTE: FDI will continue to call fdintNEXT_CABINET until it
  293. * gets the cabinet it wants, or until you return -1
  294. * to abort the FDICopy() call.
  295. *
  296. * The documentation below on the FDI error codes provides explicit
  297. * guidance on how to avoid each error.
  298. *
  299. * If you find you must return a failure to FDI from one of your
  300. * callback functions, then FDICopy() frees all resources it allocated
  301. * and closes all files. If you can figure out how to overcome the
  302. * problem, you can call FDICopy() again on the last cabinet, and
  303. * skip any files that you already copied. But, note that FDI does
  304. * *not* maintain any state between FDICopy() calls, other than possibly
  305. * memory allocated for the decompressor.
  306. *
  307. * See FDIERROR for details on FDI error codes and recommended actions.
  308. *
  309. *
  310. * Progress Indicator Suggestions:
  311. * As above, all of the file I/O functions are supplied by you. So,
  312. * updating a progress indicator is very simple. You keep track of
  313. * the target files handles you have opened, along with the uncompressed
  314. * size of the target file. When you see writes to the handle of a
  315. * target file, you use the write count to update your status!
  316. * Since this method is available, there is no separate callback from
  317. * FDI just for progess indication.
  318. */
  319. #include <basetsd.h>
  320. #ifndef INCLUDED_FDI
  321. #define INCLUDED_FDI 1
  322. #ifdef __cplusplus
  323. extern "C" { /* Assume C declarations for C++ */
  324. #endif /* __cplusplus */
  325. //** Specify structure packing explicitly for clients of FDI
  326. #ifndef _WIN64
  327. #pragma pack(4)
  328. #endif
  329. /*** FDIERROR - Error codes returned in erf.erfOper field
  330. *
  331. * In general, FDI will only fail if one of the passed in memory or
  332. * file I/O functions fails. Other errors are pretty unlikely, and are
  333. * caused by corrupted cabinet files, passing in a file which is not a
  334. * cabinet file, or cabinet files out of order.
  335. *
  336. * Description: Summary of error.
  337. * Cause: List of possible causes of this error.
  338. * Response: How client might respond to this error, or avoid it in
  339. * the first place.
  340. */
  341. typedef enum {
  342. FDIERROR_NONE,
  343. // Description: No error
  344. // Cause: Function was successfull.
  345. // Response: Keep going!
  346. FDIERROR_CABINET_NOT_FOUND,
  347. // Description: Cabinet not found
  348. // Cause: Bad file name or path passed to FDICopy(), or returned
  349. // to fdintNEXT_CABINET.
  350. // Response: To prevent this error, validate the existence of the
  351. // the cabinet *before* passing the path to FDI.
  352. FDIERROR_NOT_A_CABINET,
  353. // Description: Cabinet file does not have the correct format
  354. // Cause: File passed to to FDICopy(), or returned to
  355. // fdintNEXT_CABINET, is too small to be a cabinet file,
  356. // or does not have the cabinet signature in its first
  357. // four bytes.
  358. // Response: To prevent this error, call FDIIsCabinet() to check a
  359. // cabinet before calling FDICopy() or returning the
  360. // cabinet path to fdintNEXT_CABINET.
  361. FDIERROR_UNKNOWN_CABINET_VERSION,
  362. // Description: Cabinet file has an unknown version number.
  363. // Cause: File passed to to FDICopy(), or returned to
  364. // fdintNEXT_CABINET, has what looks like a cabinet file
  365. // header, but the version of the cabinet file format
  366. // is not one understood by this version of FDI. The
  367. // erf.erfType field is filled in with the version number
  368. // found in the cabinet file.
  369. // Response: To prevent this error, call FDIIsCabinet() to check a
  370. // cabinet before calling FDICopy() or returning the
  371. // cabinet path to fdintNEXT_CABINET.
  372. FDIERROR_CORRUPT_CABINET,
  373. // Description: Cabinet file is corrupt
  374. // Cause: FDI returns this error any time it finds a problem
  375. // with the logical format of a cabinet file, and any
  376. // time one of the passed-in file I/O calls fails when
  377. // operating on a cabinet (PFNOPEN, PFNSEEK, PFNREAD,
  378. // or PFNCLOSE). The client can distinguish these two
  379. // cases based upon whether the last file I/O call
  380. // failed or not.
  381. // Response: Assuming this is not a real corruption problem in
  382. // a cabinet file, the file I/O functions could attempt
  383. // to do retries on failure (for example, if there is a
  384. // temporary network connection problem). If this does
  385. // not work, and the file I/O call has to fail, then the
  386. // FDI client will have to clean up and call the
  387. // FDICopy() function again.
  388. FDIERROR_ALLOC_FAIL,
  389. // Description: Could not allocate enough memory
  390. // Cause: FDI tried to allocate memory with the PFNALLOC
  391. // function, but it failed.
  392. // Response: If possible, PFNALLOC should take whatever steps
  393. // are possible to allocate the memory requested. If
  394. // memory is not immediately available, it might post a
  395. // dialog asking the user to free memory, for example.
  396. // Note that the bulk of FDI's memory allocations are
  397. // made at FDICreate() time and when the first cabinet
  398. // file is opened during FDICopy().
  399. FDIERROR_BAD_COMPR_TYPE,
  400. // Description: Unknown compression type in a cabinet folder
  401. // Cause: [Should never happen.] A folder in a cabinet has an
  402. // unknown compression type. This is probably caused by
  403. // a mismatch between the version of Diamond used to
  404. // create the cabinet and the FDI. LIB used to read the
  405. // cabinet.
  406. // Response: Abort.
  407. FDIERROR_MDI_FAIL,
  408. // Description: Failure decompressing data from a cabinet file
  409. // Cause: The decompressor found an error in the data coming
  410. // from the file cabinet. The cabinet file was corrupted.
  411. // [11-Apr-1994 bens When checksuming is turned on, this
  412. // error should never occur.]
  413. // Response: Probably should abort; only other choice is to cleanup
  414. // and call FDICopy() again, and hope there was some
  415. // intermittent data error that will not reoccur.
  416. FDIERROR_TARGET_FILE,
  417. // Description: Failure writing to target file
  418. // Cause: FDI returns this error any time it gets an error back
  419. // from one of the passed-in file I/O calls fails when
  420. // writing to a file being extracted from a cabinet.
  421. // Response: To avoid or minimize this error, the file I/O functions
  422. // could attempt to avoid failing. A common cause might
  423. // be disk full -- in this case, the PFNWRITE function
  424. // could have a check for free space, and put up a dialog
  425. // asking the user to free some disk space.
  426. FDIERROR_RESERVE_MISMATCH,
  427. // Description: Cabinets in a set do not have the same RESERVE sizes
  428. // Cause: [Should never happen]. FDI requires that the sizes of
  429. // the per-cabinet, per-folder, and per-data block
  430. // RESERVE sections be consistent across all the cabinet
  431. // in a set. Diamond will only generate cabinet sets
  432. // with these properties.
  433. // Response: Abort.
  434. FDIERROR_WRONG_CABINET,
  435. // Description: Cabinet returned on fdintNEXT_CABINET is incorrect
  436. // Cause: NOTE: THIS ERROR IS NEVER RETURNED BY FDICopy()!
  437. // Rather, FDICopy() keeps calling the fdintNEXT_CABINET
  438. // callback until either the correct cabinet is specified,
  439. // or you return ABORT.
  440. // When FDICopy() is extracting a file that crosses a
  441. // cabinet boundary, it calls fdintNEXT_CABINET to ask
  442. // for the path to the next cabinet. Not being very
  443. // trusting, FDI then checks to make sure that the
  444. // correct continuation cabinet was supplied! It does
  445. // this by checking the "setID" and "iCabinet" fields
  446. // in the cabinet. When DIAMOND.EXE creates a set of
  447. // cabinets, it constructs the "setID" using the sum
  448. // of the bytes of all the destination file names in
  449. // the cabinet set. FDI makes sure that the 16-bit
  450. // setID of the continuation cabinet matches the
  451. // cabinet file just processed. FDI then checks that
  452. // the cabinet number (iCabinet) is one more than the
  453. // cabinet number for the cabinet just processed.
  454. // Response: You need code in your fdintNEXT_CABINET (see below)
  455. // handler to do retries if you get recalled with this
  456. // error. See the sample code (EXTRACT.C) to see how
  457. // this should be handled.
  458. FDIERROR_USER_ABORT,
  459. // Description: FDI aborted.
  460. // Cause: An FDI callback returnd -1 (usually).
  461. // Response: Up to client.
  462. } FDIERROR;
  463. /*
  464. * FAT file attribute flag used by FCI/FDI to indicate that
  465. * the filename in the CAB is a UTF string
  466. */
  467. #ifndef _A_NAME_IS_UTF
  468. #define _A_NAME_IS_UTF 0x80
  469. #endif
  470. /*
  471. * FAT file attribute flag used by FCI/FDI to indicate that
  472. * the file should be executed after extraction
  473. */
  474. #ifndef _A_EXEC
  475. #define _A_EXEC 0x40
  476. #endif
  477. /*** HFDI - Handle to an FDI context
  478. *
  479. * FDICreate() creates this, and it must be passed to all other FDI
  480. * functions.
  481. */
  482. typedef void FAR *HFDI; /* hfdi */
  483. /*** FDICABINETINFO - Information about a cabinet
  484. *
  485. */
  486. typedef struct {
  487. long cbCabinet; // Total length of cabinet file
  488. USHORT cFolders; // Count of folders in cabinet
  489. USHORT cFiles; // Count of files in cabinet
  490. USHORT setID; // Cabinet set ID
  491. USHORT iCabinet; // Cabinet number in set (0 based)
  492. BOOL fReserve; // TRUE => RESERVE present in cabinet
  493. BOOL hasprev; // TRUE => Cabinet is chained prev
  494. BOOL hasnext; // TRUE => Cabinet is chained next
  495. } FDICABINETINFO; /* fdici */
  496. typedef FDICABINETINFO FAR *PFDICABINETINFO; /* pfdici */
  497. /*** FDIDECRYPTTYPE - PFNFDIDECRYPT command types
  498. *
  499. */
  500. typedef enum {
  501. fdidtNEW_CABINET, // New cabinet
  502. fdidtNEW_FOLDER, // New folder
  503. fdidtDECRYPT, // Decrypt a data block
  504. } FDIDECRYPTTYPE; /* fdidt */
  505. /*** FDIDECRYPT - Data for PFNFDIDECRYPT function
  506. *
  507. */
  508. typedef struct {
  509. FDIDECRYPTTYPE fdidt; // Command type (selects union below)
  510. void FAR *pvUser; // Decryption context
  511. union {
  512. struct { // fdidtNEW_CABINET
  513. void FAR *pHeaderReserve; // RESERVE section from CFHEADER
  514. USHORT cbHeaderReserve; // Size of pHeaderReserve
  515. USHORT setID; // Cabinet set ID
  516. int iCabinet; // Cabinet number in set (0 based)
  517. } cabinet;
  518. struct { // fdidtNEW_FOLDER
  519. void FAR *pFolderReserve; // RESERVE section from CFFOLDER
  520. USHORT cbFolderReserve; // Size of pFolderReserve
  521. USHORT iFolder; // Folder number in cabinet (0 based)
  522. } folder;
  523. struct { // fdidtDECRYPT
  524. void FAR *pDataReserve; // RESERVE section from CFDATA
  525. USHORT cbDataReserve; // Size of pDataReserve
  526. void FAR *pbData; // Data buffer
  527. USHORT cbData; // Size of data buffer
  528. BOOL fSplit; // TRUE if this is a split data block
  529. USHORT cbPartial; // 0 if this is not a split block, or
  530. // the first piece of a split block;
  531. // Greater than 0 if this is the
  532. // second piece of a split block.
  533. } decrypt;
  534. };
  535. } FDIDECRYPT; /* fdid */
  536. typedef FDIDECRYPT FAR *PFDIDECRYPT; /* pfdid */
  537. /*** FNALLOC - Memory Allocation
  538. * FNFREE - Memory Free
  539. *
  540. * These are modeled after the C run-time routines malloc() and free()
  541. * (16-bit clients please note -- the size is a ULONG, so you may need
  542. * to write a wrapper routine for halloc!). FDI expects error
  543. * handling to be identical to these C run-time routines.
  544. *
  545. * As long as you faithfully copy the semantics of malloc() and free(),
  546. * you can supply any functions you like!
  547. *
  548. * WARNING: You should never assume anything about the sequence of
  549. * PFNALLOC and PFNFREE calls -- incremental releases of
  550. * Diamond/FDI may have radically different numbers of
  551. * PFNALLOC calls and allocation sizes!
  552. */
  553. //** Memory functions for FDI
  554. typedef void HUGE * (FAR DIAMONDAPI *PFNALLOC)(ULONG cb); /* pfna */
  555. #define FNALLOC(fn) void HUGE * FAR DIAMONDAPI fn(ULONG cb)
  556. typedef void (FAR DIAMONDAPI *PFNFREE)(void HUGE *pv); /* pfnf */
  557. #define FNFREE(fn) void FAR DIAMONDAPI fn(void HUGE *pv)
  558. //** File I/O functions for FDI
  559. typedef INT_PTR (FAR DIAMONDAPI *PFNOPEN) (char FAR *pszFile, int oflag, int pmode);
  560. typedef UINT (FAR DIAMONDAPI *PFNREAD) (INT_PTR hf, void FAR *pv, UINT cb);
  561. typedef UINT (FAR DIAMONDAPI *PFNWRITE)(INT_PTR hf, void FAR *pv, UINT cb);
  562. typedef int (FAR DIAMONDAPI *PFNCLOSE)(INT_PTR hf);
  563. typedef long (FAR DIAMONDAPI *PFNSEEK) (INT_PTR hf, long dist, int seektype);
  564. #define FNOPEN(fn) INT_PTR FAR DIAMONDAPI fn(char FAR *pszFile, int oflag, int pmode)
  565. #define FNREAD(fn) UINT FAR DIAMONDAPI fn(INT_PTR hf, void FAR *pv, UINT cb)
  566. #define FNWRITE(fn) UINT FAR DIAMONDAPI fn(INT_PTR hf, void FAR *pv, UINT cb)
  567. #define FNCLOSE(fn) int FAR DIAMONDAPI fn(INT_PTR hf)
  568. #define FNSEEK(fn) long FAR DIAMONDAPI fn(INT_PTR hf, long dist, int seektype)
  569. /*** PFNFDIDECRYPT - FDI Decryption callback
  570. *
  571. * If this function is passed on the FDICopy() call, then FDI calls it
  572. * at various times to update the decryption state and to decrypt FCDATA
  573. * blocks.
  574. *
  575. * Common Entry Conditions:
  576. * pfdid->fdidt - Command type
  577. * pfdid->pvUser - pvUser value from FDICopy() call
  578. *
  579. * fdidtNEW_CABINET: //** Notification of a new cabinet
  580. * Entry:
  581. * pfdid->cabinet.
  582. * pHeaderReserve - RESERVE section from CFHEADER
  583. * cbHeaderReserve - Size of pHeaderReserve
  584. * setID - Cabinet set ID
  585. * iCabinet - Cabinet number in set (0 based)
  586. * Exit-Success:
  587. * returns anything but -1;
  588. * Exit-Failure:
  589. * returns -1; FDICopy() is aborted.
  590. * Notes:
  591. * (1) This call allows the decryption code to pick out any information
  592. * from the cabinet header reserved area (placed there by DIACRYPT)
  593. * needed to perform decryption. If there is no such information,
  594. * this call would presumably be ignored.
  595. * (2) This call is made very soon after fdintCABINET_INFO.
  596. *
  597. * fdidtNEW_FOLDER: //** Notification of a new folder
  598. * Entry:
  599. * pfdid->folder.
  600. * pFolderReserve - RESERVE section from CFFOLDER
  601. * cbFolderReserve - Size of pFolderReserve
  602. * iFolder - Folder number in cabinet (0 based)
  603. * Exit-Success:
  604. * returns anything but -1;
  605. * Exit-Failure:
  606. * returns -1; FDICopy() is aborted.
  607. * Notes:
  608. * This call allows the decryption code to pick out any information
  609. * from the folder reserved area (placed there by DIACRYPT) needed
  610. * to perform decryption. If there is no such information, this
  611. * call would presumably be ignored.
  612. *
  613. * fdidtDECRYPT: //** Decrypt a data buffer
  614. * Entry:
  615. * pfdid->folder.
  616. * pDataReserve - RESERVE section for this CFDATA block
  617. * cbDataReserve - Size of pDataReserve
  618. * pbData - Data buffer
  619. * cbData - Size of data buffer
  620. * fSplit - TRUE if this is a split data block
  621. * cbPartial - 0 if this is not a split block, or the first
  622. * piece of a split block; Greater than 0 if
  623. * this is the second piece of a split block.
  624. * Exit-Success:
  625. * returns TRUE;
  626. * Exit-Failure:
  627. * returns FALSE; error during decrypt
  628. * returns -1; FDICopy() is aborted.
  629. * Notes:
  630. * Diamond will split CFDATA blocks across cabinet boundaries if
  631. * necessary. To provide maximum flexibility, FDI will call the
  632. * fdidtDECRYPT function twice on such split blocks, once when
  633. * the first portion is read, and again when the second portion
  634. * is read. And, of course, most data blocks will not be split.
  635. * So, there are three cases:
  636. *
  637. * 1) fSplit == FALSE
  638. * You have the entire data block, so decrypt it.
  639. *
  640. * 2) fSplit == TRUE, cbPartial == 0
  641. * This is the first portion of a split data block, so cbData
  642. * is the size of this portion. You can either choose to decrypt
  643. * this piece, or ignore this call and decrypt the full CFDATA
  644. * block on the next (second) fdidtDECRYPT call.
  645. *
  646. * 3) fSplit == TRUE, cbPartial > 0
  647. * This is the second portion of a split data block (indeed,
  648. * cbPartial will have the same value as cbData did on the
  649. * immediately preceeding fdidtDECRYPT call!). If you decrypted
  650. * the first portion on the first call, then you can decrypt the
  651. * second portion now. If you ignored the first call, then you
  652. * can decrypt the entire buffer.
  653. * NOTE: pbData points to the second portion of the split data
  654. * block in this case, *not* the entire data block. If
  655. * you want to wait until the second piece to decrypt the
  656. * *entire* block, pbData-cbPartial is the address of the
  657. * start of the whole block, and cbData+cbPartial is its
  658. * size.
  659. */
  660. typedef int (FAR DIAMONDAPI *PFNFDIDECRYPT)(PFDIDECRYPT pfdid); /* pfnfdid */
  661. #define FNFDIDECRYPT(fn) int FAR DIAMONDAPI fn(PFDIDECRYPT pfdid)
  662. /*** FDINOTIFICATION - Notification structure for PFNFDINOTIFY
  663. *
  664. * See the FDINOTIFICATIONTYPE definition for information on usage and
  665. * meaning of these fields.
  666. */
  667. typedef struct {
  668. // long fields
  669. long cb;
  670. char FAR *psz1;
  671. char FAR *psz2;
  672. char FAR *psz3; // Points to a 256 character buffer
  673. void FAR *pv; // Value for client
  674. // int fields
  675. INT_PTR hf;
  676. // short fields
  677. USHORT date;
  678. USHORT time;
  679. USHORT attribs;
  680. USHORT setID; // Cabinet set ID
  681. USHORT iCabinet; // Cabinet number (0-based)
  682. USHORT iFolder; // Folder number (0-based)
  683. FDIERROR fdie;
  684. } FDINOTIFICATION, FAR *PFDINOTIFICATION; /* fdin, pfdin */
  685. /*** FDINOTIFICATIONTYPE - FDICopy notification types
  686. *
  687. * The notification function for FDICopy can be called with the following
  688. * values for the fdint parameter. In all cases, the pfdin->pv field is
  689. * filled in with the value of the pvUser argument passed in to FDICopy().
  690. *
  691. * A typical sequence of calls will be something like this:
  692. * fdintCABINET_INFO // Info about the cabinet
  693. * fdintENUMERATE // Starting enumeration
  694. * fdintPARTIAL_FILE // Only if this is not the first cabinet, and
  695. * // one or more files were continued from the
  696. * // previous cabinet.
  697. * ...
  698. * fdintPARTIAL_FILE
  699. * fdintCOPY_FILE // The first file that starts in this cabinet
  700. * ...
  701. * fdintCOPY_FILE // Now let's assume you want this file...
  702. * // PFNWRITE called multiple times to write to this file.
  703. * fdintCLOSE_FILE_INFO // File done, set date/time/attributes
  704. *
  705. * fdintCOPY_FILE // Now let's assume you want this file...
  706. * // PFNWRITE called multiple times to write to this file.
  707. * fdintNEXT_CABINET // File was continued to next cabinet!
  708. * fdintCABINET_INFO // Info about the new cabinet
  709. * // PFNWRITE called multiple times to write to this file.
  710. * fdintCLOSE_FILE_INFO // File done, set date/time/attributes
  711. * ...
  712. * fdintENUMERATE // Ending enumeration
  713. *
  714. * fdintCABINET_INFO:
  715. * Called exactly once for each cabinet opened by FDICopy(), including
  716. * continuation cabinets opened due to file(s) spanning cabinet
  717. * boundaries. Primarily intended to permit EXTRACT.EXE to
  718. * automatically select the next cabinet in a cabinet sequence even if
  719. * not copying files that span cabinet boundaries.
  720. * Entry:
  721. * pfdin->psz1 = name of next cabinet
  722. * pfdin->psz2 = name of next disk
  723. * pfdin->psz3 = cabinet path name
  724. * pfdin->setID = cabinet set ID (a random 16-bit number)
  725. * pfdin->iCabinet = Cabinet number within cabinet set (0-based)
  726. * Exit-Success:
  727. * Return anything but -1
  728. * Exit-Failure:
  729. * Returns -1 => Abort FDICopy() call
  730. * Notes:
  731. * This call is made *every* time a new cabinet is examined by
  732. * FDICopy(). So if "foo2.cab" is examined because a file is
  733. * continued from "foo1.cab", and then you call FDICopy() again
  734. * on "foo2.cab", you will get *two* fdintCABINET_INFO calls all
  735. * told.
  736. *
  737. * fdintCOPY_FILE:
  738. * Called for each file that *starts* in the current cabinet, giving
  739. * the client the opportunity to request that the file be copied or
  740. * skipped.
  741. * Entry:
  742. * pfdin->psz1 = file name in cabinet
  743. * pfdin->cb = uncompressed size of file
  744. * pfdin->date = file date
  745. * pfdin->time = file time
  746. * pfdin->attribs = file attributes
  747. * pfdin->iFolder = file's folder index
  748. * Exit-Success:
  749. * Return non-zero file handle for destination file; FDI writes
  750. * data to this file use the PFNWRITE function supplied to FDICreate,
  751. * and then calls fdintCLOSE_FILE_INFO to close the file and set
  752. * the date, time, and attributes. NOTE: This file handle returned
  753. * must also be closeable by the PFNCLOSE function supplied to
  754. * FDICreate, since if an error occurs while writing to this handle,
  755. * FDI will use the PFNCLOSE function to close the file so that the
  756. * client may delete it.
  757. * Exit-Failure:
  758. * Returns 0 => Skip file, do not copy
  759. * Returns -1 => Abort FDICopy() call
  760. *
  761. * fdintCLOSE_FILE_INFO:
  762. * Called after all of the data has been written to a target file.
  763. * This function must close the file and set the file date, time,
  764. * and attributes.
  765. * Entry:
  766. * pfdin->psz1 = file name in cabinet
  767. * pfdin->hf = file handle
  768. * pfdin->date = file date
  769. * pfdin->time = file time
  770. * pfdin->attribs = file attributes
  771. * pfdin->iFolder = file's folder index
  772. * pfdin->cb = Run After Extract (0 - don't run, 1 Run)
  773. * Exit-Success:
  774. * Returns TRUE
  775. * Exit-Failure:
  776. * Returns FALSE, or -1 to abort;
  777. *
  778. * IMPORTANT NOTE IMPORTANT:
  779. * pfdin->cb is overloaded to no longer be the size of
  780. * the file but to be a binary indicated run or not
  781. *
  782. * IMPORTANT NOTE:
  783. * FDI assumes that the target file was closed, even if this
  784. * callback returns failure. FDI will NOT attempt to use
  785. * the PFNCLOSE function supplied on FDICreate() to close
  786. * the file!
  787. *
  788. * fdintPARTIAL_FILE:
  789. * Called for files at the front of the cabinet that are CONTINUED
  790. * from a previous cabinet. This callback occurs only when FDICopy is
  791. * started on second or subsequent cabinet in a series that has files
  792. * continued from a previous cabinet.
  793. * Entry:
  794. * pfdin->psz1 = file name of file CONTINUED from a PREVIOUS cabinet
  795. * pfdin->psz2 = name of cabinet where file starts
  796. * pfdin->psz3 = name of disk where file starts
  797. * Exit-Success:
  798. * Return anything other than -1; enumeration continues
  799. * Exit-Failure:
  800. * Returns -1 => Abort FDICopy() call
  801. *
  802. * fdintENUMERATE:
  803. * Called once after a call to FDICopy() starts scanning a CAB's
  804. * CFFILE entries, and again when there are no more CFFILE entries.
  805. * If CAB spanning occurs, an additional call will occur after the
  806. * first spanned file is completed. If the pfdin->iFolder value is
  807. * changed from zero, additional calls will occur next time it reaches
  808. * zero. If iFolder is changed to zero, FDICopy will terminate, as if
  809. * there were no more CFFILE entries. Primarily intended to allow an
  810. * application with it's own file list to help FDI advance quickly to
  811. * a CFFILE entry of interest. Can also be used to allow an
  812. * application to determine the cb values for each file in the CAB.
  813. * Entry:
  814. * pfdin->cb = current CFFILE position
  815. * pfdin->iFolder = number of files remaining
  816. * pfdin->setID = current CAB's setID value
  817. * Exit-Don't Care:
  818. * Don't change anything.
  819. * Return anything but -1.
  820. * Exit-Forcing a skip:
  821. * pfdin->cb = desired CFFILE position
  822. * pfdin->iFolder = desired # of files remaining
  823. * Return anything but -1.
  824. * Exit-Stop:
  825. * pfdin->iFolder = set to 0
  826. * Return anything but -1.
  827. * Exit-Failure:
  828. * Return -1 => Abort FDICopy call ("user aborted".)
  829. * Notes:
  830. * This call can be ignored by applications which want normal file
  831. * searching. The application can adjust the supplied values to
  832. * force FDICopy() to continue it's search at another location, or
  833. * to force FDICopy() to terminate the search, by setting iFolder to 0.
  834. * (FDICopy() will report no error when terminated this way.)
  835. * FDI has no means to verify the supplied cb or iFolder values.
  836. * Arbitrary values are likely to cause undesirable results. An
  837. * application should cross-check pfdin->setID to be certain the
  838. * external database is in sync with the CAB. Reverse-skips are OK
  839. * (but may be inefficient) unless fdintNEXT_CABINET has been called.
  840. *
  841. * fdintNEXT_CABINET:
  842. * This function is *only* called when fdintCOPY_FILE was told to copy
  843. * a file in the current cabinet that is continued to a subsequent
  844. * cabinet file. It is important that the cabinet path name (psz3)
  845. * be validated before returning! This function should ensure that
  846. * the cabinet exists and is readable before returning. So, this
  847. * is the function that should, for example, issue a disk change
  848. * prompt and make sure the cabinet file exists.
  849. *
  850. * When this function returns to FDI, FDI will check that the setID
  851. * and iCabinet match the expected values for the next cabinet.
  852. * If not, FDI will continue to call this function until the correct
  853. * cabinet file is specified, or until this function returns -1 to
  854. * abort the FDICopy() function. pfdin->fdie is set to
  855. * FDIERROR_WRONG_CABINET to indicate this case.
  856. *
  857. * If you *haven't* ensured that the cabinet file is present and
  858. * readable, or the cabinet file has been damaged, pfdin->fdie will
  859. * receive other appropriate error codes:
  860. *
  861. * FDIERROR_CABINET_NOT_FOUND
  862. * FDIERROR_NOT_A_CABINET
  863. * FDIERROR_UNKNOWN_CABINET_VERSION
  864. * FDIERROR_CORRUPT_CABINET
  865. * FDIERROR_BAD_COMPR_TYPE
  866. * FDIERROR_RESERVE_MISMATCH
  867. * FDIERROR_WRONG_CABINET
  868. *
  869. * Entry:
  870. * pfdin->psz1 = name of next cabinet where current file is continued
  871. * pfdin->psz2 = name of next disk where current file is continued
  872. * pfdin->psz3 = cabinet path name; FDI concatenates psz3 with psz1
  873. * to produce the fully-qualified path for the cabinet
  874. * file. The 256-byte buffer pointed at by psz3 may
  875. * be modified, but psz1 may not!
  876. * pfdin->fdie = FDIERROR_WRONG_CABINET if the previous call to
  877. * fdintNEXT_CABINET specified a cabinet file that
  878. * did not match the setID/iCabinet that was expected.
  879. * Exit-Success:
  880. * Return anything but -1
  881. * Exit-Failure:
  882. * Returns -1 => Abort FDICopy() call
  883. * Notes:
  884. * This call is almost always made when a target file is open and
  885. * being written to, and the next cabinet is needed to get more
  886. * data for the file.
  887. */
  888. typedef enum {
  889. fdintCABINET_INFO, // General information about cabinet
  890. fdintPARTIAL_FILE, // First file in cabinet is continuation
  891. fdintCOPY_FILE, // File to be copied
  892. fdintCLOSE_FILE_INFO, // close the file, set relevant info
  893. fdintNEXT_CABINET, // File continued to next cabinet
  894. fdintENUMERATE, // Enumeration status
  895. } FDINOTIFICATIONTYPE; /* fdint */
  896. typedef INT_PTR (FAR DIAMONDAPI *PFNFDINOTIFY)(FDINOTIFICATIONTYPE fdint,
  897. PFDINOTIFICATION pfdin); /* pfnfdin */
  898. #define FNFDINOTIFY(fn) INT_PTR FAR DIAMONDAPI fn(FDINOTIFICATIONTYPE fdint, \
  899. PFDINOTIFICATION pfdin)
  900. /*** PFNOPEN - File I/O callbacks for FDI
  901. * PFNREAD
  902. * PFNWRITE
  903. * PFNCLOSE
  904. * PFNSEEK
  905. *
  906. * These are modeled after the C run-time routines _open, _read,
  907. * _write, _close, and _lseek. The values for the PFNOPEN oflag
  908. * and pmode calls are those defined for _open. FDI expects error
  909. * handling to be identical to these C run-time routines.
  910. *
  911. * As long as you faithfully copy these aspects, you can supply
  912. * any functions you like!
  913. *
  914. *
  915. * SPECIAL NOTE FOR QUANTUM DECOMPRESSION:
  916. * When using Quantum compression, at compress time (with Diamond)
  917. * you specify how much memory Quantum requires at *decompress* time
  918. * to store the decompression history buffer. This can be as large
  919. * as *2Mb*, and in an MS-DOS environment, for example, this much
  920. * memory may not be available (certainly not under 640K!). To permit
  921. * large CompressionMemory settings on any machine, the Quantum
  922. * decompressor will attempt to create a "spill file" if there is not
  923. * sufficient memory available.
  924. *
  925. * For PFNOPEN, a special pszFile parameter is passed to indicate that
  926. * a temporary "spill file" is requested. The name passed is "*", and
  927. * you should cast the pszFile parameter to an FDISPILLFILE pointer,
  928. * and get the requested file size. You then need to create a file
  929. * of the specified size with read/write access, save the file name and
  930. * handle for later use by PFNCLOSE, and then return the handle. If
  931. * you cannot create the file of the specified size, you should return
  932. * an error (-1). This file should be placed on a fast local hard disk,
  933. * to maximize the speed of decompression.
  934. *
  935. * For PFNCLOSE, you should check the handle to see if it the spill file
  936. * created previously by PFNOPEN (FDI will create at most one spill file
  937. * per FDICreate() call). If it is the spill file handle, you should
  938. * close the handle and then delete the file, using the file name you
  939. * saved when you created the spill file in PFNOPEN.
  940. *
  941. * WARNING: You should never assume you know what file is being
  942. * opened at any one point in time! FDI will usually
  943. * stick to opening cabinet files, but it is possible
  944. * that in a future implementation it may open temporary
  945. * files or open cabinet files in a different order.
  946. *
  947. * Notes for Memory Mapped File fans:
  948. * You can write wrapper routines to allow FDI to work on memory
  949. * mapped files. You'll have to create your own "handle" type so that
  950. * you can store the base memory address of the file and the current
  951. * seek position, and then you'll allocate and fill in one of these
  952. * structures and return a pointer to it in response to the PFNOPEN
  953. * call and the fdintCOPY_FILE call. Your PFNREAD and PFNWRITE
  954. * functions will do memcopy(), and update the seek position in your
  955. * "handle" structure. PFNSEEK will just change the seek position
  956. * in your "handle" structure.
  957. */
  958. #ifndef _WIN64
  959. #pragma pack (1)
  960. #endif
  961. /** FDISPILLFILE - Pass as pszFile on PFNOPEN to create spill file
  962. *
  963. * ach - A two byte string to signal to PFNOPEN that a spill file is
  964. * requested. Value is '*','\0'.
  965. * cbFile - Required spill file size, in bytes.
  966. */
  967. typedef struct {
  968. char ach[2]; // Set to { '*', '\0' }
  969. long cbFile; // Required spill file size
  970. } FDISPILLFILE; /* fdisf */
  971. typedef FDISPILLFILE *PFDISPILLFILE; /* pfdisf */
  972. #ifndef _WIN64
  973. #pragma pack ()
  974. #endif
  975. /*** cpuType values for FDICreate()
  976. *
  977. * WARNING: For 16-bit Windows applications, the CPU detection may not
  978. * correctly detect 286 CPUs. Instead, use the following code:
  979. *
  980. * DWORD flags;
  981. * int cpuType;
  982. *
  983. * flags = GetWinFlags();
  984. * if (flags & WF_CPU286)
  985. * cpuType = cpu80286;
  986. * else
  987. * cpuType = cpu80386;
  988. *
  989. * hfdi = FDICreate(....,cpuType,...);
  990. */
  991. #define cpuUNKNOWN (-1) /* FDI does detection */
  992. #define cpu80286 (0) /* '286 opcodes only */
  993. #define cpu80386 (1) /* '386 opcodes used */
  994. /*** FDICreate - Create an FDI context
  995. *
  996. * Entry:
  997. * pfnalloc
  998. * pfnfree
  999. * pfnopen
  1000. * pfnread
  1001. * pfnwrite
  1002. * pfnclose
  1003. * pfnlseek
  1004. * cpuType - Select CPU type (auto-detect, 286, or 386+)
  1005. * WARNING: Don't use auto-detect from a 16-bit Windows
  1006. * application! Use GetWinFlags()!
  1007. * NOTE: For the 32-bit FDI.LIB, this parameter is ignored!
  1008. * perf
  1009. *
  1010. * Exit-Success:
  1011. * Returns non-NULL FDI context handle.
  1012. *
  1013. * Exit-Failure:
  1014. * Returns NULL; perf filled in with error code
  1015. *
  1016. * Special notes for Quantum Decompression:
  1017. * If you have used a high setting for CompressionMemory in creating
  1018. * the cabinet file(s), then FDI will attempt to allocate a lot of
  1019. * memory (as much as 2Mb, if you specified 21 for CompressionMemory).
  1020. * Therefore, if you plan to allocate additional memory *after* the
  1021. * FDICreate() call, you should reserve some memory *prior* to calling
  1022. * FDICreate(), and then free it up afterwards (or do all your allocation
  1023. * before calling FDICreate().
  1024. */
  1025. HFDI FAR DIAMONDAPI FDICreate(PFNALLOC pfnalloc,
  1026. PFNFREE pfnfree,
  1027. PFNOPEN pfnopen,
  1028. PFNREAD pfnread,
  1029. PFNWRITE pfnwrite,
  1030. PFNCLOSE pfnclose,
  1031. PFNSEEK pfnseek,
  1032. int cpuType,
  1033. PERF perf);
  1034. /*** FDIIsCabinet - Determines if file is a cabinet, returns info if it is
  1035. *
  1036. * Entry:
  1037. * hfdi - Handle to FDI context (created by FDICreate())
  1038. * hf - File handle suitable for PFNREAD/PFNSEEK, positioned
  1039. * at offset 0 in the file to test.
  1040. * pfdici - Buffer to receive info about cabinet if it is one.
  1041. *
  1042. * Exit-Success:
  1043. * Returns TRUE; file is a cabinet, pfdici filled in.
  1044. *
  1045. * Exit-Failure:
  1046. * Returns FALSE, file is not a cabinet; If an error occurred,
  1047. * perf (passed on FDICreate call!) filled in with error.
  1048. */
  1049. BOOL FAR DIAMONDAPI FDIIsCabinet(HFDI hfdi,
  1050. INT_PTR hf,
  1051. PFDICABINETINFO pfdici);
  1052. /*** FDICopy - extracts files from a cabinet
  1053. *
  1054. * Entry:
  1055. * hfdi - handle to FDI context (created by FDICreate())
  1056. * pszCabinet - main name of cabinet file
  1057. * pszCabPath - Path to cabinet file(s)
  1058. * flags - Flags to modify behavior
  1059. * pfnfdin - Notification function
  1060. * pfnfdid - Decryption function (pass NULL if not used)
  1061. * pvUser - User specified value to pass to notification function
  1062. *
  1063. * Exit-Success:
  1064. * Returns TRUE;
  1065. *
  1066. * Exit-Failure:
  1067. * Returns FALSE, perf (passed on FDICreate call!) filled in with
  1068. * error.
  1069. *
  1070. * Notes:
  1071. * (1) If FDICopy() fails while a target file is being written out, then
  1072. * FDI will use the PFNCLOSE function to close the file handle for that
  1073. * target file that was returned from the fdintCOPY_FILE notification.
  1074. * The client application is then free to delete the target file, since
  1075. * it will not be in a valid state (since there was an error while
  1076. * writing it out).
  1077. */
  1078. BOOL FAR DIAMONDAPI FDICopy(HFDI hfdi,
  1079. char FAR *pszCabinet,
  1080. char FAR *pszCabPath,
  1081. int flags,
  1082. PFNFDINOTIFY pfnfdin,
  1083. PFNFDIDECRYPT pfnfdid,
  1084. void FAR *pvUser);
  1085. /*** FDIDestroy - Destroy an FDI context
  1086. *
  1087. * Entry:
  1088. * hfdi - handle to FDI context (created by FDICreate())
  1089. *
  1090. * Exit-Success:
  1091. * Returns TRUE;
  1092. *
  1093. * Exit-Failure:
  1094. * Returns FALSE;
  1095. */
  1096. BOOL FAR DIAMONDAPI FDIDestroy(HFDI hfdi);
  1097. /*** FDITruncateCabinet - truncate a cabinet, starting at folder #
  1098. *
  1099. * Entry:
  1100. * hfdi - handle to FDI context (created by FDICreate())
  1101. * pszCabinet - full pathname of cabinet file
  1102. * iFolderToDelete - first folder # to delete
  1103. *
  1104. * Exit-Success:
  1105. * Returns TRUE;
  1106. *
  1107. * Exit-Failure:
  1108. * Returns FALSE;
  1109. *
  1110. * Most likely failure is unable to open cabinet for writing.
  1111. *
  1112. * NOTE: This function relies on additional feature in the
  1113. * supplied PFNWRITE function, that a write of 0 bytes
  1114. * will truncate the file at the current position.
  1115. */
  1116. BOOL FAR DIAMONDAPI FDITruncateCabinet(HFDI hfdi,
  1117. char * pszCabinetName,
  1118. USHORT iFolderToDelete);
  1119. //** Revert to default structure packing
  1120. #ifndef _WIN64
  1121. #pragma pack()
  1122. #endif
  1123. #ifdef __cplusplus
  1124. }
  1125. #endif /* __cplusplus */
  1126. #endif //!INCLUDED_FDI
  1127.