// Copyright (c) 1997-1999 Microsoft Corporation // // core utility functions // // 30 Nov 1999 sburns #include "headers.hxx" HINSTANCE Burnslib::GetResourceModuleHandle() { ASSERT(hResourceModuleHandle); return hResourceModuleHandle; } // Attempt to locate a message in a given module. Return the message string // if found, the empty string if not. // // flags - FormatMessage flags to use // // module - module handle of message dll to look in, or 0 to use the system // message table. // // code - message code to look for. This could be an HRESULT, or a win32 // error code. String GetMessageHelper(DWORD flags, HMODULE module, DWORD code) { // REVIEWED-2002/03/29-sburns no unbounded allocation error here. // If I pass nSize = 0 and FORMAT_MESSAGE_ALLOCATE_BUFFER in dwFlags, // the max result size is 32K - 1 characters. Looking at the code in // message.c, it looks like the reserve space is whatever the user asked // as a maximum rounded up to the nearest 64K. That makes sense given my // test, since 32K chars = 64K bytes. Experimentally, even if I ask for // a max buffer size > 0x87FFF chars, it looks like the most I can get // is 0x87FFE chars. flags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; String message; TCHAR* sysMessage = 0; DWORD result = ::FormatMessage( flags, module, code, 0, reinterpret_cast(&sysMessage), 0, 0); if (result) { ASSERT(sysMessage); if (sysMessage) { message = sysMessage; ASSERT(result == message.length()); ::LocalFree(sysMessage); message.replace(L"\r\n", L" "); } } return message; } // Attempts to locate message strings for various facility codes in the // HRESULT String Burnslib::GetErrorMessage(HRESULT hr) { LOG_FUNCTION2(GetErrorMessage, String::format(L"%1!08X!", hr)); if (!FAILED(hr) && hr != S_OK) { // no messages for success codes other than S_OK ASSERT(false); return String(); } String message; // default is the system error message table HMODULE module = 0; do { WORD code = static_cast(HRESULT_CODE(hr)); if (code == -1) { // return "unknown" message break; } DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM; if (!HRESULT_FACILITY(hr) && (code >= 0x5000 && code <= 0x50FF)) { // It's an ADSI error flags |= FORMAT_MESSAGE_FROM_HMODULE; module = ::LoadLibraryEx( L"activeds.dll", 0, LOAD_LIBRARY_AS_DATAFILE | DONT_RESOLVE_DLL_REFERENCES); if (!module) { // return "unknown" message LOG_HRESULT(Win32ToHresult(::GetLastError())); break; } } // try FormatMessage with the full HRESULT first message = GetMessageHelper(flags, module, hr); if (message.empty()) { // try again with just the error code message = GetMessageHelper(flags, module, code); } } while (0); if (message.empty()) { message = String::load(IDS_UNKNOWN_ERROR_CODE); } if (module) { BOOL unused = ::FreeLibrary(module); ASSERT(unused); } return message.strip(String::BOTH); }