format PE GUI 4.0 DLL
entry DllEntryPoint

include '%fasminc%\win32a.inc'
include 'constant.txt'

; ------------------------------------------------
section '.sdata' data readable writeable shareable
; ------------------------------------------------
instH			dd ?	; dll instance

d1			db '%s --- DLL_PROCESS_ATTACH',0
d2			db '%s -------------- _DETACH',0
d3			db 'We will try subclass this',0
d4			db '%lu --> RegisterPatchHandle',0
d5			db 'RegisterTargetHandle %x',0
d6			db 'Error %X, Failed SetWindowLong',0
d7			db 'OK SetWindowLong',0

buff			rb MAX_PATH
modPath			rb MAX_PATH
modTargetAppName	db '\notepad.exe',0
modTargetFound		dd 0	; 0 = no, 1 = yes

procAddr		dd 0	; old default proc addr before subclass

patchH			dd 0	; patch window handle

targetH			dd 0	; target window handle



; --------------------------------------
section '.text' code readable executable
; --------------------------------------
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
	push	[hinstDLL]
	pop	[instH]

	cmp	[fdwReason],DLL_PROCESS_ATTACH
	je	.attach
	cmp	[fdwReason],DLL_PROCESS_DETACH
	je	.detach

.exit:
	mov	eax,TRUE
	ret

.attach:
	stdcall	Trim_To_Last
	jmp	.exit

.detach:
	jmp	.exit

endp


; --------------- [ get module path, check for target ]
proc Trim_To_Last
; ---------------
		cmp	[modTargetFound],0
		jne	.exit
	invoke	GetModuleHandle,NULL
	invoke	GetModuleFileName,eax,modPath,MAX_PATH
		cmp	eax,0
		je	.exit

		pusha
	invoke	OutputDebugString,modPath
		popa

		add	eax,modPath

	.trim:
	; ----
		dec	eax
		cmp	byte [eax],"\"
		jne	.trim

	.compare:
	; -------
	invoke	lstrcmpi,eax,modTargetAppName
		cmp	eax,0
		jne	.exit

		mov	[modTargetFound],1

		cmp	[patchH],0
		je	.exit

	invoke	SendMessage,[patchH],UM_FINDTARGETWINDOW,0,0

	.exit:
	; ----
		ret
endp


; ------------------------------ [ register patch window handle, send message here if target detected ]
proc RegisterPatchHandle _patchH
; ------------------------------
		push	[_patchH]
		pop	[patchH]
		ret
endp



; -------------------------------- [ register target window handle, ready to subclass ]
proc RegisterTargetHandle _targetH
; --------------------------------
		push	[_targetH]
		pop	[targetH]
	cinvoke	wsprintf,buff,d5,[_targetH]
	invoke	OutputDebugString,buff
		ret
endp


; -------------- [ target quits, set so that dll attach could re-detect ]
proc TargetQuits
; --------------
		mov	[modTargetFound],0
		ret
endp


; ----------------- [ subclass target window ]
proc TargetSubclass
; -----------------
	invoke	SetWindowLong,[targetH],GWL_WNDPROC,TargetWndProc
		cmp	eax,0
		je	.error
		push	eax
		pop	[procAddr]
	invoke	OutputDebugString,d7
		ret

	.error:
 	; -----
	invoke	GetLastError
	cinvoke	wsprintf,buff,d6,eax
	invoke	OutputDebugString,buff
		ret
endp



; ---------------- [ target subclass window procedure ]
proc TargetWndProc hwnd,msg,wparam,lparam
; ----------------

	.exit:
	; ----
	invoke	CallWindowProc,[procAddr],[hwnd],[msg],[wparam],[lparam]
		ret
endp


; ---------------------------------------------
section '.idata' import data readable writeable
; ---------------------------------------------
library	kernel32,	'KERNEL32.DLL',\
	user32,		'USER32.DLL'

include '%fasminc%\api\kernel32.inc'
include '%fasminc%\api\user32.inc'



; -----------------------------------
section '.edata' export data readable
; -----------------------------------
	export 'AUTO.DLL',\
		TargetQuits,			'TargetQuits',\
		RegisterPatchHandle,		'RegisterPatchHandle',\
		RegisterTargetHandle,		'RegisterTargetHandle',\
		TargetSubclass,			'TargetSubclass'



section '.reloc' fixups data discardable
; --------------------------------------
