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
Do you 'need' to use those functions specifically? I would assume they map directly onto createfile, readfile, etc
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.
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
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
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