UINT __stdcall CreateUUID()
{
UUID uuid;
HKEY hOpenKey = NULL;
if( UuidCreate( &uuid ) == RPC_S_OK )
{
char *oldStr = NULL;
char *tmpBin = NULL;
int ret;
tmpBin = (char *) &uuid;
oldStr = new char[22];
ret = base64encode( tmpBin, oldStr, sizeof(UUID), 22);
// now add bytes
char* newStr = new char[44];
for (int i = 0; i < 22; i++)
{
newStr[i*2] = oldStr[i];
newStr[i*2 + 1] = 0;
}
DWORD dwDisp;
if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\My Company\\Client"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hOpenKey, &dwDisp ) == ERROR_SUCCESS )
{
// only update key if it doeson't exist
if(dwDisp == REG_CREATED_NEW_KEY){
RegSetValueEx( hOpenKey, L"MyUUID", 0, REG_SZ, (unsigned char *) (newStr), 44 );
RegCloseKey( hOpenKey );
}
}
}
return ERROR_SUCCESS;
}
-
-
What sort of bug? Is it simply breaking, in which case you might want to try stepping through in the compiler (a good idea anyway), or is it returning an incorrect UUID, or is the registry value not being set?
-
You're passing an ANSI string to RegSetValueEx with a value of REG_SZ. It needs to be a Unicode string.
EDIT: I take that back. You're doing the oldStr/newStr thing.
Hmmm. Do you have the endianness backwards?
EDIT2: Also you're dropping a lot of new'd memory on the floor. Consider static arrays:
char oldStr[22];
instead of
char *oldStr = new char[22]; -
-
I believe that I explained it the last time you asked. You are sending hand-coded bytes to API's expecting Unicode strings. Use the ANSI version of the API if you don't feel like messing with Unicode.
-
evildictaitor wrote:What sort of bug? Is it simply breaking, in which case you might want to try stepping through in the compiler (a good idea anyway), or is it returning an incorrect UUID, or is the registry value not being set?
It works on a lot of machines, but it's failing here and there on particular machines. I don't yet have the tooling to capture the environment details for those situations... but I thought I'd see if anything was real obvious.
Disclaimer: I'm one of those C# non-programmers who hasn't done any serious C++ since my undergrad work.
-
JChung2006 wrote:I believe that I explained it the last time you asked. You are sending hand-coded bytes to API's expecting Unicode strings. Use the ANSI version of the API if you don't feel like messing with Unicode.
Does that explain the intermittent behavior?
I'll try to do a proper Unicode version and see if that helps.
-
OK, I'm slowing working your code into mine. But what I've found so far is that your buffers seem to be a little short... that's why I try to avoid using raw buffers...

You can see that the ATL routine requires a buffer of 26 chars.
Now I know that this particular routine does need more chars than strictly necessary (two more, I think), so my guess is that your 22 char buffer is too short... -
RichardRudek wrote:OK, I'm slowing working your code into mine. But what I've found so far is that your buffers seem to be a little short... that's why I try to avoid using raw buffers...

You can see that the ATL routine requires a buffer of 26 chars.
Now I know that this particular routine does need more chars than strictly necessary (two more, I think), so my guess is that your 22 char buffer is too short...
Wish I could use the ATL routine.
I must have my math mixed up. If anything, I thought 16 bytes encoded base64 would end up as 24 characters if you included the "==".
-
Larsenal wrote:
Wish I could use the ATL routine.
Why can't you ?
Anyway, by it's very nature, ATL ships with the source code...inline int Base64EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags=ATL_BASE64_FLAG_NONE)
{
__int64 nSrcLen4=static_cast<__int64>(nSrcLen)*4;
ATLENSURE(nSrcLen4 <= INT_MAX);
int nRet = static_cast<int>(nSrcLen4/3);
if ((dwFlags & ATL_BASE64_FLAG_NOPAD) == 0)
nRet += nSrcLen % 3;
int nCRLFs = nRet / 76 + 1;
int nOnLastLine = nRet % 76;
if (nOnLastLine)
{
if (nOnLastLine % 4)
nRet += 4-(nOnLastLine % 4);
}
nCRLFs *= 2;
if ((dwFlags & ATL_BASE64_FLAG_NOCRLF) == 0)
nRet += nCRLFs;
return nRet;
} -
RichardRudek wrote:
Why can't you ?
Larsenal wrote:
Wish I could use the ATL routine.
This is part of a bootstrapper for our system. We've already had several situations where ATL would have been nice, but its use has been nixed. Static linking is out as well.
-
Whoever is making that decision (about ATL) knows something I don't them.
Anyway, I need to work on something else. Here's what I've done so far (having been interrupted by clients and head hunters...)
A snippet of the console output:Larsenal's hacks, moderated...
pxBg0Q7VeUCSG+HEEMoKcA==
and decoded, the UUID's are equal in length, and do compare.And a code snippet. Hopefully I've got the right bits - I was seriously tempted to rename those vars... :
// Larsenal's hack...
// UUID uuid;
HKEY hOpenKey = NULL;
if( UuidCreate( &uuid ) == RPC_S_OK )
{
char *oldStr = NULL;
char *tmpBin = NULL;
int ret;
tmpBin = (char *) &uuid;
// ret = base64encode( tmpBin, oldStr, sizeof(UUID), 22);
int za, zb, zb2;
za = sizeof(uuid);
zb = ATL::Base64EncodeGetRequiredLength( za ); // Cheat... :)
oldStr = new char[zb];
zb2 = zb;
if ( ATL::Base64Encode( (BYTE *)tmpBin, za, oldStr, &zb2) )
{
//// now add bytes
//char* newStr = new char[44];
//for (int i = 0; i < zb2; i++)
//{
// newStr[i*2] = oldStr[i];
// newStr[i*2 + 1] = 0;
//}
USES_CONVERSION;
oldStr[zb2] = 0;
LPWSTR newStr = A2W(oldStr);
wprintf (L"\n Larsenal's hacks, moderated...\n%s", newStr);
//
//DWORD dwDisp;
//if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\My Company\\Client"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hOpenKey, &dwDisp ) == ERROR_SUCCESS )
//{
// // only update key if it doeson't exist
// if(dwDisp == REG_CREATED_NEW_KEY){
// RegSetValueEx( hOpenKey, L"MyUUID", 0, REG_SZ, (unsigned char *) (newStr), 44 );
// RegCloseKey( hOpenKey );
// }
} // Base64Encode
// Decoding
za = zb2;
zb = ATL::Base64DecodeGetRequiredLength( za ); // Cheat.
tmpBin = new char[zb];
zb2 = zb;
if (ATL::Base64Decode( oldStr, za, (BYTE *) tmpBin , &zb2) )
{
printf("\n and decoded, the UUID's are %sequal in length, and %s compare.\n",
(zb2 == sizeof(uuid)) ? "" : "not ",
(memcmp( &uuid, tmpBin, sizeof(uuid) ) == 0) ? "do" : "do not"
);
}
else
{
puts("Base64Decode failed");
}
delete[] oldStr; // Important to free char arrays... use bloody objects !
delete[] tmpBin; // Important to free char arrays... use bloody objects !
} // UuidCreateEDIT: added the delete[] oldStr.... read the comment... !
-
You using C++. Wait some people are masochist and do not think that is a bug.
-
odujosh wrote:You using C++. Wait some people are masochist and do not think that is a bug.
Such slander! C++ is the language of the gods themselves, beaten only by Haskell and C for their genius. Which language would you prefer?
-
Sure, pad the strings to make room for the “==”. But if it’s the same UUID and only failing on some machines, then I would suspect that it’s not being run as an administrator install on Vista or Server2008 machines.
It would help to know the symptoms of the failure. Does the key fail to appear after the machine is rebooted, or is the key in the registry and not being retrieved correctly; does the program crash with an access violation?

Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.