На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Как получить описания для кодов системных ошибок?
    Я делаю вывод уведомлений об ошибках примерно так:

    ExpandedWrap disabled
      error_code = GetLastError();
      result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code, 0, buff1, _countof(buff1), 0)
      if (result)
      {
          wnsprintfW(buff2, _countof(buff2), L"%Ошибка: %d - %s", error_code, buffer_text_error);
      }
      else
      {
          wnsprintfW(buff2, _countof(buff2), L"Ошибка: %d", error_code);
      }


    Столкнулся с тем что для некоторых ошибок FormatMessage возвращает 0 и не трогает буфер.

    Например, работая с WinHttp-функциями при недоступности запрашиваемого сайта получаю ошибку 12002.
    В WinInet.h она описана - ERROR_INTERNET_TIMEOUT.
    Но в FormatMessage её нет. Т.е. я пользователю могу сказать только «произошла ошибка 12002», а что это за ошибка – пользователю самому придётся искать.
    А как бы найти в системе человеческие описания подобных кодов ошибок?
    Есть варианты?

    Встроить в свою программу весь текст списков ошибок из WinInet.h и прочих заголовков - не хотелось бы…
      Цитата f2065 @
      Столкнулся с тем что для некоторых ошибок FormatMessage возвращает 0 и не трогает буфер.

      f2065, в этом случае попробуй получить описание
      ошибки из конкретного модуля.
      Например:
      ExpandedWrap disabled
            result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code, 0, buff1, _countof(buff1), 0)
            if (result)
            {
                wnsprintfW(buff2, _countof(buff2), L"%Ошибка: %d - %s", error_code, buffer_text_error);
            }
            else
            {
         
               HMODULE hDll = ::LoadLibraryEx(_T("netmsg.dll"),NULL,DONT_RESOLVE_DLL_REFERENCES);
               if(hDll)
               {
                result = ::FormatMessage
                       (
                        FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                        hDll,
         ...
         ...
                        );
                ::FreeLibrary(hDll);
               }
         
         
              
            }
        Да, направление правильное.
        Впрочем ситуация оказалась сложнее, нашёл в микрософте схожий пример…
        Суть в том что оказывается есть пересекающиеся диапазоны ошибок, надо помнить откуда ошибка была получена и использовать правильную DLL.

        В случае если ошибки жду только от WinHttp - получается так
        ExpandedWrap disabled
          HMODULE hModuleExtra = 0;
          DWORD dwFormatFlags = FORMAT_MESSAGE_IGNORE_INSERTS;
          if (error_code >= WINHTTP_ERROR_BASE && error_code <= WINHTTP_ERROR_LAST)
          {
              hModuleExtra = LoadLibraryExW(L"WinHTTP.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
              if (hModuleExtra)
              {
                  dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
              }
          }
          if (!hModuleExtra)
          {
              dwFormatFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
          }
              if (FormatMessageW(dwFormatFlags, hModuleExtra, error_code, 0, buffer_text_error, _countof(buffer_text_error), 0))
          {
              wnsprintfW(tmp_pos, tmp_size, L"Error: %d - %s", error_code, buffer_text_error);
          }
          else
          {
              wnsprintfW(tmp_pos, tmp_size, L"Error: %d", error_code);
          }
          if (hModuleExtra)
          {
              FreeLibrary(hModuleExtra);
          }
        Но глобально, если в программе могут быть ошибки например от RRAS, WinInet, служб роутинга, мультимедии и прочих - то у них местами есть диапазоны кодов перекрывающиеся с системными.
        Даже вот с WinInet и WinHTTP - им выделен один и тот же диапазон (WINHTTP_ERROR_BASE == INTERNET_ERROR_BASE), часть кодов ошибок у них по сути совпадают, часть уникальные.
        Т.е. если у меня программа работает и с WinInet и с WinHTTP - то единую процедуру обработки ошибок сделать нельзя, ибо диапазон одинаковый а DLL с текстами ошибок у них надо разные грузить…

        Теперь вопрос такой - если у меня программа например работает с WinHTTP, и WinHTTP.dll статически прилинкована, то можно ли как-то избежать лишнего LoadLibrary ?
        Ведь DLL эта уже и так находится в адресном пространстве программы…
        А лишний LoadLibrary может ведь подхватить совсем не то что надо (если например в интервале между запуском программы и обработкой ошибки в %path% появится какая-то другая DLL с этим же именем).
          Цитата f2065 @
          Теперь вопрос такой - если у меня программа например работает с WinHTTP, и WinHTTP.dll статически прилинкована, то можно ли как-то избежать лишнего LoadLibrary ?
          Ведь DLL эта уже и так находится в адресном пространстве программы…

          Лишний LoadLibrary ни к каким проблемам не приведёт.
          Просто вернёт handle на загруженную уже библиотеку и всё.
          Надо только не забыть использовать FreeLibrary.
          ---
          Попробуй использовать "GetModuleHandle".
          Но я так не делал.
          ---
          Можно сделать объект (c++), вызывать FreeLibrary
          из деструктора, и тогда потенциальные проблемы с высвобождением
          ресурса вообще исчезнут.
          Сообщение отредактировано: ЫукпШ -
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0227 ]   [ 16 queries used ]   [ Generated: 7.05.24, 14:05 GMT ]