rcmaehl Posted March 27, 2023 Share Posted March 27, 2023 (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 March 27, 2023 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 WhyNotWin11Cisco Finesse, Github, IRC UDF, WindowEx UDF Link to comment Share on other sites More sharing options...
Solution mistersquirrle Posted March 27, 2023 Solution Share Posted March 27, 2023 (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: expandcollapse popup#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 March 27, 2023 by mistersquirrle rcmaehl 1 We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
rcmaehl Posted March 28, 2023 Author Share Posted March 28, 2023 21 hours ago, mistersquirrle said: expandcollapsepopup expandcollapse popup#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 WhyNotWin11Cisco Finesse, Github, IRC UDF, WindowEx UDF Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now