X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fcross_windows.cc;h=0549615787214dbd0ce4ef18b31ced6b5df78aca;hp=723828d7e235dce6617e01041389756ad6201620;hb=b17c280ea98f89fe141e9ef2a8372316c44e0155;hpb=a3d4dfb4357a265d4c3a4bfafe7d17a8ecc72f66 diff --git a/src/lib/cross_windows.cc b/src/lib/cross_windows.cc index 723828d7e..054961578 100644 --- a/src/lib/cross_windows.cc +++ b/src/lib/cross_windows.cc @@ -29,6 +29,7 @@ #include "exceptions.h" #include "dcpomatic_assert.h" #include "util.h" +#include #include #include extern "C" { @@ -44,7 +45,9 @@ extern "C" { #include #undef DATADIR #include +#include #include +#include #include #include #include @@ -160,7 +163,7 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out) return; } - auto o = fopen_boost (out, "w"); + dcp::File o(out, "w"); if (!o) { LOG_ERROR_NC (N_("ffprobe call failed (could not create output file)")); return; @@ -174,10 +177,10 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out) if (!ReadFile(child_stderr_read, buffer, sizeof(buffer), &read, 0) || read == 0) { break; } - fwrite (buffer, read, 1, o); + o.write(buffer, read, 1); } - fclose (o); + o.close(); WaitForSingleObject (process_info.hProcess, INFINITE); CloseHandle (process_info.hProcess); @@ -208,16 +211,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 (); } @@ -237,61 +233,6 @@ disk_writer_path () #endif -/** Windows can't "by default" cope with paths longer than 260 characters, so if you pass such a path to - * any boost::filesystem method it will fail. There is a "fix" for this, which is to prepend - * the string \\?\ to the path. This will make it work, so long as: - * - the path is absolute. - * - the path only uses backslashes. - * - individual path components are "short enough" (probably less than 255 characters) - * - * See https://www.boost.org/doc/libs/1_57_0/libs/filesystem/doc/reference.html under - * "Warning: Long paths on Windows" for some details. - * - * Our fopen_boost uses this method to get this fix, but any other calls to boost::filesystem - * will not unless this method is explicitly called to pre-process the pathname. - */ -boost::filesystem::path -fix_long_path (boost::filesystem::path long_path) -{ - using namespace boost::filesystem; - - path fixed = "\\\\?\\"; - if (boost::algorithm::starts_with(long_path.string(), fixed.string())) { - 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). - */ - if (long_path.is_absolute()) { - fixed += long_path.make_preferred(); - } else { - fixed += boost::filesystem::current_path() / long_path.make_preferred(); - } - return fixed; -} - - -/* Apparently there is no way to create an ofstream using a UTF-8 - filename under Windows. We are hence reduced to using fopen - with this wrapper. -*/ -FILE * -fopen_boost (boost::filesystem::path p, string t) -{ - wstring w (t.begin(), t.end()); - /* c_str() on fixed here should give a UTF-16 string */ - return _wfopen (fix_long_path(p).c_str(), w.c_str()); -} - - -int -dcpomatic_fseek (FILE* stream, int64_t offset, int whence) -{ - return _fseeki64 (stream, offset, whence); -} - - void Waker::nudge () { @@ -355,10 +296,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 utf8(length); + WideCharToMultiByte (CP_UTF8, 0, s, -1, utf8.data(), length, 0, 0); + string u (utf8.data()); return u; } @@ -394,7 +334,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 +599,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) { @@ -672,11 +620,14 @@ Drive::unmount () boost::filesystem::path -config_path () +config_path (optional version) { boost::filesystem::path p; p /= g_get_user_config_dir (); p /= "dcpomatic2"; + if (version) { + p /= *version; + } return p; }