The cbCount
parameter of ExtTextOut()
is expressed in characters, but the input parameter of malloc()
is expressed in bytes. You are hooking the Unicode version of ExtTextOut()
(aka ExtTextOutW()
), where sizeof(WCHAR)
is 2 bytes. You are trying to treat the input string as Ansi, which it is not, and you are not taking UTF-16 surrogates into account.
To do what you are attempting, you need to actually decode the UTF-16 data into Unicode codepoints first before deciding which ones to keep, eg:
BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
{
if ((cbCount > 0) && (text != NULL) && (text[0] == L'>'))
{
// worse case, every UTF-16 character is ASCII and will be kept,
// so allocate enough memory for at least that many characters
std::string buffer(cbCount);
std::string bufferCopy(cbCount);
int ix1 = 0;
for (UINT i = 0; i < cbCount;)
{
ULONG c;
// is it a UTF-16 high surrogate?
if ((text[i] >= 0xD800) && (text[i] <= 0xDBFF))
{
// is it at the end of the string?
if ((i+1) == cbCount)
{
// malformed surrogate
break;
}
// is it followed by a UTF-16 low surrogate?
if ((text[i+1] < 0xDC00) || (text[i+1] > 0xDFFF))
{
// malformed surrogate
break;
}
// decode the surrogate and skip past it
c = ((ULONG(text[i] - 0xD800) << 10) | ULONG(text[i+1] - 0xDC00)) + 0x10000;
i += 2;
}
// is it a UTF-16 low surrogate?
else if (text[i] >= 0xDC00) && (text[i] <= 0xDFFF))
{
// malformed surrogate
break;
}
// must be a non-surrogated character
else
{
c = (ULONG) text[i];
++i;
}
// keep it?
if( c > 127 )
buffer[ix1] = ' ';
else
buffer[ix1] = (char) c;
++ix1;
}
bool wasBlank = false;
int ix2 = 0;
for(int i = 0; i < ix1; ++i)
{
if (buffer[i] == ' ')
{
if (wasBlank || (i < 2)) continue;
bufferCopy[ix2++] = buffer[i];
wasBlank = true;
continue;
}
wasBlank = false;
if (buffer[i] == '>') continue;
bufferCopy[ix2++] = buffer[i];
}
ofstream myFile;
myFile.open("C:\\temp\\textHooking\\textHook\\example2.txt", ios::app);
if (myFile)
{
myFile.write(bufferCopy.c_str(), ix2);
myFile << endl;
}
}
return Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
}