From 5d463c3a1c8377cfe09ec9c76cee0cba81e3e19d Mon Sep 17 00:00:00 2001 From: aleks-f Date: Fri, 14 Dec 2012 12:09:23 -0600 Subject: [PATCH] GH 30:Poco::Path::home() throws GH #30: Poco::Path::home() throws when called from Windows Service done for Win32 and Win32U, return root for WinCE --- CONTRIBUTORS | 39 ++++++++++++++------------- Foundation/include/Poco/Path_WIN32.h | 1 + Foundation/include/Poco/Path_WIN32U.h | 1 + Foundation/include/Poco/Path_WINCE.h | 1 + Foundation/src/Path.cpp | 2 +- Foundation/src/Path_WIN32.cpp | 30 +++++++++++++++++++-- Foundation/src/Path_WIN32U.cpp | 32 ++++++++++++++++++++-- Foundation/src/Path_WINCE.cpp | 14 ++-------- Foundation/testsuite/src/PathTest.cpp | 18 +++++++++++++ Foundation/testsuite/src/PathTest.h | 1 + 10 files changed, 103 insertions(+), 36 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index c40d556c6..30956cf0f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,23 +1,23 @@ -Guenter Obiltschnig -Alex Fabijanic -Peter Schojer -Ferdinand Beyer -Krzysztof Burghardt -Claus Dabringer -Caleb Epstein -Eran Hammer-Lahav -Chris Johnson -Sergey Kholodilov -Ryan Kraay -Larry Lewis -Andrew J. P. Maclean -Andrew Marlow -Paschal Mushubi -Jiang Shan -David Shawley -Sergey Skorokhodov +Guenter Obiltschnig +Alex Fabijanic +Peter Schojer +Ferdinand Beyer +Krzysztof Burghardt +Claus Dabringer +Caleb Epstein +Eran Hammer-Lahav +Chris Johnson +Sergey Kholodilov +Ryan Kraay +Larry Lewis +Andrew J. P. Maclean +Andrew Marlow +Paschal Mushubi +Jiang Shan +David Shawley +Sergey Skorokhodov Tom Tan -Sergey N. Yatskevich +Sergey N. Yatskevich Marc Chevrier Philippe Cuvillier Marian Krivos @@ -28,6 +28,7 @@ Rangel Reale Fabrizio Duhem Patrick White Mike Naquin +Roger Meier -- $Id$ diff --git a/Foundation/include/Poco/Path_WIN32.h b/Foundation/include/Poco/Path_WIN32.h index 956b6ae19..066c64a1d 100644 --- a/Foundation/include/Poco/Path_WIN32.h +++ b/Foundation/include/Poco/Path_WIN32.h @@ -54,6 +54,7 @@ public: static std::string homeImpl(); static std::string tempImpl(); static std::string nullImpl(); + static std::string systemImpl(); static std::string expandImpl(const std::string& path); static void listRootsImpl(std::vector& roots); }; diff --git a/Foundation/include/Poco/Path_WIN32U.h b/Foundation/include/Poco/Path_WIN32U.h index ac05a4629..f12c71894 100644 --- a/Foundation/include/Poco/Path_WIN32U.h +++ b/Foundation/include/Poco/Path_WIN32U.h @@ -54,6 +54,7 @@ public: static std::string homeImpl(); static std::string tempImpl(); static std::string nullImpl(); + static std::string systemImpl(); static std::string expandImpl(const std::string& path); static void listRootsImpl(std::vector& roots); diff --git a/Foundation/include/Poco/Path_WINCE.h b/Foundation/include/Poco/Path_WINCE.h index ef6b9f06a..dc3a12647 100644 --- a/Foundation/include/Poco/Path_WINCE.h +++ b/Foundation/include/Poco/Path_WINCE.h @@ -55,6 +55,7 @@ public: static std::string homeImpl(); static std::string tempImpl(); static std::string nullImpl(); + static std::string systemImpl(); static std::string expandImpl(const std::string& path); static void listRootsImpl(std::vector& roots); diff --git a/Foundation/src/Path.cpp b/Foundation/src/Path.cpp index acc19dfce..c96bd956c 100644 --- a/Foundation/src/Path.cpp +++ b/Foundation/src/Path.cpp @@ -599,7 +599,7 @@ Path& Path::clear() _dirs.clear(); _version.clear(); _absolute = false; - return *this; + return *this; } diff --git a/Foundation/src/Path_WIN32.cpp b/Foundation/src/Path_WIN32.cpp index f38d6594a..4b6c68640 100644 --- a/Foundation/src/Path_WIN32.cpp +++ b/Foundation/src/Path_WIN32.cpp @@ -57,10 +57,36 @@ std::string PathImpl::currentImpl() } +std::string PathImpl::systemImpl() +{ + char buffer[MAX_PATH]; + DWORD n = GetSystemDirectoryA(buffer, sizeof(buffer)); + if (n > 0 && n < sizeof(buffer)) + { + std::string result(buffer, n); + if (result[n - 1] != '\\') + result.append("\\"); + return result; + } + else throw SystemException("Cannot get system directory"); +} + + std::string PathImpl::homeImpl() { - std::string result = EnvironmentImpl::getImpl("HOMEDRIVE"); - result.append(EnvironmentImpl::getImpl("HOMEPATH")); + std::string result; + + // windows service has no home dir, return system directory instead + try + { + result = EnvironmentImpl::getImpl("HOMEDRIVE"); + result.append(EnvironmentImpl::getImpl("HOMEPATH")); + } + catch (NotFoundException&) + { + result = systemImpl(); + } + std::string::size_type n = result.size(); if (n > 0 && result[n - 1] != '\\') result.append("\\"); diff --git a/Foundation/src/Path_WIN32U.cpp b/Foundation/src/Path_WIN32U.cpp index d9fe50003..99b162ffa 100644 --- a/Foundation/src/Path_WIN32U.cpp +++ b/Foundation/src/Path_WIN32U.cpp @@ -65,10 +65,38 @@ std::string PathImpl::currentImpl() } +std::string PathImpl::systemImpl() +{ + Buffer buffer(MAX_PATH_LEN); + DWORD n = GetSystemDirectoryW(buffer.begin(), static_cast(buffer.size())); + if (n > 0) + { + n = GetLongPathNameW(buffer.begin(), buffer.begin(), static_cast(buffer.size())); + if (n <= 0) throw SystemException("Cannot get system directory long path name"); + std::string result; + UnicodeConverter::toUTF8(buffer.begin(), result); + if (result[result.size() - 1] != '\\') result.append("\\"); + return result; + } + throw SystemException("Cannot get temporary directory path"); +} + + std::string PathImpl::homeImpl() { - std::string result = EnvironmentImpl::getImpl("HOMEDRIVE"); - result.append(EnvironmentImpl::getImpl("HOMEPATH")); + std::string result; + + // windows service has no home dir, return system directory instead + try + { + result = EnvironmentImpl::getImpl("HOMEDRIVE"); + result.append(EnvironmentImpl::getImpl("HOMEPATH")); + } + catch (NotFoundException&) + { + result = systemImpl(); + } + std::string::size_type n = result.size(); if (n > 0 && result[n - 1] != '\\') result.append("\\"); diff --git a/Foundation/src/Path_WINCE.cpp b/Foundation/src/Path_WINCE.cpp index 612711407..8c02a76e0 100644 --- a/Foundation/src/Path_WINCE.cpp +++ b/Foundation/src/Path_WINCE.cpp @@ -58,19 +58,9 @@ std::string PathImpl::homeImpl() } -std::string PathImpl::tempImpl() +std::string PathImpl::systemImpl() { - Buffer buffer(MAX_PATH_LEN); - DWORD n = GetTempPathW(static_cast(buffer.size()), buffer.begin()); - if (n > 0) - { - std::string result; - UnicodeConverter::toUTF8(buffer.begin(), result); - if (result[n - 1] != '\\') - result.append("\\"); - return result; - } - throw SystemException("Cannot get current directory"); + return("\\"); } diff --git a/Foundation/testsuite/src/PathTest.cpp b/Foundation/testsuite/src/PathTest.cpp index 3f5ec1123..924e1cb1d 100644 --- a/Foundation/testsuite/src/PathTest.cpp +++ b/Foundation/testsuite/src/PathTest.cpp @@ -39,6 +39,15 @@ #include "Poco/Environment.h" #include +#if defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_WIN32_UTF8) +#if defined(_WIN32_WCE) +#include "Poco/Path_WINCE.h" +#else +#include "Poco/Path_WIN32U.h" +#endif +#elif defined(POCO_OS_FAMILY_WINDOWS) +#include "Poco/Path_WIN32.h" +#endif using Poco::Path; using Poco::PathSyntaxException; @@ -1625,6 +1634,14 @@ void PathTest::testPushPop() } +void PathTest::testWindowsSystem() +{ +#if defined(POCO_OS_FAMILY_WINDOWS) + std::cout << Poco::PathImpl::systemImpl() << std::endl; +#endif +} + + void PathTest::setUp() { } @@ -1666,6 +1683,7 @@ CppUnit::Test* PathTest::suite() CppUnit_addTest(pSuite, PathTest, testSwap); CppUnit_addTest(pSuite, PathTest, testResolve); CppUnit_addTest(pSuite, PathTest, testPushPop); + CppUnit_addTest(pSuite, PathTest, testWindowsSystem); return pSuite; } diff --git a/Foundation/testsuite/src/PathTest.h b/Foundation/testsuite/src/PathTest.h index b616d777f..5ad17a6f7 100644 --- a/Foundation/testsuite/src/PathTest.h +++ b/Foundation/testsuite/src/PathTest.h @@ -73,6 +73,7 @@ public: void testSwap(); void testResolve(); void testPushPop(); + void testWindowsSystem(); void setUp(); void tearDown();