News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

64-bit "Create Shortcut" example

Started by ognil, September 19, 2024, 10:35:34 PM

Previous topic - Next topic

ognil

Hi,

This example creates a shortcut to notepad.exe in the same directory. This is a 64-bit VS 2022 project
but it can also be compiled with makeit.bat. :thup:

; MSDN example
; https://learn.microsoft.com/en-us/windows/win32/shell/links#creating-a-shortcut-and-a-folder-shortcut-to-a-file

include  \masm32\include64\masm64rt.inc

.data

;********************************************
IID_IShellLinkA  dd 214EEh
dw 0,0,0c0h
db 0,0,0,0,0,46h
;********************************************
IID_IShellLinkW  dd 214F9h
dw 0,0,0c0h
db 0,0,0,0,0,46h
;********************************************
CLSID_ShellLink  dd 21401h
dw 0,0,0c0h
db 0,0,0,0,0,46h
;********************************************
IID_IPersistFile dd 10bh
dw 0,0,0c0h
db 0,0,0,0,0,46h
;********************************************
pIShellLink  dq 0
ppf          dq 0
lpszPathLink dw "t","o","N","o","t","e","p","a","d",".","l","n","k",0,0,0,0
lpszPathObj  db "C:\Windows\System32\notepad.exe",0
lpszDesc     db "Shortcut to Notepad",0
;*******************************************************************; 

.code
main                        proc                           
                            xor     ecx, ecx
                            mov     edx, 2
                            call    CoInitializeEx
                            call    Shortcut
                            call    CoUninitialize                   
                            xor     ecx, ecx
                            call    ExitProcess
main                        endp
;*******************************************************************; 
Shortcut                    proc
                           
                            lea     rax, pIShellLink                ; Result -> IID_IShellLinkW interface
                            lea     r9,  IID_IShellLinkA
                            mov     [rsp+4*8], rax
                            mov     r8d, 1                          ; 1 = CLSCTX_INPROC_SERVER
                            xor     edx, edx
                            lea     rcx, CLSID_ShellLink
                            call    CoCreateInstance
                            test    eax, eax                        ; eax = 0 -> Success
                            jne     Ret_0     ; return FALSE
                           
                            mov     rcx, pIShellLink                ; IID_IShellLinkW interface
                            lea     r8,  ppf                        ; Result -> IID_IPersistFile interface
                            mov     rax, [rcx]                      ; rax -> Vtbl with methods           
                            lea     rdx, IID_IPersistFile
                            call    qword ptr [rax+0*8]             ; IID_IShellLinkW::QueryInterface method = 0*8
                            test    eax, eax                        ; eax = 0 -> Success
                            jne     Ret_B                     ; return FALSE
                           
                            mov     rcx, pIShellLink                ; IID_IShellLinkW interface
                            mov     rax, [rcx]                      ; IID_IShellLink::IShellLinkAVtbl
                            lea     rdx, lpszPathObj                ; Pointer to ANSI string
                            call    qword ptr [rax+20*8]            ; IID_IShellLinkW::SetPath method in IShellLinkA = 20*8
                            test    eax, eax                        ; eax = 0 -> Success
                            jne     Ret_A
                           
                            mov     rcx, pIShellLink                ; IID_IShellLinkW interface
                            lea     rdx, lpszDesc                   ; Pointer to ANSI string
                            mov     rax, [rcx]                      ; IID_IShellLinkW::IShellLinkWVtbl ; Vtbl with methods 
                            call    qword ptr [rax+7*8]             ; IID_IShellLinkW::SetDescription method in IShellLinkAVtbl = 7*8
                            test    eax, eax                        ; eax = 0 -> Success
                            jne     Ret_A            
                           
                            mov     rcx, ppf                        ; IID_IPersistFile interface
                            lea     rdx, lpszPathLink               ; Pointer to Unicode string
                            xor     r8d, r8d                        ; fRemember parameter = 0
                            mov     rax, [rcx]                      ; IID_IPersistFile::Vtbl with methods
                            call    qword ptr [rax+6*8]             ; IID_IPersistFile::Save method = 6*8
                            test    eax, eax                        ; eax = 0 -> Success
                            jne     Ret_A
; ppf->Release()           
                            mov     rcx, ppf                        ; IID_IPersistFile interface
                            mov     rax, [rcx]                      ; IID_IPersistFile::Vtbl with methods
                            call    qword ptr [rax+2*8]             ; IID_IPersistFile::Release method
; pIShellLink->Release()   
                            mov     rcx, pIShellLink                ; IID_IShellLinkW interface
                            mov     rax, [rcx]                      ; IID_IShellLinkW::IShellLinkWVtbl ; Vtbl with methods
                            call    qword ptr [rax+2*8]             ; IID_IShellLinkW::Release method                     
                           
                            mov     eax, 1                          ; Return 1 -> success
                            ret
Ret_A:                     
; ppf->Release()           
                            mov     rcx, ppf                        ; IID_IPersistFile interface
                            mov     rax, [rcx]                      ; Vtbl with methods
                            call    qword ptr [rax+2*8]             ; IID_IPersistFile::Release method
Ret_B:                     
; pIShellLink->Release()   
                            mov     rcx, pIShellLink                ; IID_IShellLinkW interface
                            mov     rax, [rcx]                      ; Vtbl with methods
                            call    qword ptr [rax+2*8]             ; IID_IShellLinkW::Release method
Ret_0:                     
                            xor     eax, eax                        ; Error -> return FALSE
                            ret
Shortcut                    endp
;*******************************************************************;
end
"Not keeping emotions under control is another type of mental distortion."

zedd151

Nice.  :thumbsup:
You cannot view this attachment.
:azn:

ognil

Thank you zedd151, :thumbsup:

Quoteby zedd151:  I will delegate that task to the 64 bit gurus.

The "64 bit gurus" are probably still on long vacation... Just kidding... :biggrin:

"Not keeping emotions under control is another type of mental distortion."

zedd151

#3
Just because I don't write code in 64 bit, doesn't mean I can't test other peoples work.  :biggrin:

I had to adjust the paths btw - for my build environment - to make it work.  :cool:  attached below

for the source file:
"include  \masm32\include64\masm64rt.inc"
to
"include  \masm64\include64\masm64rt.inc"

for the batch file:
"\masm32\bin64\ml64.exe /c /nologo %appname%.asm"
"\masm32\bin64\polink.exe /SUBSYSTEM:WINDOWS /ENTRY:main %appname%.obj"
to
"\masm64\bin64\ml64.exe /c /nologo %appname%.asm"
"\masm64\bin64\link.exe /SUBSYSTEM:WINDOWS /ENTRY:main %appname%.obj"

and changed "polink" to "link", as I have removed polink from my install of the SDK. :smiley:

The attachment contains only what is needed to build without Visual Studio.
:azn: