⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdi.pas

📁 fdi
💻 PAS
📖 第 1 页 / 共 4 页
字号:
{++

f d i . p a s
Copyright (c) 1997 Alexander Staubo, all rights reserved.

Abstract:

  Translation of fdi.h, part of the Cabinet SDK.

Revision history:

  06/07/1997 20:17  alexs  1.0
    Autogenerated by htrans
  26/12/1997 02:55  alexs  1.1
    Fixed declarations of function callbacks, other minor stuff

--}

unit Fdi;

{$A+}
{$MINENUMSIZE 4}
{$WEAKPACKAGEUNIT ON}

interface

uses
  Windows, SysUtils;

type
  PVoid = Pointer;
  USHORT = Word;

(*
 *  FDI.H -- File Decompression Interface
 *
 *  Copyright (C) Microsoft Corporation 1993-1997
 *  All Rights Reserved.
 *)

type
                                       { f }
  TBYTE = Char;
  
                                       { b }
  TUINT = Integer;
  
                                       { ui }
  TUSHORT = Smallint;
  
                                       { us }
  TULONG = Longint;
  
                                       { ul }

type
  TCHECKSUM = Longint;
  
                                       { csum }
  TUOFF = Longint;
  
                                       { uoff - uncompressed offset }
  TCOFF = Longint;
  
                                       { coff - cabinet file offset }

{**    ERF - Error structure
 *
 *  This structure returns error information from FCI/FDI.  The caller should
 *  not modify this structure.
 }

type
  TERF =     
    record
      erfOper : Integer;  // FCI/FDI error code -- see FDIERROR_XXX
        //  and FCIERR_XXX equates for details.
      erfType : Integer;  // Optional error value filled in by FCI/FDI.
        // For FCI, this is usually the C run-time
        // *errno* value.
      fError : BOOL;  // TRUE => error present
    end;
    
                                       { erf }
  PERF = ^TERF;
  
                                       { perf }

const
  CB_MAX_CHUNK = 32768;
  CB_MAX_DISK = $7ffffff;
  CB_MAX_FILENAME = 256;
  CB_MAX_CABINET_NAME = 256;
  CB_MAX_CAB_PATH = 256;
  CB_MAX_DISK_NAME = 256;

{**    tcompXXX - Compression types
 *
 *  These are passed to FCIAddFile(), and are also stored in the CFFOLDER
 *  structures in cabinet files.
 *
 *  NOTE: We reserve bits for the TYPE, QUANTUM_LEVEL, and QUANTUM_MEM
 *        to provide room for future expansion.  Since this value is stored
 *        in the CFDATA records in the cabinet file, we don't want to
 *        have to change the format for existing compression configurations
 *        if we add new ones in the future.  This will allows us to read
 *        old cabinet files in the future.
 }

type
  TCOMP = Smallint;
  
                                       { tcomp }

const
  tcompMASK_TYPE = $000F;
  tcompTYPE_NONE = $0000;
  tcompTYPE_MSZIP = $0001;
  tcompTYPE_QUANTUM = $0002;
  tcompTYPE_LZX = $0003;
  tcompBAD = $000F;
  tcompMASK_LZX_WINDOW = $1F00;
  tcompLZX_WINDOW_LO = $0F00;
  tcompLZX_WINDOW_HI = $1500;
  tcompSHIFT_LZX_WINDOW = 8;
  tcompMASK_QUANTUM_LEVEL = $00F0;
  tcompQUANTUM_LEVEL_LO = $0010;
  tcompQUANTUM_LEVEL_HI = $0070;
  tcompSHIFT_QUANTUM_LEVEL = 4;
  tcompMASK_QUANTUM_MEM = $1F00;
  tcompQUANTUM_MEM_LO = $0A00;
  tcompQUANTUM_MEM_HI = $1500;
  tcompSHIFT_QUANTUM_MEM = 8;
  tcompMASK_RESERVED = $E000;

