Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

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.

ValueMeaning
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

Fdi.h

See also

FDICopy
FDINOTIFICATION

 

 

Show: