I'm trying to make a randomly named file on the desktop by getting the desktop path and then combining it with the buffer of BCryptGetRandom
but the function PathCombineW
doesn't accept the buffer
#include <Windows.h>
#include <Shlobj.h>
int main()
{
BYTE Buffer[15];
DWORD size = sizeof(Buffer);
BCryptGenRandom(NULL, Buffer, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
LPWSTR desktop;
SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &desktop);
WCHAR filePath[MAX_PATH];
PathCombineW(filePath, desktop, Buffer); //the error is here
CreateFileW(filePath, GENERIC_ALL, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
}
CodePudding user response:
WCHAR
on Windows is UTF-16LE and you therefore should not use random bytes directly because not everything is going to be valid UTF-16.
You can use a WCHAR Buffer[15] = {};
and fill 0-13 with numbers in a known valid range, for example from 0x20 to 0xD7FF (excluding things that are invalid in filenames).
If you want to interoperate with non-Unicode programs you might want to limit yourself to ASCII...
CodePudding user response:
A byte array is not a valid null-terminated UTF16 string, which is why PathCombineW()
won't accept it.
Also, random bytes are not guaranteed to represent valid UTF16 characters.
What you can do is hex-encode the generated bytes into an ASCII string in UTF16 encoding, eg:
#include <Windows.h>
#include <Shlobj.h>
int main()
{
BYTE Buffer[15];
BCryptGenRandom(NULL, Buffer, sizeof(Buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
LPWSTR desktop = NULL;
SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &desktop);
WCHAR fileName[(sizeof(Buffer)*2) 1];
for(int i = 0, j = 0; i < sizeof(Buffer); i, j = 2) {
wsprintfW(&fileName[j], L"02X", Buffer[i]);
}
WCHAR filePath[MAX_PATH];
PathCombineW(filePath, desktop, fileName);
HANDLE hFile = CreateFileW(filePath, GENERIC_ALL, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hFile);
CoTaskMemFree(desktop);
}