Jump to content

DLL Function Call Issue: Missing Expected Return Value - (Moved)


Go to solution Solved by TheXman,

Recommended Posts

Posted (edited)

Hi,

I am having a problem invoking the "IdnToAscii" (documentation) function to convert an IDN hostname into its "Punycode" form.

Description:

I'm encountering a problem with the "IdnToAscii" function, when trying to convert an Internationalized Domain Name (IDN) to its ASCII equivalent using the "normaliz.dll" library. While the function call itself doesn't result in an error (returns 0), the output buffer doesn't contain the expected ASCII representation of the IDN.

Details:

  • I've confirmed that the "normaliz.dll" library is loaded correctly.
  • The parameters passed to the "IdnToAscii" function, including the Unicode string and buffer sizes, appear to be correct.
  • I'm using the following flags: 0x01 for IDN_ALLOW_UNASSIGNED.

Issue:

Despite these preparations, the function doesn't return the expected ASCII representation of the IDN in the output buffer. I've checked the function's return value, and it doesn't indicate an error.

I'm try to understand why the "IdnToAscii" function isn't providing the correct result. Any insights, suggestions, or guidance would be greatly appreciated.

Thank you in advance for your help!

Code:

 

#include <WinAPI.au3>
#include <Array.au3>

Local $dll = DllOpen(@SystemDir & "\normaliz.dll")
Local $unicodeDomain = "bücher.example.com"
Local $unicodeDomainPtr = DllStructCreate("wchar[" & StringLen($unicodeDomain) + 1 & "]")
DllStructSetData($unicodeDomainPtr, 1, $unicodeDomain)

Local $bufferSize = 255 ;Note that IDN names have a maximum length.
Local $output = DllStructCreate("wchar[" & $bufferSize & "]")

Local $returnValue = DllCall($dll, "wstr", "IdnToAscii", _
    "dword", 0x01, _
    "wstr", DllStructGetPtr($unicodeDomainPtr), _
    "int", StringLen($unicodeDomain), _
    "ptr", DllStructGetPtr($output), _
    "int", $bufferSize)

If @error Or Not IsArray($returnValue) Then
    MsgBox(16, "Error converting to Punycode", @error)
Else
    _ArrayDisplay($returnValue)
    MsgBox(64, "Punycode value", DllStructGetData($output, 1, 0))
    _WinAPI_GetLastErrorMessage()
    ConsoleWrite( @error & @CRLF)
EndIf
DllClose($dll)

 

 

Edited by oHenry

Regards.

Henry

  • Solution
Posted (edited)

You can compare the script below to your original one to see the differences.  If you have additional questions, feel free to ask.

int IdnToAscii(
  [in]            DWORD   dwFlags,
  [in]            LPCWSTR lpUnicodeCharStr,
  [in]            int     cchUnicodeChar,
  [out, optional] LPWSTR  lpASCIICharStr,
  [in]            int     cchASCIIChar
);

 

#include <WinAPI.au3>
#include <Array.au3>

;IDN (International Domain Name) Flags
Const $IDN_ALLOW_UNASSIGNED     = 0x01, _ ;Allow unassigned "query" behavior per RFC 3454
      $IDN_USE_STD3_ASCII_RULES = 0x02, _ ;Enforce STD3 ASCII restrictions for legal characters
      $IDN_EMAIL_ADDRESS        = 0x04, _ ;Enable EAI algorithmic fallback for email local parts behavior
      $IDN_RAW_PUNYCODE         = 0x08    ;Disable validation and mapping of punycode.

Global $hDll           = DllOpen("normaliz.dll")
Global $sUnicodeDomain = "bücher.example.com"
Global $tOutput        = DllStructCreate("wchar[255]") ;Note that IDN names have a maximum length.

Global $aResult        = DllCall($hDll, "int", "IdnToAscii", _
                                 "dword", $IDN_ALLOW_UNASSIGNED, _
                                 "wstr" , $sUnicodeDomain, _
                                 "int"  , StringLen($sUnicodeDomain), _
                                 "wstr" , DllStructGetPtr($tOutput), _
                                 "int"  , DllStructGetSize($tOutput) _
                                 )
If @error Then
    MsgBox(16, "DllCall Error", "@error = " & @error)
ElseIf $aResult[0] = 0 Then
    MsgBox(16, "Bad return code from DllCall", "Return value: " & $aResult[0])
    ConsoleWrite("ERROR: " & _WinAPI_GetLastErrorMessage() & @CRLF)
Else
    _ArrayDisplay($aResult)
    MsgBox(64, "Punycode value", $aResult[4])
EndIf
DllClose($hDll)

image.png.13bbf644e97c09ea2c09472285965494.png

image.png.808eb6353b76fd3b76b035682ed043ef.png

Click below to see the potential and/or actual issues with the script in your original post:

  Reveal hidden contents

 

Edited by TheXman
Posted
  On 10/1/2023 at 4:35 PM, TheXman said:

You can compare the script below to your original one to see the differences.  If you have additional questions, feel free to ask.

int IdnToAscii(
  [in]            DWORD   dwFlags,
  [in]            LPCWSTR lpUnicodeCharStr,
  [in]            int     cchUnicodeChar,
  [out, optional] LPWSTR  lpASCIICharStr,
  [in]            int     cchASCIIChar
);

 

#include <WinAPI.au3>
#include <Array.au3>

;IDN (International Domain Name) Flags
Const $IDN_ALLOW_UNASSIGNED     = 0x01, _ ;Allow unassigned "query" behavior per RFC 3454
      $IDN_USE_STD3_ASCII_RULES = 0x02, _ ;Enforce STD3 ASCII restrictions for legal characters
      $IDN_EMAIL_ADDRESS        = 0x04, _ ;Enable EAI algorithmic fallback for email local parts behavior
      $IDN_RAW_PUNYCODE         = 0x08    ;Disable validation and mapping of punycode.

Global $hDll           = DllOpen("normaliz.dll")
Global $sUnicodeDomain = "bücher.example.com"
Global $tOutput        = DllStructCreate("wchar[255]") ;Note that IDN names have a maximum length.

Global $aResult        = DllCall($hDll, "int", "IdnToAscii", _
                                 "dword", $IDN_ALLOW_UNASSIGNED, _
                                 "wstr" , $sUnicodeDomain, _
                                 "int"  , StringLen($sUnicodeDomain), _
                                 "wstr" , DllStructGetPtr($tOutput), _
                                 "int"  , DllStructGetSize($tOutput) _
                                 )
If @error Then
    MsgBox(16, "DllCall Error", "@error = " & @error)
ElseIf $aResult[0] = 0 Then
    MsgBox(16, "Bad return code from DllCall", "Return value: " & $aResult[0])
    ConsoleWrite("ERROR: " & _WinAPI_GetLastErrorMessage() & @CRLF)
Else
    _ArrayDisplay($aResult)
    MsgBox(64, "Punycode value", $aResult[4])
EndIf
DllClose($hDll)

image.png.13bbf644e97c09ea2c09472285965494.png

image.png.808eb6353b76fd3b76b035682ed043ef.png

Click below to see the potential and/or actual issues with the script in your original post:

  Reveal hidden contents

 

Expand  

Hi TheXman,

Excellent!

Thank you very much for taking the time to list the problems my script had. I really appreciate it.

 

Regards.

Henry

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
×
×
  • Create New...