flat assembler
Message board for the users of flat assembler.

flat assembler > Projects and Ideas > Can anyone help with macros for that

Thread Post new topic Reply to topic

Joined: 24 Mar 2012
Posts: 157
Location: Russian Federation, Sochi
realizing COM-server in fasm
stage: sources are not finished

the main file USECOM2.0.ASM
format PE GUI 4.0 DLL entry DllEntryPoint include 'win32w.inc' include 'COMINCLUDES.INC' section '.data' data readable writeable CMyObj: ISPSE IShellPropSheetExt@vtbl \ <CMyObj@@QueryInterface@adjustor@4,\ CMyObj@@AddRef@adjustor@4,\ CMyObj@@Release@adjustor@4>,\ CMyObj@@AddPages,\;(int (*)(_PSP *,long),long) CMyObj@@ReplacePage ;(uint,int (*)(_PSP *,long),long) ISEI IShellExtInit@vtbl \ <CMyObj@@QueryInterface,\ CMyObj@@AddRef,\ CMyObj@@Release>,\ CMyObj@@Initialize ;(_ITEMIDLIST const *,IDataObject *,HKEY__ *) CLSID_CMyObj GUID 00FF00FF-00FF-00FF-00FF-123456789ABC vMyObjClassFactory: IClassFactory@vtbl \ <CMyObjCF@@QueryInterface,\ CMyObjCF@@AddRef,\ CMyObjCF@@Release>,\ CMyObjCF@@CreateInstance,\;(IUnknown *,_GUID const &,void * *) CMyObjCF@@LockServer ;(int) IID_IUnknown GUID 00000000-0000-0000-C000-000000000046 IID_IClassFactory GUID 00000001-0000-0000-C000-000000000046 IID_IShellExtInit GUID 000214E8-0000-0000-C000-000000000046 IID_IShellPropSheetExt GUID 000214E9-0000-0000-C000-000000000046 cInstancesMyObj dd 0 pvMyObjClassFactory dd vMyObjClassFactory section '.text' code readable executable ;#in progress proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov eax,TRUE ret endp ;#in progress proc DllCanUnloadNow hinstDLL,fdwReason,lpvReserved mov eax,TRUE ret endp include 'MyObj.inc' include 'MyObjClassFactory.inc' proc CMyObj@@Constructor ; ecx=This push esi mov esi, ecx xor eax, eax mov dword [esi+ 0], ISEI mov dword [esi+ 4], ISPSE mov dword [esi+ 8], eax mov dword [esi+0Ch], eax mov dword [esi+10h], eax stdcall CMyObj@@AddRef,esi mov eax,esi pop esi ret endp proc CMyObj@@Destructor ; ecx=This push esi mov esi, ecx mov dword [esi+ 0], ISEI mov dword [esi+ 4], ISPSE mov eax, [esi+0Ch] test eax, eax jz @F comcall eax,IUnknown,Release @@: mov eax, [esi+10h] test eax, eax jz @F invoke RegCloseKey,eax mov dword [esi+10h], 0 @@: pop esi ret endp proc DllGetClassObject rclsid,riid,ppv push esi edi GUIDcmp [rclsid],CLSID_CMyObj pop esi edi mov eax, E_NO_INTERFACE jnz @F stdcall CMyObjCF@@QueryInterface,pvMyObjClassFactory,[riid],[ppv] @@: ret endp section '.idata' import data readable library comctl,'COMCTL32.DLL',\ advapi,'ADVAPI32.DLL',\ kernel,'KERNEL32.DLL' import comctl,\ CreatePropertySheetPageW, 'CreatePropertySheetPageW',\ DestroyPropertySheetPage,'DestroyPropertySheetPage' import advapi,\ RegCloseKey ,'RegCloseKey',\ RegOpenKeyExW ,'RegOpenKeyExW' import kernel,\ InterlockedDecrement,'InterlockedDecrement',\ InterlockedIncrement,'InterlockedIncrement' section '.edata' export data readable export 'USECOM2.0.DLL',\ DllCanUnloadNow,'DllCanUnloadNow',\ DllGetClassObject,'DllGetClassObject' section '.reloc' fixups data readable discardable

