flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Projects and Ideas > Can anyone help with macros for that

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 88
Location: Russian Federation, Sochi
Can anyone help with macros for that
realizing COM-server in fasm
stage: sources are not finished

the main file USECOM2.0.ASM

Code:

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     esiecx
        xor     eaxeax

        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     esiecx
        mov     dword [esi+  0], ISEI
        mov     dword [esi+  4], ISPSE
        mov     eax, [esi+0Ch]
        test    eaxeax
        jz      @F
        comcall eax,IUnknown,Release
    @@:
        mov     eax, [esi+10h]
        test    eaxeax
        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     eaxE_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

Code:

struc GUID def
 {
   match d1-d2-d3-d4-d5def
    \{
      .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




ideas

Code:

;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
;}                                                                 




MyObjClassFactory.inc

Code:

proc CMyObjCF@@QueryInterface This,riid,ppv
  push    ebx esi edi
        xor     ebxebx
        setptr  [ppv],ebx
        mov     ebx, [This]
        GUIDcmp [riid],IID_IUnknown
        jz      @F
        GUIDcmp [riid],IID_IClassFactory
        jz      @F
        mov     eaxE_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     eaxE_NOTIMPL
        jmp     .locret
    @@:

        ;stdcall new,14h
        pop     ecx
        test    eax,eax
        jz      .loc_5F0F1A24
        mov     ecxeax
        call    CMyObj@@Constructor
        test    eax,eax
        jz      .loc_5F0F1A24
        mov     esieax
        comcall esi,IShellExtInit,QueryInterface,[rclsid],[ppv]
        push    edi
        mov     edi,eax
        comcall esi,IShellExtInit,Release
        test    ediedi
        pop     edi
        jge     .loc_5F0F1A53
        mov     eaxE_NO_INTERFACE
        jmp     .locret
    .loc_5F0F1A24:
        mov     eaxE_OUTOFMEMORY
        jmp     .locret
    .loc_5F0F1A53:
        xor     eaxeax
    .locret:
  pop     esi
        ret
endp

proc CMyObjCF@@LockServer This,fLock
        xor     eaxeax
        ret
endp                                                           




MyObj.inc

Code:

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     ebxebx
        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     eaxE_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    eaxeax
        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     eaxeax
  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
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15158
Location: GW170817
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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.