Skip to content
⌘ NSIS Forum Archive

How can I extract the address of a website from a link?

12 posts

Coby#

How can I extract the address of a website from a link?

Hello!
Does anyone know how to extract the base address of a website from a link
Example link: https://www.youtube.com/watch?v=1BmcE6OFRyE
Example website: https://www.youtube.com/
Anders#
You can manually parse with NSIS string functions or call InternetCrackUrl with the system plug-in.
Coby#
On this subject, my knowledge is minimal, so I have not managed to solve this problem.
The code below shows me a negative result.
However, someone can help me with this issue.

# DETAILS #
Name "CrackUrl"
OutFile "CrackUrl.exe"
InstallDir "$TEMP\CrackUrl"
# COMPRESS #
SetCompressor /SOLID /FINAL lzma
# ELEVATED #
RequestExecutionLevel 'User'
# RUNTIME SWITCHES #
ShowInstDetails hide
ShowInstDetails nevershow
ShowUnInstDetails nevershow
AutoCloseWindow true 
# INCLUDE #
!include "MUI.nsh"
!include "WinCore.nsh"
!include "nsDialogs.nsh"
!include "FileFunc.nsh"
!include "LogicLib.nsh"
!include "WinMessages.nsh"
# STYLE #
BrandingText /TRIMRIGHT " "
# PAGE #
Page custom "PageWelcomeShow" ""
Page 'InstFiles'
# LANGUAGE #
!insertmacro MUI_LANGUAGE "English"
# INIT #
Function ".onInit"
FunctionEnd
# WELCOME #
Function "PageWelcomeShow" 
  var /GLOBAL Lbl.Add.Url
  var /GLOBAL PATH_Link
  var /GLOBAL Btn_Check
  var /GLOBAL Lbl.ShowLink1
  var /GLOBAL Lbl.ShowLink2
  var /GLOBAL Lbl.ShowLink3
  GetDlgItem $0 $HWNDPARENT 1
  EnableWindow $0 1
  nsDialogs::Create /NOUNLOAD 1044
  Pop $0
  ${If} $0 == error
    Abort
  ${EndIf}
  # Add Url # 
  nsDialogs::CreateControl /NOUNLOAD STATIC 0x40000000|0x10000000|0x04000000|0x00000100 0x00000020 5% 5% 90% 4% "Add your url:"  
  Pop $Lbl.Add.Url 
  nsDialogs::CreateControl /NOUNLOAD EDIT 0x40000000|0x10000000|0x04000000|0x00010000|0x00000080 0 5% 15% 72% 5% "" 
  Pop $PATH_Link
  nsDialogs::CreateControl /NOUNLOAD BUTTON 0x40000000|0x10000000|0x04000000|0x00010000 0 80% 15% 15% 5% "Check"
  Pop $Btn_Check
  StrCpy $1 $Btn_Check
  GetFunctionAddress $3 ".onClick.CrackUrl"
  nsDialogs::onClick /NOUNLOAD $1 $3
  nsDialogs::CreateControl /NOUNLOAD STATIC 0x40000000|0x10000000|0x04000000|0x00000100 0x00000020 5% 40% 85% 5% ""
  Pop $Lbl.ShowLink1
  nsDialogs::CreateControl /NOUNLOAD STATIC 0x40000000|0x10000000|0x04000000|0x00000100 0x00000020 5% 45% 85% 5% ""
  Pop $Lbl.ShowLink2
  nsDialogs::CreateControl /NOUNLOAD STATIC 0x40000000|0x10000000|0x04000000|0x00000100 0x00000020 5% 50% 85% 5% ""
  Pop $Lbl.ShowLink3
  nsDialogs::Show
