5128eecc9f 2011-02-23 kinaba: /* 5128eecc9f 2011-02-23 kinaba: * FDI.H -- File Decompression Interface 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Copyright (C) Microsoft Corporation 1993-1997 5128eecc9f 2011-02-23 kinaba: * All Rights Reserved. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifdef __cplusplus 5128eecc9f 2011-02-23 kinaba: extern "C" { 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef INCLUDED_TYPES_FCI_FDI 5128eecc9f 2011-02-23 kinaba: #define INCLUDED_TYPES_FCI_FDI 1 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef HUGE 5128eecc9f 2011-02-23 kinaba: #define HUGE 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef FAR 5128eecc9f 2011-02-23 kinaba: #define FAR 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef DIAMONDAPI 5128eecc9f 2011-02-23 kinaba: #define DIAMONDAPI __cdecl 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //** Specify structure packing explicitly for clients of FDI 5128eecc9f 2011-02-23 kinaba: #pragma pack(4) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //** Don't redefine types defined in Win16 WINDOWS.H (_INC_WINDOWS) 5128eecc9f 2011-02-23 kinaba: // or Win32 WINDOWS.H (_WINDOWS_) 5128eecc9f 2011-02-23 kinaba: // 5128eecc9f 2011-02-23 kinaba: #if !defined(_INC_WINDOWS) && !defined(_WINDOWS_) 5128eecc9f 2011-02-23 kinaba: typedef int BOOL; /* f */ 5128eecc9f 2011-02-23 kinaba: typedef unsigned char BYTE; /* b */ 5128eecc9f 2011-02-23 kinaba: typedef unsigned int UINT; /* ui */ 5128eecc9f 2011-02-23 kinaba: typedef unsigned short USHORT; /* us */ 5128eecc9f 2011-02-23 kinaba: typedef unsigned long ULONG; /* ul */ 5128eecc9f 2011-02-23 kinaba: #endif // _INC_WINDOWS 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef unsigned long CHECKSUM; /* csum */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef unsigned long UOFF; /* uoff - uncompressed offset */ 5128eecc9f 2011-02-23 kinaba: typedef unsigned long COFF; /* coff - cabinet file offset */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef TRUE 5128eecc9f 2011-02-23 kinaba: #define TRUE 1 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef FALSE 5128eecc9f 2011-02-23 kinaba: #define FALSE 0 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef NULL 5128eecc9f 2011-02-23 kinaba: #define NULL 0 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** ERF - Error structure 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * This structure returns error information from FCI/FDI. The caller should 5128eecc9f 2011-02-23 kinaba: * not modify this structure. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef struct { 5128eecc9f 2011-02-23 kinaba: int erfOper; // FCI/FDI error code -- see FDIERROR_XXX 5128eecc9f 2011-02-23 kinaba: // and FCIERR_XXX equates for details. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int erfType; // Optional error value filled in by FCI/FDI. 5128eecc9f 2011-02-23 kinaba: // For FCI, this is usually the C run-time 5128eecc9f 2011-02-23 kinaba: // *errno* value. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: BOOL fError; // TRUE => error present 5128eecc9f 2011-02-23 kinaba: } ERF; /* erf */ 5128eecc9f 2011-02-23 kinaba: typedef ERF FAR *PERF; /* perf */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifdef _DEBUG 5128eecc9f 2011-02-23 kinaba: // don't hide statics from map during debugging 5128eecc9f 2011-02-23 kinaba: #define STATIC 5128eecc9f 2011-02-23 kinaba: #else // !DEBUG 5128eecc9f 2011-02-23 kinaba: #define STATIC static 5128eecc9f 2011-02-23 kinaba: #endif // !DEBUG 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_CHUNK 32768U 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_DISK 0x7fffffffL 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_FILENAME 256 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_CABINET_NAME 256 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_CAB_PATH 256 5128eecc9f 2011-02-23 kinaba: #define CB_MAX_DISK_NAME 256 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** tcompXXX - Compression types 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * These are passed to FCIAddFile(), and are also stored in the CFFOLDER 5128eecc9f 2011-02-23 kinaba: * structures in cabinet files. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * NOTE: We reserve bits for the TYPE, QUANTUM_LEVEL, and QUANTUM_MEM 5128eecc9f 2011-02-23 kinaba: * to provide room for future expansion. Since this value is stored 5128eecc9f 2011-02-23 kinaba: * in the CFDATA records in the cabinet file, we don't want to 5128eecc9f 2011-02-23 kinaba: * have to change the format for existing compression configurations 5128eecc9f 2011-02-23 kinaba: * if we add new ones in the future. This will allows us to read 5128eecc9f 2011-02-23 kinaba: * old cabinet files in the future. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef unsigned short TCOMP; /* tcomp */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define tcompMASK_TYPE 0x000F // Mask for compression type 5128eecc9f 2011-02-23 kinaba: #define tcompTYPE_NONE 0x0000 // No compression 5128eecc9f 2011-02-23 kinaba: #define tcompTYPE_MSZIP 0x0001 // MSZIP 5128eecc9f 2011-02-23 kinaba: #define tcompTYPE_QUANTUM 0x0002 // Quantum 5128eecc9f 2011-02-23 kinaba: #define tcompTYPE_LZX 0x0003 // LZX 5128eecc9f 2011-02-23 kinaba: #define tcompBAD 0x000F // Unspecified compression type 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define tcompMASK_LZX_WINDOW 0x1F00 // Mask for LZX Compression Memory 5128eecc9f 2011-02-23 kinaba: #define tcompLZX_WINDOW_LO 0x0F00 // Lowest LZX Memory (15) 5128eecc9f 2011-02-23 kinaba: #define tcompLZX_WINDOW_HI 0x1500 // Highest LZX Memory (21) 5128eecc9f 2011-02-23 kinaba: #define tcompSHIFT_LZX_WINDOW 8 // Amount to shift over to get int 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define tcompMASK_QUANTUM_LEVEL 0x00F0 // Mask for Quantum Compression Level 5128eecc9f 2011-02-23 kinaba: #define tcompQUANTUM_LEVEL_LO 0x0010 // Lowest Quantum Level (1) 5128eecc9f 2011-02-23 kinaba: #define tcompQUANTUM_LEVEL_HI 0x0070 // Highest Quantum Level (7) 5128eecc9f 2011-02-23 kinaba: #define tcompSHIFT_QUANTUM_LEVEL 4 // Amount to shift over to get int 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define tcompMASK_QUANTUM_MEM 0x1F00 // Mask for Quantum Compression Memory 5128eecc9f 2011-02-23 kinaba: #define tcompQUANTUM_MEM_LO 0x0A00 // Lowest Quantum Memory (10) 5128eecc9f 2011-02-23 kinaba: #define tcompQUANTUM_MEM_HI 0x1500 // Highest Quantum Memory (21) 5128eecc9f 2011-02-23 kinaba: #define tcompSHIFT_QUANTUM_MEM 8 // Amount to shift over to get int 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define tcompMASK_RESERVED 0xE000 // Reserved bits (high 3 bits) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define CompressionTypeFromTCOMP(tc) \ 5128eecc9f 2011-02-23 kinaba: ((tc) & tcompMASK_TYPE) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define CompressionLevelFromTCOMP(tc) \ 5128eecc9f 2011-02-23 kinaba: (((tc) & tcompMASK_QUANTUM_LEVEL) >> tcompSHIFT_QUANTUM_LEVEL) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define CompressionMemoryFromTCOMP(tc) \ 5128eecc9f 2011-02-23 kinaba: (((tc) & tcompMASK_QUANTUM_MEM) >> tcompSHIFT_QUANTUM_MEM) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define TCOMPfromTypeLevelMemory(t,l,m) \ 5128eecc9f 2011-02-23 kinaba: (((m) << tcompSHIFT_QUANTUM_MEM ) | \ 5128eecc9f 2011-02-23 kinaba: ((l) << tcompSHIFT_QUANTUM_LEVEL) | \ 5128eecc9f 2011-02-23 kinaba: ( t )) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define LZXCompressionWindowFromTCOMP(tc) \ 5128eecc9f 2011-02-23 kinaba: (((tc) & tcompMASK_LZX_WINDOW) >> tcompSHIFT_LZX_WINDOW) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define TCOMPfromLZXWindow(w) \ 5128eecc9f 2011-02-23 kinaba: (((w) << tcompSHIFT_LZX_WINDOW ) | \ 5128eecc9f 2011-02-23 kinaba: ( tcompTYPE_LZX )) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //** Revert to default structure packing 5128eecc9f 2011-02-23 kinaba: #pragma pack() 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #endif // !INCLUDED_TYPES_FCI_FDI 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* 5128eecc9f 2011-02-23 kinaba: * Concepts: 5128eecc9f 2011-02-23 kinaba: * A *cabinet* file contains one or more *folders*. A folder contains 5128eecc9f 2011-02-23 kinaba: * one or more (pieces of) *files*. A folder is by definition a 5128eecc9f 2011-02-23 kinaba: * decompression unit, i.e., to extract a file from a folder, all of 5128eecc9f 2011-02-23 kinaba: * the data from the start of the folder up through and including the 5128eecc9f 2011-02-23 kinaba: * desired file must be read and decompressed. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * A folder can span one (or more) cabinet boundaries, and by implication 5128eecc9f 2011-02-23 kinaba: * a file can also span one (or more) cabinet boundaries. Indeed, more 5128eecc9f 2011-02-23 kinaba: * than one file can span a cabinet boundary, since FCI concatenates 5128eecc9f 2011-02-23 kinaba: * files together into a single data stream before compressing (actually, 5128eecc9f 2011-02-23 kinaba: * at most one file will span any one cabinet boundary, but FCI does 5128eecc9f 2011-02-23 kinaba: * not know which file this is, since the mapping from uncompressed bytes 5128eecc9f 2011-02-23 kinaba: * to compressed bytes is pretty obscure. Also, since FCI compresses 5128eecc9f 2011-02-23 kinaba: * in blocks of 32K (at present), any files with data in a 32K block that 5128eecc9f 2011-02-23 kinaba: * spans a cabinet boundary require FDI to read both cabinet files 5128eecc9f 2011-02-23 kinaba: * to get the two halves of the compressed block). 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Overview: 5128eecc9f 2011-02-23 kinaba: * The File Decompression Interface is used to simplify the reading of 5128eecc9f 2011-02-23 kinaba: * cabinet files. A setup program will proceed in a manner very 5128eecc9f 2011-02-23 kinaba: * similar to the pseudo code below. An FDI context is created, the 5128eecc9f 2011-02-23 kinaba: * setup program calls FDICopy() for each cabinet to be processed. For 5128eecc9f 2011-02-23 kinaba: * each file in the cabinet, FDICopy() calls a notification callback 5128eecc9f 2011-02-23 kinaba: * routine, asking the setup program if the file should be copied. 5128eecc9f 2011-02-23 kinaba: * This call-back approach is great because it allows the cabinet file 5128eecc9f 2011-02-23 kinaba: * to be read and decompressed in an optimal manner, and also makes FDI 5128eecc9f 2011-02-23 kinaba: * independent of the run-time environment -- FDI makes *no* C run-time 5128eecc9f 2011-02-23 kinaba: * calls whatsoever. All memory allocation and file I/O functions are 5128eecc9f 2011-02-23 kinaba: * passed into FDI by the client. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * main(...) 5128eecc9f 2011-02-23 kinaba: * { 5128eecc9f 2011-02-23 kinaba: * // Read INF file to construct list of desired files. 5128eecc9f 2011-02-23 kinaba: * // Ideally, these would be sorted in the same order as the 5128eecc9f 2011-02-23 kinaba: * // files appear in the cabinets, so that you can just walk 5128eecc9f 2011-02-23 kinaba: * // down the list in response to fdintCOPY_FILE notifications. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * // Construct list of required cabinets. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * hfdi = FDICreate(...); // Create FDI context 5128eecc9f 2011-02-23 kinaba: * For (cabinet in List of Cabinets) { 5128eecc9f 2011-02-23 kinaba: * FDICopy(hfdi,cabinet,fdiNotify,...); // Process each cabinet 5128eecc9f 2011-02-23 kinaba: * } 5128eecc9f 2011-02-23 kinaba: * FDIDestroy(hfdi); 5128eecc9f 2011-02-23 kinaba: * ... 5128eecc9f 2011-02-23 kinaba: * } 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * // Notification callback function 5128eecc9f 2011-02-23 kinaba: * fdiNotify(fdint,...) 5128eecc9f 2011-02-23 kinaba: * { 5128eecc9f 2011-02-23 kinaba: * If (User Aborted) // Permit cancellation 5128eecc9f 2011-02-23 kinaba: * if (fdint == fdintCLOSE_FILE_INFO) 5128eecc9f 2011-02-23 kinaba: * close open file 5128eecc9f 2011-02-23 kinaba: * return -1; 5128eecc9f 2011-02-23 kinaba: * switch (fdint) { 5128eecc9f 2011-02-23 kinaba: * case fdintCOPY_FILE: // File to copy, maybe 5128eecc9f 2011-02-23 kinaba: * // Check file against list of desired files 5128eecc9f 2011-02-23 kinaba: * if want to copy file 5128eecc9f 2011-02-23 kinaba: * open destination file and return handle 5128eecc9f 2011-02-23 kinaba: * else 5128eecc9f 2011-02-23 kinaba: * return NULL; // Skip file 5128eecc9f 2011-02-23 kinaba: * case fdintCLOSE_FILE_INFO: 5128eecc9f 2011-02-23 kinaba: * close file 5128eecc9f 2011-02-23 kinaba: * set date, time, and attributes 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * case fdintNEXT_CABINET: 5128eecc9f 2011-02-23 kinaba: * if not an error callback 5128eecc9f 2011-02-23 kinaba: * Tell FDI to use suggested directory name 5128eecc9f 2011-02-23 kinaba: * else 5128eecc9f 2011-02-23 kinaba: * Tell user what the problem was, and prompt 5128eecc9f 2011-02-23 kinaba: * for a new disk and/or path. 5128eecc9f 2011-02-23 kinaba: * if user aborts 5128eecc9f 2011-02-23 kinaba: * Tell FDI to abort 5128eecc9f 2011-02-23 kinaba: * else 5128eecc9f 2011-02-23 kinaba: * return to FDI to try another cabinet 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * default: 5128eecc9f 2011-02-23 kinaba: * return 0; // more messages may be defined 5128eecc9f 2011-02-23 kinaba: * ... 5128eecc9f 2011-02-23 kinaba: * } 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Error Handling Suggestions: 5128eecc9f 2011-02-23 kinaba: * Since you the client have passed in *all* of the functions that 5128eecc9f 2011-02-23 kinaba: * FDI uses to interact with the "outside" world, you are in prime 5128eecc9f 2011-02-23 kinaba: * position to understand and deal with errors. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * The general philosophy of FDI is to pass all errors back up to 5128eecc9f 2011-02-23 kinaba: * the client. FDI returns fairly generic error codes in the case 5128eecc9f 2011-02-23 kinaba: * where one of the callback functions (PFNOPEN, PFNREAD, etc.) fail, 5128eecc9f 2011-02-23 kinaba: * since it assumes that the callback function will save enough 5128eecc9f 2011-02-23 kinaba: * information in a static/global so that when FDICopy() returns 5128eecc9f 2011-02-23 kinaba: * fail, the client can examine this information and report enough 5128eecc9f 2011-02-23 kinaba: * detail about the problem that the user can take corrective action. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * For very specific errors (CORRUPT_CABINET, for example), FDI returns 5128eecc9f 2011-02-23 kinaba: * very specific error codes. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * THE BEST POLICY IS FOR YOUR CALLBACK ROUTINES TO AVOID RETURNING 5128eecc9f 2011-02-23 kinaba: * ERRORS TO FDI! 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Examples: 5128eecc9f 2011-02-23 kinaba: * (1) If the disk is getting full, instead of returning an error 5128eecc9f 2011-02-23 kinaba: * from your PFNWRITE function, you should -- inside your 5128eecc9f 2011-02-23 kinaba: * PFNWRITE function -- put up a dialog telling the user to free 5128eecc9f 2011-02-23 kinaba: * some disk space. 5128eecc9f 2011-02-23 kinaba: * (2) When you get the fdintNEXT_CABINET notification, you should 5128eecc9f 2011-02-23 kinaba: * verify that the cabinet you return is the correct one (call 5128eecc9f 2011-02-23 kinaba: * FDIIsCabinet(), and make sure the setID matches the one for 5128eecc9f 2011-02-23 kinaba: * the current cabinet specified in the fdintCABINET_INFO, and 5128eecc9f 2011-02-23 kinaba: * that the disk number is one greater. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * NOTE: FDI will continue to call fdintNEXT_CABINET until it 5128eecc9f 2011-02-23 kinaba: * gets the cabinet it wants, or until you return -1 5128eecc9f 2011-02-23 kinaba: * to abort the FDICopy() call. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * The documentation below on the FDI error codes provides explicit 5128eecc9f 2011-02-23 kinaba: * guidance on how to avoid each error. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * If you find you must return a failure to FDI from one of your 5128eecc9f 2011-02-23 kinaba: * callback functions, then FDICopy() frees all resources it allocated 5128eecc9f 2011-02-23 kinaba: * and closes all files. If you can figure out how to overcome the 5128eecc9f 2011-02-23 kinaba: * problem, you can call FDICopy() again on the last cabinet, and 5128eecc9f 2011-02-23 kinaba: * skip any files that you already copied. But, note that FDI does 5128eecc9f 2011-02-23 kinaba: * *not* maintain any state between FDICopy() calls, other than possibly 5128eecc9f 2011-02-23 kinaba: * memory allocated for the decompressor. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * See FDIERROR for details on FDI error codes and recommended actions. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Progress Indicator Suggestions: 5128eecc9f 2011-02-23 kinaba: * As above, all of the file I/O functions are supplied by you. So, 5128eecc9f 2011-02-23 kinaba: * updating a progress indicator is very simple. You keep track of 5128eecc9f 2011-02-23 kinaba: * the target files handles you have opened, along with the uncompressed 5128eecc9f 2011-02-23 kinaba: * size of the target file. When you see writes to the handle of a 5128eecc9f 2011-02-23 kinaba: * target file, you use the write count to update your status! 5128eecc9f 2011-02-23 kinaba: * Since this method is available, there is no separate callback from 5128eecc9f 2011-02-23 kinaba: * FDI just for progess indication. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef INCLUDED_FDI 5128eecc9f 2011-02-23 kinaba: #define INCLUDED_FDI 1 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //** Specify structure packing explicitly for clients of FDI 5128eecc9f 2011-02-23 kinaba: #pragma pack(4) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDIERROR - Error codes returned in erf.erfOper field 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * In general, FDI will only fail if one of the passed in memory or 5128eecc9f 2011-02-23 kinaba: * file I/O functions fails. Other errors are pretty unlikely, and are 5128eecc9f 2011-02-23 kinaba: * caused by corrupted cabinet files, passing in a file which is not a 5128eecc9f 2011-02-23 kinaba: * cabinet file, or cabinet files out of order. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Description: Summary of error. 5128eecc9f 2011-02-23 kinaba: * Cause: List of possible causes of this error. 5128eecc9f 2011-02-23 kinaba: * Response: How client might respond to this error, or avoid it in 5128eecc9f 2011-02-23 kinaba: * the first place. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef enum { 5128eecc9f 2011-02-23 kinaba: FDIERROR_NONE, 5128eecc9f 2011-02-23 kinaba: // Description: No error 5128eecc9f 2011-02-23 kinaba: // Cause: Function was successfull. 5128eecc9f 2011-02-23 kinaba: // Response: Keep going! 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_CABINET_NOT_FOUND, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinet not found 5128eecc9f 2011-02-23 kinaba: // Cause: Bad file name or path passed to FDICopy(), or returned 5128eecc9f 2011-02-23 kinaba: // to fdintNEXT_CABINET. 5128eecc9f 2011-02-23 kinaba: // Response: To prevent this error, validate the existence of the 5128eecc9f 2011-02-23 kinaba: // the cabinet *before* passing the path to FDI. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_NOT_A_CABINET, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinet file does not have the correct format 5128eecc9f 2011-02-23 kinaba: // Cause: File passed to to FDICopy(), or returned to 5128eecc9f 2011-02-23 kinaba: // fdintNEXT_CABINET, is too small to be a cabinet file, 5128eecc9f 2011-02-23 kinaba: // or does not have the cabinet signature in its first 5128eecc9f 2011-02-23 kinaba: // four bytes. 5128eecc9f 2011-02-23 kinaba: // Response: To prevent this error, call FDIIsCabinet() to check a 5128eecc9f 2011-02-23 kinaba: // cabinet before calling FDICopy() or returning the 5128eecc9f 2011-02-23 kinaba: // cabinet path to fdintNEXT_CABINET. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_UNKNOWN_CABINET_VERSION, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinet file has an unknown version number. 5128eecc9f 2011-02-23 kinaba: // Cause: File passed to to FDICopy(), or returned to 5128eecc9f 2011-02-23 kinaba: // fdintNEXT_CABINET, has what looks like a cabinet file 5128eecc9f 2011-02-23 kinaba: // header, but the version of the cabinet file format 5128eecc9f 2011-02-23 kinaba: // is not one understood by this version of FDI. The 5128eecc9f 2011-02-23 kinaba: // erf.erfType field is filled in with the version number 5128eecc9f 2011-02-23 kinaba: // found in the cabinet file. 5128eecc9f 2011-02-23 kinaba: // Response: To prevent this error, call FDIIsCabinet() to check a 5128eecc9f 2011-02-23 kinaba: // cabinet before calling FDICopy() or returning the 5128eecc9f 2011-02-23 kinaba: // cabinet path to fdintNEXT_CABINET. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_CORRUPT_CABINET, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinet file is corrupt 5128eecc9f 2011-02-23 kinaba: // Cause: FDI returns this error any time it finds a problem 5128eecc9f 2011-02-23 kinaba: // with the logical format of a cabinet file, and any 5128eecc9f 2011-02-23 kinaba: // time one of the passed-in file I/O calls fails when 5128eecc9f 2011-02-23 kinaba: // operating on a cabinet (PFNOPEN, PFNSEEK, PFNREAD, 5128eecc9f 2011-02-23 kinaba: // or PFNCLOSE). The client can distinguish these two 5128eecc9f 2011-02-23 kinaba: // cases based upon whether the last file I/O call 5128eecc9f 2011-02-23 kinaba: // failed or not. 5128eecc9f 2011-02-23 kinaba: // Response: Assuming this is not a real corruption problem in 5128eecc9f 2011-02-23 kinaba: // a cabinet file, the file I/O functions could attempt 5128eecc9f 2011-02-23 kinaba: // to do retries on failure (for example, if there is a 5128eecc9f 2011-02-23 kinaba: // temporary network connection problem). If this does 5128eecc9f 2011-02-23 kinaba: // not work, and the file I/O call has to fail, then the 5128eecc9f 2011-02-23 kinaba: // FDI client will have to clean up and call the 5128eecc9f 2011-02-23 kinaba: // FDICopy() function again. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_ALLOC_FAIL, 5128eecc9f 2011-02-23 kinaba: // Description: Could not allocate enough memory 5128eecc9f 2011-02-23 kinaba: // Cause: FDI tried to allocate memory with the PFNALLOC 5128eecc9f 2011-02-23 kinaba: // function, but it failed. 5128eecc9f 2011-02-23 kinaba: // Response: If possible, PFNALLOC should take whatever steps 5128eecc9f 2011-02-23 kinaba: // are possible to allocate the memory requested. If 5128eecc9f 2011-02-23 kinaba: // memory is not immediately available, it might post a 5128eecc9f 2011-02-23 kinaba: // dialog asking the user to free memory, for example. 5128eecc9f 2011-02-23 kinaba: // Note that the bulk of FDI's memory allocations are 5128eecc9f 2011-02-23 kinaba: // made at FDICreate() time and when the first cabinet 5128eecc9f 2011-02-23 kinaba: // file is opened during FDICopy(). 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_BAD_COMPR_TYPE, 5128eecc9f 2011-02-23 kinaba: // Description: Unknown compression type in a cabinet folder 5128eecc9f 2011-02-23 kinaba: // Cause: [Should never happen.] A folder in a cabinet has an 5128eecc9f 2011-02-23 kinaba: // unknown compression type. This is probably caused by 5128eecc9f 2011-02-23 kinaba: // a mismatch between the version of FCI.LIB used to 5128eecc9f 2011-02-23 kinaba: // create the cabinet and the FDI.LIB used to read the 5128eecc9f 2011-02-23 kinaba: // cabinet. 5128eecc9f 2011-02-23 kinaba: // Response: Abort. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_MDI_FAIL, 5128eecc9f 2011-02-23 kinaba: // Description: Failure decompressing data from a cabinet file 5128eecc9f 2011-02-23 kinaba: // Cause: The decompressor found an error in the data coming 5128eecc9f 2011-02-23 kinaba: // from the file cabinet. The cabinet file was corrupted. 5128eecc9f 2011-02-23 kinaba: // [11-Apr-1994 bens When checksuming is turned on, this 5128eecc9f 2011-02-23 kinaba: // error should never occur.] 5128eecc9f 2011-02-23 kinaba: // Response: Probably should abort; only other choice is to cleanup 5128eecc9f 2011-02-23 kinaba: // and call FDICopy() again, and hope there was some 5128eecc9f 2011-02-23 kinaba: // intermittent data error that will not reoccur. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_TARGET_FILE, 5128eecc9f 2011-02-23 kinaba: // Description: Failure writing to target file 5128eecc9f 2011-02-23 kinaba: // Cause: FDI returns this error any time it gets an error back 5128eecc9f 2011-02-23 kinaba: // from one of the passed-in file I/O calls fails when 5128eecc9f 2011-02-23 kinaba: // writing to a file being extracted from a cabinet. 5128eecc9f 2011-02-23 kinaba: // Response: To avoid or minimize this error, the file I/O functions 5128eecc9f 2011-02-23 kinaba: // could attempt to avoid failing. A common cause might 5128eecc9f 2011-02-23 kinaba: // be disk full -- in this case, the PFNWRITE function 5128eecc9f 2011-02-23 kinaba: // could have a check for free space, and put up a dialog 5128eecc9f 2011-02-23 kinaba: // asking the user to free some disk space. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_RESERVE_MISMATCH, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinets in a set do not have the same RESERVE sizes 5128eecc9f 2011-02-23 kinaba: // Cause: [Should never happen]. FDI requires that the sizes of 5128eecc9f 2011-02-23 kinaba: // the per-cabinet, per-folder, and per-data block 5128eecc9f 2011-02-23 kinaba: // RESERVE sections be consistent across all the cabinets 5128eecc9f 2011-02-23 kinaba: // in a set. 5128eecc9f 2011-02-23 kinaba: // Response: Abort. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_WRONG_CABINET, 5128eecc9f 2011-02-23 kinaba: // Description: Cabinet returned on fdintNEXT_CABINET is incorrect 5128eecc9f 2011-02-23 kinaba: // Cause: NOTE: THIS ERROR IS NEVER RETURNED BY FDICopy()! 5128eecc9f 2011-02-23 kinaba: // Rather, FDICopy() keeps calling the fdintNEXT_CABINET 5128eecc9f 2011-02-23 kinaba: // callback until either the correct cabinet is specified, 5128eecc9f 2011-02-23 kinaba: // or you return ABORT. 5128eecc9f 2011-02-23 kinaba: // When FDICopy() is extracting a file that crosses a 5128eecc9f 2011-02-23 kinaba: // cabinet boundary, it calls fdintNEXT_CABINET to ask 5128eecc9f 2011-02-23 kinaba: // for the path to the next cabinet. Not being very 5128eecc9f 2011-02-23 kinaba: // trusting, FDI then checks to make sure that the 5128eecc9f 2011-02-23 kinaba: // correct continuation cabinet was supplied! It does 5128eecc9f 2011-02-23 kinaba: // this by checking the "setID" and "iCabinet" fields 5128eecc9f 2011-02-23 kinaba: // in the cabinet. When MAKECAB.EXE creates a set of 5128eecc9f 2011-02-23 kinaba: // cabinets, it constructs the "setID" using the sum 5128eecc9f 2011-02-23 kinaba: // of the bytes of all the destination file names in 5128eecc9f 2011-02-23 kinaba: // the cabinet set. FDI makes sure that the 16-bit 5128eecc9f 2011-02-23 kinaba: // setID of the continuation cabinet matches the 5128eecc9f 2011-02-23 kinaba: // cabinet file just processed. FDI then checks that 5128eecc9f 2011-02-23 kinaba: // the cabinet number (iCabinet) is one more than the 5128eecc9f 2011-02-23 kinaba: // cabinet number for the cabinet just processed. 5128eecc9f 2011-02-23 kinaba: // Response: You need code in your fdintNEXT_CABINET (see below) 5128eecc9f 2011-02-23 kinaba: // handler to do retries if you get recalled with this 5128eecc9f 2011-02-23 kinaba: // error. See the sample code (EXTRACT.C) to see how 5128eecc9f 2011-02-23 kinaba: // this should be handled. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR_USER_ABORT, 5128eecc9f 2011-02-23 kinaba: // Description: FDI aborted. 5128eecc9f 2011-02-23 kinaba: // Cause: An FDI callback returnd -1 (usually). 5128eecc9f 2011-02-23 kinaba: // Response: Up to client. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: } FDIERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* 5128eecc9f 2011-02-23 kinaba: * FAT file attribute flag used by FCI/FDI to indicate that 5128eecc9f 2011-02-23 kinaba: * the filename in the CAB is a UTF string 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: #ifndef _A_NAME_IS_UTF 5128eecc9f 2011-02-23 kinaba: #define _A_NAME_IS_UTF 0x80 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* 5128eecc9f 2011-02-23 kinaba: * FAT file attribute flag used by FCI/FDI to indicate that 5128eecc9f 2011-02-23 kinaba: * the file should be executed after extraction 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: #ifndef _A_EXEC 5128eecc9f 2011-02-23 kinaba: #define _A_EXEC 0x40 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** HFDI - Handle to an FDI context 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * FDICreate() creates this, and it must be passed to all other FDI 5128eecc9f 2011-02-23 kinaba: * functions. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef void FAR *HFDI; /* hfdi */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDICABINETINFO - Information about a cabinet 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef struct { 5128eecc9f 2011-02-23 kinaba: long cbCabinet; // Total length of cabinet file 5128eecc9f 2011-02-23 kinaba: USHORT cFolders; // Count of folders in cabinet 5128eecc9f 2011-02-23 kinaba: USHORT cFiles; // Count of files in cabinet 5128eecc9f 2011-02-23 kinaba: USHORT setID; // Cabinet set ID 5128eecc9f 2011-02-23 kinaba: USHORT iCabinet; // Cabinet number in set (0 based) 5128eecc9f 2011-02-23 kinaba: BOOL fReserve; // TRUE => RESERVE present in cabinet 5128eecc9f 2011-02-23 kinaba: BOOL hasprev; // TRUE => Cabinet is chained prev 5128eecc9f 2011-02-23 kinaba: BOOL hasnext; // TRUE => Cabinet is chained next 5128eecc9f 2011-02-23 kinaba: } FDICABINETINFO; /* fdici */ 5128eecc9f 2011-02-23 kinaba: typedef FDICABINETINFO FAR *PFDICABINETINFO; /* pfdici */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDIDECRYPTTYPE - PFNFDIDECRYPT command types 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef enum { 5128eecc9f 2011-02-23 kinaba: fdidtNEW_CABINET, // New cabinet 5128eecc9f 2011-02-23 kinaba: fdidtNEW_FOLDER, // New folder 5128eecc9f 2011-02-23 kinaba: fdidtDECRYPT, // Decrypt a data block 5128eecc9f 2011-02-23 kinaba: } FDIDECRYPTTYPE; /* fdidt */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDIDECRYPT - Data for PFNFDIDECRYPT function 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef struct { 5128eecc9f 2011-02-23 kinaba: FDIDECRYPTTYPE fdidt; // Command type (selects union below) 5128eecc9f 2011-02-23 kinaba: void FAR *pvUser; // Decryption context 5128eecc9f 2011-02-23 kinaba: union { 5128eecc9f 2011-02-23 kinaba: struct { // fdidtNEW_CABINET 5128eecc9f 2011-02-23 kinaba: void FAR *pHeaderReserve; // RESERVE section from CFHEADER 5128eecc9f 2011-02-23 kinaba: USHORT cbHeaderReserve; // Size of pHeaderReserve 5128eecc9f 2011-02-23 kinaba: USHORT setID; // Cabinet set ID 5128eecc9f 2011-02-23 kinaba: int iCabinet; // Cabinet number in set (0 based) 5128eecc9f 2011-02-23 kinaba: } cabinet; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: struct { // fdidtNEW_FOLDER 5128eecc9f 2011-02-23 kinaba: void FAR *pFolderReserve; // RESERVE section from CFFOLDER 5128eecc9f 2011-02-23 kinaba: USHORT cbFolderReserve; // Size of pFolderReserve 5128eecc9f 2011-02-23 kinaba: USHORT iFolder; // Folder number in cabinet (0 based) 5128eecc9f 2011-02-23 kinaba: } folder; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: struct { // fdidtDECRYPT 5128eecc9f 2011-02-23 kinaba: void FAR *pDataReserve; // RESERVE section from CFDATA 5128eecc9f 2011-02-23 kinaba: USHORT cbDataReserve; // Size of pDataReserve 5128eecc9f 2011-02-23 kinaba: void FAR *pbData; // Data buffer 5128eecc9f 2011-02-23 kinaba: USHORT cbData; // Size of data buffer 5128eecc9f 2011-02-23 kinaba: BOOL fSplit; // TRUE if this is a split data block 5128eecc9f 2011-02-23 kinaba: USHORT cbPartial; // 0 if this is not a split block, or 5128eecc9f 2011-02-23 kinaba: // the first piece of a split block; 5128eecc9f 2011-02-23 kinaba: // Greater than 0 if this is the 5128eecc9f 2011-02-23 kinaba: // second piece of a split block. 5128eecc9f 2011-02-23 kinaba: } decrypt; 5128eecc9f 2011-02-23 kinaba: }; 5128eecc9f 2011-02-23 kinaba: } FDIDECRYPT; /* fdid */ 5128eecc9f 2011-02-23 kinaba: typedef FDIDECRYPT FAR *PFDIDECRYPT; /* pfdid */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FNALLOC - Memory Allocation 5128eecc9f 2011-02-23 kinaba: * FNFREE - Memory Free 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * These are modeled after the C run-time routines malloc() and free() 5128eecc9f 2011-02-23 kinaba: * FDI expects error handling to be identical to these C run-time routines. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * As long as you faithfully copy the semantics of malloc() and free(), 5128eecc9f 2011-02-23 kinaba: * you can supply any functions you like! 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * WARNING: You should never assume anything about the sequence of 5128eecc9f 2011-02-23 kinaba: * PFNALLOC and PFNFREE calls -- incremental releases of 5128eecc9f 2011-02-23 kinaba: * FDI may have radically different numbers of 5128eecc9f 2011-02-23 kinaba: * PFNALLOC calls and allocation sizes! 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: //** Memory functions for FDI 5128eecc9f 2011-02-23 kinaba: typedef void HUGE * (FAR DIAMONDAPI *PFNALLOC)(ULONG cb); /* pfna */ 5128eecc9f 2011-02-23 kinaba: #define FNALLOC(fn) void HUGE * FAR DIAMONDAPI fn(ULONG cb) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef void (FAR DIAMONDAPI *PFNFREE)(void HUGE *pv); /* pfnf */ 5128eecc9f 2011-02-23 kinaba: #define FNFREE(fn) void FAR DIAMONDAPI fn(void HUGE *pv) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** PFNOPEN - File I/O callbacks for FDI 5128eecc9f 2011-02-23 kinaba: * PFNREAD 5128eecc9f 2011-02-23 kinaba: * PFNWRITE 5128eecc9f 2011-02-23 kinaba: * PFNCLOSE 5128eecc9f 2011-02-23 kinaba: * PFNSEEK 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * These are modeled after the C run-time routines _open, _read, 5128eecc9f 2011-02-23 kinaba: * _write, _close, and _lseek. The values for the PFNOPEN oflag 5128eecc9f 2011-02-23 kinaba: * and pmode calls are those defined for _open. FDI expects error 5128eecc9f 2011-02-23 kinaba: * handling to be identical to these C run-time routines. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * As long as you faithfully copy these aspects, you can supply 5128eecc9f 2011-02-23 kinaba: * any functions you like! 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * WARNING: You should never assume you know what file is being 5128eecc9f 2011-02-23 kinaba: * opened at any one point in time! FDI will usually 5128eecc9f 2011-02-23 kinaba: * stick to opening cabinet files, but it is possible 5128eecc9f 2011-02-23 kinaba: * that in a future implementation it may open temporary 5128eecc9f 2011-02-23 kinaba: * files or open cabinet files in a different order. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Notes for Memory Mapped File fans: 5128eecc9f 2011-02-23 kinaba: * You can write wrapper routines to allow FDI to work on memory 5128eecc9f 2011-02-23 kinaba: * mapped files. You'll have to create your own "handle" type so that 5128eecc9f 2011-02-23 kinaba: * you can store the base memory address of the file and the current 5128eecc9f 2011-02-23 kinaba: * seek position, and then you'll allocate and fill in one of these 5128eecc9f 2011-02-23 kinaba: * structures and return a pointer to it in response to the PFNOPEN 5128eecc9f 2011-02-23 kinaba: * call and the fdintCOPY_FILE call. Your PFNREAD and PFNWRITE 5128eecc9f 2011-02-23 kinaba: * functions will do memcopy(), and update the seek position in your 5128eecc9f 2011-02-23 kinaba: * "handle" structure. PFNSEEK will just change the seek position 5128eecc9f 2011-02-23 kinaba: * in your "handle" structure. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: //** File I/O functions for FDI 5128eecc9f 2011-02-23 kinaba: typedef int (FAR DIAMONDAPI *PFNOPEN) (char FAR *pszFile, int oflag, int pmode); 5128eecc9f 2011-02-23 kinaba: typedef UINT (FAR DIAMONDAPI *PFNREAD) (int hf, void FAR *pv, UINT cb); 5128eecc9f 2011-02-23 kinaba: typedef UINT (FAR DIAMONDAPI *PFNWRITE)(int hf, void FAR *pv, UINT cb); 5128eecc9f 2011-02-23 kinaba: typedef int (FAR DIAMONDAPI *PFNCLOSE)(int hf); 5128eecc9f 2011-02-23 kinaba: typedef long (FAR DIAMONDAPI *PFNSEEK) (int hf, long dist, int seektype); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define FNOPEN(fn) int FAR DIAMONDAPI fn(char FAR *pszFile, int oflag, int pmode) 5128eecc9f 2011-02-23 kinaba: #define FNREAD(fn) UINT FAR DIAMONDAPI fn(int hf, void FAR *pv, UINT cb) 5128eecc9f 2011-02-23 kinaba: #define FNWRITE(fn) UINT FAR DIAMONDAPI fn(int hf, void FAR *pv, UINT cb) 5128eecc9f 2011-02-23 kinaba: #define FNCLOSE(fn) int FAR DIAMONDAPI fn(int hf) 5128eecc9f 2011-02-23 kinaba: #define FNSEEK(fn) long FAR DIAMONDAPI fn(int hf, long dist, int seektype) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** PFNFDIDECRYPT - FDI Decryption callback 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * If this function is passed on the FDICopy() call, then FDI calls it 5128eecc9f 2011-02-23 kinaba: * at various times to update the decryption state and to decrypt FCDATA 5128eecc9f 2011-02-23 kinaba: * blocks. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Common Entry Conditions: 5128eecc9f 2011-02-23 kinaba: * pfdid->fdidt - Command type 5128eecc9f 2011-02-23 kinaba: * pfdid->pvUser - pvUser value from FDICopy() call 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdidtNEW_CABINET: //** Notification of a new cabinet 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdid->cabinet. 5128eecc9f 2011-02-23 kinaba: * pHeaderReserve - RESERVE section from CFHEADER 5128eecc9f 2011-02-23 kinaba: * cbHeaderReserve - Size of pHeaderReserve 5128eecc9f 2011-02-23 kinaba: * setID - Cabinet set ID 5128eecc9f 2011-02-23 kinaba: * iCabinet - Cabinet number in set (0 based) 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * returns anything but -1; 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * returns -1; FDICopy() is aborted. 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * (1) This call allows the decryption code to pick out any information 5128eecc9f 2011-02-23 kinaba: * from the cabinet header reserved area (placed there by DIACRYPT) 5128eecc9f 2011-02-23 kinaba: * needed to perform decryption. If there is no such information, 5128eecc9f 2011-02-23 kinaba: * this call would presumably be ignored. 5128eecc9f 2011-02-23 kinaba: * (2) This call is made very soon after fdintCABINET_INFO. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdidtNEW_FOLDER: //** Notification of a new folder 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdid->folder. 5128eecc9f 2011-02-23 kinaba: * pFolderReserve - RESERVE section from CFFOLDER 5128eecc9f 2011-02-23 kinaba: * cbFolderReserve - Size of pFolderReserve 5128eecc9f 2011-02-23 kinaba: * iFolder - Folder number in cabinet (0 based) 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * returns anything but -1; 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * returns -1; FDICopy() is aborted. 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * This call allows the decryption code to pick out any information 5128eecc9f 2011-02-23 kinaba: * from the folder reserved area (placed there by DIACRYPT) needed 5128eecc9f 2011-02-23 kinaba: * to perform decryption. If there is no such information, this 5128eecc9f 2011-02-23 kinaba: * call would presumably be ignored. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdidtDECRYPT: //** Decrypt a data buffer 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdid->folder. 5128eecc9f 2011-02-23 kinaba: * pDataReserve - RESERVE section for this CFDATA block 5128eecc9f 2011-02-23 kinaba: * cbDataReserve - Size of pDataReserve 5128eecc9f 2011-02-23 kinaba: * pbData - Data buffer 5128eecc9f 2011-02-23 kinaba: * cbData - Size of data buffer 5128eecc9f 2011-02-23 kinaba: * fSplit - TRUE if this is a split data block 5128eecc9f 2011-02-23 kinaba: * cbPartial - 0 if this is not a split block, or the first 5128eecc9f 2011-02-23 kinaba: * piece of a split block; Greater than 0 if 5128eecc9f 2011-02-23 kinaba: * this is the second piece of a split block. 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * returns TRUE; 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * returns FALSE; error during decrypt 5128eecc9f 2011-02-23 kinaba: * returns -1; FDICopy() is aborted. 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * FCI will split CFDATA blocks across cabinet boundaries if 5128eecc9f 2011-02-23 kinaba: * necessary. To provide maximum flexibility, FDI will call the 5128eecc9f 2011-02-23 kinaba: * fdidtDECRYPT function twice on such split blocks, once when 5128eecc9f 2011-02-23 kinaba: * the first portion is read, and again when the second portion 5128eecc9f 2011-02-23 kinaba: * is read. And, of course, most data blocks will not be split. 5128eecc9f 2011-02-23 kinaba: * So, there are three cases: 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * 1) fSplit == FALSE 5128eecc9f 2011-02-23 kinaba: * You have the entire data block, so decrypt it. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * 2) fSplit == TRUE, cbPartial == 0 5128eecc9f 2011-02-23 kinaba: * This is the first portion of a split data block, so cbData 5128eecc9f 2011-02-23 kinaba: * is the size of this portion. You can either choose to decrypt 5128eecc9f 2011-02-23 kinaba: * this piece, or ignore this call and decrypt the full CFDATA 5128eecc9f 2011-02-23 kinaba: * block on the next (second) fdidtDECRYPT call. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * 3) fSplit == TRUE, cbPartial > 0 5128eecc9f 2011-02-23 kinaba: * This is the second portion of a split data block (indeed, 5128eecc9f 2011-02-23 kinaba: * cbPartial will have the same value as cbData did on the 5128eecc9f 2011-02-23 kinaba: * immediately preceeding fdidtDECRYPT call!). If you decrypted 5128eecc9f 2011-02-23 kinaba: * the first portion on the first call, then you can decrypt the 5128eecc9f 2011-02-23 kinaba: * second portion now. If you ignored the first call, then you 5128eecc9f 2011-02-23 kinaba: * can decrypt the entire buffer. 5128eecc9f 2011-02-23 kinaba: * NOTE: pbData points to the second portion of the split data 5128eecc9f 2011-02-23 kinaba: * block in this case, *not* the entire data block. If 5128eecc9f 2011-02-23 kinaba: * you want to wait until the second piece to decrypt the 5128eecc9f 2011-02-23 kinaba: * *entire* block, pbData-cbPartial is the address of the 5128eecc9f 2011-02-23 kinaba: * start of the whole block, and cbData+cbPartial is its 5128eecc9f 2011-02-23 kinaba: * size. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef int (FAR DIAMONDAPI *PFNFDIDECRYPT)(PFDIDECRYPT pfdid); /* pfnfdid */ 5128eecc9f 2011-02-23 kinaba: #define FNFDIDECRYPT(fn) int FAR DIAMONDAPI fn(PFDIDECRYPT pfdid) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDINOTIFICATION - Notification structure for PFNFDINOTIFY 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * See the FDINOTIFICATIONTYPE definition for information on usage and 5128eecc9f 2011-02-23 kinaba: * meaning of these fields. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef struct { 5128eecc9f 2011-02-23 kinaba: // long fields 5128eecc9f 2011-02-23 kinaba: long cb; 5128eecc9f 2011-02-23 kinaba: char FAR *psz1; 5128eecc9f 2011-02-23 kinaba: char FAR *psz2; 5128eecc9f 2011-02-23 kinaba: char FAR *psz3; // Points to a 256 character buffer 5128eecc9f 2011-02-23 kinaba: void FAR *pv; // Value for client 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // int fields 5128eecc9f 2011-02-23 kinaba: int hf; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // short fields 5128eecc9f 2011-02-23 kinaba: USHORT date; 5128eecc9f 2011-02-23 kinaba: USHORT time; 5128eecc9f 2011-02-23 kinaba: USHORT attribs; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: USHORT setID; // Cabinet set ID 5128eecc9f 2011-02-23 kinaba: USHORT iCabinet; // Cabinet number (0-based) 5128eecc9f 2011-02-23 kinaba: USHORT iFolder; // Folder number (0-based) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIERROR fdie; 5128eecc9f 2011-02-23 kinaba: } FDINOTIFICATION, FAR *PFDINOTIFICATION; /* fdin, pfdin */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDINOTIFICATIONTYPE - FDICopy notification types 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * The notification function for FDICopy can be called with the following 5128eecc9f 2011-02-23 kinaba: * values for the fdint parameter. In all cases, the pfdin->pv field is 5128eecc9f 2011-02-23 kinaba: * filled in with the value of the pvUser argument passed in to FDICopy(). 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * A typical sequence of calls will be something like this: 5128eecc9f 2011-02-23 kinaba: * fdintCABINET_INFO // Info about the cabinet 5128eecc9f 2011-02-23 kinaba: * fdintENUMERATE // Starting enumeration 5128eecc9f 2011-02-23 kinaba: * fdintPARTIAL_FILE // Only if this is not the first cabinet, and 5128eecc9f 2011-02-23 kinaba: * // one or more files were continued from the 5128eecc9f 2011-02-23 kinaba: * // previous cabinet. 5128eecc9f 2011-02-23 kinaba: * ... 5128eecc9f 2011-02-23 kinaba: * fdintPARTIAL_FILE 5128eecc9f 2011-02-23 kinaba: * fdintCOPY_FILE // The first file that starts in this cabinet 5128eecc9f 2011-02-23 kinaba: * ... 5128eecc9f 2011-02-23 kinaba: * fdintCOPY_FILE // Now let's assume you want this file... 5128eecc9f 2011-02-23 kinaba: * // PFNWRITE called multiple times to write to this file. 5128eecc9f 2011-02-23 kinaba: * fdintCLOSE_FILE_INFO // File done, set date/time/attributes 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintCOPY_FILE // Now let's assume you want this file... 5128eecc9f 2011-02-23 kinaba: * // PFNWRITE called multiple times to write to this file. 5128eecc9f 2011-02-23 kinaba: * fdintNEXT_CABINET // File was continued to next cabinet! 5128eecc9f 2011-02-23 kinaba: * fdintCABINET_INFO // Info about the new cabinet 5128eecc9f 2011-02-23 kinaba: * // PFNWRITE called multiple times to write to this file. 5128eecc9f 2011-02-23 kinaba: * fdintCLOSE_FILE_INFO // File done, set date/time/attributes 5128eecc9f 2011-02-23 kinaba: * ... 5128eecc9f 2011-02-23 kinaba: * fdintENUMERATE // Ending enumeration 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintCABINET_INFO: 5128eecc9f 2011-02-23 kinaba: * Called exactly once for each cabinet opened by FDICopy(), including 5128eecc9f 2011-02-23 kinaba: * continuation cabinets opened due to file(s) spanning cabinet 5128eecc9f 2011-02-23 kinaba: * boundaries. Primarily intended to permit EXTRACT.EXE to 5128eecc9f 2011-02-23 kinaba: * automatically select the next cabinet in a cabinet sequence even if 5128eecc9f 2011-02-23 kinaba: * not copying files that span cabinet boundaries. 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->psz1 = name of next cabinet 5128eecc9f 2011-02-23 kinaba: * pfdin->psz2 = name of next disk 5128eecc9f 2011-02-23 kinaba: * pfdin->psz3 = cabinet path name 5128eecc9f 2011-02-23 kinaba: * pfdin->setID = cabinet set ID (a random 16-bit number) 5128eecc9f 2011-02-23 kinaba: * pfdin->iCabinet = Cabinet number within cabinet set (0-based) 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Return anything but -1 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns -1 => Abort FDICopy() call 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * This call is made *every* time a new cabinet is examined by 5128eecc9f 2011-02-23 kinaba: * FDICopy(). So if "foo2.cab" is examined because a file is 5128eecc9f 2011-02-23 kinaba: * continued from "foo1.cab", and then you call FDICopy() again 5128eecc9f 2011-02-23 kinaba: * on "foo2.cab", you will get *two* fdintCABINET_INFO calls all 5128eecc9f 2011-02-23 kinaba: * told. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintCOPY_FILE: 5128eecc9f 2011-02-23 kinaba: * Called for each file that *starts* in the current cabinet, giving 5128eecc9f 2011-02-23 kinaba: * the client the opportunity to request that the file be copied or 5128eecc9f 2011-02-23 kinaba: * skipped. 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->psz1 = file name in cabinet 5128eecc9f 2011-02-23 kinaba: * pfdin->cb = uncompressed size of file 5128eecc9f 2011-02-23 kinaba: * pfdin->date = file date 5128eecc9f 2011-02-23 kinaba: * pfdin->time = file time 5128eecc9f 2011-02-23 kinaba: * pfdin->attribs = file attributes 5128eecc9f 2011-02-23 kinaba: * pfdin->iFolder = file's folder index 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Return non-zero file handle for destination file; FDI writes 5128eecc9f 2011-02-23 kinaba: * data to this file use the PFNWRITE function supplied to FDICreate, 5128eecc9f 2011-02-23 kinaba: * and then calls fdintCLOSE_FILE_INFO to close the file and set 5128eecc9f 2011-02-23 kinaba: * the date, time, and attributes. NOTE: This file handle returned 5128eecc9f 2011-02-23 kinaba: * must also be closeable by the PFNCLOSE function supplied to 5128eecc9f 2011-02-23 kinaba: * FDICreate, since if an error occurs while writing to this handle, 5128eecc9f 2011-02-23 kinaba: * FDI will use the PFNCLOSE function to close the file so that the 5128eecc9f 2011-02-23 kinaba: * client may delete it. 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns 0 => Skip file, do not copy 5128eecc9f 2011-02-23 kinaba: * Returns -1 => Abort FDICopy() call 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintCLOSE_FILE_INFO: 5128eecc9f 2011-02-23 kinaba: * Called after all of the data has been written to a target file. 5128eecc9f 2011-02-23 kinaba: * This function must close the file and set the file date, time, 5128eecc9f 2011-02-23 kinaba: * and attributes. 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->psz1 = file name in cabinet 5128eecc9f 2011-02-23 kinaba: * pfdin->hf = file handle 5128eecc9f 2011-02-23 kinaba: * pfdin->date = file date 5128eecc9f 2011-02-23 kinaba: * pfdin->time = file time 5128eecc9f 2011-02-23 kinaba: * pfdin->attribs = file attributes 5128eecc9f 2011-02-23 kinaba: * pfdin->iFolder = file's folder index 5128eecc9f 2011-02-23 kinaba: * pfdin->cb = Run After Extract (0 - don't run, 1 Run) 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Returns TRUE 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns FALSE, or -1 to abort; 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * IMPORTANT NOTE IMPORTANT: 5128eecc9f 2011-02-23 kinaba: * pfdin->cb is overloaded to no longer be the size of 5128eecc9f 2011-02-23 kinaba: * the file but to be a binary indicated run or not 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * IMPORTANT NOTE: 5128eecc9f 2011-02-23 kinaba: * FDI assumes that the target file was closed, even if this 5128eecc9f 2011-02-23 kinaba: * callback returns failure. FDI will NOT attempt to use 5128eecc9f 2011-02-23 kinaba: * the PFNCLOSE function supplied on FDICreate() to close 5128eecc9f 2011-02-23 kinaba: * the file! 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintPARTIAL_FILE: 5128eecc9f 2011-02-23 kinaba: * Called for files at the front of the cabinet that are CONTINUED 5128eecc9f 2011-02-23 kinaba: * from a previous cabinet. This callback occurs only when FDICopy is 5128eecc9f 2011-02-23 kinaba: * started on second or subsequent cabinet in a series that has files 5128eecc9f 2011-02-23 kinaba: * continued from a previous cabinet. 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->psz1 = file name of file CONTINUED from a PREVIOUS cabinet 5128eecc9f 2011-02-23 kinaba: * pfdin->psz2 = name of cabinet where file starts 5128eecc9f 2011-02-23 kinaba: * pfdin->psz3 = name of disk where file starts 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Return anything other than -1; enumeration continues 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns -1 => Abort FDICopy() call 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintENUMERATE: 5128eecc9f 2011-02-23 kinaba: * Called once after a call to FDICopy() starts scanning a CAB's 5128eecc9f 2011-02-23 kinaba: * CFFILE entries, and again when there are no more CFFILE entries. 5128eecc9f 2011-02-23 kinaba: * If CAB spanning occurs, an additional call will occur after the 5128eecc9f 2011-02-23 kinaba: * first spanned file is completed. If the pfdin->iFolder value is 5128eecc9f 2011-02-23 kinaba: * changed from zero, additional calls will occur next time it reaches 5128eecc9f 2011-02-23 kinaba: * zero. If iFolder is changed to zero, FDICopy will terminate, as if 5128eecc9f 2011-02-23 kinaba: * there were no more CFFILE entries. Primarily intended to allow an 5128eecc9f 2011-02-23 kinaba: * application with it's own file list to help FDI advance quickly to 5128eecc9f 2011-02-23 kinaba: * a CFFILE entry of interest. Can also be used to allow an 5128eecc9f 2011-02-23 kinaba: * application to determine the cb values for each file in the CAB. 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->cb = current CFFILE position 5128eecc9f 2011-02-23 kinaba: * pfdin->iFolder = number of files remaining 5128eecc9f 2011-02-23 kinaba: * pfdin->setID = current CAB's setID value 5128eecc9f 2011-02-23 kinaba: * Exit-Don't Care: 5128eecc9f 2011-02-23 kinaba: * Don't change anything. 5128eecc9f 2011-02-23 kinaba: * Return anything but -1. 5128eecc9f 2011-02-23 kinaba: * Exit-Forcing a skip: 5128eecc9f 2011-02-23 kinaba: * pfdin->cb = desired CFFILE position 5128eecc9f 2011-02-23 kinaba: * pfdin->iFolder = desired # of files remaining 5128eecc9f 2011-02-23 kinaba: * Return anything but -1. 5128eecc9f 2011-02-23 kinaba: * Exit-Stop: 5128eecc9f 2011-02-23 kinaba: * pfdin->iFolder = set to 0 5128eecc9f 2011-02-23 kinaba: * Return anything but -1. 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Return -1 => Abort FDICopy call ("user aborted".) 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * This call can be ignored by applications which want normal file 5128eecc9f 2011-02-23 kinaba: * searching. The application can adjust the supplied values to 5128eecc9f 2011-02-23 kinaba: * force FDICopy() to continue it's search at another location, or 5128eecc9f 2011-02-23 kinaba: * to force FDICopy() to terminate the search, by setting iFolder to 0. 5128eecc9f 2011-02-23 kinaba: * (FDICopy() will report no error when terminated this way.) 5128eecc9f 2011-02-23 kinaba: * FDI has no means to verify the supplied cb or iFolder values. 5128eecc9f 2011-02-23 kinaba: * Arbitrary values are likely to cause undesirable results. An 5128eecc9f 2011-02-23 kinaba: * application should cross-check pfdin->setID to be certain the 5128eecc9f 2011-02-23 kinaba: * external database is in sync with the CAB. Reverse-skips are OK 5128eecc9f 2011-02-23 kinaba: * (but may be inefficient) unless fdintNEXT_CABINET has been called. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * fdintNEXT_CABINET: 5128eecc9f 2011-02-23 kinaba: * This function is *only* called when fdintCOPY_FILE was told to copy 5128eecc9f 2011-02-23 kinaba: * a file in the current cabinet that is continued to a subsequent 5128eecc9f 2011-02-23 kinaba: * cabinet file. It is important that the cabinet path name (psz3) 5128eecc9f 2011-02-23 kinaba: * be validated before returning! This function should ensure that 5128eecc9f 2011-02-23 kinaba: * the cabinet exists and is readable before returning. So, this 5128eecc9f 2011-02-23 kinaba: * is the function that should, for example, issue a disk change 5128eecc9f 2011-02-23 kinaba: * prompt and make sure the cabinet file exists. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * When this function returns to FDI, FDI will check that the setID 5128eecc9f 2011-02-23 kinaba: * and iCabinet match the expected values for the next cabinet. 5128eecc9f 2011-02-23 kinaba: * If not, FDI will continue to call this function until the correct 5128eecc9f 2011-02-23 kinaba: * cabinet file is specified, or until this function returns -1 to 5128eecc9f 2011-02-23 kinaba: * abort the FDICopy() function. pfdin->fdie is set to 5128eecc9f 2011-02-23 kinaba: * FDIERROR_WRONG_CABINET to indicate this case. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * If you *haven't* ensured that the cabinet file is present and 5128eecc9f 2011-02-23 kinaba: * readable, or the cabinet file has been damaged, pfdin->fdie will 5128eecc9f 2011-02-23 kinaba: * receive other appropriate error codes: 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * FDIERROR_CABINET_NOT_FOUND 5128eecc9f 2011-02-23 kinaba: * FDIERROR_NOT_A_CABINET 5128eecc9f 2011-02-23 kinaba: * FDIERROR_UNKNOWN_CABINET_VERSION 5128eecc9f 2011-02-23 kinaba: * FDIERROR_CORRUPT_CABINET 5128eecc9f 2011-02-23 kinaba: * FDIERROR_BAD_COMPR_TYPE 5128eecc9f 2011-02-23 kinaba: * FDIERROR_RESERVE_MISMATCH 5128eecc9f 2011-02-23 kinaba: * FDIERROR_WRONG_CABINET 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfdin->psz1 = name of next cabinet where current file is continued 5128eecc9f 2011-02-23 kinaba: * pfdin->psz2 = name of next disk where current file is continued 5128eecc9f 2011-02-23 kinaba: * pfdin->psz3 = cabinet path name; FDI concatenates psz3 with psz1 5128eecc9f 2011-02-23 kinaba: * to produce the fully-qualified path for the cabinet 5128eecc9f 2011-02-23 kinaba: * file. The 256-byte buffer pointed at by psz3 may 5128eecc9f 2011-02-23 kinaba: * be modified, but psz1 may not! 5128eecc9f 2011-02-23 kinaba: * pfdin->fdie = FDIERROR_WRONG_CABINET if the previous call to 5128eecc9f 2011-02-23 kinaba: * fdintNEXT_CABINET specified a cabinet file that 5128eecc9f 2011-02-23 kinaba: * did not match the setID/iCabinet that was expected. 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Return anything but -1 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns -1 => Abort FDICopy() call 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * This call is almost always made when a target file is open and 5128eecc9f 2011-02-23 kinaba: * being written to, and the next cabinet is needed to get more 5128eecc9f 2011-02-23 kinaba: * data for the file. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: typedef enum { 5128eecc9f 2011-02-23 kinaba: fdintCABINET_INFO, // General information about cabinet 5128eecc9f 2011-02-23 kinaba: fdintPARTIAL_FILE, // First file in cabinet is continuation 5128eecc9f 2011-02-23 kinaba: fdintCOPY_FILE, // File to be copied 5128eecc9f 2011-02-23 kinaba: fdintCLOSE_FILE_INFO, // close the file, set relevant info 5128eecc9f 2011-02-23 kinaba: fdintNEXT_CABINET, // File continued to next cabinet 5128eecc9f 2011-02-23 kinaba: fdintENUMERATE, // Enumeration status 5128eecc9f 2011-02-23 kinaba: } FDINOTIFICATIONTYPE; /* fdint */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef int (FAR DIAMONDAPI *PFNFDINOTIFY)(FDINOTIFICATIONTYPE fdint, 5128eecc9f 2011-02-23 kinaba: PFDINOTIFICATION pfdin); /* pfnfdin */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define FNFDINOTIFY(fn) int FAR DIAMONDAPI fn(FDINOTIFICATIONTYPE fdint, \ 5128eecc9f 2011-02-23 kinaba: PFDINOTIFICATION pfdin) 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** cpuType values for FDICreate() 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * (Ignored by 32-bit FDI.) 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: #define cpuUNKNOWN (-1) /* FDI does detection */ 5128eecc9f 2011-02-23 kinaba: #define cpu80286 (0) /* '286 opcodes only */ 5128eecc9f 2011-02-23 kinaba: #define cpu80386 (1) /* '386 opcodes used */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDICreate - Create an FDI context 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * pfnalloc 5128eecc9f 2011-02-23 kinaba: * pfnfree 5128eecc9f 2011-02-23 kinaba: * pfnopen 5128eecc9f 2011-02-23 kinaba: * pfnread 5128eecc9f 2011-02-23 kinaba: * pfnwrite 5128eecc9f 2011-02-23 kinaba: * pfnclose 5128eecc9f 2011-02-23 kinaba: * pfnlseek 5128eecc9f 2011-02-23 kinaba: * cpuType - Select CPU type (auto-detect, 286, or 386+) 5128eecc9f 2011-02-23 kinaba: * NOTE: For the 32-bit FDI.LIB, this parameter is ignored! 5128eecc9f 2011-02-23 kinaba: * perf 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Returns non-NULL FDI context handle. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns NULL; perf filled in with error code 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: HFDI FAR DIAMONDAPI FDICreate(PFNALLOC pfnalloc, 5128eecc9f 2011-02-23 kinaba: PFNFREE pfnfree, 5128eecc9f 2011-02-23 kinaba: PFNOPEN pfnopen, 5128eecc9f 2011-02-23 kinaba: PFNREAD pfnread, 5128eecc9f 2011-02-23 kinaba: PFNWRITE pfnwrite, 5128eecc9f 2011-02-23 kinaba: PFNCLOSE pfnclose, 5128eecc9f 2011-02-23 kinaba: PFNSEEK pfnseek, 5128eecc9f 2011-02-23 kinaba: int cpuType, 5128eecc9f 2011-02-23 kinaba: PERF perf); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDIIsCabinet - Determines if file is a cabinet, returns info if it is 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * hfdi - Handle to FDI context (created by FDICreate()) 5128eecc9f 2011-02-23 kinaba: * hf - File handle suitable for PFNREAD/PFNSEEK, positioned 5128eecc9f 2011-02-23 kinaba: * at offset 0 in the file to test. 5128eecc9f 2011-02-23 kinaba: * pfdici - Buffer to receive info about cabinet if it is one. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Returns TRUE; file is a cabinet, pfdici filled in. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns FALSE, file is not a cabinet; If an error occurred, 5128eecc9f 2011-02-23 kinaba: * perf (passed on FDICreate call!) filled in with error. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: BOOL FAR DIAMONDAPI FDIIsCabinet(HFDI hfdi, 5128eecc9f 2011-02-23 kinaba: int hf, 5128eecc9f 2011-02-23 kinaba: PFDICABINETINFO pfdici); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDICopy - extracts files from a cabinet 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * hfdi - handle to FDI context (created by FDICreate()) 5128eecc9f 2011-02-23 kinaba: * pszCabinet - main name of cabinet file 5128eecc9f 2011-02-23 kinaba: * pszCabPath - Path to cabinet file(s) 5128eecc9f 2011-02-23 kinaba: * flags - Flags to modify behavior 5128eecc9f 2011-02-23 kinaba: * pfnfdin - Notification function 5128eecc9f 2011-02-23 kinaba: * pfnfdid - Decryption function (pass NULL if not used) 5128eecc9f 2011-02-23 kinaba: * pvUser - User specified value to pass to notification function 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Returns TRUE; 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns FALSE, perf (passed on FDICreate call!) filled in with 5128eecc9f 2011-02-23 kinaba: * error. 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Notes: 5128eecc9f 2011-02-23 kinaba: * (1) If FDICopy() fails while a target file is being written out, then 5128eecc9f 2011-02-23 kinaba: * FDI will use the PFNCLOSE function to close the file handle for that 5128eecc9f 2011-02-23 kinaba: * target file that was returned from the fdintCOPY_FILE notification. 5128eecc9f 2011-02-23 kinaba: * The client application is then free to delete the target file, since 5128eecc9f 2011-02-23 kinaba: * it will not be in a valid state (since there was an error while 5128eecc9f 2011-02-23 kinaba: * writing it out). 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: BOOL FAR DIAMONDAPI FDICopy(HFDI hfdi, 5128eecc9f 2011-02-23 kinaba: char FAR *pszCabinet, 5128eecc9f 2011-02-23 kinaba: char FAR *pszCabPath, 5128eecc9f 2011-02-23 kinaba: int flags, 5128eecc9f 2011-02-23 kinaba: PFNFDINOTIFY pfnfdin, 5128eecc9f 2011-02-23 kinaba: PFNFDIDECRYPT pfnfdid, 5128eecc9f 2011-02-23 kinaba: void FAR *pvUser); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /*** FDIDestroy - Destroy an FDI context 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Entry: 5128eecc9f 2011-02-23 kinaba: * hfdi - handle to FDI context (created by FDICreate()) 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Success: 5128eecc9f 2011-02-23 kinaba: * Returns TRUE; 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Exit-Failure: 5128eecc9f 2011-02-23 kinaba: * Returns FALSE; 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: BOOL FAR DIAMONDAPI FDIDestroy(HFDI hfdi); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //** Revert to default structure packing 5128eecc9f 2011-02-23 kinaba: #pragma pack() 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #endif // !INCLUDED_FDI 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifdef __cplusplus 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: #endif