Unicode Literals in Windows

While coding up the BCrypt interop API, there were a lot of unicode string literals in the Windows header.  They look like this:

-- DeriveKey KDF Types
 BCRYPT_KDF_HASH                     = L"HASH";
 BCRYPT_KDF_HMAC                     = L"HMAC";
 BCRYPT_KDF_TLS_PRF                  = L"TLS_PRF";
 BCRYPT_KDF_SP80056A_CONCAT          = L"SP800_56A_CONCAT";

In Windows programming, a Unicode literal is expressed in this way.  It’s a compiler thing, where the compiler will see the ‘L’ and know that what follows is a unicode literal.

Well, I want the same thing to happen in Lua, but the Lua compiler doesn’t know anything about expressing Unicode string literals.  But, it is very flexible, so how about it?

First, the MultiByteToWideChar() function will turn an ascii string into a unicode string, when fed the right parameters.  Given a little wrapper, this becomes an easy function to call in Lua:

local function AnsiToUnicode16(in_Src)
  local nsrcBytes = #in_Src

  -- find out how many characters needed
  local charsneeded = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, nil, 0);

  if charsneeded < 0 then
    return nil;
  end
  local buff = ffi.new("uint16_t[?]", charsneeded+1)
  local charswritten = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, buff, charsneeded)
  buff[charswritten] = 0

  return ffi.string(buff, (charswritten*2)+1);
end

So, with this in hand, it’s pretty easy to do this:

local BCRYPT_KDF_HASH = AnsiToUnicode16("HASH");

Here’s where Lua’s flexibility and little quirks make things a bit easier. First of call, it’s pretty easy to alias a function with another name.

local L = AnsiToUnicode16
local BCRYPT_KDF_HASH = L("HASH");

Second, as it turns out, if the function has a single string parameter, you can just drop the ‘(‘, and just use the ” on its own. These two combined give you this:

local L = AnsiToUnicode16
local BCRYPT_KDF_HASH = L"HASH";

And there you have it! Now, whenever you’re calling one of those “…W()” functions within Windows, you can just use this little mechanism, and you’re all set.

And who said Lua doesn’t do Unicode?

Advertisements


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s