FunctionEnd
!define INTERNET_MAX_HOST_NAME_LENGTH 256
!define INTERNET_MAX_USER_NAME_LENGTH 128
!define INTERNET_MAX_PASSWORD_LENGTH 128
!define INTERNET_MAX_PORT_NUMBER_LENGTH 5
!define INTERNET_MAX_PORT_NUMBER_VALUE 65535
!define INTERNET_MAX_PATH_LENGTH 2048
!define INTERNET_MAX_SCHEME_LENGTH 32
!define INTERNET_MAX_URL_LENGTH ${INTERNET_MAX_SCHEME_LENGTH} + 3 ${INTERNET_MAX_PATH_LENGTH}
Function ".onClick.CrackUrl"
  var /GLOBAL LINK
  ${NSD_GetText} $PATH_LINK $0
  StrCpy $LINK "$0"
  System::Call "Wininet.dll::InternetCrackUrlA(t '$LINK', i ${INTERNET_MAX_PATH_LENGTH}, i 0) i .r0" 
  ${If} $0 == "1" 
    SendMessage $Lbl.ShowLink1 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Else}
    SendMessage $Lbl.ShowLink1 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Endif}
  System::Call "Wininet.dll::InternetCrackUrlW(t '$LINK', i ${INTERNET_MAX_PATH_LENGTH}, i 0) i .r0" 
  ${If} $0 == "1" 
    SendMessage $Lbl.ShowLink2 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Else}
    SendMessage $Lbl.ShowLink2 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Endif}
  System::Call "Winhttp.dll::WinHttpCrackUrl(t '$LINK', i ${INTERNET_MAX_PATH_LENGTH}, i 0) i .r0" 
  ${If} $0 == "1" 
    SendMessage $Lbl.ShowLink3 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Else}
    SendMessage $Lbl.ShowLink3 ${WM_SETTEXT} 0 "STR:Result: $0"
  ${Endif}
FunctionEnd
# SECTION #
Section "MAIN" SEC01
SectionEnd
# End #
Function ".onGUIEnd"
FunctionEnd 
Anders#
You can't just guess what the system syntax is, you should not mix A/W functions and the t string type etc.

Just looking for / or ? or # after ://* should be doable with just StrCmp and StrCpy in a loop.
Anders#
Not pretty:

Section
!macro Test URL
StrCpy $8 "${URL}"
!if "${NSIS_PTR_SIZE}" > 4
System::Call '*(&l8,p,i1,i,p,i1,i,p,&i8,p,&i8,p,&i8 1,p,&i8)p.r1'
!else
System::Call '*(&l4,p,i1,i,p,i1,i,p,i,p,i,p,i1,p,i)p.r1'
!endif
System::Call 'WinINet::InternetCrackUrl(t r8, i0, i0, pr1)i.r0'
System::Call '*$1(p,p.r5,i,i,p,p,i,i,p,p,p,p.r7)'
System::Free $1
!include Util.nsh
!ifndef IntPtrOp
!define IntPtrOp IntOp
!endif
${IntPtrOp} $3 $7 - $5
!if "${NSIS_CHAR_SIZE}" > 1
IntOp $3 $3 / 2
!endif
StrCpy $8 $8 $3
DetailPrint "|$8| from ${URL}"
!macroend
!insertmacro Test "https://example.com/foo?bar=baz#top"
!insertmacro Test "https://example.com/foo"
!insertmacro Test "https://example.com/"
!insertmacro Test "https://example.com"
!insertmacro Test "https://example"
SectionEnd 
Coby#
Thanks Anders, you're phenomenal.
Unfortunately, the NSIS 2.51 version shows an error but works with version 3.0
Coby#
Error code

