Reputation:
From the wincrypt api I am receiving a void* pointing to a char*.
This char* is pointing to the start of a char[]. I am also receiving a void*
pointing to a int with the size of the char*
.
Regarding pvData and cbData I have the following documentation from Microsoft.
Data type of pvData: A pointer to an array of BYTE values. The size of this array is specified in the cbData parameter. Returns a null-terminated Unicode character string that contains the display name for the certificate.
I want to convert this void*
to a std::string
but so far all I am getting when outputting my std::string
is the first character.
I have read: Converting a void* to a std::string but since my void*
is pointing to a char*
instead of std::string
the static_cast
in the accepted answer fails and the returned std::string*
triggers a null pointer exception.
So far I have the following:
// pvData = void* pointing to char*
// cbData = void* pointing to int*
std::string tempName;
tempName.assign(static_cast<char*>(pvData), static_cast<int*>(cbData));
printf("%S \n", pvData); // entire string is shown
printf("%s \n", tempName.c_str()); // only first character is shown
I have also tried
tempName = static_cast<char*>(pvData); // only single character returned
tempName.assign(static_cast<char*>(pvData)); // only single character returned
char* arr = static_cast<char*>(pvData);
std::string tempName(arr); // only single character returned empty with printf must
// use std::cout
Upvotes: 0
Views: 5438
Reputation: 308091
The documentation specifically states that it returns a Unicode string, which in Microsoft-speak means UTF-16. Characters that are part of the ASCII range will contain a zero in their second byte, which ends a string copy prematurely. You would get better results using wstring
with a cast to wchar_t*
.
If copying to string appears to work, it's because those zero bytes are invisible.
Putting this in the context of your original code:
std::wstring tempName;
tempName.assign(static_cast<wchar_t*>(pvData), (*static_cast<int*>(cbData)) / sizeof(wchar_t));
printf("%S \n", tempName.c_str());
Note that this isn't the easiest way to do it, you should also follow the advice from qxz regarding the string constructor and the passing of cbData
.
Upvotes: 1
Reputation: 3854
If the char buffer isn't null-terminated, then to use the (void*)cbData
length:
char* data = static_cast<char*>(pvData);
size_t len = *static_cast<int*>(cbData);
std::string tempName(data, len);
See the std::string
constructor reference (#5, from buffer) and ::assign
reference (#4, buffer).
EDIT: If you're trying to use the function CertGetCertificateContextProperty with dwPropId
CERT_FRIENDLY_NAME_PROP_ID
, here is how you should call the function:
CERT_CONTEXT ctx;
BYTE buf[100];
DWORD len = 100;
CertGetCertificateContextProperty(&ctx, CERT_FRIENDLY_NAME_PROP_ID, buf, &len);
std::string tempName(reinterpret_cast<char*>(buf), len);
No dealing with void*
pointers!
Upvotes: 5