; misc !define CreateParentFolder "!insertmacro CreateParentFolder" !macro CreateParentFolder Path Push $1 ${GetParent} "${Path}" $1 CreateDirectory "$1" Pop $1 !macroend ; info !define IsLink "!insertmacro IsLink" !define IsSoftLink "!insertmacro IsSoftLink" !define IsHardLink "!insertmacro IsHardLink" Function IsSoftLink Exch $0 ${GetFileAttributes} "$0" "REPARSE_POINT" $0 ${If} $0 != "1" StrCpy $0 "0" ${EndIf} Exch $0 FunctionEnd !macro IsSoftLink Path outVar Push "${Path}" Call IsSoftLink Pop ${outVar} !macroend Function IsHardLink Exch $1 System::Call "kernel32::CreateFileW(w `$1`, i 0x40000000, i 0, i 0, i 3, i 0, i 0) i .r0" ${If} $0 = "-1" StrCpy $0 "0" goto is_hard_link_end ${EndIf} System::Call "*(&i256 0) i. r1" System::Call "kernel32::GetFileInformationByHandle(i r0, i r1) i .s" System::Call "kernel32::CloseHandle(i r0) i.r0" Pop $0 ${If} $0 == "0" goto is_hard_link_end ${EndIf} System::Call "*$1(&i40 0, &i4 .r0)" ${If} $0 != "0" IntOp $0 $0 - 1 ${EndIf} is_hard_link_end: Pop $1 FunctionEnd !macro IsHardLink Path outVar Push $0 Push "${Path}" Call IsHardLink StrCpy ${outVar} $0 Pop $0 !macroend !macro IsLink Path outVar ${IsSoftLink} "${Path}" ${outVar} ${If} ${outVar} == 0 ${IsHardLink} "${Path}" ${outVar} ${EndIf} !macroend ; files !define CreateHardLink "!insertmacro CreateHardLink" !define CreateSymbolicLinkFile "!insertmacro CreateSymbolicLinkFile" !define CreateLinkFile "!insertmacro CreateLinkFile" !define DeleteLinkFile "!insertmacro DeleteLinkFile" !macro CreateSymbolicLinkFile Junction Target outVar ${CreateParentFolder} "${Junction}" System::Call "kernel32::CreateSymbolicLinkW(w `${Junction}`, w `${Target}`, i 0) i .s" Pop ${outVar} ${If} ${outVar} == "error" StrCpy ${outVar} "0" ${EndIf} !macroend !macro CreateHardLink Junction Target outVar ${CreateParentFolder} "${Junction}" System::Call "kernel32::CreateHardLinkW(w `${Junction}`, w `${Target}`, i 0) i .s" Pop ${outVar} !macroend !macro CreateLinkFile Junction Target outVar ${CreateSymbolicLinkFile} "${Junction}" "${Target}" ${outVar} ${If} ${outVar} == 0 ${CreateHardLink} "${Junction}" "${Target}" ${outVar} ${EndIf} !macroend !macro DeleteLinkFile Path outVar ${IsLink} "${Path}" ${outVar} ${If} ${outVar} != 0 SetFileAttributes "${Path}" "NORMAL" System::Call "kernel32::DeleteFileW(w `${Path}`) i.s" Pop ${outVar} ${EndIf} !macroend ; folders !define CreateJunction "!insertmacro CreateJunction" !define CreateSymbolicLinkFolder "!insertmacro CreateSymbolicLinkFolder" !define CreateLinkFolder "!insertmacro CreateLinkFolder" !define DeleteLinkFolder "!insertmacro DeleteLinkFolder" Function CreateJunction Exch $4 Exch Exch $5 Push $1 Push $2 Push $3 Push $6 CreateDirectory "$5" System::Call "kernel32::CreateFileW(w `$5`, i 0x40000000, i 0, i 0, i 3, i 0x02200000, i 0) i .r6" ${If} $0 = "-1" StrCpy $0 "0" RMDir "$5" goto create_junction_end ${EndIf} CreateDirectory "$4" ; Windows XP requires that the destination exists StrCpy $4 "\??\$4" StrLen $0 $4 IntOp $0 $0 * 2 IntOp $1 $0 + 2 IntOp $2 $1 + 10 IntOp $3 $1 + 18 System::Call "*(i 0xA0000003, &i4 $2, &i2 0, &i2 $0, &i2 $1, &i2 0, &w$1 `$4`, &i2 0)i.r2" System::Call "kernel32::DeviceIoControl(i r6, i 0x900A4, i r2, i r3, i 0, i 0, *i r4r4, i 0) i.r0" System::Call "kernel32::CloseHandle(i r6) i.r1" ${If} $0 == "0" RMDir "$5" ${EndIf} create_junction_end: Pop $6 Pop $3 Pop $2 Pop $1 Pop $5 Pop $4 FunctionEnd !macro CreateJunction Junction Target outVar Push $0 Push "${Junction}" Push "${Target}" Call CreateJunction StrCpy ${outVar} $0 Pop $0 !macroend !macro CreateSymbolicLinkFolder Junction Target outVar ${CreateParentFolder} "${Junction}" System::Call "kernel32::CreateSymbolicLinkW(w `${Junction}`, w `${Target}`, i 1) i .s" Pop ${outVar} ${If} ${outVar} == "error" StrCpy ${outVar} "0" ${EndIf} !macroend !macro CreateLinkFolder Junction Target outVar ${CreateSymbolicLinkFolder} "${Junction}" "${Target}" ${outVar} ${If} ${outVar} == 0 ${CreateJunction} "${Junction}" "${Target}" ${outVar} ${EndIf} !macroend !macro DeleteLinkFolder Path outVar ${IsSoftLink} "${Path}" ${outVar} ${If} ${outVar} != 0 SetFileAttributes "${Path}" "NORMAL" System::Call "kernel32::RemoveDirectoryW(w `${Path}`) i.s" Pop ${outVar} ${EndIf} !macroend