Replace some raw arrays with std::vectors.
[dcpomatic.git] / src / lib / cross_windows.cc
index b3d9a1558add1fbd2f7e70a74a23b2017accc985..f7638083656c2731411075144fbd10f8b72f9a2b 100644 (file)
@@ -44,7 +44,9 @@ extern "C" {
 #include <fileapi.h>
 #undef DATADIR
 #include <shlwapi.h>
+#include <shlobj.h>
 #include <shellapi.h>
+#include <knownfolders.h>
 #include <fcntl.h>
 #include <fstream>
 #include <map>
@@ -208,16 +210,9 @@ resources_path ()
 
 
 boost::filesystem::path
-xsd_path ()
+libdcp_resources_path ()
 {
-       return directory_containing_executable().parent_path() / "xsd";
-}
-
-
-boost::filesystem::path
-tags_path ()
-{
-       return directory_containing_executable().parent_path() / "tags";
+       return resources_path ();
 }
 
 
@@ -255,14 +250,17 @@ fix_long_path (boost::filesystem::path long_path)
 {
        using namespace boost::filesystem;
 
-       path fixed = "\\\\?\\";
-       if (boost::algorithm::starts_with(long_path.string(), fixed.string())) {
+       if (boost::algorithm::starts_with(long_path.string(), "\\\\")) {
+               /* This could mean it starts with \\ (i.e. a SMB path) or \\?\ (a long path)
+                * or a variety of other things... anyway, we'll leave it alone.
+                */
                return long_path;
        }
 
        /* We have to make the path canonical but we can't call canonical() on the long path
         * as it will fail.  So we'll sort of do it ourselves (possibly badly).
         */
+       path fixed = "\\\\?\\";
        if (long_path.is_absolute()) {
                fixed += long_path.make_preferred();
        } else {
@@ -355,10 +353,9 @@ static string
 wchar_to_utf8 (wchar_t const * s)
 {
        int const length = (wcslen(s) + 1) * 2;
-       char* utf8 = new char[length];
-       WideCharToMultiByte (CP_UTF8, 0, s, -1, utf8, length, 0, 0);
-       string u (utf8);
-       delete[] utf8;
+       std::vector<char> utf8(length);
+       WideCharToMultiByte (CP_UTF8, 0, s, -1, utf8.data(), length, 0, 0);
+       string u (utf8.data());
        return u;
 }
 
@@ -394,7 +391,17 @@ maybe_open_console ()
 boost::filesystem::path
 home_directory ()
 {
-       return boost::filesystem::path(getenv("userprofile"));
+       PWSTR wide_path;
+       auto result = SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &wide_path);
+
+       if (result != S_OK) {
+               CoTaskMemFree(wide_path);
+               return boost::filesystem::path("c:\\");
+       }
+
+       auto path = wchar_to_utf8(wide_path);
+       CoTaskMemFree(wide_path);
+       return path;
 }
 
 
@@ -649,8 +656,6 @@ Drive::unmount ()
        DCPOMATIC_ASSERT (_mount_points.size() == 1);
        string const device_name = String::compose ("\\\\.\\%1", _mount_points.front());
        string const truncated = device_name.substr (0, device_name.length() - 1);
-       //LOG_DISK("Actually opening %1", _device);
-       //HANDLE device = CreateFileA (_device.c_str(), (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        LOG_DISK("Actually opening %1", truncated);
        HANDLE device = CreateFileA (truncated.c_str(), (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        if (device == INVALID_HANDLE_VALUE) {