Сбой во введенном / подключенном целевом приложении - PullRequest
0 голосов
/ 02 июля 2010

Я вставил свою DLL в целевое приложение, где я подключил несколько WINAPI-функций также. Одним из них является DrawTextExW. Я пытаюсь заменить все буквы 'l' на '!' до это распечатывает это. Мое решение работает отлично в течение нескольких секунд, но затем целевое приложение вылетает. Я действительно не понимаю, почему.

Вот функция:

Редактировать - Рабочий раствор:

int WINAPI DetouredDrawTextExW(__in    HDC hdc,
                               __inout LPWSTR lpchText,
                               __in    int cchText,
                               __inout LPRECT lprc,
                               __in    UINT dwDTFormat,
                               __in    LPDRAWTEXTPARAMS lpDTParams)
{
    std::wstring s_wc(lpchText, cchText);

    std::replace(s_wc.begin(), s_wc.end(), L'l', L'!');

    return ::DrawTextExW(hdc, const_cast<wchar_t *>(s_wc.c_str()), 
        s_wc.length(), lprc, dwDTFormat, lpDTParams);
}

Итак, кто-нибудь может указать мне, что я делаю неправильно?

1 Ответ

1 голос
/ 02 июля 2010

Я вижу, что вы игнорируете cchText, можете ли вы получить строку, не заканчивающуюся NULL, с положительным значением для cchText, что приведет к чтению за концом строки в недействительную память? Эта ошибка будет отображаться как исключение Win32 в конструкторе s_wc.

Кроме того, вы не проверяете DT_MODIFYSTRING в параметре dwDTFormat. Если этот флаг присутствует, то :: DrawTextExW () может перезаписывать недопустимую память. Это будет представлено как исключение Win32 в :: DrawTextExW () или, возможно, как исключение C ++ в деструкторе s_wc.

1012 * редактировать *

Вот нескомпилированный , непроверенный код, который, как я считаю, подчиняется контракту ::DrawTextExW()

int WINAPI DetouredDrawTextExW(__in    HDC hdc,
                               __inout LPWSTR lpchText,
                               __in    int cchText,
                               __inout LPRECT lprc,
                               __in    UINT dwDTFormat,
                               __in    LPDRAWTEXTPARAMS lpDTParams)
{
    std::vector<wchar_t> v_wc;
    int strSize = cchText == -1 ? wcslen(lpchText) : cchText;
    v_wc.resize(strSize + 4);
    std::copy(lpchText, lpchText + strSize, &v_wc.front());
    std::replace(v_wc.begin(), v_wc.end() - 4, L'l', L'!');

    int result = ::DrawTextExW(hdc, &v_wc.front(), 
        strSize, lprc, dwDTFormat, lpDTParams);
    if (dwDTFormat & DT_MODIFYSTRING)
    {
      std::copy(&v_wc.front(), &v_wc.front() + v_wc.size(), lpchText);
    }
}
...