FDICopy (CABINET.22)
BOOL FDICopy ( HFDI hfdi, char* pszCabinet, char* pszCabPath, int flags, PFNFDINOTIFY pfnfdin, PFNFDIDECRYPT pfnfdid, void* pvUser )
Iterates through the files in the Cabinet file indicated by name and file-location. May chain forward to additional cabinets (typically only one) if files which begin in this Cabinet are continued in another cabinet. For each file which is partially contained in this cabinet, and partially contained in a prior cabinet, provides fdintPARTIAL_FILE notification to the pfnfdin callback. For each file which begins in this cabinet, fdintCOPY_FILE notification is provided to the pfnfdin callback, and the file is optionally decompressed and saved to disk. Notification is not provided for files which are not at least partially contained in the specified cabinet file.
See below for a thorough explanation of the various notification callbacks.
hfdi | [In] | An HFDI from FDICreate. |
pszCabinet | [In] | C-style string containing the filename of the cabinet. |
pszCabPath | [In] | C-style string containing the file path of the cabinet. |
flags | [In] | "Decoder parameters". Ignored. Suggested value: 0. |
pfnfdin | [In] | Pointer to a notification function. See CALLBACKS below. |
pfnfdid | [In] | Pointer to a decryption function. Ignored. Suggested value: NULL. |
pvUser | [In] | arbitrary void * value which is passed to callbacks. |
TRUE if successful. FALSE if unsuccessful (error information is provided in the ERF structure associated with the provided decompression handle by FDICreate).
Two pointers to callback functions are provided as parameters to FDICopy: pfnfdin(of type PFNFDINOTIFY), and pfnfdid (of type PFNFDIDECRYPT). These types are as follows:
typedef INT_PTR (__cdecl *PFNFDINOTIFY) ( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin );.
typedef int (__cdecl *PFNFDIDECRYPT) ( PFDIDECRYPT pfdid );.
You can create functions of this type using the FNFDINOTIFY and FNFDIDECRYPT macros, respectively. For example:
FNFDINOTIFY(mycallback) { / * use variables fdint and pfdin to process notification * / }.
The second callback, which could be used for decrypting encrypted data, is not used at all.
Each notification informs the user of some event which has occurred during decompression of the cabinet file; each notification is also an opportunity for the callee to abort decompression. The information provided to the callback and the meaning of the callback's return value vary drastically across the various types of notification. The type of notification is the fdint parameter; all other information is provided to the callback in notification-specific parts of the FDINOTIFICATION structure pointed to by pfdin. The only part of that structure which is assigned for every callback is the pv element, which contains the arbitrary value which was passed to FDICopy in the pvUser argument (psz1 is also used each time, but its meaning is highly dependent on fdint).
If you encounter unknown notifications, you should return zero if you want decompression to continue (or -1 to abort). All strings used in the callbacks are regular C-style strings. Detailed descriptions of each notification type follow:
fdintCABINET_INFO:
This is the first notification provided after calling FDICopy, and provides the user with various information about the cabinet. Note that this is called for each cabinet FDICopy opens, not just the first one. In the structure pointed to by pfdin, psz1 contains a pointer to the name of the next cabinet file in the set after the one just loaded (if any), psz2 contains a pointer to the name or "info" of the next disk, psz3 contains a pointer to the file-path of the current cabinet, setID contains an arbitrary constant associated with this set of cabinet files, and iCabinet contains the numerical index of the current cabinet within that set. Return zero, or -1 to abort.
fdintPARTIAL_FILE:
This notification is provided when FDICopy encounters a part of a file contained in this cabinet which is missing its beginning. Files can be split across cabinets, so this is not necessarily an abnormality; it just means that the file in question begins in another cabinet. No file corresponding to this notification is extracted from the cabinet. In the structure pointed to by pfdin, psz1 contains a pointer to the name of the partial file, psz2 contains a pointer to the file name of the cabinet in which this file begins, and psz3 contains a pointer to the disk name or "info" of the cabinet where the file begins. Return zero, or -1 to abort.
fdintCOPY_FILE:
This notification is provided when FDICopy encounters a file which starts in the cabinet file, provided to FDICopy in pszCabinet. (FDICopy will not look for files in cabinets after the first one). One notification will be sent for each such file, before the file is decompressed. By returning zero, the callback can instruct FDICopy to skip the file. In the structure pointed to by pfdin, psz1 contains a pointer to the file's name, cb contains the size of the file (uncompressed), attribs contains the file attributes, and date and time contain the date and time of the file. attributes, date, and time are of the 16-bit ms-dos variety. Return -1 to abort decompression for the entire cabinet, 0 to skip just this file but continue scanning the cabinet for more files, or an FDIClose-compatible file-handle.
fdintCLOSE_FILE_INFO:
This notification is important, don't forget to implement it. This notification indicates that a file has been successfully uncompressed and written to disk. Upon receipt of this notification, the callee is expected to close the file handle, to set the attributes and date/time of the closed file, and possibly to execute the file. In the structure pointed to by pfdin, psz1 contains a pointer to the name of the file, hf will be the open file handle (close it), cb contains 1 or zero, indicating respectively that the callee should or should not execute the file, and date, time and attributes will be set as in fdintCOPY_FILE. Bizarrely, the Cabinet SDK specifies that _A_EXEC will be xor'ed out of attributes! Wine does not do do so. Return TRUE, or FALSE to abort decompression.
fdintNEXT_CABINET:
This notification is called when FDICopy must load in another cabinet. This can occur when a file's data is "split" across multiple cabinets. The callee has the opportunity to request that FDICopy look in a different file path for the specified cabinet file, by writing that data into a provided buffer (see below for more information). This notification will be received more than once per-cabinet in the instance that FDICopy failed to find a valid cabinet at the location specified by the first per-cabinet fdintNEXT_CABINET notification. In such instances, the fdie element of the structure pointed to by pfdin indicates the error which prevented FDICopy from proceeding successfully. Return zero to indicate success, or -1 to indicate failure and abort FDICopy.
Upon receipt of this notification, the structure pointed to by pfdin will contain the following values: psz1 pointing to the name of the cabinet which FDICopy is attempting to open, psz2 pointing to the name ("info") of the next disk, psz3 pointing to the presumed file-location of the cabinet, and fdie containing either FDIERROR_NONE, or one of the following:
FDIERROR_CABINET_NOT_FOUND, FDIERROR_NOT_A_CABINET, FDIERROR_UNKNOWN_CABINET_VERSION, FDIERROR_CORRUPT_CABINET, FDIERROR_BAD_COMPR_TYPE, FDIERROR_RESERVE_MISMATCH, and FDIERROR_WRONG_CABINET.
The callee may choose to change the path where FDICopy will look for the cabinet after this notification. To do so, the caller may write the new pathname to the buffer pointed to by psz3, which is 256 characters in length, including the terminating NULL character, before returning zero.
fdintENUMERATE:
Undocumented and unimplemented in Wine, this seems to be sent each time a cabinet is opened, along with the fdintCABINET_INFO notification. It probably has an interface similar to that of fdintCABINET_INFO; maybe this provides information about the current cabinet instead of the next one.... this is just a guess, it has not been looked at closely.
fdi.c
Declared in "include/fdi.h". gitlab.winehq.org/wine/wine/blob/master/include/fdi.h
Implemented in "dlls/cabinet/fdi.c". gitlab.winehq.org/wine/wine/blob/master/dlls/cabinet/fdi.c
Debug channel "cabinet".
Copyright © 2024 The Wine Project. All trademarks are the property of their respective owners. Visit WineHQ for license details. Generated Dec 2024.