Alexander Nickolov said:
Oh, I know how it's allocated
. I'm just pointing out that
this is officially undocumented.
So in Win64 we have:
byte len content
-8 4 unused
-4 4 length
0 n string
and add a '\0' after the n string.
(unicode)
It's working. I had still somewhere an invalid memory location calculation
(-4 instead of -8)
#include "stdafx.h"
#include "bstrnocache.h"
void __stdcall FreeString(BSTR * theString) throw()
{
if (theString != NULL && *theString != NULL )
{
SysFreeString2(*theString);
*theString = NULL;
}
}
int __stdcall SysReAllocStringByteLen2(BSTR * bstr, const char* input, UINT
cch) throw()
{
// ATLASSERT(bstr != NULL);
if (*bstr == NULL)
*bstr = SysAllocStringByteLen(input, cch);
else
{
UINT copyIntoLen = input != NULL ? lstrlenA(input): 0;
if (copyIntoLen > cch)
copyIntoLen = cch;
UINT_PTR newlen = cch + sizeof(OLECHAR) + sizeof(UINT_PTR);
PCHAR temp = (PCHAR)(*bstr) - sizeof(UINT_PTR);
temp = (PCHAR)::CoTaskMemRealloc(temp, newlen);
if (temp != NULL)
{
UINT_PTR* plen = (UINT_PTR*)temp;
UINT* plen2 = (UINT*)temp;
plen2[sizePtrCorrection] = cch ; //asign bytelength for BSTR
if (copyIntoLen > 0) //copy chars
memcpy(&plen[1],
input,
(copyIntoLen + 1));
temp[sizeof(UINT_PTR) + cch ] = 0; //terminate LPWSTR with a wide_string
temp[sizeof(UINT_PTR) + cch + 1] = 0;
*bstr = (BSTR)&temp[sizeof(UINT_PTR)];
}
}
return *bstr == NULL ? FALSE : TRUE;
}
int __stdcall SysReAllocStringLen2(BSTR * bstr, const OLECHAR* input, UINT
cch) throw()
{
//ATLASSERT(bstr != NULL);
if (*bstr == NULL)
{
*bstr = SysAllocStringLen2(input, cch);
}
else
{
UINT_PTR copyIntoLen = input != NULL ? lstrlenW(input): 0;
if (copyIntoLen > cch)
copyIntoLen = cch;
UINT_PTR newlen = cch * sizeof(OLECHAR) + sizeof(OLECHAR) +
sizeof(UINT_PTR);
PWSTR temp = *bstr - sizeof(UINT_PTR) / sizeof(OLECHAR);
temp = (PWSTR)::CoTaskMemRealloc(temp, newlen);
if (temp != NULL)
{
UINT_PTR* plen = (UINT_PTR*)temp;
UINT* plen2 = (UINT*)temp;
plen2[sizePtrCorrection] = cch * sizeof(OLECHAR); //asign bytelength for
BSTR
if (copyIntoLen > 0) //copy values
memcpy(&temp[sizeof(UINT_PTR) / sizeof(OLECHAR)],
input,
(copyIntoLen + 1) * sizeof(OLECHAR));
temp[sizeof(UINT_PTR) / sizeof(OLECHAR) + cch ] = 0; //terminate LPWSTR
*bstr = &temp[sizeof(UINT_PTR) / sizeof(OLECHAR)];
}
}
return *bstr == NULL ? FALSE : TRUE;
}
BSTR __stdcall SysAllocStringLen2(const OLECHAR * input, UINT cch) throw()
{
UINT_PTR copyIntoLen = input != NULL ? lstrlenW(input) : 0;
if (copyIntoLen > cch)
copyIntoLen = cch;
UINT_PTR newlen = cch * sizeof(OLECHAR) + sizeof(OLECHAR) +
sizeof(UINT_PTR);
PWSTR temp = (PWSTR)::CoTaskMemAlloc(newlen);
if (temp != NULL)
{
UINT_PTR* plen = (UINT_PTR*)temp;
UINT*plen2 = (UINT*)temp;
plen2[0] =0;
plen2[sizePtrCorrection] = cch * sizeof(OLECHAR);
if (copyIntoLen > 0)
memcpy(&plen[1],
input,
(copyIntoLen + 1) * sizeof(OLECHAR));
temp[sizeof(UINT_PTR) / sizeof(OLECHAR) + cch ] = 0;
return &temp[sizeof(UINT_PTR) / sizeof(OLECHAR)];
}
else
return NULL;
}
BSTR __stdcall SysAllocStringByteLen2(const char* input, UINT cch)
throw()
{
UINT_PTR copyIntoLen = input != NULL ? lstrlenA(input) : 0;
if (copyIntoLen > cch)
copyIntoLen = cch;
UINT_PTR newlen = cch + sizeof(OLECHAR) + sizeof(UINT_PTR);
PWSTR temp = (PWSTR)::CoTaskMemAlloc(newlen);
if (temp != NULL)
{
UINT_PTR* plen = (UINT_PTR*)temp;
UINT* plen2 = (UINT*)temp;
plen2[sizePtrCorrection] = cch;
if (copyIntoLen > 0)
memcpy(&temp[sizeof(UINT_PTR) / sizeof(OLECHAR)],
input,
copyIntoLen + 1);
char* zeroit = (char*)temp;
zeroit[sizeof(UINT_PTR) + cch ] = 0; //terminate LPWSTR with a wide_string
zeroit[sizeof(UINT_PTR) + cch + 1] = 0;
//temp[sizeof(unsigned int) / sizeof(wchar_t) + cch ] = 0;
return &temp[sizeof(UINT_PTR) / sizeof(OLECHAR)];
}
else
return NULL;
}
///<summary>
/// Identical to SysAllocString
///</summary>
BSTR __stdcall SysAllocString2(const OLECHAR * input) throw()
{
PWSTR retval = NULL;
if (input != NULL)
{
UINT_PTR slen = lstrlenW(input);
UINT_PTR newlen = slen * sizeof(OLECHAR)+ sizeof(UINT_PTR) +
sizeof(OLECHAR);
PWSTR temp = NULL;
temp = (PWSTR)::CoTaskMemAlloc(newlen);
if (temp != NULL)
{
UINT* plen = (UINT*)temp;
plen[sizePtrCorrection] = (UINT)slen * sizeof(OLECHAR);
retval = &temp[sizeof(UINT_PTR) / sizeof(OLECHAR)];
if (slen > 0)
memcpy(retval, input, (slen + 1) * sizeof(OLECHAR));
}
}
return retval;
}
int __stdcall SysReAllocString2(BSTR * bstr, const OLECHAR * input) throw()
{
//ATLASSERT(bstr != NULL);
bool didEmpty = FALSE;
if (*bstr == NULL)
{
*bstr = SysAllocString2(input);
}
else
{
if (input == NULL)
{
FreeString(bstr);
didEmpty = true;
}
else
{
UINT_PTR slen = lstrlenW(input);
UINT_PTR newlen = slen * sizeof(OLECHAR) + sizeof(OLECHAR) +
sizeof(UINT_PTR);
BSTR temp = *bstr - sizeof(INT_PTR) / sizeof(OLECHAR); //get real address
temp = (BSTR)::CoTaskMemRealloc(temp, newlen);
if (temp != NULL)
{
UINT_PTR* plen = (UINT_PTR*)temp;
UINT* plen2 = (UINT*)temp;
plen2[sizePtrCorrection] = (UINT)slen * sizeof(OLECHAR);
*bstr = &temp[sizeof(UINT_PTR) / sizeof(OLECHAR)];
memcpy(*bstr, input, (slen + 1) * sizeof(OLECHAR));
}
}
}
return *bstr == NULL && didEmpty == false? FALSE : TRUE;
}
UINT __stdcall SysStringByteLen2(BSTR theString) throw()
{
UINT retval = 0;
if (theString != NULL)
{
UINT* temp = (UINT*)theString;
temp--;
retval = *temp;
}
return retval;
}
UINT __stdcall SysStringLen2(BSTR theString) throw()
{
UINT retval = 0;
if (theString != NULL)
{
UINT* temp = (UINT*)theString;
temp--;
retval = *temp / sizeof(OLECHAR);
}
return retval;
}