Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Creating & Extracting ZIP files?
Message
From
18/02/2004 13:23:54
 
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Miscellaneous
Thread ID:
00859913
Message ID:
00878429
Views:
20
Hi Michael,

I found some spare time and poked a bit harder at the DeviceIOControl call and got it to work. The secret was in working out a value for FSCTL_SET_COMPRESSION.

The result is the ability to compress and uncompress files and directories programmatically using API calls. Apparently this facility was added in the Win98 Plus! pack and later OS's. It can only compress individual files and doesn't have span diskette, etc options. Still it's free and it's only three calls.

This is system different to the WinZip option on the right click menu. You begin to wonder just how many compression options there are in the OS.

Looking at my registry the WinZip option uses the zipfldr.dll which has the following mysterious entry points: RouteTheCall, DllCanUnloadNow, DllGetClassObject, DllRegisterServer, DllUnregisterServer and RegisterSendto. All of these are meaningless to me. Somewhere on the Net I found a reference to this dll which suggested that it could be used as a command line parameter to rundll32.exe. But when I try
rundll32.exe zipfldr.dll RouteTheCall C:\temp
all I get is an Explorer view of the directory. There is obviously more to it.

Anyway, the code to compress and uncompress files the simple way:
* Compressing and uncompressing files and directories
* using API calls.

****************************************************
* Defines and Declares                             *
****************************************************
#DEFINE COMPRESSION_FORMAT_DEFAULT 0x00000001
#DEFINE COMPRESSION_FORMAT_NONE    0x00000000
#DEFINE CREATE_ALWAYS              0x00000002 
#DEFINE CREATE_NEW                 0x00000001 
#DEFINE FILE_ATTRIBUTE_NORMAL      0x00000080 
#DEFINE FILE_DEVICE_FILE_SYSTEM    0x00000009
#DEFINE FILE_FLAG_BACKUP_SEMANTICS 0x02000000
#DEFINE FILE_READ_DATA             0x00000001
#DEFINE FILE_SHARE_READ            0x00000001 
#DEFINE FILE_SHARE_WRITE           0x00000002 
#DEFINE FILE_SHARE_DELETE          0x00000004 
#DEFINE FILE_WRITE_DATA            0x00000002
#DEFINE GENERIC_ALL                0x10000000 
#DEFINE GENERIC_READ               0x80000000 
#DEFINE GENERIC_WRITE              0x40000000
#DEFINE MAXIMUM_ALLOWED            0x02000000 
#DEFINE METHOD_BUFFERED            0x00000000
#DEFINE OPEN_EXISTING              0x00000003 
#DEFINE STANDARD_RIGHTS_ALL        0x001F0000 

#DEFINE INVALID_HANDLE_VALUE               -1 

DECLARE INTEGER GetLastError IN kernel32

DECLARE INTEGER CloseHandle  IN kernel32;
        INTEGER hObject 

DECLARE INTEGER CreateFile   IN kernel32; 
        STRING  @ lpFileName           ,; 
        INTEGER dwDesiredAccess        ,; 
        INTEGER dwShareMode            ,; 
        INTEGER @ lpSecurityAttr       ,; 
        INTEGER dwCreationDisp         ,; 
        INTEGER dwFlagsAndAttrs        ,; 
        INTEGER hTemplateFile 

DECLARE INTEGER DeviceIoControl IN kernel32;
        INTEGER hDevice                   ,;
        INTEGER dwIoControlCode           ,;
        INTEGER @ lpInBuffer              ,;
        INTEGER nInBufferSize             ,;
        INTEGER @ lpOutBuffer             ,;
        INTEGER nOutBufferSize            ,;
        INTEGER @ lpBytesReturned         ,;
        INTEGER @ lpOverlapped


****************************************************
* Start to do something                            *
****************************************************

*lpFileName  = "c:\temp\New Folder\"
lpFileName  = "c:\temp\fred.zip"	&& Use your own file name

* Get a file/directory handle
Handle    = GetHandle(lpFileName)

IF Handle = INVALID_HANDLE_VALUE

   * Failed to get a handle
   DO GetHandleError

ELSE

   * Compress it
   RetVal = ZipUnzip(Handle, COMPRESSION_FORMAT_DEFAULT)
   WAIT WINDOW IIF(RetVal=0,'Failed','Compressed') TIMEOUT 5
   
   * Uncompress it
   RetVal = ZipUnzip(Handle, COMPRESSION_FORMAT_NONE)
   WAIT WINDOW IIF(RetVal=0,'Failed','Uncompressed') TIMEOUT 5
   
   * Tidy up
   = CloseHandle(Handle) 

ENDIF

****************************************************
* Procedures and Functions                         *
****************************************************

* Get a handle for the file/directory
FUNCTION GetHandle
   PARAMETERS lpFileName
   
   hFile = CreateFile(                       ;
           lpFileName                       ,; 
           GENERIC_READ+GENERIC_WRITE       ,; 
           FILE_SHARE_READ+FILE_SHARE_WRITE ,; 
           0                                ,; 
           OPEN_EXISTING                    ,; 
           FILE_FLAG_BACKUP_SEMANTICS       ,;   && Needed for directories
           0)
   RETURN hFile
   
ENDFUNC

* Report if failed to get a handle
PROCEDURE GetHandleError

   lnLastError = GetLastError()
   DO CASE
   CASE lnLastError = 2
      lcMess = 'ERROR_FILE_NOT_FOUND'
   CASE lnLastError = 3
      lcMess = 'ERROR_PATH_NOT_FOUND'
   CASE lnLastError = 13
      lcMess = 'ERROR_INVALID_DATA'
   CASE lnLastError = 87
      lcMess = 'ERROR_INVALID_PARAMETER'
   OTHERWISE
      lcMess = 'Error code' + STR(lnLastError)
   ENDCASE
   MESSAGEBOX("Unable to get a handle: " + lcMess)
    
ENDPROC

* Compress and Uncompress
FUNCTION ZipUnzip
   PARAMETERS FDHandle, lpInBuffer
	
   FSCTL_GET_COMPRESSION = CalcControlCode(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_READ_DATA + FILE_WRITE_DATA)
   FSCTL_SET_COMPRESSION = CalcControlCode(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA + FILE_WRITE_DATA)
	
   RetVal = DeviceIoControl(;
      FDHandle             ,;
      FSCTL_SET_COMPRESSION,;
      lpInBuffer           ,;
      4                    ,;
      0                    ,;
      0                    ,;
      0                    ,;
      0)

   RETURN RetVal
	
ENDFUNC

* Calculate value of the control code required by DeviceIOControl (Macro in WinIoCtl.h)
FUNCTION CalcControlCode
   PARAMETERS nDeviceType, nFunction, nMethod, nAccess
   
   RETURN INT(nDeviceType*2^16 + nAccess*2^14 + nFunction*2^2 + nMethod)
   
ENDFUNC
Alan
Previous
Reply
Map
View

Click here to load this message in the networking platform