Первое, на что нужно обратить внимание, это то, что внутренний строковый буфер PUNICODE_STRING может не заканчиваться нулем. Так что было бы лучше пройти через стандартную широкую строку с нулевым символом в конце, которая затем может быть передана прямо в SysAllocString.
Попробуйте это:
BSTR PUNICODEToBSTR(PUNICODE_STRING pStr)
{
// create a null-terminated version of the input string
wchar_t* nullTerminatedString = new wchar_t[pStr->Length + 1];
memset(nullTerminatedString, 0, sizeof(wchar_t) * (pStr->Length + 1)];
wcsncpy(nullTerminatedString, pStr->Buffer, pStr->Length);
// create a BSTR
BSTR bstrString = ::SysAllocString(nullTerminatedString);
// tidy-up and return the BSTR
delete [] nullTerminatedString;
return bstrString;
}