diff --git a/Main/StackWalker/StackWalker.cpp b/Main/StackWalker/StackWalker.cpp index e1b25eb..bc1928b 100644 --- a/Main/StackWalker/StackWalker.cpp +++ b/Main/StackWalker/StackWalker.cpp @@ -81,17 +81,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **********************************************************************/ - #include "StackWalker.h" +#include #include #include +#include #include #include #pragma comment(lib, "version.lib") // for "VerQueryValue" #pragma warning(disable : 4826) - // If VC7 and later, then use the shipped 'dbghelp.h'-file #pragma pack(push, 8) #if _MSC_VER >= 1300 @@ -1418,6 +1418,53 @@ void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) OnOutput(buffer); } +namespace +{ +namespace details +{ +namespace char_traits +{ +template std::size_t length(const char_type* s) +{ + return strlen(s); +} + +template <> std::size_t length(const WCHAR* s) +{ + return wcslen(s); +} +} // namespace char_traits +} // namespace details + +template std::string to_string(const OsInfo& osInfo) +{ + std::ostringstream oss; + oss << "OS-Version: " << osInfo.dwMajorVersion << "." << osInfo.dwMinorVersion << "." + << osInfo.dwBuildNumber; + if (details::char_traits::length(osInfo.szCSDVersion) > 0) + { + oss << " (" << osInfo.szCSDVersion << ")"; + } + oss << " 0x" << std::hex << osInfo.wSuiteMask << "-0x" << std::hex + << static_cast(osInfo.wProductType); + oss << std::endl; + return oss.str(); +} + +template <> std::string to_string(const OSVERSIONINFOA& osInfo) +{ + std::ostringstream oss; + oss << "OS-Version: " << osInfo.dwMajorVersion << "." << osInfo.dwMinorVersion << "." + << osInfo.dwBuildNumber; + if (details::char_traits::length(osInfo.szCSDVersion) > 0) + { + oss << " (" << osInfo.szCSDVersion << ")"; + } + oss << std::endl; + return oss.str(); +} +} // namespace + void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) { CHAR buffer[STACKWALK_MAX_NAMELEN]; @@ -1425,41 +1472,57 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser #if _MSC_VER >= 1400 maxLen = _TRUNCATE; #endif - _snprintf_s(buffer, maxLen, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", - szSearchPath, symOptions, szUserName); - buffer[STACKWALK_MAX_NAMELEN - 1] = 0; + _snprintf_s(buffer, sizeof(buffer), maxLen, + "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, + symOptions, szUserName); + buffer[_countof(buffer) - 1] = '\0'; OnOutput(buffer); + // Also display the OS-version -#if _MSC_VER <= 1200 - OSVERSIONINFOA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); - ver.dwOSVersionInfoSize = sizeof(ver); - if (GetVersionExA(&ver) != FALSE) +#if _WIN32_WINNT > 0x0600 // _WIN32_WINNT_VISTA + // Get a handle on RtlGetVersion + HMODULE h_NtDll = GetModuleHandleW(L"ntdll.dll"); + typedef LONG(WINAPI * tRtlGetVersion)(RTL_OSVERSIONINFOEXW*); + tRtlGetVersion f_RtlGetVersion = (tRtlGetVersion)GetProcAddress(h_NtDll, "RtlGetVersion"); + if (f_RtlGetVersion) { - _snprintf_s(buffer, maxLen, "OS-Version: %d.%d.%d (%s)\n", ver.dwMajorVersion, - ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion); - buffer[STACKWALK_MAX_NAMELEN - 1] = 0; - OnOutput(buffer); + RTL_OSVERSIONINFOEXW osInfo; + osInfo.dwOSVersionInfoSize = sizeof(osInfo); + f_RtlGetVersion(&osInfo); + //CHAR servicePack[128] = {'\0'}; + //if (wcslen(osInfo.szCSDVersion) > 0) + //{ + // _snprintf_s(servicePack, sizeof(servicePack), _countof(servicePack), "(%s) ", osInfo.szCSDVersion); + //} + //_snprintf_s(buffer, sizeof(buffer), maxLen, "OS-Version: %d.%d.%d %s0x%x-0x%x\n", + // osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber, servicePack, + // osInfo.wSuiteMask, osInfo.wProductType); + //buffer[_countof(buffer) - 1] = '\0'; + //OnOutput(buffer); + OnOutput(::to_string(osInfo).c_str()); } #else - OSVERSIONINFOEXA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); - ver.dwOSVersionInfoSize = sizeof(ver); -#if _MSC_VER >= 1900 -#pragma warning(push) -#pragma warning(disable : 4996) +#if _MSC_VER <= 1200 + OSVERSIONINFOA osInfo; +#else + OSVERSIONINFOEXA osInfo; #endif - if (GetVersionExA((OSVERSIONINFOA*)&ver) != FALSE) + ZeroMemory(&osInfo, sizeof(osInfo)); + osInfo.dwOSVersionInfoSize = sizeof(osInfo); + if (GetVersionExA((OSVERSIONINFOA*)&osInfo) != FALSE) { - _snprintf_s(buffer, maxLen, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", ver.dwMajorVersion, - ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion, ver.wSuiteMask, - ver.wProductType); - buffer[STACKWALK_MAX_NAMELEN - 1] = 0; - OnOutput(buffer); + //#if _MSC_VER <= 1200 + // _snprintf_s(buffer, sizeof(buffer), maxLen, "OS-Version: %d.%d.%d (%s)\n", ver.dwMajorVersion, + // ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion); + //#else + // _snprintf_s(buffer, sizeof(buffer), maxLen, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", ver.dwMajorVersion, + // ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion, ver.wSuiteMask, + // ver.wProductType); + //#endif + // buffer[_countof(buffer) - 1] = '\0'; + // OnOutput(buffer); + OnOutput(::to_string(osInfo).c_str()); } -#if _MSC_VER >= 1900 -#pragma warning(pop) -#endif #endif }