Jump to content

What's needed to create _WinAPI_URLUnescape


Go to solution Solved by mistersquirrle,

Recommended Posts

Posted (edited)

Hi all,

Can someone give me a rundown on what all is needed to create a WinAPI function. I'm not a real programmer yet so DLLStructures and DLLCalls still escape me. I'd like to call URLUnescape as existing autoit UDF solutions for Unicode/UTF-8 have issues on non-English Windows builds. 

I'm assuming I need something similar to

Func _WinHTTPURLUnescape($sURL, $bFlag)
    Local $aCall = DllCall("shlwapi.dll", "UrlUnescape", _
            "pstr", $sURL, _
            "dwFlags", $bFlag)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc

 

but I know this isn't fully right. As I know $sURL is a string and not a pointer to a string and I honestly have no clue how to create, manage, or remove pointers in autoit.

Thanks all

Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11
Cisco FinesseGithubIRC UDFWindowEx UDF

 

  • rcmaehl changed the title to What's needed to create _WinAPI_URLUnescape
  • Solution
Posted (edited)

I'm not that familiar with DllStructs and calls myself, but I've been using them a bit lately, so I gave this a try. Check this out, it seems to work for me. I have a couple of test strings in there and they all do what's expected. For the first one, it should be run through the function until the StringLen doesn't change, so put a URL through it until there's no changes:

#include <WinAPI.au3>

Global $asUrls[] = [ _
        'https%253A%252F%252Flearn.microsoft.com%252Fen-us%252Fwindows%252Fwin32%252Fseccrypto%252Fcommon-hresult-values', _
        'https%3A%2F%2Fwww.autoitscript.com%2Fforum%2Ftopic%2F209966-whats-needed-to-create-_winapi_urlunescape%2F', _
        '\vbnet%20code%20library\', _
        'https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlescapew' _
        ]
Global $sReturn

For $iIndex = 0 To UBound($asUrls) - 1
    $sReturn = _WinAPI_UrlUnescape($asUrls[$iIndex])
    If @error Then
        ConsoleWrite('Error: ' & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite('Output ' & $iIndex & ': ' & $sReturn & @CRLF)
Next

Func _WinAPI_UrlUnescape($sUrl, $dFlags = 0)

    ; https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlunescapew
    Local $aUrlUnescape = DllCall("Shlwapi.dll", "long", "UrlUnescapeW", _
            "wstr", $sUrl, _ ; PWSTR pszUrl - A pointer to a null-terminated string with the URL
            "wstr", "decodedUrl", _ ; PWSTR pszUnescaped - A pointer to a buffer that will receive a null-terminated string that contains the unescaped version of pszURL
            "dword*", 1024, _ ; DWORD *pcchUnescaped - The number of characters in the buffer pointed to by pszUnescaped
            "dword", $dFlags) ; DWORD dwFlags
    If @error Then
        ConsoleWrite('UrlUnescape error: ' & @error & ', LastErr: ' & _WinAPI_GetLastError() & ', LastMsg: ' & _WinAPI_GetLastErrorMessage() & @CRLF)
        Return SetError(@error, @extended, 0)
    EndIf

    If IsArray($aUrlUnescape) Then
        For $iIndex = 0 To UBound($aUrlUnescape) - 1
            ConsoleWrite('    $aUrlUnescape[' & $iIndex & ']: ' & VarGetType($aUrlUnescape[$iIndex]) & ' - ' & $aUrlUnescape[$iIndex] & @CRLF)
        Next
    EndIf

    Return $aUrlUnescape[2]
EndFunc   ;==>_WinAPI_UrlUnescape

 

Edit: Note that there is nothing special about this line: "wstr", "decodedUrl", the "decodedUrl" can be anything, really, even just 0 works.

Edited by mistersquirrle

We ought not to misbehave, but we should look as though we could.

Posted
21 hours ago, mistersquirrle said:

expandcollapsepopup

#include <WinAPI.au3>

Global $asUrls[] = [ _
        'https%253A%252F%252Flearn.microsoft.com%252Fen-us%252Fwindows%252Fwin32%252Fseccrypto%252Fcommon-hresult-values', _
        'https%3A%2F%2Fwww.autoitscript.com%2Fforum%2Ftopic%2F209966-whats-needed-to-create-_winapi_urlunescape%2F', _
        '\vbnet%20code%20library\', _
        'https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlescapew' _
        ]
Global $sReturn

For $iIndex = 0 To UBound($asUrls) - 1
    $sReturn = _WinAPI_UrlUnescape($asUrls[$iIndex])
    If @error Then
        ConsoleWrite('Error: ' & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite('Output ' & $iIndex & ': ' & $sReturn & @CRLF)
Next

Func _WinAPI_UrlUnescape($sUrl, $dFlags = 0)

    ; https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlunescapew
    Local $aUrlUnescape = DllCall("Shlwapi.dll", "long", "UrlUnescapeW", _
            "wstr", $sUrl, _ ; PWSTR pszUrl - A pointer to a null-terminated string with the URL
            "wstr", "decodedUrl", _ ; PWSTR pszUnescaped - A pointer to a buffer that will receive a null-terminated string that contains the unescaped version of pszURL
            "dword*", 1024, _ ; DWORD *pcchUnescaped - The number of characters in the buffer pointed to by pszUnescaped
            "dword", $dFlags) ; DWORD dwFlags
    If @error Then
        ConsoleWrite('UrlUnescape error: ' & @error & ', LastErr: ' & _WinAPI_GetLastError() & ', LastMsg: ' & _WinAPI_GetLastErrorMessage() & @CRLF)
        Return SetError(@error, @extended, 0)
    EndIf

    If IsArray($aUrlUnescape) Then
        For $iIndex = 0 To UBound($aUrlUnescape) - 1
            ConsoleWrite('    $aUrlUnescape[' & $iIndex & ']: ' & VarGetType($aUrlUnescape[$iIndex]) & ' - ' & $aUrlUnescape[$iIndex] & @CRLF)
        Next
    EndIf

    Return $aUrlUnescape[2]
EndFunc   ;==>_WinAPI_UrlUnescape

Ah. So I can ignore pointers entirely if I specifically tell it so. Good to know. 

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...