The HIWORD
and LOWORD
macros are intended to extract the high and low 16-bit words from a 32-bit DWORD
. CreateFileMapping
, on the other hand, expects two DWORD
s that together make up a 64-bit unsigned integer, which is the size of the mapping object.
Both HIWORD(UBS_MEM_SIZE)
and LOWORD(UBS_MEM_SIZE)
yield 0xffff
(the two 16-bit halves), which are then converted to 32-bit unsigned integers (which is what the function expects).
So, what you're actually doing is asking for a file mapping of size 0x0000ffff0000ffff
. This is more than 255 TB
. Since you're using INVALID_HANDLE_VALUE
, this has to be backed by RAM or the system page file; I doubt you have that much available in there.
If UBS_MEM_SIZE
is always 32-bit, you can simply use
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, 0, UBS_MEM_SIZE,
TEXT("dllmemfilemap"));
If you actually need to handle sizes over 4 GB
, you can do something like this:
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(UBS_MEM_SIZE >> 32), static_cast<DWORD>(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));
Make sure UBS_MEM_SIZE
actually has a type larger than 32-bit (even if its value may be less than that), since otherwise shifting by 32 bits is undefined behaviour in C++. So, if you want to use the second variant above with your initial value, it will have to be something like
#define UBS_MEM_SIZE 0xFFFFFFFFull
(By the way, use const
...)
To make it safer, I'd wrap the call into something like this:
inline HANDLE MyCreateMapping(unsigned long long size, LPCTSTR name)
{
return CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), name);
}
This way, you don't need to remember any tricky details about bits, shifts and integer type sizes.