macros & strucs & definitions file COMINCLUDES.INC
struc GUID def { match d1-d2-d3-d4-d5, def \{ .Data1 dd 0x\#d1 .Data2 dw 0x\#d2 .Data3 dw 0x\#d3 .Data4 db 0x\#d4 shr 8,0x\#d4 and 0FFh .Data5 db 0x\#d5 shr 40,0x\#d5 shr 32 and 0FFh,0x\#d5 shr 24 and 0FFh,0x\#d5 shr 16 and 0FFh,0x\#d5 shr 8 and 0FFh,0x\#d5 and 0FFh \} } macro GUIDcmp dest,src { mov esi,src mov edi,dest mov ecx,4 repe cmpsd } macro setptr dest,src ; used|trashed eax { if src eqtype eax | src eqtype 0 if dest eqtype eax | dest eqtype 0 local ..dest label ..dest at dest mov [..dest],src else mov eax,dest mov [eax],src end if else if ~ dest eq eax mov eax,dest end if push src pop [eax] end if } struct PROPSHEETPAGEW_V3 dwSize dd ? dwFlags dd ? hInstance dd ? pszTemplate dd ? pszIcon dd ? pszTitle dd ? pfnDlgProc dd ? lParam dd ? pfnCallback dd ? pcRefParent dd ? ; PSP_V1 end here pszHeaderTitle dd ? pszHeaderSubTitle dd ? hActCtx dd ? ends struct IUnknown@vtbl QueryInterface dd ? AddRef dd ? Release dd ? ends struct IClassFactory@vtbl IUnk IUnknown@vtbl CreateInstance dd ? LockServer dd ? ends struct IShellPropSheetExt@vtbl IUnk IUnknown@vtbl AddPages dd ? ReplacePage dd ? ends struct IShellExtInit@vtbl IUnk IUnknown@vtbl Initialize dd ? ends struct IDataObject@vtbl IUnk IUnknown@vtbl GetData dd ? GetDataHere dd ? QueryGetData dd ? GetCanonicalFormatEtc dd ? SetData dd ? EnumFormatEtc dd ? DAdvise dd ? DUnadvise dd ? EnumDAdvise dd ? ends interface IUnknown,\ QueryInterface,\ AddRef,\ Release interface IClassFactory,\ QueryInterface,\ AddRef,\ Release,\ CreateInstance,\ LockServer interface IShellExtInit,\ QueryInterface,\ AddRef,\ Release,\ Initialize interface IDataObject,\ QueryInterface,\ AddRef,\ Release,\ GetData,\ GetDataHere,\ QueryGetData,\ GetCanonicalFormatEtc,\ SetData,\ EnumFormatEtc,\ DAdvise,\ DUnadvise,\ EnumDAdvise sizeof.IID = 16 E_NOTIMPL = 80004001h E_NO_INTERFACE = 80004002h E_FAIL = 80004005h E_OUTOFMEMORY = 8007000Eh

;This- structure of COM-object ; in most coommon case ; with N number of slots for interface (each slot has ptr to interface) ; if one interface comletely included in other interface they share same interface slot ; with F number of additional fields ; in simplest case (for ex. ClassFactory): N=1, F=0 - whole structure is just 1 ptr ; in most complex case (for. ex. OOP interfaced object): structure is multilevel - it not contains slots for interface, but contain ptr to that slots (or ptr to ptr to) ; one rule: relization of all methods of every interface supported by pvself structure must know relativities of all members in this structure (members that used in that method) ;cInstances - dll field, increased with all AddRef & decreased with all Release of every COM-object created from interfaces realized in that DLL ;every COM-object exept ClassFactory has its own refCounter, that is affected with AddRef & Release too. ;#pseudocode QueryInterface(This,riid,ppv) ;{ ; if [riid] in list of supported IID ; comcall ([This]+IndexofInterfaceSlot),IUnknown,AddRef ; setptr [ppv],[This] ; RESULT S_OK ; else ; setptr [ppv],0 ; RESULT E_NO_INTERFACE ;} ;#pseudocode AddRef(This) ;{ ; InterlockedIncrement(cAllInstances) ; if This is not ClassFactory (because ClassFactory has only 1 instance direct in DLL) ; InterlockedIncrement(InstanceCounter) of that This structure ;} ;#pseudocode Release(This) ;{ ; InterlockedDecrement(cAllInstances) ; if This is not ClassFactory (because ClassFactory has only 1 instance direct in DLL) ; InterlockedDecrement(InstanceCounter) of that This structure ;}

proc CMyObjCF@@QueryInterface This,riid,ppv push ebx esi edi xor ebx, ebx setptr [ppv],ebx mov ebx, [This] GUIDcmp [riid],IID_IUnknown jz @F GUIDcmp [riid],IID_IClassFactory jz @F mov eax, E_NO_INTERFACE jmp .locret @@: comcall ebx,IClassFactory,AddRef setptr [ppv],ebx xor eax,eax .locret: pop ebx esi edi ret endp proc CMyObjCF@@AddRef This invoke InterlockedIncrement,cInstancesMyObj ret endp proc CMyObjCF@@Release This invoke InterlockedDecrement,cInstancesMyObj ret endp proc CMyObjCF@@CreateInstance This,pUnk,rclsid,ppv push esi cmp [pUnk], 0 jz @F mov eax, E_NOTIMPL jmp .locret @@: ;stdcall new,14h pop ecx test eax,eax jz .loc_5F0F1A24 mov ecx, eax call CMyObj@@Constructor test eax,eax jz .loc_5F0F1A24 mov esi, eax comcall esi,IShellExtInit,QueryInterface,[rclsid],[ppv] push edi mov edi,eax comcall esi,IShellExtInit,Release test edi, edi pop edi jge .loc_5F0F1A53 mov eax, E_NO_INTERFACE jmp .locret .loc_5F0F1A24: mov eax, E_OUTOFMEMORY jmp .locret .loc_5F0F1A53: xor eax, eax .locret: pop esi ret endp proc CMyObjCF@@LockServer This,fLock xor eax, eax ret endp

proc CMyObj@@QueryInterface@adjustor@4 This,riid,ppv sub [This], 4 jmp CMyObj@@QueryInterface endp proc CMyObj@@AddRef@adjustor@4 This sub [This], 4 jmp CMyObj@@AddRef endp proc CMyObj@@Release@adjustor@4 This,riid,ppv sub [This], 4 jmp CMyObj@@Release endp ;#in progress body proc CMyObj@@AddPages This,pfnAddPage,lParam mov eax,TRUE ret endp proc CMyObj@@ReplacePage This,uPageID,pfnReplacePage,lParam mov eax,E_NOTIMPL ret endp proc CMyObj@@QueryInterface This,riid,ppv ;1st ptr to interface ([ [This]+0]) of COM-object points to both IShellExtInit & IUnknown(IUnknown is part of IShellExtInit) ;because of IShellExtInit & IShellPropSheetExt no one of them don`t include second one ;2nd ptr to interface ([ [This]+4]) of COM-object points to only IShellPropSheetExt (IUnknown is part of IShellPropSheetExt, but it already realized inside IShellExtInit) push ebx esi edi xor ebx, ebx setptr [ppv],ebx mov ebx,[This] GUIDcmp [riid],IID_IUnknown jz @F GUIDcmp [riid],IID_IShellExtInit jz @F GUIDcmp [riid],IID_IShellPropSheetExt jnz .loc_5F0F1ACF lea ebx,[ebx+4] ; fix for IShellPropSheetExt because it in 2nd slot of COM-object interfaces jmp @F .loc_5F0F1ACF: mov eax, E_NO_INTERFACE jmp .locret @@: comcall ebx,IUnknown,AddRef setptr [ppv],ebx xor eax,eax .locret: pop ebx esi edi ret endp proc CMyObj@@AddRef This push esi mov esi,[InterlockedIncrement] stdcall esi,cInstancesMyObj mov eax,[This] add eax,8 stdcall esi,eax pop esi ret endp proc CMyObj@@Release This push esi mov esi,[InterlockedDecrement] stdcall esi,cInstancesMyObj mov eax,[This] add eax,8 stdcall esi,eax pop esi ret endp proc CMyObj@@Initialize This,pidlFolder,pDO,hkeyProgID push esi mov esi,[This] mov ecx,esi call CMyObj@@Destructor mov eax, [pDO] mov [esi+0Ch], eax test eax, eax jz @F comcall eax,IUnknown,AddRef ;eax,IDataObject,AddRef @@: cmp [hkeyProgID],0 jz @F add esi,10 invoke RegOpenKeyExW,[hkeyProgID],0,0,2000000h,esi @@: xor eax, eax pop esi ret endp

i expect some critics if i do some things wrong
in the end i will post here complete & working src (hopely with your suggestions) - but i need time

I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.

Last edited by ProMiNick on 04 Apr 2017, 18:53; edited 3 times in total
Post 03 Apr 2017, 17:23
View user's profile Send private message Send e-mail Reply with quote
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 15860
Location: 162173 Ryugu
It is not clear what you want the macros for?
Post 04 Apr 2017, 13:30
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  

< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum

Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.