;;;; DEVELOPER COMMENTS ARE IN CODE SECTION

format PE GUI 4.0
entry _start

include 'win32a.inc'

struc GUID def
 {
   match d1-d2-d3-d4-d5, def
    \{
      .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
    \}
 }

interface IMoniker,\
	  QueryInterface, AddRef, Release,\
	  BindToObject, BindToStorage, Reduce, ComposeWith, Enum, IsEqual, Hash, IsRunning, GetTimeOfLastChange, Inverse, \
	  CommonPrefixWith, RelativePathTo, GetDisplayName, ParseDisplayName, IsSystemMoniker

CLSCTX_INPROC_SERVER	    = 0x1

section '.udata' readable writeable

	_hheap	 dd ?
	_modfn	 dd ?
	_strbuf  dd ?

	_ShowHTMLDialog_library   dd ?

section '.data' readable writeable

	CLSID_URLMoniker GUID 79EAC9E0-BAF9-11CE-8C82-00AA004BA90B
	IID_IMoniker	 GUID 0000000f-0000-0000-C000-000000000046

	pURLMoniker IMoniker

	_fmt_ResURL db 'res://%s/DEFAULT.HTML',0
	_fmt_ImportLib db '%s\SYSTEM32\MSHTML.DLL',0

	_ShowHTMLDialog_api db 'ShowHTMLDialog',0
	ShowHTMLDialog dd 0

section '.code' code readable executable

_createHeap:
	invoke	GetProcessHeap
	mov	[_hheap],eax
	invoke	HeapAlloc,[_hheap],HEAP_ZERO_MEMORY,1000h
     ret

_start:
	; create some memory to make up the res:// href.
	call	_createHeap
	mov	[_strbuf],eax
	call	_createHeap
	mov	[_modfn],eax

	  ; get the filename and path of this application

	     ; FASM Forum question:
	     ; Compairing the next three lines with similar Code [##],
	     ; if I use just _strbuf instead of _modfn as well, I get
	     ; res://res://res://res:///DEFAULT.HTML instead of
	     ; res://C:\....exe/default.html.  How do I fix this?

	invoke	GetModuleFileName,0,[_modfn],100h
	invoke	wsprintf,[_strbuf],_fmt_ResURL,[_modfn]
	invoke	HeapFree,[_hheap],0,[_modfn]
	  ; so by now, _strbuf should have res://C:\....\HTMLDlg.EXE/DEFAULT.HTML

	    ; If you've scrolled to the rsrc section of this script, you might
	    ; have noticed that I havent included any DEFAULT.HTML statements.
	    ; I actually plan to do this later on using a third-party resource
	    ; editing program called reshacker.

	; Now to access the ShowHTMLDialog API from SYSTEM32\MSHTML.DLL.

	  ; To be honest, I have no idea what the next three lines do. Most of
	  ; the code in this script I actually cutnpasted from other FASM scripts
	  ; and translated code from Windows2003.PSDK C++ examples.

	  ; According to Ollydbg, the functions complete successfully, I think.

	invoke	CoInitialize,NULL
	invoke	CoCreateInstance,CLSID_URLMoniker,NULL,CLSCTX_INPROC_SERVER,IID_IMoniker,[pURLMoniker]
	invoke	CreateURLMoniker,[pURLMoniker],[_strbuf],[pURLMoniker]

	  ; link to MSHTML.DLL and call ShowHTMLDialog API

	call	_createHeap
	mov	[_ShowHTMLDialog_library],eax

;##
	  ; get Windows Directory
	invoke	GetWindowsDirectory,[_ShowHTMLDialog_library],100h
	  ; make the full path of MSHTML.dll
	invoke	wsprintf,[_ShowHTMLDialog_library],_fmt_ImportLib,[_ShowHTMLDialog_library]
;##

	  ; The following lines of code complete successfully according to Ollydbg
	  ; but beyond ExitProcess, no HTML dialog appears on the screen.

	invoke	LoadLibrary,[_ShowHTMLDialog_library]
	or	eax,eax
	jz	_terminate
	invoke	GetProcAddress,eax,_ShowHTMLDialog_api
	or	eax,eax
	jz	_terminate
	mov	[ShowHTMLDialog],eax
	invoke	ShowHTMLDialog,eax,[pURLMoniker],0,0,0

    _terminate:

    invoke  HeapFree,[_hheap],0,[_strbuf]

invoke	ExitProcess,0

section '.idata' import data readable writeable

  library kernel,	     'KERNEL32.DLL',\
	  user32,	     'USER32.DLL',\
	  urlmon,	     'urlmon.dll',\
	  ole,		     'OLE32.DLL'

  import kernel,\
	 LoadLibrary,	     'LoadLibraryA',\
	 FreeLibrary,	     'FreeLibrary',\
	 GetProcAddress,     'GetProcAddress',\
	 GetModuleHandle,    'GetModuleHandleA',\
	 GetModuleFileName,  'GetModuleFileNameA',\
	 GetWindowsDirectory,'GetWindowsDirectoryA',\
	 GetProcessHeap,     'GetProcessHeap',\
	 CreateProcess,      'CreateProcessA',\
	 CloseHandle,	     'CloseHandle',\
	 HeapAlloc,	     'HeapAlloc',\
	 HeapFree,	     'HeapFree',\
	 ExitProcess,	     'ExitProcess'

  import urlmon,\
	 CreateURLMoniker,  'CreateURLMoniker'

  import user32,\
	 wsprintf,	    'wsprintfA'

  import ole,\
	 CoInitialize,'CoInitialize',\
	 CoCreateInstance,'CoCreateInstance'
