views:

564

answers:

2

Hi, I have a string that starts out in a .Net application, is encrypted and stored in AD. It's then picked up by a native C++ app and decrypted to produce an array of bytes e.g "ABCDEF" becomes 00,41,00,42,00,43,00,44,00,45 once it has been decrypted at the C++ end.

I need to take this byte array and convert it to the BSTR "ABCDEF" so that I can use it elsewhere and I can't find a way to acomplish this last step.

Can anybody help?

A: 

The "decrypted string" is just a Unicode string - latin characters contain the first byte equal to null when represented in Unicode. So you don't need any real conversion, just cook a BSTR out of that buffer.

Knowing the number of Unicode characters - it will be half the length of the buffer - call SysAllocStringLen() to allocate a long enough null-terminated uninitialized BSTR. Then copy your array onto the allocated string with memcpy(). Alternatively you can call SysAllocStringLen() and pass it the byte buffer so that it does the copy for you and skip the memcpy(). Don't forget to call SysFreeString() when you no longer need the BSTR.

sharptooth
Why create an uninitialized string and then copy the characters afterward? `SysAllocStringLen` will copy the characters for you if you let it.
Rob Kennedy
I think the presumption is that the characters are in some storage which can be streamed; in this case we can avoid allocation for the source buffer by streaming them directly into the BSTR. In practice, this likely doesn't matter in this particular case.
Pavel Minaev
@Rob Kennedy: Yes, quite a reasonable ammendment.
sharptooth
+1  A: 

If you really have an array of arbitrary bytes, use SysAllocStringByteLen. But it looks like, despite being in a byte array, your data is really a UTF-16-encoded Unicode string, so in that case, you're probably better off using SysAllocStringLen instead. Pass the byte-array pointer to the function (type-cast to OLECHAR*), and the characters will be copied into the new string for you, along with an additional null character at the end.

Rob Kennedy
Thanks for your answers. I'd already been down this road and what ends up in the BSTR is not a valid unicode string.Whan I print the BSTR to the console I get a bunch of ?s (oddly except for a space character that comes out correctly), the right number of ?s but not the correct characters.On the assumption that I've screwed up the console output I tested the BSTR against what shoud be in there and the tests fail. I'm using BSTR newStr = SysAllocStringLen((OLECHAR *)decryptedBytes, dataLength/2); to create the string. The decryptedBytes array does contain a valid byte stream 00,41... etc.
That may be an endianness problem - bytes within every Unicode char are swapped and you need to swap them back.
sharptooth
Doh! Thank you, that's the problem. It's working fine now :-)