News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Number and type of arguments required for call to C library

Started by jj2007, May 21, 2014, 10:21:19 PM

Previous topic - Next topic

peter_asm

I've seen some HLL examples that use IShellFolder to create ZIP files.
Not sure how compatible they would be with WinZip, WinRAR or 7zip but might be worth a look.

jj2007

Quote from: peter_asm on May 22, 2014, 09:06:13 AM
I've seen some HLL examples that use IShellFolder to create ZIP files.
Not sure how compatible they would be with WinZip, WinRAR or 7zip but might be worth a look.

The only comment says "The sad thing is of course that the zip compatibility is crap" - but I can't open it because you need an account there.

Besides, it looks pretty complicated. A simpler solution seems Quickly unzipping a file by imagiro, and I've tried my luck in assembler (see attachment, RTF format), but currently I'm stuck with hilariously sick stuff like

(shldisp.h)
#ifndef __Folder_FWD_DEFINED__
#define __Folder_FWD_DEFINED__
typedef interface Folder Folder;
#endif    /* __Folder_FWD_DEFINED__ */


... and I won't have time in the coming days to dig into this can of worms :(

nidud

deleted

GoneFishing

Hi Jochen,

Here's what I wrote for simple zip-unzip operations - not perfect and not pure ( I forgot about releasing the object after all the work is done   :redface: ) but it works fine here

include \masm32\include\masm32rt.inc

__UNICODE__ EQU
__DEBUG__  EQU 0

IDispatch_Invoke  PROTO  :DWORD,:DWORD,:DWORD,:DWORD
IDispatch_GetIDsOfNames   PROTO :DWORD,:DWORD
SetParams PROTO  :DWORD

VARIANT STRUCT
  dw1   dd 0CCh
  dw2   dd 0CCh
  dw3   dd 0CCh
  dw4   dd 0CCh
VARIANT   ENDS

DISPPARAMS   STRUCT
  rgvarg         dd ?
  rgdispidNamedArgs dd ?
  cArgs         dd ?
  cNamedArgs        dd ?
DISPPARAMS     ENDS

IFERROR  MACRO arg
   .if    eax!=S_OK
          printf("%s FAILED with hr 0x%08X\n",arg,eax)
          print  LastError$(),13,10,0
          print "Exiting ...",13,10,0
          jmp _exit
   .endif   
          ENDM

IFDEBUG   MACRO arg
   IFDEF  __DEBUG__
          printf("%s : SUCCESS\n",arg)
   ENDIF   
          ENDM
         
FEEDBACK MACRO arg
  IFERROR   arg
  IFDEBUG   arg
           ENDM

.data   
     IID_IDispatch  GUID <00020400h,0000h,0000h,<0C0h,0h,0h,0h,0h,0h,0h,46h>>
     IID_NULL       GUID <00000000h,0000h,0000h,<0h,0h,0h,0h,0h,0h,0h,0h>>
     dpar DISPPARAMS <>
     varg VARIANT    <>
     vres VARIANT    <>   
.data?
     DISPID         dd ?,?
     pclsid         dd ?
     ppvShA         dd ?
     ppvFld         dd ?
.code
     start:
            call main
            inkey
            exit
main proc
     mov eax, uc$("Shell.Application")
     invoke   CLSIDFromProgID, eax, addr pclsid

                              FEEDBACK "CLSIDFromProgID"

     invoke   CoInitialize, NULL
     invoke   CoCreateInstance, addr pclsid,
                                NULL,
                                CLSCTX_INPROC_SERVER,
                                addr IID_IDispatch,
                                addr ppvShA

                              FEEDBACK "CoCreateInstance"
     
     ; Define the DESTINATION in the third parameter "path"
     ; Note that it must be an already EXISTING ZIP file (for zip operation)
     ;                                         or folder (for unzip operation)   

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Below is an example of zipping of "C:\masm32\projects\TST\ZIPIT" folder
;                     to "C:\masm32\projects\TST\NEW\NEW.ZIP" zip archive
; ! REPLACE THEM with your own paths !
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

      invoke IDispatch_Invoke, ppvShA,uc$("NameSpace"),uc$("C:\masm32\projects\TST\NEW\NEW.ZIP"),addr vres
                             
                               m2m ppvFld, vres.dw3

     ; Define the SOURCE file or folder in the third parameter "path"
     ; Note that NO WILDCARDS ALLOWED for zip operation
     ; Though "C:\folder\new.zip\*" seems to work for unzip operation
       
     invoke IDispatch_Invoke, ppvFld,uc$("CopyHere"),uc$("C:\masm32\projects\TST\ZIPIT"),NULL

     _exit::

     invoke CoUninitialize
   
     ret
     
main endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; PROCEDURES
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

  IDispatch_Invoke proc ppv:DWORD,member:DWORD,path:DWORD,result:DWORD
            invoke IDispatch_GetIDsOfNames,ppv,member
            invoke SetParams,path
            push NULL
            push NULL
            push result
            push offset dpar
            push 1                    ; DISPATCH_METHOD
            push 409h
            push offset IID_NULL
            push DISPID
           
            mov  edx, ppv           
            mov  ecx, [edx]
            push edx
            call dword ptr  [ecx+24] ; offset of INVOKE
            FEEDBACK "IDispatch_Invoke"
            ret
  IDispatch_Invoke endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; WORKER SUBROUTINES
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
 
  IDispatch_GetIDsOfNames  proc  ppv:DWORD, mname:DWORD
            printf("GetIDsOfNames %s\n ",mname)
            push mname
            mov  eax,esp
            push offset DISPID       
            push 409h
            push 1
            push eax
            push offset IID_NULL
            mov  edx, ppv           
            mov  ecx, [edx]
            push edx
            call dword ptr  [ecx+20] ; offset of GetIDsOfNames
            pop  edx
            FEEDBACK "GetIDsOfNames"
            ret
  IDispatch_GetIDsOfNames endp
 
  SetParams proc wstr:DWORD
            mov     eax,wstr
            mov     varg.dw1,8       
            mov     varg.dw2,0
            mov     varg.dw3,eax
            mov     varg.dw4,0
       
            mov dpar.rgvarg, offset varg
            mov dpar.rgdispidNamedArgs,0
            mov dpar.cArgs,1
            mov dpar.cNamedArgs,0
            ret
  SetParams endp

end start
   


CONSOLE ASSEMBLE & LINK in QEDITOR

jj2007

Hi Vertograd,
On Win7-32, it crashes (with an existing zip file and an existing folder):

CLSIDFromProgID : SUCCESS
CoCreateInstance : SUCCESS
GetIDsOfNames NameSpace
GetIDsOfNames : SUCCESS
IDispatch_Invoke FAILED with hr 0x80020009
桔⁥灯牥瑡潩潣灭敬整⁤畳捣獥晳汵祬മ

Exiting ...


@nidud: Thanks, I will have a look asap.

GoneFishing

0x80020009 error code  is  DISP_E_EXCEPTION
It's working fine here 
Honestly I don't know what is wrong  :(
I use ML 6.14
LOCALE ID = 409

[EDIT]: Jochen, did you create that empty(?) zip file by built-in windows means?
            Could you try this in powershell with your paths ? (just to make sure that the problem is in my code)

jj2007

I used a zip file that matches the specs at http://www.codeproject.com/Tips/257193/Easily-zip-unzip-files-using-Windows-Shell
      '1) Lets create an empty Zip File .
        'The following data represents an empty zip file .

        Dim startBuffer() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, _
                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

I am off for a few days now, sorry. See you back on Saturday 8)

dedndave

when you right-click, New, you can create a new "Compressed Folder"
which we all know is a file
right-click/New can use templates (premade files that exist in user folders),
or it can use data from the registry

under my version of XP.....
[HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew]
"Data"=hex:50,4b,05,06,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

this format might be different for newer OS's

you can read the registry and either locate the template file or get the raw binary data to create a new (empty) ZIP file
that way, it will always be compatible with the shell functions you are about to use to put things in it

dedndave


dedndave

my guess is.....
ppv means "pointer to a pointer"
you want to pass the address of the pv variable, not the contents

or....
if the pointer is not filled when you create the interface (some sort of error creating interface)
you pass a 0, and it tries to access [00000000]

that would seem to be the case, as EDX = 0

GoneFishing

#25
...

sinsi

Using the Windows zip/unzip interface is probably a bad idea.
120MB zip file (140 uncompressed) takes less than 2 seconds to unzip with WinRAR but at least 20 seconds with Explorer.

jj2007

Quote from: sinsi on May 25, 2014, 05:44:10 PM
Using the Windows zip/unzip interface is probably a bad idea.
120MB zip file (140 uncompressed) takes less than 2 seconds to unzip with WinRAR but at least 20 seconds with Explorer.

Yes, it's lousy, and it would be limited to files compressed with the built-in zipper, which most likely nobody uses.

I found a MUCH better solution in the meantime, but it requires digging into the zip file specs - which is what I'll be doing the next few days ;-)

@vertograd: my condolencies for your drive, and thanks anyway for posting this very personal code :icon14:

GoneFishing

#28
Quote from: sinsi on May 25, 2014, 05:44:10 PM
Using the Windows zip/unzip interface is probably a bad idea.
120MB zip file (140 uncompressed) takes less than 2 seconds to unzip with WinRAR but at least 20 seconds with Explorer.

Maybe it's so when it comes to system-wide backups  ... and what if you need something like FILE HISTORY for your source code ? I suppose that no one of your actively developed MASM projects is SO big .
I'm just learning to use built-in features  ;)

@DAVE:
    I've tested it on Windows XP . It crashes with access violation at 401190  :t
The reason most likely is   in " m2m ppvFld, vres.dw3" line of code
Could you try this:
Quote
     invoke IDispatch_Invoke, ppvShA,uc$("NameSpace"),uc$("C:\masm32\projects\TST\NEW\NEW.ZIP"),addr vres
                             
                              printf("vres.dw3 = %08X\n",  vres.dw3)
                               m2m ppvFld, vres.dw3
                               printf("ppvFld = %08X\n",  ppvFld)

     ; Define the SOURCE file or folder in the third parameter "path"
     ; Note that NO WILDCARDS ALLOWED for zip operation
     ; Though "C:\folder\new.zip\*" seems to work for unzip operation

Now I'll continue work on enhancing the debug output    :t

[EDIT]: All is good with that line of code here . Going to find out where that pointer is lost ...






 

GoneFishing

#29
...