doubango/tinyDAV/src/tdav_win32.c
c732d49e
 #if HAVE_CRT
 #define _CRTDBG_MAP_ALLOC 
 #include <stdlib.h> 
 #include <crtdbg.h>
 #endif //HAVE_CRT
 /*
 * Copyright (C) 2017, 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 */