News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Cabinet SDK

Started by jdoe, June 03, 2006, 11:55:28 PM

Previous topic - Next topic

jdoe

Hi,

I'm doing a Cabinet compression/decompression program based on the Cabinet SDK and I would like to have some inputs about old functions.

From SDK it is stated that I need to use _open, _read, _write, _close, _lseek like functions but I didn't found satisfying informations about what are the constants and returned values for these.

I saw that these functions still exist in kernel32.dll so can I use them in the way the SDK want me to (this way I only need constants).

Does someone have a good links to give me about constants and returned values for these old functions?


Thanks

Tedd

Do you 'need' to use those functions specifically? I would assume they map directly onto createfile, readfile, etc
No snowflake in an avalanche feels responsible.

jdoe

From what I can see, yes they are mapped to more recent function (lseek call SetFilePointer and so on) and no, I don't have to call these function specifically but I must use the same input and output. This is why I asked for some info about the constants and returned values.

This is what I have done without being sure if I'm right. On the web I found few informations that are making lie each others.  :(


FDIFileRead proc p_hf:dword, p_pv:dword, p_cb:dword

   local l_dwNumberOfBytesRead:dword

   invoke ReadFile, p_hf, p_pv, p_cb, addr l_dwNumberOfBytesRead, NULL
   test eax, eax
   jz @F

   mov eax, l_dwNumberOfBytesRead

@@:
   ret

FDIFileRead endp


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FDIFileWrite proc p_hf:dword, p_pv:dword, p_cb:dword

   local l_dwNumberOfBytesWritten:dword

   invoke WriteFile, p_hf, p_pv, p_cb, addr l_dwNumberOfBytesWritten, NULL
   test eax, eax
   jz @F

   mov eax, l_dwNumberOfBytesWritten

@@:
   ret

FDIFileWrite endp


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FDIFileClose proc p_hf:dword

   invoke CloseHandle, p_hf
   test eax, eax
   jz @F

   xor eax, eax
   ret

@@:
   mov eax, -1
   ret

FDIFileClose endp


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FDIFileSeek proc p_hf:dword, p_dist:dword, p_seektype:dword

   local l_dwMoveMethod:dword

   mov eax, p_seektype

   .if (eax == SEEK_SET)
       mov l_dwMoveMethod, FILE_BEGIN
   .elseif (eax == SEEK_CUR)
       mov l_dwMoveMethod, FILE_CURRENT
   .elseif (eax == SEEK_END)
       mov l_dwMoveMethod, FILE_END
   .else
       mov eax, -1
       ret
   .endif

   invoke SetFilePointer, p_hf, p_dist, NULL, l_dwMoveMethod
   ;cmp eax, -1   ; INVALID_SET_FILE_POINTER
   ;je @F

   ;xor eax, eax

;@@:
   ret

FDIFileSeek endp



But with _open it become really complicated to guess on what the inputs are. For the output it must be a file handle.




MichaelW

This is a list of the exports from the version of cabinet.dll that I have (1.0.601.0).

000011A0    0    11 FCIAddFile
00001010    1    10 FCICreate
00001350    2    14 FCIDestroy
000012A0    3    13 FCIFlushCabinet
00001320    4    12 FCIFlushFolder
000091C0    5    22 FDICopy
00008FE0    6    20 FDICreate
00009080    7    23 FDIDestroy
000090F0    8    21 FDIIsCabinet
00001000    9     1 GetDllVersion


All I/O is apparently done through callbacks.

From FCI.H:

/***    PFNFCIOPEN  - File I/O callbacks for FCI
*      PFNFCIREAD
*      PFNFCIWRITE
*      PFNFCICLOSE
*      PFNFCISEEK
*
*  These are modeled after the C run-time routines _open, _read,
*  _write, _close, and _lseek.  The values for the PFNFCIOPEN oflag
*  and pmode calls are those defined for _open.  FCI expects error
*  handling to be identical to these C run-time routines, except that
*  the value of errno should be returned via *err.
*
*  As long as you faithfully copy these aspects, you can supply
*  any functions you like!
*


From FID.H:

*      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.
...
/***    PFNOPEN  - File I/O callbacks for FDI
*      PFNREAD
*      PFNWRITE
*      PFNCLOSE
*      PFNSEEK
*
*  These are modeled after the C run-time routines _open, _read,
*  _write, _close, and _lseek.  The values for the PFNOPEN oflag
*  and pmode calls are those defined for _open.  FDI expects error
*  handling to be identical to these C run-time routines.
*
*  As long as you faithfully copy these aspects, you can supply
*  any functions you like!
*
...

*  Notes for Memory Mapped File fans:
*      You can write wrapper routines to allow FDI to work on memory
*      mapped files.  You'll have to create your own "handle" type so that
*      you can store the base memory address of the file and the current
*      seek position, and then you'll allocate and fill in one of these
*      structures and return a pointer to it in response to the PFNOPEN
*      call and the fdintCOPY_FILE call.  Your PFNREAD and PFNWRITE
*      functions will do memcopy(), and update the seek position in your
*      "handle" structure.  PFNSEEK will just change the seek position
*      in your "handle" structure.


FCI apparently expects C run-time errno values, so perhaps it would be better to use the CRT functions for file I/O. You can read the errno value with something like this:

    ; crt__errno returns the address of the errno variable.
    errno MACRO
        invoke crt__errno
        mov   eax,[eax]
        EXITM <eax>
    ENDM

eschew obfuscation

jdoe

Thanks Michael,

I'm not used to c library but I looked at disassemble makecab.exe and I saw that these functions are in msvcrt.dll too. I think like you said, that it would be better to used the c run-time to make sure I'm doing it right.

And now from MSDN I have all the informations I want about these file I/O functions.   :U


jdoe


Few more questions...

I've been able to work with cabinet.dll by making a fdi.inc with the fdi.h from VS6. h2inc.exe helped me doing it. Is there a reason that h2inc can't create a .inc with the header files from the latest Windows SDK. It always raise an error and the resulting .inc is incomplete. Is there a more recent h2inc available out there.

The fdi.inc created with h2inc create structure with a "4t" like this...


tagERF STRUCT 4t
   erfOper                        SWORD ?   ; FCIERR_XXX / FDIERROR_XXX
   erfType                        SWORD ?   ; C run-time *errno* value
   fError                         SWORD ?   ; TRUE => error present
tagERF ENDS


What 4t mean?

-------------------

I learned that working with cabinet.dll functions is all about using the right data types because there is almost no dword use in there and all functions must follow the c calling convention which is the first time I had to use proto c and proc c. I don't know what the difference is all about but it work this way.  :red