Ticket #1395: NoExitWithCusomObject.au3

File NoExitWithCusomObject.au3, 3.7 KB (added by ProgAndy, 12 years ago)

a reproducer script for the error.

Line 
1#include<Memory.au3>
2
3Global Const $__Au3Obj_E_NOTIMPL = 0x80004001;
4Global Const $__Au3Obj_S_OK = 0;
5Global Const $__Au3Obj_E_NOINTERFACE = 0x80004002
6Global Const $__AU3Obj_DISP_E_UNKNOWNNAME = 0x80020006
7Global Const $__AU3Obj_DISP_E_EXCEPTION = 0x80020009
8
9Global Const $__Au3Obj_vTable = DllStructCreate("ptr QueryInterface; ptr AddRef; ptr Release; ptr GetTypeInfoCount; ptr GetTypeInfo; ptr GetIDsOfNames; ptr Invoke;")
10; set DllCallbacks
11Dim $aCallbacks[8]
12                $aCallbacks[1] = DllCallbackRegister("__Au3Obj_QueryInterface", "long", "ptr;dword;dword") ;QureyInterface
13                $aCallbacks[2] = DllCallbackRegister("__Au3Obj_AddRef", "long", "ptr") ;Addref
14                $aCallbacks[3] = DllCallbackRegister("__Au3Obj_Release", "long", "ptr") ;Release
15                $aCallbacks[4] = DllCallbackRegister("__Au3Obj_GetTypeInfoCount", "long", "ptr;ptr")
16                $aCallbacks[5] = DllCallbackRegister("__Au3Obj_GetTypeInfo", "long", "ptr;uint;int;ptr")
17                $aCallbacks[6] = DllCallbackRegister("__Au3Obj_GetIDsOfNames", "long", "ptr;ptr;ptr;uint;int;ptr")
18                $aCallbacks[7] = DllCallbackRegister("__Au3Obj_Invoke", "long", "ptr;int;ptr;int;ushort;ptr;ptr;ptr;ptr")
19                For $i = 1 To 7
20                        DllStructSetData($__Au3Obj_vTable, $i, DllCallbackGetPtr($aCallbacks[$i]))
21                Next
22
23; In the end we still want the autoit object. This function converts a raw pointer to an autoit object
24Func ConvertPtrToIDispatch($pIDispatch)
25        ; Author: monoceres
26        ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs...
27        ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us.
28        Local $aCall = DllCall("kernel32.dll", "none", "RtlMoveMemory", "idispatch*", 0, "ptr*", $pIDispatch, "dword", DllStructGetSize(DllStructCreate('ptr',1)))
29        If @error Then Return SetError(1, 0, 0)
30        Return $aCall[1]
31EndFunc   ;==>ConvertPtrToIDispatch
32Func __Au3Obj_QueryInterface($pObject, $iid, $ppvObject)
33        ; Actually Autoit is not calling this function, so leave it empty for testing ;)
34        Return $__Au3Obj_E_NOINTERFACE
35EndFunc   ;==>__Au3Obj_QueryInterface
36Func __Au3Obj_AddRef($pObject)
37        ; Author: Prog@ndy
38        Local $st = DllStructCreate("ptr;dword", $pObject)
39        Local $iCount = DllStructGetData($st, 2) + 1
40        DllStructSetData($st, 2, $iCount)
41        Return $iCount
42EndFunc   ;==>__Au3Obj_AddRef
43Func __Au3Obj_Release($pObject)
44        ; Author: Prog@ndy
45        Local $st = DllStructCreate("ptr;dword", $pObject)
46        Local $iCount = DllStructGetData($st, 2) - 1
47        If $iCount < 0 Then Return 0
48        DllStructSetData($st, 2, $iCount)
49        If $iCount = 0 Then ; delete Object
50                _MemGlobalFree($pObject)
51        EndIf
52        Return $iCount
53EndFunc   ;==>__Au3Obj_Release
54Func __Au3Obj_GetTypeInfoCount($pObject, $pctinfo)
55        ; Author: Prog@ndy
56        Return $__Au3Obj_E_NOTIMPL
57EndFunc   ;==>__Au3Obj_GetTypeInfoCount
58Func __Au3Obj_GetTypeInfo($pObject, $iTInfo, $lcid, $ppTInfo)
59        ; Author: Prog@ndy
60        Return $__Au3Obj_E_NOTIMPL
61EndFunc   ;==>__Au3Obj_GetTypeInfo
62Func __Au3Obj_GetIDsOfNames($pObject, $riid, $rgszNames, $cNames, $lcid, $rgDispId)
63        Return $__AU3Obj_DISP_E_UNKNOWNNAME
64EndFunc   ;==>__Au3Obj_GetIDsOfNames
65Func __Au3Obj_Invoke($pObject, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
66        Return $__AU3Obj_DISP_E_EXCEPTION
67EndFunc   ;==>__Au3Obj_Invoke
68
69
70; construct object
71Local $iSize = DllStructGetSize(DllStructCreate("ptr vTable; dword refcount;", 1))
72Local $pMem = _MemGlobalAlloc($iSize, $GPTR) ; will be freed in Objectz::release
73Local $tStruct = DllStructCreate("ptr vTable; dword refcount;", $pMem)
74DllStructSetData($tStruct, 1, DllStructGetPtr($__Au3Obj_vTable))
75$object = ConvertPtrToIDispatch($pMem)
76OnAutoItExitRegister("__ReleaseObject")
77
78;Test: Exit without releasing the object:
79OnAutoItExitUnregister("__ReleaseObject")
80
81Func __ReleaseObject()
82        $object=0
83EndFunc