Thread overview
core.exception.UnicodeException@src\rt\util\utf.d(400): illegal UTF-16 value
Sep 15, 2014
notna
Sep 15, 2014
notna
Sep 15, 2014
Ali Çehreli
Sep 16, 2014
AsmMan
Sep 16, 2014
notna
Sep 17, 2014
Marc Schütz
Sep 16, 2014
notna
September 15, 2014
Hi all.

somehow, for me, the following is against the "DMD philosophy", because this code builds successfully with DMD and the executable gives the expected result... but also the below strange messages...

CODE:
-----

    module main;

    import std.stdio;
    import std.c.windows.windows;

    pragma(lib, "user32.lib");
    pragma(lib, "Advapi32");


    void main(string[] args)
    {
    	WCHAR lpwszUsername[254];
    	debug writefln("lpwszUsername.sizeof is %s, WCHAR.sizeof is %s", lpwszUsername.sizeof, WCHAR.sizeof);
    	// DWORD dUsername2 = lpwszUsername.sizeof / WCHAR.sizeof;
    	DWORD dUsername2 = 254;
    	GetUserNameW(lpwszUsername.ptr, &dUsername2);
    	writefln("Welcome userW %s", lpwszUsername);
    	writeln();
    }

build command:
--------------
- dmd -v -w  main.d

OUTPUT incl. "ERROR":
---------------------

    core.exception.UnicodeException@src\rt\util\utf.d(400): illegal UTF-16 value
    ----------------
    0x0041022C
    0x004074B7
    0x004074A1
    0x00406E66
    0x00406DCF
    0x00406D28
    0x00406C41
    0x00406828
    0x0040678C
    0x0040B66E
    0x0040B643
    0x0040B559
    0x00408737
    0x754D338A in BaseThreadInitThunk
    0x7714BF32 in RtlInitializeExceptionChain
    0x7714BF05 in RtlInitializeExceptionChain
    Welcome userW <my account name here>

environment:
------------
- DMD32 D Compiler v2.066.0
- Win7 Enterprise, SP1, 64bit


Any ideas?
September 15, 2014
btw., thats the only thing I found for the given error... which is +10years old:
http://forum.dlang.org/thread/ccto20$18bq$1@digitaldaemon.com


On Monday, 15 September 2014 at 23:36:53 UTC, notna wrote:
> Hi all.
>
 ...
>
> OUTPUT incl. "ERROR":
> ---------------------
>
>     core.exception.UnicodeException@src\rt\util\utf.d(400): illegal UTF-16 value
>     ----------------
>     0x0041022C
>     0x004074B7
>     0x004074A1
>     0x00406E66
>     0x00406DCF
>     0x00406D28
>     0x00406C41
>     0x00406828
>     0x0040678C
>     0x0040B66E
>     0x0040B643
>     0x0040B559
>     0x00408737
>     0x754D338A in BaseThreadInitThunk
>     0x7714BF32 in RtlInitializeExceptionChain
>     0x7714BF05 in RtlInitializeExceptionChain
>     Welcome userW <my account name here>
>


September 15, 2014
On 09/15/2014 04:36 PM, notna wrote:

>          WCHAR lpwszUsername[254];
>          debug writefln("lpwszUsername.sizeof is %s, WCHAR.sizeof is
> %s", lpwszUsername.sizeof, WCHAR.sizeof);
>          // DWORD dUsername2 = lpwszUsername.sizeof / WCHAR.sizeof;
>          DWORD dUsername2 = 254;
>          GetUserNameW(lpwszUsername.ptr, &dUsername2);

You must make use of the returned value to slice your wstring. Something like this (not compiled):

    auto actualLength = GetUserNameW(lpwszUsername.ptr, &dUsername2);
    auto userName = lpwszUsername[0..actualLength];

Otherwise, D knows that lpwszUsername is a 254-char string and will try to print all of it.

Ali

September 16, 2014
On Monday, 15 September 2014 at 23:57:59 UTC, Ali Çehreli wrote:
> On 09/15/2014 04:36 PM, notna wrote:
>
> >          WCHAR lpwszUsername[254];
> >          debug writefln("lpwszUsername.sizeof is %s,
> WCHAR.sizeof is
> > %s", lpwszUsername.sizeof, WCHAR.sizeof);
> >          // DWORD dUsername2 = lpwszUsername.sizeof /
> WCHAR.sizeof;
> >          DWORD dUsername2 = 254;
> >          GetUserNameW(lpwszUsername.ptr, &dUsername2);
>
> You must make use of the returned value to slice your wstring. Something like this (not compiled):
>
>     auto actualLength = GetUserNameW(lpwszUsername.ptr, &dUsername2);
>     auto userName = lpwszUsername[0..actualLength];
>
> Otherwise, D knows that lpwszUsername is a 254-char string and will try to print all of it.
>
> Ali

GetUserNameW() return a zero on error and non-zero on success. The actual number of bytes copied into lpwszUsernam is in dUsername2.

auto userName = lpwszUsername[0..dUsername2];

September 16, 2014
Thanks Ali.

As always, your examples and explanations are amazingly clear and "easy to understand".


On Monday, 15 September 2014 at 23:57:59 UTC, Ali Çehreli wrote:
> You must make use of the returned value to slice your wstring. Something like this (not compiled):
>
>     auto actualLength = GetUserNameW(lpwszUsername.ptr, &dUsername2);
>     auto userName = lpwszUsername[0..actualLength];
>
> Otherwise, D knows that lpwszUsername is a 254-char string and will try to print all of it.
>
> Ali

September 16, 2014
Thanks AsmMan,

Found http://msdn.microsoft.com/en-us/library/windows/desktop/ms724432%28v=vs.85%29.aspx and with your help, now understand :)

The syntax below prints a blank after my username, so the slice seems a bit too long :O So my "final solution" looks like:

 module main;

 import std.stdio;
 import std.c.windows.windows;

 pragma(lib, "user32.lib");
 pragma(lib, "Advapi32");

 void main(string[] args)
 {
    WCHAR lpwszUsername[254];
    DWORD dUsername2 = 254;
    GetUserNameW(lpwszUsername.ptr, &dUsername2);
    writefln("Welcome userW %s", lpwszUsername[0..(dUsername2 - 1));
    writeln();
  }

THANKS again!!!

On Tuesday, 16 September 2014 at 00:03:55 UTC, AsmMan wrote:
>
> GetUserNameW() return a zero on error and non-zero on success. The actual number of bytes copied into lpwszUsernam is in dUsername2.
>
> auto userName = lpwszUsername[0..dUsername2];

September 17, 2014
On Tuesday, 16 September 2014 at 20:19:24 UTC, notna wrote:
> Thanks AsmMan,
>
> Found http://msdn.microsoft.com/en-us/library/windows/desktop/ms724432%28v=vs.85%29.aspx and with your help, now understand :)
>
> The syntax below prints a blank after my username, so the slice seems a bit too long :O So my "final solution" looks like:

Most likely because the length returned by `GetUserNameW()` includes the trailing zero byte.