(*
 *  Concepts:
 *      A *cabinet* file contains one or more *folders*.  A folder contains
 *      one or more (pieces of) *files*.  A folder is by definition a
 *      decompression unit, i.e., to extract a file from a folder, all of
 *      the data from the start of the folder up through and including the
 *      desired file must be read and decompressed.
 *
 *      A folder can span one (or more) cabinet boundaries, and by implication
 *      a file can also span one (or more) cabinet boundaries.  Indeed, more
 *      than one file can span a cabinet boundary, since FCI concatenates
 *      files together into a single data stream before compressing (actually,
 *      at most one file will span any one cabinet boundary, but FCI does
 *      not know which file this is, since the mapping from uncompressed bytes
 *      to compressed bytes is pretty obscure.  Also, since FCI compresses
 *      in blocks of 32K (at present), any files with data in a 32K block that
 *      spans a cabinet boundary require FDI to read both cabinet files
 *      to get the two halves of the compressed block).
 *
 *  Overview:
 *      The File Decompression Interface is used to simplify the reading of
 *      cabinet files.  A setup program will proceed in a manner very
 *      similar to the pseudo code below.  An FDI context is created, the
 *      setup program calls FDICopy() for each cabinet to be processed.  For
 *      each file in the cabinet, FDICopy() calls a notification callback
 *      routine, asking the setup program if the file should be copied.
 *      This call-back approach is great because it allows the cabinet file
 *      to be read and decompressed in an optimal manner, and also makes FDI
 *      independent of the run-time environment -- FDI makes *no* C run-time
 *      calls whatsoever.  All memory allocation and file I/O functions are
 *      passed into FDI by the client.
 *
 *      main(...)
 *      {
 *          // Read INF file to construct list of desired files.   
 *          //  Ideally, these would be sorted in the same order as the
 *          //  files appear in the cabinets, so that you can just walk
 *          //  down the list in response to fdintCOPY_FILE notifications.
 *
 *          // Construct list of required cabinets. 
 *
 *          hfdi = FDICreate(...);          // Create FDI context
 *          For (cabinet in List of Cabinets) {
 *              FDICopy(hfdi,cabinet,fdiNotify,...);  // Process each cabinet
 *          [#125]
 *          FDIDestroy(hfdi);
 *          ...
 *      [#125]
 *
 *      // Notification callback function 
 *      fdiNotify(fdint,...)
 *      {
 *          If (User Aborted)               // Permit cancellation
 *              if (fdint == fdintCLOSE_FILE_INFO)
 *                  close open file
 *              return -1;
 *          switch (fdint) {
 *              case fdintCOPY_FILE:        // File to copy, maybe
 *                  // Check file against list of desired files 
 *                  if want to copy file
 *                      open destination file and return handle
 *                  else
 *                      return NULL;        // Skip file
 *              case fdintCLOSE_FILE_INFO:
 *                  close file
 *                  set date, time, and attributes
 *
 *              case fdintNEXT_CABINET:
 *                  if not an error callback
 *                      Tell FDI to use suggested directory name
 *                  else
 *                      Tell user what the problem was, and prompt
 *                          for a new disk and/or path.
 *                      if user aborts
 *                          Tell FDI to abort
 *                      else
 *                          return to FDI to try another cabinet
 *
 *              default:
 *                  return 0;               // more messages may be defined
 *              ...
 *      [#125]
 *
 *  Error Handling Suggestions:
 *      Since you the client have passed in *all* of the functions that
 *      FDI uses to interact with the "outside" world, you are in prime
 *      position to understand and deal with errors.
 *
 *      The general philosophy of FDI is to pass all errors back up to
 *      the client.  FDI returns fairly generic error codes in the case
 *      where one of the callback functions (PFNOPEN, PFNREAD, etc.) fail,
 *      since it assumes that the callback function will save enough
 *      information in a static/global so that when FDICopy() returns
 *      fail, the client can examine this information and report enough
 *      detail about the problem that the user can take corrective action.
 *
 *      For very specific errors (CORRUPT_CABINET, for example), FDI returns
 *      very specific error codes.
 *
 *      THE BEST POLICY IS FOR YOUR CALLBACK ROUTINES TO AVOID RETURNING
 *      ERRORS TO FDI!
 *
 *      Examples:
 *          (1) If the disk is getting full, instead of returning an error
 *              from your PFNWRITE function, you should -- inside your
 *              PFNWRITE function -- put up a dialog telling the user to free
 *              some disk space.
 *          (2) When you get the fdintNEXT_CABINET notification, you should
 *              verify that the cabinet you return is the correct one (call
 *              FDIIsCabinet(), and make sure the setID matches the one for
 *              the current cabinet specified in the fdintCABINET_INFO, and
 *              that the disk number is one greater.
 *
 *              NOTE: FDI will continue to call fdintNEXT_CABINET until it
 *                    gets the cabinet it wants, or until you return -1
 *                    to abort the FDICopy() call.
 *
 *      The documentation below on the FDI error codes provides explicit
 *      guidance on how to avoid each error.
 *
 *      If you find you must return a failure to FDI from one of your
 *      callback functions, then FDICopy() frees all resources it allocated
 *      and closes all files.  If you can figure out how to overcome the
 *      problem, you can call FDICopy() again on the last cabinet, and
 *      skip any files that you already copied.  But, note that FDI does
 *      *not* maintain any state between FDICopy() calls, other than possibly
 *      memory allocated for the decompressor.
 *
 *      See FDIERROR for details on FDI error codes and recommended actions.
 *
 *
 *  Progress Indicator Suggestions:
 *      As above, all of the file I/O functions are supplied by you.  So,
 *      updating a progress indicator is very simple.  You keep track of
 *      the target files handles you have opened, along with the uncompressed
 *      size of the target file.  When you see writes to the handle of a
 *      target file, you use the write count to update your status!
 *      Since this method is available, there is no separate callback from
 *      FDI just for progess indication.
 *)

{**    FDIERROR - Error codes returned in erf.erfOper field
 *
 *  In general, FDI will only fail if one of the passed in memory or
 *  file I/O functions fails.  Other errors are pretty unlikely, and are
 *  caused by corrupted cabinet files, passing in a file which is not a

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -