FNFDINOTIFY macro
The FNFDINOTIFY macro provides the declaration for the application-defined callback notification function to update the application on the status of the decoder.
Syntax
INT_PTR FNFDINOTIFY( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin );
Parameters
- fdint
-
The type of notification.
Value Meaning - fdintCABINET_INFO
- 0x00
General information about the cabinet.
When this value is set, the FDINOTIFICATION structure is populated with the following information:
- psz1 will point to the name of the next cabinet (excluding path information)
- psz2 will point to the name of the next disk
- psz3 will point to the cabinet path name
- setID will equal the set ID of the current cabinet
- iCabinet will equal the cabinet number within the cabinet set (0 for the first cabinet, 1 for the second cabinet, etc.)
The application should return 0 to indicate success, or -1 to indicate failure, which will abort FDICopy. An fdintCABINET_INFO notification will be provided once for each cabinet opened by FDICopy; this includes continuation cabinets opened due to files spanning cabinet boundaries.
- fdintPARTIAL_FILE
- 0x01
First file in the cabinet is a continuation of a file from previous cabinet.
When this value is set, the FDINOTIFICATION structure is populated with the following information:
- psz1 will point to the name of the file continued from a previous cabinet
- psz2 will point to the name of the cabinet on which the first segment of the file exists
- psz3 will point to the name of the disk on which the first segment of the file exists
The fdintPARTIAL_FILE notification is called for files at the beginning of a cabinet that have continued from a previous cabinet. This notification will occur only when FDICopy is started on the second or subsequent cabinet in a series, which has files continued from a previous cabinet. The application should return 0 for success, or -1 to indicate failure.
- fdintCOPY_FILE
- 0x02
Information identifying the file to be copied.
When this value is set, the FDINOTIFICATION structure is populated with the following information:
- psz1will point to the name of a file in the cabinet; cb will equal the uncompressed size of the file
- date will equal the file's 16-bit MS-DOS date
- time will equal the file's 16-bit MS-DOS time
- attrib will equal the file's 16-bit MS-DOS attributes
The application should return one of three values; 0 to skip (i.e. not copy) the file; -1 (negative one) to abort FDICopy; or a nonzero (and non-negative-one) file handle that indicates where to write the file. The file handle must be compatible with the PFNCLOSE function supplied to FDICreate. The fdintCOPY_FILE notification is called for each file that starts within the current cabinet, providing the opportunity for the application to request that the file be copied or skipped.
- fdintCLOSE_FILE_INFO
- 0x03
Close the file, set relevant information.
When this value is set, the FDINOTIFICATION structure is populated with the following information:
- psz1will point to the name of a file in the cabinet
- hf will be a file handle (which originated from fdintCOPY_FILE)
- date date will equal the file's 16-bit MS-DOS date
- time time will equal the file's 16-bit MS-DOS time
- attrib attributes will equal the file's 16-bit MS-DOS attributes (minus the _A_EXEC bit)
- cb will equal either 0 or 1, indicating whether the file should be executed after extract (1), or not (0)
It is the responsibility of the application to execute the file if cb equals 1. The fdintCLOSE_FILE_INFO notification is called after all of the data has been written to a target file. The application must close the file (using the provided hf handle), and set the file date, time, and attributes. The application should return TRUE for success, and FALSE or -1 to abort FDICopy. FDI assumes that the target file was closed, even if this callback returns failure; FDI will not attempt to use PFNCLOSE to close the file.
- fdintNEXT_CABINET
- 0x04
File continued to next cabinet.
When this value is set, the FDINOTIFICATION structure is populated with the following information:
- psz1will point to the name of the next cabinet on which the current file is continued
- psz2 will be a file handle (which originated from fdintCOPY_FILE)
- psz3 will point to the cabinet path information
- fdie will equal a success or error value
This notification is called only if fdintCOPY_FILE is instructed to copy a file, which is continued from a subsequent cabinet, to the current cabinet . Since it is possible for the application to modify the cabinet name, it is important that the cabinet path name, indicated by psz3, be validated before it is returned. Additionally, the application should ensure that the cabinet exists and is readable before returning; if necessary, the application should issue a disk change prompt to confirm.
When this function returns to FDI, FDI will verify that the setID and iCabinet fields of the supplied cabinet match the expected values for that cabinet. If not, FDI will continue to send fdintNEXT_CABINET notification messages with the fdie field set to FDIERROR_WRONG_CABINET, until the correct cabinet file is specified, or until this function returns -1 and aborts the FDICopy call. If, after returning from this function, the cabinet file is not present, readable, or has been damaged, then the fdie field will equal one of the following values:
- FDIERROR_CABINET_NOT_FOUND
- FDIERROR_NOT_A_CABINET
- FDIERROR_UNKNOWN_CABINET_VERSION
- FDIERROR_CORRUPT_CABINET
- FDIERROR_BAD_COMPR_TYPE
- FDIERROR_RESERVE_MISMATCH
- FDIERROR_WRONG_CABINET
If there was no error, fdie will equal FDIERROR_NONE. The application should return 0 to indicate success, or -1 to indicate failure, which will abort FDICopy.
- fdintENUMERATE
- 0x05
Enumeration status.
- pfdin
-
Pointer to an FDINOTIFICATION structure that contains notification information.
Return value
Varies depending on the notification. See table above.
Examples
FNFDINOTIFY(fnNotify)
{
INT_PTR iResult = 0;
switch(fdint)
{
case fdintCOPY_FILE:
{
CHAR cResponse;
CHAR pszNewFileName[MAX_PATH];
LPSTR pszFileName;
HRESULT hr = S_OK;
//TODO Validate if file name contains characters
//that are not allowed by the file system.
//Remove any directory structure from the file name in cabinet
pszFileName = strrchr(pfdin->psz1, '\\');
if ( pszFileName == NULL )
{
pszFileName = pfdin->psz1;
}
//Append the destination directory to the file name.
hr = StringCchPrintfA(pszNewFileName,
ARRAYSIZE(pszNewFileName),
"%s\\%s",
pfdin->pv, //Destination directory provided by user
pszFileName);
if ( SUCCEEDED(hr) )
{
printf("Extract File \"%s\" (Size: %d bytes) -> \"%s\"? (Yes/No/Quit): ",
pfdin->psz1,
pfdin->cb,
pszNewFileName); //uncompressed size of file
do
{
cResponse = (CHAR)_getch();
cResponse = (CHAR)toupper(cResponse);
} while ( cResponse != 'Y' && cResponse != 'N' && cResponse != 'Q');
printf("\n");
if ( cResponse == 'Y' )
{
iResult = fnFileOpen(pszNewFileName, _O_WRONLY | _O_CREAT, 0);
}
else if ( cResponse == 'Q' )
{
iResult = -1;
}
}
else
{
printf("Failed to append file name \"%s\" to destination directory \"%s\"\n",
pszFileName,
pfdin->pv);
iResult = -1;
}
break;
}
case fdintCLOSE_FILE_INFO:
{
FILETIME fileTime;
FILETIME fileTimeLocal;
FILE_BASIC_INFO fbi;
//Converts MS-DOS date and time values to a file time
if ( DosDateTimeToFileTime(pfdin->date, pfdin->time, &fileTime) == TRUE &&
LocalFileTimeToFileTime(&fileTime, &fileTimeLocal) == TRUE )
{
fbi.CreationTime.LowPart = fileTimeLocal.dwLowDateTime;
fbi.CreationTime.HighPart = fileTimeLocal.dwHighDateTime;
fbi.LastWriteTime.QuadPart = -1;
fbi.ChangeTime.QuadPart = -1;
fbi.LastAccessTime.QuadPart = -1;
//Retrieve the file attributes.
fbi.FileAttributes = pfdin->attribs;
fbi.FileAttributes &= ( _A_RDONLY | _A_HIDDEN |
_A_SYSTEM | _A_ARCH );
//Set the date, time and attributes
SetFileInformationByHandle((HANDLE)pfdin->hf,
FileBasicInfo,
&fbi,
sizeof(FILE_BASIC_INFO));
}
iResult = !fnFileClose(pfdin->hf);
break;
}
case fdintNEXT_CABINET:
if ( pfdin->fdie != FDIERROR_NONE )
{
printf("Failed to process the spanned cabinet file \"%s\""
"with error code %d: %s\n",
pfdin->psz1,
pfdin->fdie,
FDIErrorToString(pfdin->fdie));
iResult = -1;
}
break;
case fdintPARTIAL_FILE:
iResult = 0;
break;
case fdintCABINET_INFO:
iResult = 0;
break;
case fdintENUMERATE:
iResult = 0;
break;
default:
iResult = -1;
break;
}
return iResult;
}
Requirements
|
Header |
|
|---|
See also