Jump to content

What's needed to create _WinAPI_URLUnescape


Go to solution Solved by mistersquirrle,

Recommended Posts

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

 

Link to comment
Share on other sites

  • rcmaehl changed the title to What's needed to create _WinAPI_URLUnescape
  • Solution

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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