Starg Posted August 13, 2013 Share Posted August 13, 2013 First of all, please read this:>7z UDF WIP : Can 7z.dll be used in AutoIt? I'd like to start a new topic because dany seems to have given up the idea and has been off-line for about eight months. I've tried 7z.au3 and found a few bugs.GUID verification fails due to the bad regexGUIDs defined in the UDF are wrong. For example, $7Z_INTERFACE_IN_ARCHIVE should be { 23170F69-40C1-278A-0000-000600 600000}After correcting them, I succeeded in calling CreateObject. However, I can't find a way to use the objects created by CreateObject. Can anyone help me please? Link to comment Share on other sites More sharing options...
Artisan Posted August 13, 2013 Share Posted August 13, 2013 My Google-fu is not up to this task, it seems. The 7-Zip documentation is lacking in the extreme. The only maybe-sorta helpful thing I could find was this: http://www.codeproject.com/Articles/27148/C-NET-Interface-for-7-Zip-Archive-DLLs It doesn't elaborate on what the objects are or how to interact with them, but I didn't get into the details and I'm not a C# person. Maybe you'll have better luck with it. Link to comment Share on other sites More sharing options...
Starg Posted August 13, 2013 Author Share Posted August 13, 2013 Artisan, Thanks for providing me a link, but I've read that before. Link to comment Share on other sites More sharing options...
Starg Posted August 14, 2013 Author Share Posted August 14, 2013 I managed to create IInArchive instance, but I don't know how to call open() method. Link to comment Share on other sites More sharing options...
Starg Posted August 18, 2013 Author Share Posted August 18, 2013 (edited) Is IInArchive instance structure of function pointers? From 7-Zip IArchive.h#define INTERFACE_IInArchive(x) \ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ STDMETHOD(Close)() x; \ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; Edited August 18, 2013 by Starg Link to comment Share on other sites More sharing options...
trancexx Posted August 18, 2013 Share Posted August 18, 2013 (edited) So if you know that what exactly is the problem? expandcollapse popup#include <WinApi.au3> ; ZIP CLSID Global Const $sCLSID_Zip = "{23170f69-40c1-278a-1000-000110010000}" ; Interface IInArchive is defined like this: Global Const $sIID_IInArchive = "{23170F69-40C1-278A-0000-000600600000}" Global Const $tagIInArchive = _ "Open hresult(ptr;uint64*;ptr);" & _ "Close hresult();" & _ "GetNumberOfItems hresult(uint*);" & _ "GetProperty hresult(uint;int;variant*);" & _ "Extract hresult(uint;uint;int;ptr);" & _ "GetArchiveProperty hresult(int;variant*);" & _ "GetNumberOfProperties hresult(uint*);" & _ "GetPropertyInfo hresult(uint;bstr*;int*;int*);" & _ "GetNumberOfArchiveProperties hresult(uint*);" & _ "GetArchivePropertyInfo hresult(uint;bstr*;int*;int*);" Global Const $h7ZIP_DLL = DllOpen("C:\Program Files\7-Zip\7z.dll") ; for me it would be this location. You set yours. Local $oIInArchive = Create_7Z_Object($sCLSID_Zip, $sIID_IInArchive, $tagIInArchive) ;... Do whatever you want with this object here... ; The end ; An super cool function would be: Func Create_7Z_Object($sCLSID, $sIID, $sTag) ; Guids Local $tCLSID = _WinAPI_GUIDFromString($sCLSID) Local $tIID = _WinAPI_GUIDFromString($sIID) ; Actual call. $h7ZIP_DLL is DllOpen-ed 7z.dll Local $aCall = DllCall($h7ZIP_DLL, "long", "CreateObject", "struct*", $tCLSID, "struct*", $tIID, "ptr*", 0) ; Check for errors of some kind If @error Or $aCall[0] Then Return SetError(1, 0, 0) ; Make object out of pointer Return ObjCreateInterface($aCall[3], $sIID, $sTag) EndFunc What I can see as possible problem is IInStream interface implementation. The thing is you have to do it manually but considering you had issues with the above, somehow I think you won't be able to do it....Ask for help when you hit the wall. Edited August 18, 2013 by trancexx mLipok 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 3, 2014 Share Posted May 3, 2014 Hello trancexx, I ask for help Creating an object of IInArchive is really easy, thanks for pointing that out. But how to do the thing with the streams... I tried to wrap most of 7z.dll interface, but only the IInArchive thing seems working. But this one will need streams... I also don't know, if DllCallbackRegister() and friends would be needed? Could someone help me a bit with that... just some pointing out, not more expandcollapse popup; /TR ctime 2014-05-02 ; -> totale alpha.... ; vllt. wird es so etwas wie eine UDF für 7z.dll ... falls ich es hinbekomme, wirds auf jeden fall open source, gplv2 #include <Array.au3> #include <WinApi.au3> ; 7-Zip CLSID Handler {23170F69-40C1-278A-1000-000110xx0000} Global Const $sCLSID_Format7z = "{23170f69-40c1-278a-1000-000110070000}" ; 7z ; IProgress.h {23170F69-40C1-278A-0000-000000050000} Global Const $sIID_IProgress2 = "{23170F69-40C1-278A-0000-000000050000}" ; $sTagIProgress2 ; IFolderArchive.h {23170F69-40C1-278A-0000-000100xx0000} Global Const $sIID_IArchiveFolder = "{23170F69-40C1-278A-0000-000100050000}" ;x $sTagIArchiveFolder Global Const $sIID_IOutFolderArchive = "{23170F69-40C1-278A-0000-0001000a0000}" ;x $sTagIOutFolderArchive Global Const $sIID_IFolderArchiveUpdateCallback = "{23170F69-40C1-278A-0000-0001000b0000}" ;x $sTagIFolderArchiveUpdateCallback Global Const $sIID_IInFolderArchive = "{23170F69-40C1-278A-0000-0001000e0000}" ;x $sTagIInFolderArchive ; IStream.h {23170F69-40C1-278A-0000-000300xx0000} Global Const $sIID_ISequentialInStream = "{23170F69-40C1-278A-0000-000300010000}" ; $sTagISequentialInStream Global Const $sIID_ISequentialOutStream = "{23170F69-40C1-278A-0000-000300020000}" ; $sTagISequentialOutStream Global Const $sIID_IInStream = "{23170F69-40C1-278A-0000-000300030000}" ; $sTagIInStream Global Const $sIID_IOutStream = "{23170F69-40C1-278A-0000-000300040000}" ; $sTagIOutStream Global Const $sIID_IStreamGetSize = "{23170F69-40C1-278A-0000-000300060000}" ; $sTagIStreamGetSize Global Const $sIID_IOutStreamFlush = "{23170F69-40C1-278A-0000-000300070000}" ; $sTagIOutStreamFlush ; ICoder.h {23170F69-40C1-278A-0000-000400xx0000} ; ... ; IPassword.h {23170F69-40C1-278A-0000-000500xx0000} Global Const $sIID_ICryptoGetTextPassword = "{23170F69-40C1-278A-0000-000500100000}" ; $sTagICryptoGetTextPassword Global Const $sIID_ICryptoGetTextPassword2 = "{23170F69-40C1-278A-0000-000500200000}" ; $sTagICryptoGetTextPassword2 ; IArchive.h {23170F69-40C1-278A-0000-000600xx0000} Global Const $sIID_ISetProperties = "{23170F69-40C1-278A-0000-000600030000}" Global Const $sIID_IArchiveOpenCallback = "{23170F69-40C1-278A-0000-000600100000}" ; $sTagIArchiveOpenCallback Global Const $sIID_IArchiveExtractCallback = "{23170F69-40C1-278A-0000-000600200000}" ; $sTagIArchiveExtractCallback Global Const $sIID_IArchiveOpenVolumeCallback = "{23170F69-40C1-278A-0000-000600300000}" ; $sTagIArchiveOpenVolumeCallback Global Const $sIID_IInArchiveGetStream = "{23170F69-40C1-278A-0000-000600400000}" ; $sTagIInArchiveGetStream Global Const $sIID_IArchiveOpenSetSubArchiveName = "{23170F69-40C1-278A-0000-000600500000}" ; $sTagIArchiveOpenSetSubArchiveName Global Const $sIID_IInArchive = "{23170F69-40C1-278A-0000-000600600000}" ; $sTagIInArchive Global Const $sIID_IArchiveOpenSeq = "{23170F69-40C1-278A-0000-000600610000}" ; $sTagIArchiveOpenSeq Global Const $sIID_IArchiveUpdateCallback = "{23170F69-40C1-278A-0000-000600800000}" ; $sTagIArchiveUpdateCallback Global Const $sIID_IArchiveUpdateCallback2 = "{23170F69-40C1-278A-0000-000600820000}" ; $sTagIArchiveUpdateCallback2 Global Const $sIID_IOutArchive = "{23170F69-40C1-278A-0000-000600A00000}" ; $sTagIOutArchive ; IProgress.h $sIID_IProgress2 Global Const $sTagIProgress2 = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ ; IStream.h 0x01 $sIID_ISequentialInStream Global Const $sTagISequentialInStream = _ "Read hresult(ptr,uint,uint32*);" ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; #cs Out: if size != 0, return_value = S_OK and (*processedSize == 0), then there are no more bytes in stream. if (size > 0) && there are bytes in stream, this function must read at least 1 byte. This function is allowed to read less than number of remaining bytes in stream. You must call Read function in loop, if you need exact amount of data #ce ; IStream.h 0x02 $sIID_ISequentialOutStream Global Const $sTagISequentialOutStream = _ "Write hresult(ptr,uint,uint32*);" ; STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; #cs if (size > 0) this function must write at least 1 byte. This function is allowed to write less than "size". You must call Write function in loop, if you need to write exact amount of data #ce ; IStream.h 0x03 $sIID_IInStream Global Const $sTagIInStream = _ "Read hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; "Seek hresult(int64,uint,uint64*);" ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; ; IStream.h 0x04 $sIID_IOutStream Global Const $sTagIOutStream = _ "Write hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; "Seek hresult(int64,uint,uint64*);" & _ ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; "SetSize hresult(uint64);" ; STDMETHOD(SetSize)(UInt64 newSize) PURE; ; IStream.h 0x06 $sIID_IStreamGetSize Global Const $sTagIStreamGetSize = _ "GetSize hresult(uint64*);" ; STDMETHOD(GetSize)(UInt64 *size) PURE; ; IStream.h 0x07 $sIID_IOutStreamFlush Global Const $sTagIOutStreamFlush = _ "Flush hresult();" ; STDMETHOD(Flush)() PURE; ; IPassword.h 0x10 $sIID_ICryptoGetTextPassword Global Const $sTagICryptoGetTextPassword = _ "CryptoGetTextPassword hresult(str);" ; STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; ; IPassword.h 0x11 $sIID_ICryptoGetTextPassword2 Global Const $sTagICryptoGetTextPassword2 = _ "CryptoGetTextPassword2 hresult(int*,str);" ; STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; ; IArchive.h 0x10 $sIID_IArchiveOpenCallback Global Const $sTagIArchiveOpenCallback = _ "SetTotal hresult(uint64*,uint64*);" & _ ; STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ "SetCompleted hresult(uint64*,uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ ; IArchive.h 0x20 $sIID_IArchiveExtractCallback Global Const $sTagIArchiveExtractCallback = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetStream hresult(uint,ptr*,int);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ "PrepareOperation hresult(int);" & _ ; STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \ ; IArchive.h 0x30 $sIID_IArchiveOpenVolumeCallback Global Const $sTagIArchiveOpenVolumeCallback = _ "GetProperty hresult(int,variant*);" & _ ; STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(wstr,ptr*);" ; STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ ; IArchive.h 0x40 $sIID_IInArchiveGetStream Global Const $sTagIInArchiveGetStream = _ "GetStream hresult(uint,ptr*);" ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; ; IArchive.h 0x50 $sIID_IArchiveOpenSetSubArchiveName Global Const $sTagIArchiveOpenSetSubArchiveName = _ "SetSubArchiveName hresult(wstr);" ; STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; ; IArchive.h 0x60 $sIID_IInArchive Global Const $sTagIInArchive = _ "Open hresult(ptr;uint64*;ptr);" & _ ; STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ "Close hresult();" & _ ; STDMETHOD(Close)() x; \ "GetNumberOfItems hresult(uint*);" & _ ; STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ "GetProperty hresult(uint;int;variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "Extract hresult(uint;uint;int;ptr);" & _ ; STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ "GetArchiveProperty hresult(int;variant*);" & _ ; STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetNumberOfProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ "GetPropertyInfo hresult(uint;bstr*;int*;int*);" & _ ; STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ "GetNumberOfArchiveProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ "GetArchivePropertyInfo hresult(uint;bstr*;int*;int*);" ; STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; ; IArchive.h 0x61 $sIID_IArchiveOpenSeq Global Const $sTagIArchiveOpenSeq = "OpenSeq hresult();" ; STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; ; IArchive.h 0x80 $sIID_IArchiveUpdateCallback Global Const $sTagIArchiveUpdateCallback = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetUpdateItemInfo hresult(uint,int*,int*,int*);" & _ ; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) x; \ "GetProperty hresult(uint,int,variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(uint,ptr*);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ ; IArchive.h 0x82 $sIID_IArchiveUpdateCallback2 Global Const $sTagIArchiveUpdateCallback2 = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetUpdateItemInfo hresult(uint,int*,int*,uint*);" & _ ; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) x; \ "GetProperty hresult(uint,int,variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(uint,ptr*);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ "SetOperationResult hresult(int);" & _ ; STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ "GetVolumeSize hresult(uint,uint64*);" & _ ; STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ "GetVolumeStream hresult(uint,ptr*);" ; STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ ; IArchive.h 0xA0 $sIID_IOutArchive Global Const $sTagIOutArchive = _ "UpdateItems hresult(ptr;uint;ptr);" & _ ; STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ "GetFileTimeTypehresult(uint*);" ; STDMETHOD(GetFileTimeType)(UInt32 *type) x; ; XXX, später dann mal: 7za-x32.dll / 7za-x64.dll (von 7zip.org) Global Const $h7Z_DLL = DllOpen(@ScriptDir & "\7z.dll") ; je nach system erstmal per hand anpassen If $h7z_DLL = -1 Then MsgBox(0, "error", "fehler beim laden der dll") Exit EndIf #cs 7z.dll hat folgende Funktionen: UInt32 WINAPI CreateObject(const GUID *clsID, const GUID *interfaceID, void **outObject); UInt32 WINAPI GetNumberOfMethods(UInt32 *numMethods); UInt32 WINAPI GetNumberOfFormats(UInt32 *numFormats); UInt32 WINAPI GetMethodProperty(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty2(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI SetLargePageMode(); #ce ; todo: beschreibung Func _7z_GetNumberOfMethods() Local $aCall = DllCall($h7z_DLL, 'uint', 'GetNumberOfMethods', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfMethods()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfMethods ; todo: beschreibung Func _7z_GetNumberOfFormats() Local $aCall = DllCall($h7z_DLL, 'uint', 'GetNumberOfFormats', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfFormats()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfMethods Func Create_7Z_Object($sCLSID, $sIID, $sTag) Local $tCLSID = _WinAPI_GUIDFromString($sCLSID) Local $tIID = _WinAPI_GUIDFromString($sIID) ; CreateObject(const GUID *clsid, const GUID *iid, void **outObject) Local $aCall = DllCall($h7z_DLL, "long", "CreateObject", "struct*", $tCLSID, "struct*", $tIID, "ptr*", 0) ;_ArrayDisplay($aCall) MsgBox(0,"call:", "DllCall() " & _ @CRLF & "$sCLSID = " & $sCLSID & @CRLF & "sIID = " & $sIID & @CRLF & "$sTag = " & $sTag) If @error Or $aCall[0] Then MsgBox(0,"error", "DllCall() @ Create_7Z_Object nicht ok: " & @error & " @ " & $sIID) ;_ArrayDisplay($aCall) Exit EndIf Local $oObj = ObjCreateInterface($aCall[3], $sIID, $sTag) If IsObj($oObj) Then Return $oObj EndIf ; fatal error MsgBox(0,"Create_7Z_Object() fehlgeschlagen... obj=", IsObj($oObj)) Exit EndFunc ; das hier geht: ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfMethods()) ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfFormats()) ;Local $oIArchive = Create_7Z_Object($sCLSID_Format7z, $sIID_IInArchive, $sTagIInArchive) ; das geht nicht: ; Local $oTest = Create_7Z_Object($sCLSID_Format7z, $sIID_ISequentialOutStream, $sTagISequentialOutStream) ; wie muss ich hier das stream interface bereitstellen? ; muss ich so etwas wie AutoItObject 1.2.8.3 verwenden, oder geht das auch direkt via autoit? Link to comment Share on other sites More sharing options...
trancexx Posted May 3, 2014 Share Posted May 3, 2014 Yes, you need callbacks to create stream object(s). Find function ObjectFromTag - I posted it in one thread in examples, it does everything for you. Then create windows' stream (IStream, or even a bit extended ISequentialStream) with CreateStreamOnHglobal and use it wrapped inside your stream object methods. It may sound complicated, but it's very simple task, you'll see. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 3, 2014 Share Posted May 3, 2014 Thank you, for the very fast reply. I will try my best and give some information, when I got it Link to comment Share on other sites More sharing options...
trancexx Posted May 3, 2014 Share Posted May 3, 2014 Hah! Did you see that. I started writing the post as soon as you posted yours. If I'd be faster writer you would have my reply in the same minute. Hell, even before you posted the question. ...but I'm slow, don't know English that good, have a bit longer nails then I should for this sport, and was watching some porn thingy in another tab. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 4, 2014 Share Posted May 4, 2014 Hm, I don't get I found these functions on MSDN, I think I have to use them via dllcall... but I don't get it managed with the object stuff of this DLL. It is a COM like interface, but the author says, it is not Standard... HRESULT SHCreateStreamOnFile( _In_ LPCTSTR pszFile, _In_ DWORD grfMode, _Out_ IStream **ppstm ); WINOLEAPI GetHGlobalFromStream( _In_ IStream *pstm, _Out_ HGLOBAL *phglobal ); WINOLEAPI CreateStreamOnHGlobal( _In_ HGLOBAL hGlobal, _In_ BOOL fDeleteOnRelease, _Out_ LPSTREAM *ppstm ); And with for ObjectFromTag() function, should I do it that way ? expandcollapse popupFunc ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface) Local Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*); AddRef dword(); Release dword();" ; Adding IUnknown methods $tagInterface = $tagIUnknown & $tagInterface Local Const $PTR_SIZE = DllStructGetSize(DllStructCreate("ptr")) ; Below line really simple even though it looks super complex. It's just written weird to fit one line, not to steal your eyes Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace($tagInterface, "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "variant*", "ptr"), "hresult", "long"), "bstr", "ptr"), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams ; Allocation. Read http://msdn.microsoft.com/en-us/library/ms810466.aspx to see why like this (object + methods): $tInterface = DllStructCreate("ptr[" & $iUbound + 1 & "]") If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams DllStructSetData($tInterface, 1, DllCallbackGetPtr(DllCallbackRegister($sMethod, $sRet, $sParams)), $i + 2) ; Freeing is left to AutoIt. Next DllStructSetData($tInterface, 1, DllStructGetPtr($tInterface) + $PTR_SIZE) ; Interface method pointers are actually pointer size away ConsoleWrite("huhu@obj") Return ObjCreateInterface(DllStructGetPtr($tInterface), "", $tagInterface, False) ; and first pointer is object pointer that's wrapped EndFunc ; Global Const $sIID_IArchiveOpenCallback = "{23170F69-40C1-278A-0000-000600100000}" ; $sTagIArchiveOpenCallback Local $thIArchiveOpenCallback $o = ObjectFromTag("IArchiveOpenCallback_", $sIID_IArchiveOpenCallback, $thIArchiveOpenCallback) ; Handler methods. "_MyHandler_" is the specified prefix: Func IArchiveOpenCallback_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) ConsoleWrite("@query") Switch _WinAPI_StringFromGUID($pRIID) Case $sIID_IArchiveOpenCallback Case Else ConsoleWrite("error @ ..." & @CRLF) Return 0x80004002 ; E_NOINTERFACE EndSwitch DllStructSetData($tStruct, 1, $pSelf) Return 0 ; S_OK EndFunc Func IArchiveOpenCallback_AddRef($pSelf) #forceref $pSelf ConsoleWrite("@addref") Return 1 EndFunc Func IArchiveOpenCallback_Release($pSelf) #forceref $pSelf ConsoleWrite("@release") Return 1 EndFunc Func IArchiveOpenCallback_SetTotal(ByRef $iFiles, ByRef $iBytes) ConsoleWrite("IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) EndFunc Func IArchiveOpenCallback_SetCompleted(ByRef $iFiles, ByRef $iBytes) ConsoleWrite("IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) EndFunc I am coding C for a very long time, but Autoit is new for me... but I am interested in it. So sorry for my newbie questions... and I am again going to take lunch. So I am away for some Minutes. But then, I am back on the notebook and could maybe answer as fast as you Link to comment Share on other sites More sharing options...
trancexx Posted May 4, 2014 Share Posted May 4, 2014 The most correct ObjectFromTag is at What yo should do is first create IInArchive object with Create_7Z_Object (already posted), then you create stream on archive file (go with SHCreateStreamOnFile for now, since you found it on msdn even though it will prove slower later). Then create IInStream with ObjectFromTag which is similar task as IArchiveOpenCallback you already did, only you wrapp IStream you got with SHCreateStreamOnFile. Then load archive using Open method of IInArchive. Then post your code if something wouldn't work as it should. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 4, 2014 Share Posted May 4, 2014 Yes, I got the fresher code of ObjectFromTag() and also DeleteObjectFromTag() ... and made it an include file. This is how it looks like: expandcollapse popup; Copied and slightly modified by LarsJ (for print methods) from this post by trancexx: ; http://www.autoitscript.com/forum/topic/153520-iuiautomation-ms-framework-automate-chrome-ff-ie/page*#entry1143566 #include <WinApi.au3> Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" ; Global $tIShellBrowser, $oIShellBrowser ; Global Const $sIID_IShellBrowser = "{000214E2-0000-0000-C000-000000000046}" ; Global Const $dtag_IShellBrowser = "GetWindow hresult(hwnd*);" & "..." ; $oIShellBrowser = ObjectFromTag("oIShellBrowser_", $dtag_IShellBrowser, $tIShellBrowser, Default, $sIID_IShellBrowser) ; If Not IsObj($oIShellBrowser) Then Return Func StringFromGUID( $pGUID ) Local $aResult = DllCall( "ole32.dll", "int", "StringFromGUID2", "struct*", $pGUID, "wstr", "", "int", 40 ) If @error Then Return SetError( @error, @extended, "" ) Return SetExtended( $aResult[0], $aResult[2] ) EndFunc ; Copied and slightly modified (print methods) from this post by trancexx: ; http://www.autoitscript.com/forum/topic/153520-iuiautomation-ms-framework-automate-chrome-ff-ie/page*#entry1143566 Func ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr"), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart If $fPrint Then Local $iPar = StringInStr( $sTagPart, ";", 2 ), $t If $iPar Then $t = "Ret: " & StringLeft( $sTagPart, $iPar - 1 ) & " " & _ "Par: " & StringRight( $sTagPart, StringLen( $sTagPart ) - $iPar ) Else $t = "Ret: " & $sTagPart EndIf Local $s = "Func " & $sMethod & _ "( $pSelf ) ; " & $t & @CRLF & _ "EndFunc" & @CRLF ConsoleWrite( $s ) EndIf $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) ConsoleWrite(@error & @CRLF & @CRLF) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc Func DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc Now the new coding stuff... object oriented programming is not as easy, as all other say... in C there are just functions, some structures... and of cause my lovely pointers... but OO .. So then, I get some closer to the streaming thing, hopefully expandcollapse popup; /TR ctime 2014-05-02 ; vllt. wird es so etwas wie eine UDF für 7z.dll ... falls ich es hinbekomme, wirds auf jeden fall open source, gplv2 ; -> pre pre pre pre alpha.... #include <Array.au3> #include <WinApi.au3> #include "ObjectFromTag.au3" ; 7-Zip CLSID Handler {23170F69-40C1-278A-1000-000110xx0000} Global Const $sCLSID_Format7z = "{23170f69-40c1-278a-1000-000110070000}" ; 7z ; IProgress.h {23170F69-40C1-278A-0000-000000050000} Global Const $sIID_IProgress2 = "{23170F69-40C1-278A-0000-000000050000}" ; $sTagIProgress2 ; IFolderArchive.h {23170F69-40C1-278A-0000-000100xx0000} Global Const $sIID_IArchiveFolder = "{23170F69-40C1-278A-0000-000100050000}" ;x $sTagIArchiveFolder Global Const $sIID_IOutFolderArchive = "{23170F69-40C1-278A-0000-0001000a0000}" ;x $sTagIOutFolderArchive Global Const $sIID_IFolderArchiveUpdateCallback = "{23170F69-40C1-278A-0000-0001000b0000}" ;x $sTagIFolderArchiveUpdateCallback Global Const $sIID_IInFolderArchive = "{23170F69-40C1-278A-0000-0001000e0000}" ;x $sTagIInFolderArchive ; IStream.h {23170F69-40C1-278A-0000-000300xx0000} Global Const $sIID_ISequentialInStream = "{23170F69-40C1-278A-0000-000300010000}" ; $sTagISequentialInStream Global Const $sIID_ISequentialOutStream = "{23170F69-40C1-278A-0000-000300020000}" ; $sTagISequentialOutStream Global Const $sIID_IInStream = "{23170F69-40C1-278A-0000-000300030000}" ; $sTagIInStream Global Const $sIID_IOutStream = "{23170F69-40C1-278A-0000-000300040000}" ; $sTagIOutStream Global Const $sIID_IStreamGetSize = "{23170F69-40C1-278A-0000-000300060000}" ; $sTagIStreamGetSize Global Const $sIID_IOutStreamFlush = "{23170F69-40C1-278A-0000-000300070000}" ; $sTagIOutStreamFlush ; ICoder.h {23170F69-40C1-278A-0000-000400xx0000} ; ... ; IPassword.h {23170F69-40C1-278A-0000-000500xx0000} Global Const $sIID_ICryptoGetTextPassword = "{23170F69-40C1-278A-0000-000500100000}" ; $sTagICryptoGetTextPassword Global Const $sIID_ICryptoGetTextPassword2 = "{23170F69-40C1-278A-0000-000500200000}" ; $sTagICryptoGetTextPassword2 ; IArchive.h {23170F69-40C1-278A-0000-000600xx0000} Global Const $sIID_ISetProperties = "{23170F69-40C1-278A-0000-000600030000}" Global Const $sIID_IArchiveOpenCallback = "{23170F69-40C1-278A-0000-000600100000}" ; $sTagIArchiveOpenCallback Global Const $sIID_IArchiveExtractCallback = "{23170F69-40C1-278A-0000-000600200000}" ; $sTagIArchiveExtractCallback Global Const $sIID_IArchiveOpenVolumeCallback = "{23170F69-40C1-278A-0000-000600300000}" ; $sTagIArchiveOpenVolumeCallback Global Const $sIID_IInArchiveGetStream = "{23170F69-40C1-278A-0000-000600400000}" ; $sTagIInArchiveGetStream Global Const $sIID_IArchiveOpenSetSubArchiveName = "{23170F69-40C1-278A-0000-000600500000}" ; $sTagIArchiveOpenSetSubArchiveName Global Const $sIID_IInArchive = "{23170F69-40C1-278A-0000-000600600000}" ; $sTagIInArchive Global Const $sIID_IArchiveOpenSeq = "{23170F69-40C1-278A-0000-000600610000}" ; $sTagIArchiveOpenSeq Global Const $sIID_IArchiveUpdateCallback = "{23170F69-40C1-278A-0000-000600800000}" ; $sTagIArchiveUpdateCallback Global Const $sIID_IArchiveUpdateCallback2 = "{23170F69-40C1-278A-0000-000600820000}" ; $sTagIArchiveUpdateCallback2 Global Const $sIID_IOutArchive = "{23170F69-40C1-278A-0000-000600A00000}" ; $sTagIOutArchive ; IProgress.h $sIID_IProgress2 Global Const $sTagIProgress2 = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ ; IStream.h 0x01 $sIID_ISequentialInStream Global Const $sTagISequentialInStream = _ "Read hresult(ptr,uint,uint32*);" ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; #cs Out: if size != 0, return_value = S_OK and (*processedSize == 0), then there are no more bytes in stream. if (size > 0) && there are bytes in stream, this function must read at least 1 byte. This function is allowed to read less than number of remaining bytes in stream. You must call Read function in loop, if you need exact amount of data #ce ; IStream.h 0x02 $sIID_ISequentialOutStream Global Const $sTagISequentialOutStream = _ "Write hresult(ptr,uint,uint32*);" ; STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; #cs if (size > 0) this function must write at least 1 byte. This function is allowed to write less than "size". You must call Write function in loop, if you need to write exact amount of data #ce ; IStream.h 0x03 $sIID_IInStream Global Const $sTagIInStream = _ "Read hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; "Seek hresult(int64,uint,uint64*);" ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; ; IStream.h 0x04 $sIID_IOutStream Global Const $sTagIOutStream = _ "Write hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; "Seek hresult(int64,uint,uint64*);" & _ ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; "SetSize hresult(uint64);" ; STDMETHOD(SetSize)(UInt64 newSize) PURE; ; IStream.h 0x06 $sIID_IStreamGetSize Global Const $sTagIStreamGetSize = _ "GetSize hresult(uint64*);" ; STDMETHOD(GetSize)(UInt64 *size) PURE; ; IStream.h 0x07 $sIID_IOutStreamFlush Global Const $sTagIOutStreamFlush = _ "Flush hresult();" ; STDMETHOD(Flush)() PURE; ; IPassword.h 0x10 $sIID_ICryptoGetTextPassword Global Const $sTagICryptoGetTextPassword = _ "CryptoGetTextPassword hresult(str);" ; STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; ; IPassword.h 0x11 $sIID_ICryptoGetTextPassword2 Global Const $sTagICryptoGetTextPassword2 = _ "CryptoGetTextPassword2 hresult(int*,str);" ; STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; ; IArchive.h 0x10 $sIID_IArchiveOpenCallback Global Const $sTagIArchiveOpenCallback = _ "SetTotal hresult(uint64*,uint64*);" & _ ; STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ "SetCompleted hresult(uint64*,uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ ; IArchive.h 0x20 $sIID_IArchiveExtractCallback Global Const $sTagIArchiveExtractCallback = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetStream hresult(uint,ptr*,int);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ "PrepareOperation hresult(int);" & _ ; STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \ ; IArchive.h 0x30 $sIID_IArchiveOpenVolumeCallback Global Const $sTagIArchiveOpenVolumeCallback = _ "GetProperty hresult(int,variant*);" & _ ; STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(wstr,ptr*);" ; STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ ; IArchive.h 0x40 $sIID_IInArchiveGetStream Global Const $sTagIInArchiveGetStream = _ "GetStream hresult(uint,ptr*);" ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; ; IArchive.h 0x50 $sIID_IArchiveOpenSetSubArchiveName Global Const $sTagIArchiveOpenSetSubArchiveName = _ "SetSubArchiveName hresult(wstr);" ; STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; ; IArchive.h 0x60 $sIID_IInArchive Global Const $sTagIInArchive = _ "Open hresult(ptr;uint64*;ptr);" & _ ; STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ "Close hresult();" & _ ; STDMETHOD(Close)() x; \ "GetNumberOfItems hresult(uint*);" & _ ; STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ "GetProperty hresult(uint;int;variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "Extract hresult(uint;uint;int;ptr);" & _ ; STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ "GetArchiveProperty hresult(int;variant*);" & _ ; STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetNumberOfProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ "GetPropertyInfo hresult(uint;bstr*;int*;int*);" & _ ; STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ "GetNumberOfArchiveProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ "GetArchivePropertyInfo hresult(uint;bstr*;int*;int*);" ; STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; ; IArchive.h 0x61 $sIID_IArchiveOpenSeq Global Const $sTagIArchiveOpenSeq = "OpenSeq hresult();" ; STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; ; IArchive.h 0x80 $sIID_IArchiveUpdateCallback Global Const $sTagIArchiveUpdateCallback = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetUpdateItemInfo hresult(uint,int*,int*,int*);" & _ ; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) x; \ "GetProperty hresult(uint,int,variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(uint,ptr*);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ ; IArchive.h 0x82 $sIID_IArchiveUpdateCallback2 Global Const $sTagIArchiveUpdateCallback2 = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" & _ ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ "GetUpdateItemInfo hresult(uint,int*,int*,uint*);" & _ ; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) x; \ "GetProperty hresult(uint,int,variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(uint,ptr*);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ "SetOperationResult hresult(int);" & _ ; STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ "GetVolumeSize hresult(uint,uint64*);" & _ ; STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ "GetVolumeStream hresult(uint,ptr*);" ; STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ ; IArchive.h 0xA0 $sIID_IOutArchive Global Const $sTagIOutArchive = _ "UpdateItems hresult(ptr;uint;ptr);" & _ ; STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ "GetFileTimeTypehresult(uint*);" ; STDMETHOD(GetFileTimeType)(UInt32 *type) x; ; XXX, später dann mal: 7za-x32.dll / 7za-x64.dll (von 7zip.org) Global Const $h7Z_DLL = DllOpen(@ScriptDir & "\7z.dll") ; je nach system erstmal per hand anpassen If $h7z_DLL = -1 Then MsgBox(0, "error", "fehler beim laden der dll") Exit EndIf #cs functions of 7z.dll: UInt32 WINAPI CreateObject(const GUID *clsID, const GUID *interfaceID, void **outObject); UInt32 WINAPI GetNumberOfMethods(UInt32 *numMethods); UInt32 WINAPI GetNumberOfFormats(UInt32 *numFormats); UInt32 WINAPI GetMethodProperty(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty2(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI SetLargePageMode(); #ce ; todo: beschreibung Func _7z_GetNumberOfMethods() Local $aCall = DllCall($h7z_DLL, 'uint', 'GetNumberOfMethods', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfMethods()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfMethods ; todo: beschreibung Func _7z_GetNumberOfFormats() Local $aCall = DllCall($h7z_DLL, 'uint', 'GetNumberOfFormats', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfFormats()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfMethods ; --------------------------------------------------------------------------------------------------------------------------------- Func Create_7Z_Object($sCLSID, $sIID, $sTag) Local $tCLSID = _WinAPI_GUIDFromString($sCLSID) Local $tIID = _WinAPI_GUIDFromString($sIID) ; CreateObject(const GUID *clsid, const GUID *iid, void **outObject) Local $aCall = DllCall($h7z_DLL, "long", "CreateObject", "struct*", $tCLSID, "struct*", $tIID, "ptr*", 0) ;_ArrayDisplay($aCall) ;MsgBox(0,"call:", "DllCall() " & @CRLF & "$sCLSID = " & $sCLSID & @CRLF & "sIID = " & $sIID & @CRLF & "$sTag = " & $sTag) If @error Or $aCall[0] Then MsgBox(0,"error", "DllCall() @ Create_7Z_Object nicht ok: " & @error & " @ " & $sIID) ;_ArrayDisplay($aCall) Exit EndIf Local $oObj = ObjCreateInterface($aCall[3], $sIID, $sTag) If IsObj($oObj) Then Return $oObj EndIf ; fatal error MsgBox(0,"Create_7Z_Object() fehlgeschlagen... obj=", IsObj($oObj)) Exit EndFunc ; --------------------------------------------------------------------------------------------------------------------------------- ; 1) What yo should do is first create IInArchive object with Create_7Z_Object (already posted) Local $oIInArchive = Create_7Z_Object($sCLSID_Format7z, $sIID_IInArchive, $sTagIInArchive) ;Local $iItems = 0 ;$iRet = $oIArchive.GetNumberOfItems($iItems) ;MsgBox(0,"","x=" & $iItems & " r=" & $iRet) ; 2) then you create stream on archive file (go with SHCreateStreamOnFile for now, since you found it on msdn even though it will prove slower later) ; STGM_READWRITE 0x00000002L ; STGM_CREATE 0x00001000L Func _WinAPI_SHCreateStreamOnFile($sFile) Local $iGrfMode = BitOR(0x00000002,0x00001000) Local $aCall = DllCall('shlwapi.dll', 'long', 'SHCreateStreamOnFile', 'str', $sFile, 'uint', $iGrfMode, 'ptr*', 0) If @error Or $aCall[0] <> 0 Then ConsoleWrite("error @ _WinAPI_SHCreateStreamOnFile" & @CRLF) Exit EndIf ;_ArrayDisplay($aCall) Return $aCall[3] EndFunc ;==>_WinAPI_SHCreateStreamOnFile ; lala.7z is a small testfile (created with 7zip) $stream1 = _WinAPI_SHCreateStreamOnFile("lala.7z") ; 3) Then create IInStream with ObjectFromTag which is similar task as IArchiveOpenCallback you already did, only you wrapp IStream you got with SHCreateStreamOnFile. Local $tIInStream ; interface ;Func ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default Local $oIInStream = ObjectFromTag("IInStream_", $sTagIInStream, $tIInStream, True, Default, $sIID_IInStream) ;DeleteObjectFromTag($tIInStream) ; IInStream interface Func IInStream_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) ConsoleWrite("@IInStream_QueryInterface" & @CRLF) Switch _WinAPI_StringFromGUID($pRIID) Case $sIID_IInStream Case Else ConsoleWrite("error @ IInStream_QueryInterface" & @CRLF) Return 0x80004002 ; E_NOINTERFACE EndSwitch DllStructSetData($tStruct, 1, $pSelf) ConsoleWrite("@IInStream_QueryInterface -> return S_OK" & @CRLF) Return 0 ; S_OK EndFunc Func IInStream_AddRef($pSelf) #forceref $pSelf ConsoleWrite("@IInStream_AddRef" & @CRLF) Return 1 EndFunc Func IInStream_Release($pSelf) #forceref $pSelf ConsoleWrite("@IInStream_Release" & @CRLF) Return 1 EndFunc ; "Read hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; Func IInStream_Read(ByRef $pData, $iSize, ByRef $iProcessedSize) ConsoleWrite("@IInStream_Read: $iSize:" & $iSize & " $iProcessedSize:" & $iProcessedSize & @CRLF) ; $stream1 ?? EndFunc ; "Seek hresult(int64,uint,uint64*);" ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; Func IInStream_Seek($iOffset, $iSeekOrigin, ByRef $iNewPosition) ConsoleWrite("@IInStream_Seek: $iSeekOrigin:" & $iSeekOrigin & " $iNewPosition:" & $iNewPosition & @CRLF) ; $stream1 ?? EndFunc Local $tIArchiveOpenCallback Local $oIArchiveOpenCallback = ObjectFromTag("IInStream_", $sTagIArchiveOpenCallback, $tIArchiveOpenCallback, True, Default, $sIID_IArchiveOpenCallback) Func IArchiveOpenCallback_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) ConsoleWrite("@IArchiveOpenCallback_QueryInterface" & @CRLF) Switch _WinAPI_StringFromGUID($pRIID) Case $sIID_IArchiveOpenCallback Case Else Return 0x80004002 ; E_NOINTERFACE EndSwitch DllStructSetData($tStruct, 1, $pSelf) ConsoleWrite("@IArchiveOpenCallback_QueryInterface = OK" & @CRLF) Return 0 ; S_OK EndFunc Func IArchiveOpenCallback_AddRef($pSelf) #forceref $pSelf ConsoleWrite("@IArchiveOpenCallback_AddRef" & @CRLF) Return 1 EndFunc Func IArchiveOpenCallback_Release($pSelf) #forceref $pSelf ConsoleWrite("@IArchiveOpenCallback_Release" & @CRLF) Return 1 EndFunc Func IArchiveOpenCallback_SetTotal(ByRef $iFiles, ByRef $iBytes) ConsoleWrite("@IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) EndFunc Func IArchiveOpenCallback_SetCompleted(ByRef $iFiles, ByRef $iBytes) ConsoleWrite("@IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) EndFunc ; 4) Then load archive using Open method of IInArchive. $i = $oIInArchive.Open($stream1, 4*1024*1024, $oIArchiveOpenCallback) ; this? ;$i = $oIInArchive.Open($oIInStream, 4*1024*1024, $oIArchiveOpenCallback) ; or this? MsgBox(0,"i?", "i=" & $i & @CRLF) ;"Open hresult(ptr;uint64*;ptr);" & _ ; STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ ;"Close hresult();" & _ ; STDMETHOD(Close)() x; \ ; 5) Then post your code if something wouldn't work as it should. ; --------------------------------------------------------------------------------------------------------------------------------- #cs The most correct ObjectFromTag is at http://www.autoitscript.com/forum/topic/153520-iuiautomation-ms-framework-automate-chrome-ff-ie/page-7#entry1143993 HRESULT SHCreateStreamOnFile( _In_ LPCTSTR pszFile, _In_ DWORD grfMode, _Out_ IStream **ppstm ); WINOLEAPI GetHGlobalFromStream( _In_ IStream *pstm, _Out_ HGLOBAL *phglobal ); WINOLEAPI CreateStreamOnHGlobal( _In_ HGLOBAL hGlobal, _In_ BOOL fDeleteOnRelease, _Out_ LPSTREAM *ppstm ); #ce ; this is IO: ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfMethods()) ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfFormats()) Seems this the right way? The output of the script is currently this: Func IInStream_QueryInterface( $pSelf ) ; Ret: long Par: ptr;ptr EndFunc 0 Func IInStream_AddRef( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_Release( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_Read( $pSelf ) ; Ret: long Par: ptr,uint,ptr EndFunc 3 Func IInStream_Seek( $pSelf ) ; Ret: long Par: int64,uint,ptr EndFunc 3 @IInStream_QueryInterface @IInStream_QueryInterface -> return S_OK @IInStream_Release Func IInStream_QueryInterface( $pSelf ) ; Ret: long Par: ptr;ptr EndFunc 0 Func IInStream_AddRef( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_Release( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_SetTotal( $pSelf ) ; Ret: long Par: ptr,ptr EndFunc 3 Func IInStream_SetCompleted( $pSelf ) ; Ret: long Par: ptr,ptr EndFunc 3 @IInStream_QueryInterface error @ IInStream_QueryInterface Link to comment Share on other sites More sharing options...
trancexx Posted May 4, 2014 Share Posted May 4, 2014 (edited) You have errors reported for your IInStream methods. That's because you use Byref keywords. Remove them from methods definitions. Then add real code inside them. Inside Read method call IStream.Read, inside Write call IStream.Write, etc. To do that your _WinAPI_SHCreateStreamOnFile misses ObjCreateInterface call on the result ($aCall[3]). Edited May 4, 2014 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 4, 2014 Share Posted May 4, 2014 Ah, okay, I will doit... Thank you a lot. Link to comment Share on other sites More sharing options...
milky Posted May 4, 2014 Share Posted May 4, 2014 Hm... I get now an issue with ObjCreateInterface() @ _WinAPI_SHCreateStreamOnFile() this code does not work: ; 2) then you create stream on archive file (go with SHCreateStreamOnFile for now, since you found it on msdn even though it will prove slower later) ; STGM_READWRITE 0x00000002L Func _WinAPI_SHCreateStreamOnFile($sFile) Local $iGrfMode = 0x00000002 Local $aCall = DllCall('shlwapi.dll', 'long', 'SHCreateStreamOnFile', 'str', $sFile, 'uint', $iGrfMode, 'ptr*', 0) If @error Or $aCall[0] <> 0 Then ConsoleWrite("error @ _WinAPI_SHCreateStreamOnFile" & @CRLF) Exit EndIf Local $oObj = ObjCreateInterface($aCall[3], $sIID_IInStream, $sTagIInStream) If IsObj($oObj) Then Return $oObj EndIf MsgBox(0,"error", "_WinAPI_SHCreateStreamOnFile() != obj") Exit EndFunc ;==>_WinAPI_SHCreateStreamOnFile It ends with the error MsgBox() ... but I don't know why? Link to comment Share on other sites More sharing options...
trancexx Posted May 4, 2014 Share Posted May 4, 2014 (edited) SHCreateStreamOnFile creates IStream. IInStream is different stream which is why autor of 7z said it's not "standard". That's why you need ObjectFromTag - to make IInStream out of IStream. Edited May 4, 2014 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 4, 2014 Share Posted May 4, 2014 (edited) I took now these: ;=============================================================================== #interface "ISequentialStream" Global Const $sIID_ISequentialStream = "{0c733a30-2a1c-11ce-ade5-00aa0044773d}" Global Const $tagISequentialStream = "Read hresult(struct*;dword;dword*);" & _ "Write hresult(struct*;dword;dword*);" #interface "IStream" Global Const $sIID_IStream = "{0000000c-0000-0000-C000-000000000046}" Global Const $tagIStream = $tagISequentialStream & _ "Seek hresult(int64;dword;uint64*);" & _ "SetSize hresult(uint64);" & _ "CopyTo hresult(ptr;uint64;uint64*;uint64*);" & _ "Commit hresult(dword);" & _ "Revert hresult();" & _ "LockRegion hresult(uint64;uint64;dword);" & _ "UnlockRegion hresult(uint64;uint64;dword);" & _ "Stat hresult(struct*;dword);" & _ "Clone hresult(ptr*);" I found them in this thread, which was also done by you: '?do=embed' frameborder='0' data-embedContent>> Hm... I am looking at it... maybe I get it ... just in some minutes ... .... No, I don't know, what is wrong here. I will take a new run on it tomorrow Edited May 4, 2014 by milky Link to comment Share on other sites More sharing options...
trancexx Posted May 5, 2014 Share Posted May 5, 2014 It should be: Local $oObj = ObjCreateInterface($aCall[3], $sIID_IStream, $tagIStream) and you have IStream. Then inside IInStream methods you call IStream methods passing (translating arguments). ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
milky Posted May 7, 2014 Share Posted May 7, 2014 (edited) I had again some time for testing and trying. Here is my current (not working) state of the script: expandcollapse popup; /TR ctime 2014-05-02 ; vllt. wird es so etwas wie eine UDF für 7z.dll ... falls ich es hinbekomme, wirds auf jeden fall open source, gplv2 ; -> pre pre pre pre alpha.... #include <Array.au3> #include <WinApi.au3> #include <WinAPICom.au3> #include <GDIPlus.au3> #include <Memory.au3> #include <GUIConstantsEx.au3> #include "ObjectFromTag.au3" ; 7-Zip CLSID Handler {23170F69-40C1-278A-1000-000110xx0000} Global Const $sCLSID_Format7z = "{23170f69-40c1-278a-1000-000110070000}" ; 7-Zip Handler ; IProgress.h ;=============================================================================== #interface "IProgress2" Global Const $sIID_IProgress2 = "{23170F69-40C1-278A-0000-000000050000}" ; IUnknown Global Const $dtag_IProgress2 = _ "SetTotal hresult(uint64);" & _ ; STDMETHOD(SetTotal)(UInt64 total) x; \ "SetCompleted hresult(uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ ; IFolderArchive.h ;=============================================================================== #interface "IArchiveFolder" Global Const $sIID_IArchiveFolder = "{23170F69-40C1-278A-0000-000100050000}" ; IUnknown #cs #define INTERFACE_IInFolderArchive(x) \ STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \ STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \ STDMETHOD(Close)() x; \ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) x; \ STDMETHOD(Extract)(NExtract::NPathMode::EEnum pathMode, NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \ #ce ;=============================================================================== #interface "IOutFolderArchive" Global Const $sIID_IOutFolderArchive = "{23170F69-40C1-278A-0000-0001000a0000}" ; IUnknown #cs #define INTERFACE_IOutFolderArchive(x) \ STDMETHOD(SetFolder)(IFolderFolder *folder) x; \ STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UInt32 numNames) x; \ STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \ STDMETHOD(DoOperation)(CCodecs *codecs, int index, ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback) x; \ STDMETHOD(DoOperation2)(ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback) x; \ #ce ;=============================================================================== #interface "IFolderArchiveUpdateCallback" Global Const $sIID_IFolderArchiveUpdateCallback = "{23170F69-40C1-278A-0000-0001000b0000}" ; IProgress #cs #define INTERFACE_IFolderArchiveUpdateCallback(x) \ STDMETHOD(CompressOperation)(const wchar_t *name) x; \ STDMETHOD(DeleteOperation)(const wchar_t *name) x; \ STDMETHOD(OperationResult)(Int32 operationResult) x; \ STDMETHOD(UpdateErrorMessage)(const wchar_t *message) x; \ STDMETHOD(SetNumFiles)(UInt64 numFiles) x; \ #ce ;=============================================================================== #interface "IInFolderArchive" Global Const $sIID_IInFolderArchive = "{23170F69-40C1-278A-0000-0001000e0000}" ; IUnknown #cs #define INTERFACE_IInFolderArchive(x) \ STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \ STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \ STDMETHOD(Close)() x; \ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) x; \ STDMETHOD(Extract)(NExtract::NPathMode::EEnum pathMode, \ NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \ Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \ #ce ; IStream.h ;=============================================================================== #interface "ISequentialInStream" Global Const $sIID_ISequentialInStream = "{23170F69-40C1-278A-0000-000300010000}" ; IUnknown Global Const $dtag_ISequentialInStream = "Read hresult(ptr,uint,uint32*);" #cs STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; Out: if size != 0, return_value = S_OK and (*processedSize == 0), then there are no more bytes in stream. if (size > 0) && there are bytes in stream, this function must read at least 1 byte. This function is allowed to read less than number of remaining bytes in stream. You must call Read function in loop, if you need exact amount of data #ce ;=============================================================================== #interface "ISequentialOutStream" Global Const $sIID_ISequentialOutStream = "{23170F69-40C1-278A-0000-000300020000}" ; IUnknown Global Const $dtag_ISequentialOutStream = "Write hresult(ptr,uint,uint32*);" #cs STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; if (size > 0) this function must write at least 1 byte. This function is allowed to write less than "size". You must call Write function in loop, if you need to write exact amount of data #ce ;=============================================================================== #interface "IInStream" Global Const $sIID_IInStream = "{23170F69-40C1-278A-0000-000300030000}" ; ISequentialInStream Global Const $dtag_IInStream = _ $dtag_ISequentialInStream & _ "Seek hresult(int64,uint,uint64*);" ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; ;=============================================================================== #interface "IOutStream" Global Const $sIID_IOutStream = "{23170F69-40C1-278A-0000-000300040000}" ; ISequentialOutStream Global Const $sdtag_IOutStream = _ $dtag_ISequentialOutStream & _ "Seek hresult(int64,uint,uint64*);" & _ ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; "SetSize hresult(uint64);" ; STDMETHOD(SetSize)(UInt64 newSize) PURE; ;=============================================================================== #interface "IStreamGetSize" Global Const $sIID_IStreamGetSize = "{23170F69-40C1-278A-0000-000300060000}" ; IUnknown Global Const $dtag_IStreamGetSize = _ "GetSize hresult(uint64*);" ; STDMETHOD(GetSize)(UInt64 *size) PURE; ;=============================================================================== #interface "IOutStreamFlush" Global Const $sIID_IOutStreamFlush = "{23170F69-40C1-278A-0000-000300070000}" ; IUnknown Global Const $dtag_IOutStreamFlush = _ "Flush hresult();" ; STDMETHOD(Flush)() PURE; ; IPassword.h ;=============================================================================== #interface "ICryptoGetTextPassword" Global Const $sIID_ICryptoGetTextPassword = "{23170F69-40C1-278A-0000-000500100000}" ; IUnknown Global Const $dtag_ICryptoGetTextPassword = _ "CryptoGetTextPassword hresult(str);" ; STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; ;=============================================================================== #interface "ICryptoGetTextPassword2" Global Const $sIID_ICryptoGetTextPassword2 = "{23170F69-40C1-278A-0000-000500200000}" ; IUnknown Global Const $dtag_ICryptoGetTextPassword2 = _ "CryptoGetTextPassword2 hresult(int*,str);" ; STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; ; IArchive.h ;=============================================================================== #interface "ISetProperties" Global Const $sIID_ISetProperties = "{23170F69-40C1-278A-0000-000600030000}" ; IUnknown Global Const $dtag_ISetProperties = _ "SetProperties hresult(ptr,ptr,int);" ; STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE; ;=============================================================================== #interface "IArchiveOpenCallback" Global Const $sIID_IArchiveOpenCallback = "{23170F69-40C1-278A-0000-000600100000}" ; IUnknown Global Const $dtag_IArchiveOpenCallback = _ "SetTotal hresult(uint64*,uint64*);" & _ ; STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ "SetCompleted hresult(uint64*,uint64*);" ; STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ ;=============================================================================== #interface "IArchiveExtractCallback" Global Const $sIID_IArchiveExtractCallback = "{23170F69-40C1-278A-0000-000600200000}" ; IProgress Global Const $dtag_IArchiveExtractCallback = _ $dtag_IProgress2 & _ "GetStream hresult(uint,ptr*,int);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ "PrepareOperation hresult(int);" & _ ; STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \ ;=============================================================================== #interface "IArchiveOpenVolumeCallback" Global Const $sIID_IArchiveOpenVolumeCallback = "{23170F69-40C1-278A-0000-000600300000}" ; IUnknown Global Const $sTagIArchiveOpenVolumeCallback = _ "GetProperty hresult(int,variant*);" & _ ; STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(wstr,ptr*);" ; STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ ;=============================================================================== #interface "IInArchiveGetStream" Global Const $sIID_IInArchiveGetStream = "{23170F69-40C1-278A-0000-000600400000}" ; IUnknown Global Const $dtag_IInArchiveGetStream = _ "GetStream hresult(uint,ptr*);" ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; ;=============================================================================== #interface "IArchiveOpenSetSubArchiveName" Global Const $sIID_IArchiveOpenSetSubArchiveName = "{23170F69-40C1-278A-0000-000600500000}" ; IUnknown Global Const $dtag_IArchiveOpenSetSubArchiveName = _ "SetSubArchiveName hresult(wstr);" ; STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; ;=============================================================================== #interface "IInArchive" Global Const $sIID_IInArchive = "{23170F69-40C1-278A-0000-000600600000}" ; IUnknown Global Const $dtag_IInArchive = _ "Open hresult(ptr;uint64*;ptr);" & _ ; STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ "Close hresult();" & _ ; STDMETHOD(Close)() x; \ "GetNumberOfItems hresult(uint*);" & _ ; STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ "GetProperty hresult(uint;int;variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "Extract hresult(uint;uint;int;ptr);" & _ ; STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ "GetArchiveProperty hresult(int;variant*);" & _ ; STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ "GetNumberOfProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ "GetPropertyInfo hresult(uint;bstr*;int*;int*);" & _ ; STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ "GetNumberOfArchiveProperties hresult(uint*);" & _ ; STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ "GetArchivePropertyInfo hresult(uint;bstr*;int*;int*);" ; STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; ;=============================================================================== #interface "IArchiveOpenSeq" Global Const $sIID_IArchiveOpenSeq = "{23170F69-40C1-278A-0000-000600610000}" ; IUnknown Global Const $dtag_IArchiveOpenSeq = _ "OpenSeq hresult();" ; STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; ;=============================================================================== #interface "IArchiveUpdateCallback" Global Const $sIID_IArchiveUpdateCallback = "{23170F69-40C1-278A-0000-000600800000}" ; IProgress Global Const $dtag_IArchiveUpdateCallback = _ $dtag_IProgress2 & _ "GetUpdateItemInfo hresult(uint,int*,int*,int*);" & _ ; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) x; \ "GetProperty hresult(uint,int,variant*);" & _ ; STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ "GetStream hresult(uint,ptr*);" & _ ; STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ "SetOperationResult hresult(int);" ; STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ ;=============================================================================== #interface "IArchiveUpdateCallback2" Global Const $sIID_IArchiveUpdateCallback2 = "{23170F69-40C1-278A-0000-000600820000}" ; IArchiveUpdateCallback Global Const $dtag_IArchiveUpdateCallback2 = _ $dtag_IArchiveUpdateCallback & _ "GetVolumeSize hresult(uint,uint64*);" & _ ; STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ "GetVolumeStream hresult(uint,ptr*);" ; STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ ;=============================================================================== #interface "IOutArchive" Global Const $sIID_IOutArchive = "{23170F69-40C1-278A-0000-000600A00000}" ; IUnknown Global Const $dtag_IOutArchive = _ "UpdateItems hresult(ptr;uint;ptr);" & _ ; STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ "GetFileTimeTypehresult(uint*);" ; STDMETHOD(GetFileTimeType)(UInt32 *type) x; ;=============================================================================== #interface "ISequentialStream" Global Const $sIID_ISequentialStream = "{0c733a30-2a1c-11ce-ade5-00aa0044773d}" ; IUnknown Global Const $dtag_ISequentialStream = _ "Read hresult(struct*;dword;dword*);" & _ "Write hresult(struct*;dword;dword*);" ;=============================================================================== #interface "IStream" Global Const $sIID_IStream = "{0000000c-0000-0000-C000-000000000046}" ; ISequentialStream Global Const $dtag_IStream = _ $dtag_ISequentialStream & _ "Seek hresult(int64;dword;uint64*);" & _ "SetSize hresult(uint64);" & _ "CopyTo hresult(ptr;uint64;uint64*;uint64*);" & _ "Commit hresult(dword);" & _ "Revert hresult();" & _ "LockRegion hresult(uint64;uint64;dword);" & _ "UnlockRegion hresult(uint64;uint64;dword);" & _ "Stat hresult(struct*;dword);" & _ "Clone hresult(ptr*);" ;=============================================================================== ; XXX, später dann mal: 7za-x32.dll / 7za-x64.dll (von 7zip.org) ; open 7z.dll Global Const $h7Z_DLL = DllOpen(@ScriptDir & "\7z.dll") ; je nach system erstmal per hand anpassen If $h7Z_DLL = -1 Then MsgBox(0, "error", "fehler beim laden der dll") Exit EndIf #cs exported functions of 7z.dll: IO: UInt32 WINAPI CreateObject(const GUID *clsID, const GUID *interfaceID, void **outObject); IO: UInt32 WINAPI GetNumberOfMethods(UInt32 *numMethods); IO: UInt32 WINAPI GetNumberOfFormats(UInt32 *numFormats); not used, currently: UInt32 WINAPI GetMethodProperty(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); UInt32 WINAPI GetHandlerProperty2(UInt32 index, PROPID propID, PROPVARIANT *value); UInt32 WINAPI SetLargePageMode(); #ce Func _7z_GetNumberOfMethods() Local $aCall = DllCall($h7Z_DLL, 'uint', 'GetNumberOfMethods', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfMethods()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfMethods Func _7z_GetNumberOfFormats() Local $aCall = DllCall($h7Z_DLL, 'uint', 'GetNumberOfFormats', 'uint*', 0) If @error <> 0 Then MsgBox(0, "error", "fehler _7z_GetNumberOfFormats()") Exit EndIf Return $aCall[1] EndFunc ;==>_7z_GetNumberOfFormats Func _7z_CreateObject($sCLSID, $sIID, $sTag) Local $tCLSID = _WinAPI_GUIDFromString($sCLSID) Local $tIID = _WinAPI_GUIDFromString($sIID) ; CreateObject(const GUID *clsid, const GUID *iid, void **outObject) Local $aCall = DllCall($h7Z_DLL, "long", "CreateObject", "struct*", $tCLSID, "struct*", $tIID, "ptr*", 0) ;_ArrayDisplay($aCall) ;MsgBox(0,"call:", "DllCall() " & @CRLF & "$sCLSID = " & $sCLSID & @CRLF & "sIID = " & $sIID & @CRLF & "$sTag = " & $sTag) If @error Or $aCall[0] Then MsgBox(0, "error", "DllCall() @ _7z_CreateObject nicht ok: " & @error & " @ " & $sIID) ;_ArrayDisplay($aCall) Exit EndIf Local $oObj = ObjCreateInterface($aCall[3], $sIID, $sTag) If IsObj($oObj) Then Return $oObj EndIf ; fatal error MsgBox(0, "_7z_CreateObject() fehlgeschlagen... obj=", IsObj($oObj)) Exit EndFunc ;==>_7z_CreateObject ;=============================================================================== ; 1) What yo should do is first create IInArchive object with _7z_CreateObject (already posted) Local $oIInArchive = _7z_CreateObject($sCLSID_Format7z, $sIID_IInArchive, $dtag_IInArchive) ; 2) then you create stream on archive file (go with SHCreateStreamOnFile for now, since you found it on msdn even though it will prove slower later) ; STGM_READWRITE 0x00000002L Func _WinAPI_SHCreateStreamOnFile($sFile) Local $iGrfMode = 0x00000002 Local $aCall = DllCall('shlwapi.dll', 'long', 'SHCreateStreamOnFile', 'str', $sFile, 'uint', $iGrfMode, 'ptr*', 0) If @error Or $aCall[0] <> 0 Then ConsoleWrite("error @ _WinAPI_SHCreateStreamOnFile" & @CRLF) Exit EndIf Local $oObj = ObjCreateInterface($aCall[3], $sIID_IStream, $dtag_IStream) If IsObj($oObj) Then Return $oObj EndIf MsgBox(0, "error", "_WinAPI_SHCreateStreamOnFile() != obj") Exit EndFunc ;==>_WinAPI_SHCreateStreamOnFile ;=============================================================================== ; 3) Then create IInStream with ObjectFromTag which is similar task as IArchiveOpenCallback you already did, only you wrapp IStream you got with SHCreateStreamOnFile. Local $tIArchiveOpenCallback ; Interface for IArchiveOpenCallback Local $oIArchiveOpenCallback = ObjectFromTag("IArchiveOpenCallback_", $dtag_IArchiveOpenCallback, $tIArchiveOpenCallback, True, Default, $sIID_IArchiveOpenCallback) ; lala.7z is a small testfile (created with 7zip) Local Const $sFilePath = @TempDir & "\lala.7z" Local $oIStream = _WinAPI_SHCreateStreamOnFile($sFilePath) ;Local $hData = _MemGlobalAlloc(4*1024*1024, $GMEM_MOVEABLE) -> later Func IArchiveOpenCallback_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) ConsoleWrite("@IArchiveOpenCallback_QueryInterface" & @CRLF) Switch _WinAPI_StringFromGUID($pRIID) Case $sIID_IArchiveOpenCallback Case Else ConsoleWrite("IArchiveOpenCallback_QueryInterface -> ERR (" & _WinAPI_StringFromGUID($pRIID) & ") " & @CRLF) Return $E_NOINTERFACE EndSwitch DllStructSetData($tStruct, 1, $pSelf) ConsoleWrite("@IArchiveOpenCallback_QueryInterface -> OK" & @CRLF) Return $S_OK EndFunc ;==>IArchiveOpenCallback_QueryInterface Func IArchiveOpenCallback_AddRef($pSelf) #forceref $pSelf ConsoleWrite("@IArchiveOpenCallback_AddRef" & @CRLF) Return $S_OK EndFunc ;==>IArchiveOpenCallback_AddRef Func IArchiveOpenCallback_Release($pSelf) #forceref $pSelf ConsoleWrite("@IArchiveOpenCallback_Release" & @CRLF) Return $S_OK EndFunc ;==>IArchiveOpenCallback_Release Func IArchiveOpenCallback_SetTotal($iFiles, $iBytes) ConsoleWrite("@IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) $iFiles = 1 $iBytes = FileGetSize($sFilePath) Return $S_OK EndFunc ;==>IArchiveOpenCallback_SetTotal Func IArchiveOpenCallback_SetCompleted($iFiles, $iBytes) ConsoleWrite("@IArchiveOpenCallback: files:" & $iFiles & " bytes:" & $iBytes & @CRLF) $iFiles = 0 $iBytes = 0 Return $S_OK EndFunc ;==>IArchiveOpenCallback_SetCompleted ;=============================================================================== ; 3) Then create IInStream with ObjectFromTag which is similar task as IArchiveOpenCallback you already did ; -> only you wrapp IStream you got with SHCreateStreamOnFile. Local $tIInStream ; Interface for IInStream Local $oIInStream = ObjectFromTag("IInStream_", $dtag_IInStream, $tIInStream, True, Default, $sIID_IInStream) #cs ;Func ObjectFromTag( $sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default #ce ; IInStream interface Func IInStream_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) ConsoleWrite("@IInStream_QueryInterface" & @CRLF) Switch _WinAPI_StringFromGUID($pRIID) Case $sIID_IInStream Case Else ConsoleWrite("@IInStream_QueryInterface -> ERR" & @CRLF) Return $E_NOINTERFACE EndSwitch DllStructSetData($tStruct, 1, $pSelf) ConsoleWrite("@IInStream_QueryInterface -> OK" & @CRLF) Return $S_OK EndFunc ;==>IInStream_QueryInterface Func IInStream_AddRef($pSelf) #forceref $pSelf ConsoleWrite("@IInStream_AddRef" & @CRLF) Return $S_OK EndFunc ;==>IInStream_AddRef Func IInStream_Release($pSelf) #forceref $pSelf ConsoleWrite("@IInStream_Release" & @CRLF) Return $S_OK EndFunc ;==>IInStream_Release ; "Read hresult(ptr,uint,uint32*);" & _ ; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; Func IInStream_Read($pData, $iSize, $iProcessedSize) ConsoleWrite("@IInStream_Read: $iSize:" & $iSize & " $iProcessedSize:" & $iProcessedSize & @CRLF) $oIStream.Read($pData, $iSize, $iProcessedSize) Return $S_OK EndFunc ;==>IInStream_Read ; "Seek hresult(int64,uint,uint64*);" ; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; Func IInStream_Seek($iOffset, $iSeekOrigin, $iNewPosition) ConsoleWrite("@IInStream_Seek: $iSeekOrigin:" & $iSeekOrigin & " $iNewPosition:" & $iNewPosition & @CRLF) $oIStream.Seek($iOffset, $iSeekOrigin, $iNewPosition) Return $S_OK EndFunc ;==>IInStream_Seek ;=============================================================================== ; 4) Then load archive using Open method of IInArchive. $i = $oIInArchive.Open($oIInStream, 4 * 1024 * 1024, $oIArchiveOpenCallback) ;$oIStream.Release() ;DeleteObjectFromTag($tIInStream) MsgBox(0, "i?", "i=" & $i & @CRLF) ; 5) Then post your code if something wouldn't work as it should. ; ... ; this works: ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfMethods()) ;MsgBox(0,@ScriptName, "methods=" & _7z_GetNumberOfFormats()) ;Local $iItems = 0 ;$iRet = $oIArchive.GetNumberOfItems($iItems) ;MsgBox(0,"","x=" & $iItems & " r=" & $iRet) This is the output: expandcollapse popupFunc IArchiveOpenCallback_QueryInterface( $pSelf ) ; Ret: long Par: ptr;ptr EndFunc 0 Func IArchiveOpenCallback_AddRef( $pSelf ) ; Ret: dword EndFunc 0 Func IArchiveOpenCallback_Release( $pSelf ) ; Ret: dword EndFunc 0 Func IArchiveOpenCallback_SetTotal( $pSelf ) ; Ret: long Par: ptr,ptr EndFunc error=2 @extended=0 error @ method=IArchiveOpenCallback_SetTotal ret=long params=ptr;ptr,ptr0 Func IArchiveOpenCallback_SetCompleted( $pSelf ) ; Ret: long Par: ptr,ptr EndFunc error=2 @extended=0 error @ method=IArchiveOpenCallback_SetCompleted ret=long params=ptr;ptr,ptr0 @IArchiveOpenCallback_QueryInterface @IArchiveOpenCallback_QueryInterface -> OK @IArchiveOpenCallback_Release Func IInStream_QueryInterface( $pSelf ) ; Ret: long Par: ptr;ptr EndFunc 0 Func IInStream_AddRef( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_Release( $pSelf ) ; Ret: dword EndFunc 0 Func IInStream_Read( $pSelf ) ; Ret: long Par: ptr,uint,ptr EndFunc error=2 @extended=0 error @ method=IInStream_Read ret=long params=ptr;ptr,uint,ptr0 Func IInStream_Seek( $pSelf ) ; Ret: long Par: int64,uint,ptr EndFunc error=2 @extended=0 error @ method=IInStream_Seek ret=long params=ptr;int64,uint,ptr0 @IInStream_QueryInterface @IInStream_QueryInterface -> OK @IInStream_Release @IArchiveOpenCallback_AddRef @IArchiveOpenCallback_QueryInterface IArchiveOpenCallback_QueryInterface -> ERR ({23170F69-40C1-278A-0000-000500100000}) -> {23170F69-40C1-278A-0000-000500100000} means $sIID_ICryptoGetTextPassword ? @IArchiveOpenCallback_Release Should I use FileOpen(), FileRead(), FileSetPos(), FileGetPos(), FileGetPos() and friends within the IInStream methods ? Thanks for all the help. Best regards, milky Edited May 7, 2014 by milky Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now