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: COM