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.

1233 lines
53 KiB

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