いままで紹介してきた方法ではランタイム作成時にプラグインのソースを一部書き換えて、WinMainを新たに作成するというよけいな手間がかかります。
よってここでは、そのような手間をかけずにすむ方法を紹介します。
例として、プラグインを2つ作成します。
通常と違うのは、最初に呼び出される関数名をDllMainで固定し変更できないこと、ENDディレクティブのパラメータにDllStartを指定することです。その他は通常のプラグイン作成と同じです。
;********************************************************************* ;タイトルに日付を持つMessageBoxを表示 ;TestProc p1,p2 ;TestProc2 p1,p2 ;p1:メッセ−ジ ;p2:MessageBoxのタイプ ;********************************************************************* .386 .model flat,stdcall option casemap:none include windows.inc include hspdll.inc include kernel32.inc include user32.inc includelib kernel32.lib includelib user32.lib ;********************************************************************* .data fmt db "%04d年%02d月%02d日",0 .code ;********************************************************************* DllMain PROC ,hInstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID mov eax,TRUE ret DllMain ENDP ;********************************************************************* TestProc PROC EXPORT,pBms:ptr BMSCR, pMsg:ptr CHAR ,uType ,tmp ;type 6 LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR invoke GetLocalTime,ADDR stime movzx eax,stime.wYear movzx ecx,stime.wMonth movzx edx,stime.wDay invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx mov ecx,pBms invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType neg eax ret TestProc ENDP ;********************************************************************* TestProc2 PROC EXPORT USES ebx ,pExinfo:ptr HSPEXINFO, tmp1,tmp2,tmp3 ;type$202 LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR ,pMsg ,uType invoke GetLocalTime,ADDR stime movzx eax,stime.wYear movzx ecx,stime.wMonth movzx edx,stime.wDay invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx mov ebx,pExinfo ASSUME ebx:ptr HSPEXINFO invoke [ebx].HspFunc_prm_gets mov pMsg,eax invoke [ebx].HspFunc_prm_getdi,MB_OK mov uType,eax mov ecx,[ebx].er mov eax,[ecx] .if eax ret .endif mov eax,[ebx].actscr invoke [ebx].HspFunc_getbmscr,DWORD ptr [eax] mov ecx,eax ;eaxはスタック変数のアドレス取得に使われる invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType neg eax ret TestProc2 ENDP ;********************************************************************* END DllStart
;********************************************************************* ;MessageBeepを呼び出す ;Beep p1 ;p1:サウンドの種類 ;********************************************************************* .386 .model flat,stdcall option casemap:none include windows.inc include hspdll.inc include user32.inc includelib user32.lib .code ;********************************************************************* DllMain PROC ,hInstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID mov eax,TRUE ret DllMain ENDP ;********************************************************************* Beep PROC EXPORT,uType:DWORD ,tmp,tmp2,tmp3 ;type 0 invoke MessageBeep,uType xor eax,eax ret Beep ENDP ;********************************************************************* END DllStart
これらは2つとも、通常と同じようにプラグインを作成出来ます。
@ECHO OFF ml /c /coff TestHpi.asm if errorlevel 1 goto error Link /SUBSYSTEM:WINDOWS /DLL TestHpi.obj if errorlevel 1 goto error goto fin :error echo ===============================エラー====================================== :fin echo ===============================終了=======================================
@ECHO OFF ml /c /coff Test_Beep.asm if errorlevel 1 goto error Link /SUBSYSTEM:WINDOWS /DLL Test_Beep.obj if errorlevel 1 goto error goto fin :error echo ===============================エラー====================================== :fin echo ===============================終了=======================================
次にランタイムを作成するメインファイルを作成します。
include hsphrt.inc ;SETHRTDLL p1,p2,p3,p4,・・・ ;p1:プラグインの名前(小文字で拡張子も含める) ;p2:プラグインのソースファイルのファイル名(大文字で拡張子除く) ;p3〜:関数名 SETHRTDLL testhpi.dll,TESTHPI,TestProc,TestProc2 SETHRTDLL test_beep.dll,TEST_BEEP,Beep SETDLLEND
SETHRTDLLマクロをプラグインの数だけ呼び出し、最後にSETDLLENDマクロを呼び出します。
これらのマクロで、プラグインの登録、初期化、初期化の正否チェック、HSPWinMainの呼び出し、プラグインの終了処理を行うコードを作成します。
このファイルとプラグインのファイルをアセンブルすることでランタイムを作成できます。注意する点は、ML.EXEのオプションでRUNTIMEマクロを定義する必要があることです。このマクロを定義することで、DllMainの名前変更や関数のエクスポート抑制などを行います。
@echo off
Rc.exe hsp2.rc
Ml.exe /c /coff /DRUNTIME TestHrt2.asm TestHpi.asm Test_Beep.asm
if errorlevel 1 goto error
Link.exe /SUBSYSTEM:WINDOWS /NODEFAULTLIB:OLDNAMES.LIB /OUT:TestHrt2.hrt TestHrt2.obj TestHpi.obj Test_Beep.obj hsp2.res
if errorlevel 1 goto error
goto fin
:error
echo ===============================エラー======================================
:fin
echo ===============================終了=======================================
;CTRL+F9でTest2.exeが作成されます
#packopt name "Test2.exe"
#packopt runtime "TestHrt2.hrt"
#uselib "TestHpi.dll"
#func TestProc TestProc 6
#func TestProc2 TestProc2 $202
#uselib "Test_Beep.dll"
#func Beep Beep 0
#define MB_ICONERROR $00000010
#define MB_ICONQUESTION $00000020
TestProc "test1",MB_ICONERROR
TestProc2 "test2",MB_ICONQUESTION
Beep $FFFFFFFF