From df57a981deef30d921adb1e24c71b190d18f969e Mon Sep 17 00:00:00 2001 From: Learath Lea Date: Sat, 18 Apr 2015 15:53:11 +0300 Subject: [PATCH] Add os_compare_version. Check for WinXP. --- src/base/system.c | 40 ++++++++++++++++++++++++-------- src/base/system.h | 19 +++++++++++++++ src/engine/client/autoupdate.cpp | 28 ++++++++++++++++++---- src/engine/client/autoupdate.h | 4 +++- src/engine/client/client.cpp | 16 ++----------- 5 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 1822b6d2b..cb89cbbc4 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -2352,16 +2352,36 @@ int pid() void shell_execute(const char *file) { - #if defined(CONF_FAMILY_WINDOWS) - ShellExecute(NULL, NULL, file, NULL, NULL, SW_SHOWDEFAULT); - #elif defined(CONF_FAMILY_UNIX) - char* argv[2]; - argv[0] = (char*) file; - argv[1] = NULL; - pid_t pid = fork(); - if(!pid) - execv(file, argv); - #endif +#if defined(CONF_FAMILY_WINDOWS) + ShellExecute(NULL, NULL, file, NULL, NULL, SW_SHOWDEFAULT); +#elif defined(CONF_FAMILY_UNIX) + char* argv[2]; + argv[0] = (char*) file; + argv[1] = NULL; + pid_t pid = fork(); + if(!pid) + execv(file, argv); +#endif +} + +int os_compare_version(int major, int minor) +{ +#if defined(CONF_FAMILY_WINDOWS) + OSVERSIONINFO ver; + mem_zero(&ver, sizeof(OSVERSIONINFO)); + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&ver); + if(ver.dwMajorVersion > major && ver.dwMinorVersion > minor) + return 1; + else if(ver.dwMajorVersion == major && ver.dwMinorVersion == minor) + return 0; + else if(ver.dwMajorVersion < major && ver.dwMinorVersion < minor) + return -1; + else + return -2; +#else + #error not implemented +#endif } struct SECURE_RANDOM_DATA diff --git a/src/base/system.h b/src/base/system.h index e0754268c..d52155b7c 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1327,8 +1327,27 @@ int str_utf8_check(const char *str); int pid(); +/* + Function: shell_execute + Executes a given file. +*/ void shell_execute(const char *file); +/* + Function: os_compare_version + Compares the OS version to a given major and minor. + + Parameters: + major - Major version to compare to. + minor - Minor version to compare to. + + Returns: + 1 - OS version higher. + 0 - OS version same. + -1 - OS version lower. +*/ +int os_compare_version(int major, int minor); + /* Function: secure_random_init Initializes the secure random module. diff --git a/src/engine/client/autoupdate.cpp b/src/engine/client/autoupdate.cpp index e9b99a161..3cea537ea 100644 --- a/src/engine/client/autoupdate.cpp +++ b/src/engine/client/autoupdate.cpp @@ -25,6 +25,7 @@ void CAutoUpdate::Init() m_pClient = Kernel()->RequestInterface(); m_pStorage = Kernel()->RequestInterface(); m_pFetcher = Kernel()->RequestInterface(); + m_IsWinXP = (os_compare_version(5, 0) == 1 && os_compare_version(6, 0) == -1); } void CAutoUpdate::ProgressCallback(CFetchTask *pTask, void *pUser) @@ -54,8 +55,12 @@ void CAutoUpdate::CompletionCallback(CFetchTask *pTask, void *pUser) pUpdate->ReplaceServer(); if(pUpdate->m_pClient->State() == IClient::STATE_ONLINE || pUpdate->m_pClient->EditorHasUnsavedData()) pUpdate->m_State = NEED_RESTART; - else - pUpdate->m_pClient->Restart(); + else{ + if(!pUpdate->m_IsWinXP) + pUpdate->m_pClient->Restart(); + else + pUpdate->WinXpRestart(); + } } else if(pTask->State() == CFetchTask::STATE_ERROR) pUpdate->m_State = FAIL; @@ -113,11 +118,12 @@ void CAutoUpdate::ReplaceClient() dbg_msg("autoupdate", "Replacing " PLAT_CLIENT_EXEC); //Replace running executable by renaming twice... - #if !defined(WINXP) + if(m_IsWinXP) + { m_pStorage->RemoveBinaryFile("DDNet.old"); m_pStorage->RenameBinaryFile(PLAT_CLIENT_EXEC, "DDNet.old"); m_pStorage->RenameBinaryFile("DDNet.tmp", PLAT_CLIENT_EXEC); - #endif + } #if !defined(CONF_FAMILY_WINDOWS) char aPath[512]; m_pStorage->GetBinaryPath(PLAT_CLIENT_EXEC, aPath, sizeof aPath); @@ -227,3 +233,17 @@ void CAutoUpdate::PerformUpdate() if(m_ClientUpdate) FetchFile(PLAT_CLIENT_DOWN, "DDNet.tmp"); } + +void CAutoUpdate::WinXpRestart() +{ + char aBuf[512]; + IOHANDLE bhFile = io_open(m_pStorage->GetBinaryPath("du.bat", aBuf, sizeof aBuf), IOFLAG_WRITE); + if(!bhFile) + return; + char bBuf[512]; + str_format(bBuf, sizeof(bBuf), ":_R\r\ndel \"DDNet.exe\"\r\nif exist \"DDNet.exe\" goto _R\r\nrename \"DDNet.tmp\" \"DDNet.exe\"\r\n:_T\r\nif not exist \"DDNet.exe\" goto _T\r\nstart DDNet.exe\r\ndel \"du.bat\"\r\n"); + io_write(bhFile, bBuf, str_length(bBuf)); + io_close(bhFile); + shell_execute(aBuf); + m_pClient->Quit(); +} diff --git a/src/engine/client/autoupdate.h b/src/engine/client/autoupdate.h index aae7393e7..01fab6d97 100644 --- a/src/engine/client/autoupdate.h +++ b/src/engine/client/autoupdate.h @@ -38,6 +38,8 @@ class CAutoUpdate : public IAutoUpdate class IStorage *m_pStorage; class IFetcher *m_pFetcher; + bool m_IsWinXP; + int m_State; char m_Status[256]; int m_Percent; @@ -71,7 +73,7 @@ public: virtual void InitiateUpdate(); void Init(); virtual void Update(); - void Restart(); + void WinXpRestart(); }; #endif diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 2c9304b19..343cd42bb 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1032,20 +1032,8 @@ void CClient::DebugRender() void CClient::Restart() { char aBuf[512]; - #if defined(WINXP) - IOHANDLE bhFile = io_open(Storage()->GetBinaryPath("du.bat", aBuf, sizeof aBuf);, IOFLAG_WRITE); - if(!bhFile) - return false; - - char bBuf[512]; - str_format(bBuf, sizeof(bBuf), ":_R\r\ndel \"DDNet.exe\"\r\nif exist \"DDNet.exe\" goto _R\r\nrename \"DDNet.tmp\" \"DDNet.exe\"\r\n:_T\r\nif not exist \"DDNet.exe\" goto _T\r\nstart DDNet.exe\r\ndel \"du.bat\"\r\n"); - io_write(bhFile, bBuf, str_length(bBuf)); - io_close(bhFile); - ShellExecuteA(0, 0, aBuf, 0, 0, SW_HIDE); - #else - shell_execute(Storage()->GetBinaryPath(PLAT_CLIENT_EXEC, aBuf, sizeof aBuf)); - Quit(); - #endif + shell_execute(Storage()->GetBinaryPath(PLAT_CLIENT_EXEC, aBuf, sizeof aBuf)); + Quit(); } void CClient::Quit()