#if HAVE_CRT #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #endif //HAVE_CRT /* * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com> * * The original file was part of Open Source Doubango Framework * Copyright (C) 2010-2011 Mamadou Diop. * Copyright (C) 2012 Doubango Telecom <http://doubango.org> * * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DOUBANGO. * */ /**@file tdav_win32.c * @brief tinyDAV WIN32 helper functions. * */ #include "tinydav/tdav_win32.h" #if TDAV_UNDER_WINDOWS #include "tsk_string.h" #include "tsk_memory.h" #include "tsk_debug.h" #include <windows.h> #if !TDAV_UNDER_WINDOWS_RT #include <Shlwapi.h> /* PathRemoveFileSpec */ #endif /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms724834%28v=vs.85%29.aspx Version Number Description 6.2 Windows 8 / Windows Server 2012 6.1 Windows 7 / Windows 2008 R2 6.0 Windows Vista / Windows 2008 5.2 Windows 2003 5.1 Windows XP 5.0 Windows 2000 */ static DWORD dwMajorVersion = -1; static DWORD dwMinorVersion = -1; #if (TDAV_UNDER_WINDOWS_RT || TDAV_UNDER_WINDOWS_CE) const HMODULE GetCurrentModule() { return NULL; } #else const HMODULE GetCurrentModule() { HMODULE hm = {0}; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)GetCurrentModule, &hm); return hm; } #endif /* !(TDAV_UNDER_WINDOWS_RT || TDAV_UNDER_WINDOWS_CE) */ int tdav_win32_init() { #if !TDAV_UNDER_WINDOWS_RT MMRESULT result; #if !TDAV_UNDER_WINDOWS_CE CoInitializeEx(NULL, COINIT_MULTITHREADED); #endif // Timers accuracy result = timeBeginPeriod(1); if (result) { TSK_DEBUG_ERROR("timeBeginPeriod(1) returned result=%u", result); } // Get OS version if(dwMajorVersion == -1 || dwMinorVersion == -1){ OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); dwMajorVersion = osvi.dwMajorVersion; dwMinorVersion = osvi.dwMinorVersion; fprintf(stdout, "Windows dwMajorVersion=%ld, dwMinorVersion=%ld\n", dwMajorVersion, dwMinorVersion); } #endif return 0; } int tdav_win32_get_osversion(unsigned long* version_major, unsigned long* version_minor) { if (version_major) { *version_major = dwMajorVersion; } if (version_minor) { *version_minor = dwMinorVersion; } return 0; } tsk_bool_t tdav_win32_is_win8_or_later() { if (dwMajorVersion == -1 || dwMinorVersion == -1) { TSK_DEBUG_ERROR("Version numbers are invalid"); return tsk_false; } return ((dwMajorVersion > 6) || ((dwMajorVersion == 6) && (dwMinorVersion >= 2))); } tsk_bool_t tdav_win32_is_win7_or_later() { if (dwMajorVersion == -1 || dwMinorVersion == -1) { TSK_DEBUG_ERROR("Version numbers are invalid"); return tsk_false; } return ( (dwMajorVersion > 6) || ( (dwMajorVersion == 6) && (dwMinorVersion >= 1) ) ); } tsk_bool_t tdav_win32_is_winvista_or_later() { if (dwMajorVersion == -1 || dwMinorVersion == -1) { TSK_DEBUG_ERROR("Version numbers are invalid"); return tsk_false; } return (dwMajorVersion >= 6); } tsk_bool_t tdav_win32_is_winxp_or_later() { if (dwMajorVersion == -1 || dwMinorVersion == -1) { TSK_DEBUG_ERROR("Version numbers are invalid"); return tsk_false; } return ( (dwMajorVersion > 5) || ( (dwMajorVersion == 5) && (dwMinorVersion >= 1) ) ); } const char* tdav_get_current_directory_const() { #if TDAV_UNDER_WINDOWS_RT TSK_DEBUG_ERROR("Not supported"); return tsk_null; #else static char CURRENT_DIR_PATH[MAX_PATH] = { 0 }; static DWORD CURRENT_DIR_PATH_LEN = 0; if (CURRENT_DIR_PATH_LEN == 0) { // NULL HMODULE will get the path to the executable not the DLL. When runing the code in Internet Explorer this is a BIG issue as the path is where IE.exe is installed. #if TDAV_UNDER_WINDOWS_CE static wchar_t TMP_CURRENT_DIR_PATH[MAX_PATH] = { 0 }; if ((CURRENT_DIR_PATH_LEN = GetModuleFileName(GetCurrentModule(), TMP_CURRENT_DIR_PATH, sizeof(TMP_CURRENT_DIR_PATH)))) { if ((CURRENT_DIR_PATH_LEN = wcstombs(CURRENT_DIR_PATH, TMP_CURRENT_DIR_PATH, sizeof(CURRENT_DIR_PATH) - 1))) { int idx = tsk_strLastIndexOf(CURRENT_DIR_PATH, CURRENT_DIR_PATH_LEN, "\\"); if (idx > -1) { CURRENT_DIR_PATH[idx] = '\0'; CURRENT_DIR_PATH_LEN = idx; } } } #else if ((CURRENT_DIR_PATH_LEN = GetModuleFileNameA(GetCurrentModule(), CURRENT_DIR_PATH, sizeof(CURRENT_DIR_PATH)))) { if (!PathRemoveFileSpecA(CURRENT_DIR_PATH)) { TSK_DEBUG_ERROR("PathRemoveFileSpec(%s) failed: %x", CURRENT_DIR_PATH, GetLastError()); memset(CURRENT_DIR_PATH, 0, sizeof(CURRENT_DIR_PATH)); CURRENT_DIR_PATH_LEN = 0; } } #endif /* TDAV_UNDER_WINDOWS_CE */ if (!CURRENT_DIR_PATH_LEN) { TSK_DEBUG_ERROR("GetModuleFileNameA() failed: %x", GetLastError()); } } return CURRENT_DIR_PATH; #endif /* TDAV_UNDER_WINDOWS_RT */ } TINYDAV_API void tdav_win32_print_error(const char* func, HRESULT hr) { CHAR message[1024] = {0}; #if (TDAV_UNDER_WINDOWS_RT || TDAV_UNDER_WINDOWS_CE) #if !defined(WC_ERR_INVALID_CHARS) #define WC_ERR_INVALID_CHARS 0 #endif // FormatMessageA not allowed on the Store static WCHAR wBuff[1024] = {0}; FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM, tsk_null, hr, 0, wBuff, sizeof(wBuff)-1, tsk_null); WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wBuff, wcslen(wBuff), message, sizeof(message) - 1, NULL, NULL); #else FormatMessageA ( #if !TDAV_UNDER_WINDOWS_RT FORMAT_MESSAGE_ALLOCATE_BUFFER | #endif FORMAT_MESSAGE_FROM_SYSTEM, tsk_null, hr, 0, message, sizeof(message) - 1, tsk_null); #endif TSK_DEBUG_ERROR("%s(): %s", func, message); } int tdav_win32_deinit() { #if !(TDAV_UNDER_WINDOWS_RT || TDAV_UNDER_WINDOWS_CE) MMRESULT result; // Timers accuracy result = timeEndPeriod(1); if(result){ TSK_DEBUG_ERROR("timeEndPeriod(1) returned result=%u", result); } #endif return 0; } #endif /* TDAV_UNDER_WINDOWS */