Hello, COM(MASM) World!

Posted on 5月 12th, 2012 by cx20

COM(MASM)

COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は MASM による COM クライアントの例となっている。

ソースコード

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 
 
	TITLE	hello.c
	.686P
	.XMM
	include listing.inc
	.model	flat
 
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
 
_DATA	SEGMENT
$SG113507 DB	'H', 00H, 'e', 00H, 'l', 00H, 'l', 00H, 'o', 00H, ',', 00H
	DB	' ', 00H, 'C', 00H, 'O', 00H, 'M', 00H, '(', 00H, 'M', 00H, 'A'
	DB	00H, 'S', 00H, 'M', 00H, ')', 00H, ' ', 00H, 'W', 00H, 'o', 00H
	DB	'r', 00H, 'l', 00H, 'd', 00H, '!', 00H, 00H, 00H
_DATA	ENDS
PUBLIC	_main
EXTRN	__imp__CoUninitialize@0:PROC
EXTRN	__imp__CoCreateInstance@20:PROC
EXTRN	_CLSID_Shell:BYTE
EXTRN	_IID_IShellDispatch:BYTE
EXTRN	__imp__CoInitialize@4:PROC
; Function compile flags: /Odtp
_TEXT	SEGMENT
_pFolder$ = -36						; size = 4
_vRootFolder$ = -32					; size = 16
_folder$ = -12						; size = 4
_pShell$ = -4						; size = 4
_argc$ = 8						; size = 4
_argv$ = 12						; size = 4
_main	PROC
; File hello.c
; Line 4
        push    ebp
        mov     ebp, esp
        sub     esp, 36                                 ; 00000024H
; Line 11
        push    0
        call    DWORD PTR __imp__CoInitialize@4
; Line 13
        lea     eax, DWORD PTR _pShell$[ebp]
        push    eax
        push    OFFSET _IID_IShellDispatch
        push    1
        push    0
        push    OFFSET _CLSID_Shell
        call    DWORD PTR __imp__CoCreateInstance@20
; Line 15
        mov     ecx, 3
        mov     WORD PTR _vRootFolder$[ebp], cx
; Line 16
        mov     DWORD PTR _vRootFolder$[ebp+8], 36      ; 00000024H
; Line 17
        lea     edx, DWORD PTR _folder$[ebp]
        mov     DWORD PTR _pFolder$[ebp], edx
; Line 19
        lea     eax, DWORD PTR _pFolder$[ebp]
        push    eax
        sub     esp, 16                                 ; 00000010H
        mov     ecx, esp
        mov     edx, DWORD PTR _vRootFolder$[ebp]
        mov     DWORD PTR [ecx], edx
        mov     eax, DWORD PTR _vRootFolder$[ebp+4]
        mov     DWORD PTR [ecx+4], eax
        mov     edx, DWORD PTR _vRootFolder$[ebp+8]
        mov     DWORD PTR [ecx+8], edx
        mov     eax, DWORD PTR _vRootFolder$[ebp+12]
        mov     DWORD PTR [ecx+12], eax
        push    0
        push    OFFSET $SG113507
        push    0
        mov     ecx, DWORD PTR _pShell$[ebp]
        push    ecx
        mov     edx, DWORD PTR _pShell$[ebp]
        mov     eax, DWORD PTR [edx]
        mov     ecx, DWORD PTR [eax+40]
        call    ecx
; Line 20
        cmp     DWORD PTR _pFolder$[ebp], 0
        je      SHORT $LN1@main
; Line 22
        mov     edx, DWORD PTR _pFolder$[ebp]
        push    edx
        mov     eax, DWORD PTR _pFolder$[ebp]
        mov     ecx, DWORD PTR [eax]
        mov     edx, DWORD PTR [ecx+8]
        call    edx
$LN1@main:
; Line 24
        mov     eax, DWORD PTR _pShell$[ebp]
        push    eax
        mov     ecx, DWORD PTR _pShell$[ebp]
        mov     edx, DWORD PTR [ecx]
        mov     eax, DWORD PTR [edx+8]
        call    eax
; Line 26
        call    DWORD PTR __imp__CoUninitialize@0
; Line 28
        xor     eax, eax
; Line 29
        mov     esp, ebp
        pop     ebp
        ret     0
_main   ENDP
_TEXT   ENDS
END

上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。

#include <shlobj.h>
 
int main( int argc, char* argv[] )
{
    HRESULT hResult;
    IShellDispatch* pShell;
    VARIANT vRootFolder;
    Folder* pFolder;
 
    CoInitialize( NULL );
 
    CoCreateInstance( &CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&pShell );
 
    VariantInit( &vRootFolder );
    vRootFolder.vt = VT_I4;
    vRootFolder.lVal = ssfWINDOWS;
 
    pShell->lpVtbl->BrowseForFolder( (void*)pShell, 0, L"Hello, COM(MASM) World!", 0, vRootFolder, &pFolder );
    VariantClear( &vRootFolder );
    if ( pFolder != NULL )
    {
        pFolder->lpVtbl->Release( (void*)pFolder );
    }
    pShell->lpVtbl->Release( (void*)pShell );
 
    CoUninitialize();
 
    return 0;
}

コンパイル&リンク方法

C:¥> ml -c hello.asm
C:¥> midl shldisp.idl
C:¥> cl shldisp_i.c
C:¥> link hello.obj shldisp_i.obj ole32.lib oleaut32.lib

実行結果

+----------------------------------------+
|Browse For Folder                    [X]|
+----------------------------------------+
| Hello, COM(MASM) Wolrd!                |
|                                        |
| +------------------------------------+ |
| |[Windows]                           | |
| | +[addins]                          | |
| | +[AppCompat]                       | |
| | +[AppPatch]                        | |
| | +[assembly]                        | |
| |     :                              | |
| |     :                              | |
| |     :                              | |
| +------------------------------------+ |
| [Make New Folder]    [  OK  ] [Cancel] |
+----------------------------------------+

Tags:

Categories: assembler, COM, library, MASM

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WP-SpamFree by Pole Position Marketing