!include: "C:\Program Files\NSIS\Include\MUI2.nsh"
!include: "C:\Program Files\NSIS\Contrib\Modern UI 2\MUI2.nsh"
NSIS Modern User Interface version 2.0 - Copyright 2002-2009 Joost Verburg (C:\Program Files\NSIS\Contrib\Modern UI 2\MUI2.nsh:8)
!define: "MUI_INCLUDED"=""
!define: "MUI_SYSVERSION"="2.0"
!define: "MUI_VERBOSE"="3"
!include: closed: "C:\Program Files\NSIS\Contrib\Modern UI 2\MUI2.nsh"
!include: closed: "C:\Program Files\NSIS\Include\MUI2.nsh"
!include: "C:\Program Files\NSIS\Include\WinCore.nsh"
!define: "__WIN_WINDOWS__INC"=""
!include: closed: "C:\Program Files\NSIS\Include\WinCore.nsh"
!include: "C:\Program Files\NSIS\Include\nsWindows.nsh"
!define: "NSWINDOWS_INCLUDED"=""
!include: closed: "C:\Program Files\NSIS\Include\nsWindows.nsh"
!include: "C:\Program Files\NSIS\Include\LogicLib.nsh"
!include: closed: "C:\Program Files\NSIS\Include\LogicLib.nsh"
!include: "C:\Program Files\NSIS\Include\FileFunc.nsh"
!verbose expects 1 parameters, got 2.
Usage: !verbose verbose_level | push | pop
!include: error in script: "C:\Program Files\NSIS\Include\FileFunc.nsh" on line 71
Anders#
How is that error related to this thread? You are mixing NSIS versions and headers or something but it is in no way related to this URL question.
Coby#
The error mentioned above is related to this topic
NSIS 2.51 produces the above error in this code

# DETAILS #
OutFile "CrackUrl.exe"
InstallDir "$TEMP"
# COMPRESS #
SetCompressor /SOLID /FINAL lzma
# RUNTIME SWITCHES #
ShowInstDetails show
AutoCloseWindow true 
# INCLUDE #
!include "MUI2.nsh"
!include "WinCore.nsh"
!include "nsWindows.nsh"
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!include "WinMessages.nsh"
!include "WordFunc.nsh"
!insertmacro WordFind
!insertmacro WordFind2X
!insertmacro StrFilter
# STYLE #
BrandingText /TRIMRIGHT " "
# PAGE #
Page InstFiles
# LANGUAGE #
!insertmacro MUI_LANGUAGE "English"
var /global BASEURL
var /global Link
var /global SOURCELINK
Section "" SEC01
 Strcpy $LINK "https://www.youtube.com/watch?v=1BmcE6OFRyE"
!macro Test URL 
  StrCpy $8 "${URL}" 
  !if "${NSIS_PTR_SIZE}" > 4 
    System::Call '*(&l8,p,i1,i,p,i1,i,p,&i8,p,&i8,p,&i8 1,p,&i8)p.r1' 
  !else 
    System::Call '*(&l4,p,i1,i,p,i1,i,p,i,p,i,p,i1,p,i)p.r1' 
  !endif 
  System::Call 'WinINet::InternetCrackUrl(t r8, i0, i0, pr1)i.r0' 
  System::Call '*$1(p,p.r5,i,i,p,p,i,i,p,p,p,p.r7)' 
  System::Free $1 
  !include Util.nsh
   ${IntPtrOp} $3 $7 - $5 
  !if "${NSIS_CHAR_SIZE}" > 1 
    IntOp $3 $3 / 2 
  !endif 
  StrCpy $8 $8 $3 
  DetailPrint "|$8| from ${URL}" 
  Strcpy $BASEURL "$8"
!macroend 
  !insertmacro Test "$LINK" 
  ${WordFind} $LINK "://" "+01{" $SOURCELINK
  ${StrFilter} $SOURCELINK "-" "" "" $SOURCELINK
  ${If} $SOURCELINK == "http" 
    DetailPrint "$BASEURL"
   
   Abort
  ${ElseIf} $SOURCELINK == "https"
    DetailPrint "$BASEURL"
   Abort
  ${EndIf}
SectionEnd 
# End #
Function ".onGUIEnd"
FunctionEnd 
Anders#
It is not related. I gave you exactly what you asked for and now you have moved onto some other type of parsing using headers where you claim there is a bug.

If there is indeed some type of bug then you should be able to replicate it with just a line or two and post a bug report. Instead of being helpful you insist on including useless details like BrandingText and MUI when they are totally irrelevant and I have told you this multiple times but you don't seem to get the message. Now you get to enjoy a little timeout...
JasonFriday13#
You used a 3.0 header with a 2.51 install, which is why you are getting a !verbose error because 2.51 doesn't support that syntax. USE THE HEADERS THAT COME FROM THE SAME VERSION.