PB:
Code: Select all
Interface _IPersistFile
QueryInterface(a, b)
AddRef()
Release()
GetClassID(a)
IsDirty()
Load(a, b)
Save(a.p-unicode, b)
SaveCompleted(a)
GetCurFile(a)
EndInterface
Interface _IShellLinkW
QueryInterface(a, b)
AddRef()
Release()
GetPath(a.p-unicode, b, c, d)
GetIDList(a)
SetIDList(a)
GetDescription(a.p-unicode, b)
SetDescription(a.p-unicode)
GetWorkingDirectory(a.p-unicode, b)
SetWorkingDirectory(a.p-unicode)
GetArguments(a.p-unicode, b)
SetArguments(a.p-unicode)
GetHotkey(a)
SetHotkey(a)
GetShowCmd(a)
SetShowCmd(a)
GetIconLocation(a.p-unicode, b, c)
SetIconLocation(a.p-unicode, b)
SetRelativePath(a, b)
Resolve(a, b)
SetPath(a.p-unicode)
EndInterface
ProcedureDLL CreateShortcut(Path.s, LINK.s, Argument.s, DESCRIPTION.s, WorkingDirectory.s, ShowCommand.l, IconFile.s, IconIndexInFile.l)
CoInitialize_(0)
If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLinkW,@psl._IShellLinkW) = 0
Set_ShellLink_preferences:
; The file TO which is linked ( = target for the Link )
;
psl\SetPath(Path)
; Arguments for the Target
;
psl\SetArguments(Argument)
; Working Directory
;
psl\SetWorkingDirectory(WorkingDirectory)
; Description ( also used as Tooltip for the Link )
;
psl\SetDescription(DESCRIPTION)
; Show command:
; SW_SHOWNORMAL = Default
; SW_SHOWMAXIMIZED = aehmm... Maximized
; SW_SHOWMINIMIZED = play Unreal Tournament
psl\SetShowCmd(ShowCommand)
; Hotkey:
; The virtual key code is in the low-order byte,
; and the modifier flags are in the high-order byte.
; The modifier flags can be a combination of the following values:
;
; HOTKEYF_ALT = ALT key
; HOTKEYF_CONTROL = CTRL key
; HOTKEYF_EXT = Extended key
; HOTKEYF_SHIFT = SHIFT key
;
psl\SetHotkey(HotKey)
; Set Icon for the Link:
; There can be more than 1 icons in an icon resource file,
; so you have to specify the index.
;
psl\SetIconLocation(IconFile, IconIndexInFile)
ShellLink_SAVE:
; Query IShellLink For the IPersistFile interface For saving the
; shortcut in persistent storage.
If psl\QueryInterface(?IID_IPersistFile,@ppf._IPersistFile) = 0
; Ensure that the string is Unicode.
;Save the link by calling IPersistFile::Save.
hres = ppf\Save(LINK,#True)
Result = 1
ppf\Release()
EndIf
psl\Release()
EndIf
CoUninitialize_()
ProcedureReturn Result
DataSection
CLSID_ShellLink:
; 00021401-0000-0000-C000-000000000046
Data.l $00021401
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IShellLink:
; DEFINE_SHLGUID(IID_IShellLinkA, 0x000214EEL, 0, 0);
; C000-000000000046
Data.l $000214EE
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IPersistFile:
; 0000010b-0000-0000-C000-000000000046
Data.l $0000010B
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IShellLinkW: ; {000214F9-0000-0000-C000-000000000046}
Data.l $000214F9
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection
EndProcedure
Code: Select all
format MS64 COFF
Public PB_CreateShortcut
Extrn SYS_FastAllocateString4
Extrn CoInitialize
Extrn CoCreateInstance
Extrn SYS_ToUnicode
Extrn CoUninitialize
Extrn SYS_FreeString
Extrn Droopy_l_iid_ishelllinkw
Extrn Droopy_l_clsid_shelllink
Extrn Droopy_l_iid_ipersistfile
section '.text' code readable executable
PB_CreateShortcut:
MOV qword [rsp+8],rcx
MOV qword [rsp+16],rdx
MOV qword [rsp+24],r8
MOV qword [rsp+32],r9
PUSH rbp
PUSH r15
PS116=160
MOV rdx,12
.ClearLoop:
SUB rsp,8
MOV qword [rsp],0
DEC rdx
JNZ .ClearLoop
SUB rsp,40
MOV rdx,[rsp+PS116+0]
LEA rcx,[rsp+40]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
MOV rdx,[rsp+PS116+8]
LEA rcx,[rsp+48]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
MOV rdx,[rsp+PS116+16]
LEA rcx,[rsp+56]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
MOV rdx,[rsp+PS116+24]
LEA rcx,[rsp+64]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
MOV rdx,[rsp+PS116+32]
LEA rcx,[rsp+72]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
MOV rdx,[rsp+PS116+48]
LEA rcx,[rsp+80]
SUB rsp,16
CALL SYS_FastAllocateString4
ADD rsp,16
; CoInitialize_(0)
PUSH qword 0
POP rcx
ADD rsp,-32
CALL CoInitialize
ADD rsp,32
; If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLinkW,@psl._IShellLinkW) = 0
ADD rsp,-8
LEA rax,[rsp+96]
MOV rax,rax
PUSH rax
MOV rbp,Droopy_l_iid_ishelllinkw
MOV rax,rbp
PUSH rax
PUSH qword 1
PUSH qword 0
MOV rbp,Droopy_l_clsid_shelllink
MOV rax,rbp
PUSH rax
POP rcx
POP rdx
POP r8
POP r9
ADD rsp,-32
CALL CoCreateInstance
ADD rsp,48
MOV r15,rax
AND r15,r15
JNE _EndIf115
;
; Set_ShellLink_preferences:
Droopy_l_set_shelllink_preferences:
aligngosub1
;
; The file TO which is linked ( = target for the Link )
;
; psl\SetPath(Path)
MOV rcx,qword [rsp+40]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+160]
ADD rsp,16
;
; Arguments for the Target
;
; psl\SetArguments(Argument)
MOV rcx,qword [rsp+56]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+88]
ADD rsp,16
;
; Working Directory
;
; psl\SetWorkingDirectory(WorkingDirectory)
MOV rcx,qword [rsp+72]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+72]
ADD rsp,16
;
; Description ( also used as Tooltip for the Link )
;
; psl\SetDescription(DESCRIPTION)
MOV rcx,qword [rsp+64]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+56]
ADD rsp,16
;
; Show command:
; SW_SHOWNORMAL = Default
; SW_SHOWMAXIMIZED = aehmm... Maximized
; SW_SHOWMINIMIZED = play Unreal Tournament
; psl\SetShowCmd(ShowCommand)
MOVSXD rax,dword [rsp+PS116+40]
MOV rax,rax
PUSH rax
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+120]
ADD rsp,16
;
; Hotkey:
; The virtual key code is in the low-order byte,
; and the modifier flags are in the high-order byte.
; The modifier flags can be a combination of the following values:
;
; HOTKEYF_ALT = ALT key
; HOTKEYF_CONTROL = CTRL key
; HOTKEYF_EXT = Extended key
; HOTKEYF_SHIFT = SHIFT key
;
; psl\SetHotkey(HotKey)
PUSH qword [rsp+96]
POP rdx
MOV rax,qword [rsp+88]
ADD rsp,-16
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+104]
ADD rsp,16
;
; Set Icon for the Link:
; There can be more than 1 icons in an icon resource file,
; so you have to specify the index.
;
; psl\SetIconLocation(IconFile, IconIndexInFile)
ADD rsp,-8
MOVSXD rax,dword [rsp+PS116+64]
MOV rax,rax
PUSH rax
MOV rcx,qword [rsp+96]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
POP r8
MOV rax,qword [rsp+96]
ADD rsp,-24
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+136]
ADD rsp,32
;
;
; ShellLink_SAVE:
Droopy_l_shelllink_save:
aligngosub2
; Query IShellLink For the IPersistFile interface For saving the
; shortcut in persistent storage.
; If psl\QueryInterface(?IID_IPersistFile,@ppf._IPersistFile) = 0
ADD rsp,-8
LEA rax,[rsp+112]
MOV rax,rax
PUSH rax
MOV rbp,Droopy_l_iid_ipersistfile
MOV rax,rbp
PUSH rax
POP rdx
POP r8
MOV rax,qword [rsp+96]
ADD rsp,-24
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax]
ADD rsp,32
MOV r15,rax
AND r15,r15
JNE _EndIf117
; Ensure that the string is Unicode.
;Save the link by calling IPersistFile::Save.
; hres = ppf\Save(LINK,#True)
ADD rsp,-8
PUSH qword 1
MOV rcx,qword [rsp+64]
SUB rsp,32
CALL SYS_ToUnicode
ADD rsp,32
PUSH rax
POP rdx
POP r8
MOV rax,qword [rsp+112]
ADD rsp,-24
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+48]
ADD rsp,32
MOV qword [rsp+112],rax
; Result = 1
MOV qword [rsp+120],1
; ppf\Release()
ADD rsp,-8
MOV rax,qword [rsp+112]
ADD rsp,-8
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+16]
ADD rsp,16
; EndIf
_EndIf117:
; psl\Release()
ADD rsp,-8
MOV rax,qword [rsp+96]
ADD rsp,-8
MOV rcx,rax
MOV rax,[rax]
CALL qword [rax+16]
ADD rsp,16
; EndIf
_EndIf115:
; CoUninitialize_()
ADD rsp,-32
CALL CoUninitialize
ADD rsp,32
; ProcedureReturn Result
MOV rax,qword [rsp+120]
JMP _EndProcedure117
;
; DataSection
; CLSID_ShellLink:
; 00021401-0000-0000-C000-000000000046
; Data.l $00021401
; Data.w $0000,$0000
; Data.b $C0,$00,$00,$00,$00,$00,$00,$46
; IID_IShellLink:
; DEFINE_SHLGUID(IID_IShellLinkA, 0x000214EEL, 0, 0);
; C000-000000000046
; Data.l $000214EE
; Data.w $0000,$0000
; Data.b $C0,$00,$00,$00,$00,$00,$00,$46
; IID_IPersistFile:
; 0000010b-0000-0000-C000-000000000046
; Data.l $0000010B
; Data.w $0000,$0000
; Data.b $C0,$00,$00,$00,$00,$00,$00,$46
;
; IID_IShellLinkW: ; {000214F9-0000-0000-C000-000000000046}
; Data.l $000214F9
; Data.w $0000, $0000
; Data.b $C0, $00, $00, $00, $00, $00, $00, $46
; EndDataSection
;
;
; EndProcedure
XOR rax,rax
_EndProcedure117:
PUSH rax
MOV rcx,qword [rsp+48]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
MOV rcx,qword [rsp+56]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
MOV rcx,qword [rsp+64]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
MOV rcx,qword [rsp+72]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
MOV rcx,qword [rsp+80]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
MOV rcx,qword [rsp+88]
SUB rsp,32
CALL SYS_FreeString
ADD rsp,32
POP rax
ADD rsp,136
POP r15
POP rbp
RET