From c3663fa9de96b99eac21f3aa736bd6f2e9bbc3c0 Mon Sep 17 00:00:00 2001 From: cah Date: Sun, 22 Mar 2020 20:50:11 +0100 Subject: [PATCH] Various windows hacks. --- src/lib/cross_windows.cc | 64 ++++++++++++++++++++++++++++-- src/tools/dcpomatic_dist_writer.cc | 36 ++++++++++++++++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/lib/cross_windows.cc b/src/lib/cross_windows.cc index 5d2cf5372..b97e2bbd0 100644 --- a/src/lib/cross_windows.cc +++ b/src/lib/cross_windows.cc @@ -24,6 +24,7 @@ #include "dcpomatic_log.h" #include "config.h" #include "exceptions.h" +#include "dcpomatic_assert.h" #include #include extern "C" { @@ -412,11 +413,69 @@ get_device_number (HDEVINFO device_info, SP_DEVINFO_DATA* device_info_data) return device_number.DeviceNumber; } +/** Take a volume path (with a trailing \) and add any disk numbers related to that volume + * to @ref disks. + */ +static void +add_volume_disk_number (wchar_t* volume, vector& disks) +{ + /* Strip trailing \ */ + size_t const len = wcslen (volume); + DCPOMATIC_ASSERT (len > 0); + volume[len - 1] = L'\0'; + + HANDLE handle = CreateFileW ( + volume, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, 0, 0 + ); + + DCPOMATIC_ASSERT (handle != INVALID_HANDLE_VALUE); + + VOLUME_DISK_EXTENTS extents; + DWORD size; + BOOL r = DeviceIoControl (handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0, 0, &extents, sizeof(extents), &size, 0); + CloseHandle (handle); + if (!r) { + return; + } + DCPOMATIC_ASSERT (extents.NumberOfDiskExtents == 1); + return disks.push_back (extents.Extents[0].DiskNumber); +} + +/* Return a list of disk numbers that contain volumes; i.e. a list of disk numbers that should + * not be offered as targets to write to as they are "mounted" (whatever that means on Windows). + */ +vector +disk_numbers_with_volumes () +{ + vector disks; + + wchar_t volume_name[512]; + HANDLE volume = FindFirstVolumeW (volume_name, sizeof(volume_name) / sizeof(wchar_t)); + if (volume == INVALID_HANDLE_VALUE) { + return disks; + } + + add_volume_disk_number (volume_name, disks); + while (true) { + if (!FindNextVolumeW(volume, volume_name, sizeof(volume_name) / sizeof(wchar_t))) { + break; + } + add_volume_disk_number (volume_name, disks); + } + FindVolumeClose (volume); + + return disks; +} + vector get_drives () { vector drives; + vector disks_to_ignore = disk_numbers_with_volumes (); + /* Get a `device information set' containing information about all disks */ HDEVINFO device_info = SetupDiGetClassDevsA (&GUID_DEVICE_INTERFACE_DISK, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (device_info == INVALID_HANDLE_VALUE) { @@ -454,6 +513,7 @@ get_drives () if (device == INVALID_HANDLE_VALUE) { LOG_DIST_NC("Could not open PHYSICALDRIVE"); + continue; } DISK_GEOMETRY geom; @@ -463,11 +523,9 @@ get_drives () &geom, sizeof(geom), &returned, 0 ); - if (r) { + if (r && find(disks_to_ignore.begin(), disks_to_ignore.end(), *device_number) == disks_to_ignore.end()) { uint64_t const disk_size = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector; drives.push_back (Drive(physical_drive, disk_size, false, friendly_name, optional())); - } else { - LOG_DIST("Error %1", GetLastError()); } CloseHandle (device); diff --git a/src/tools/dcpomatic_dist_writer.cc b/src/tools/dcpomatic_dist_writer.cc index 084f82c34..7f76c9ba4 100644 --- a/src/tools/dcpomatic_dist_writer.cc +++ b/src/tools/dcpomatic_dist_writer.cc @@ -23,6 +23,8 @@ #include "lib/exceptions.h" #include "lib/cross.h" #include "lib/digester.h" +#include "lib/file_log.h" +#include "lib/dcpomatic_log.h" extern "C" { #include #include @@ -358,7 +360,12 @@ idle () if (r > 0 && (input[0].revents & POLLIN)) { #else DWORD num; - GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &num); + LOG_DIST ("now handle in is %1", reinterpret_cast(GetStdHandle(STD_INPUT_HANDLE))); + if (!GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &num)) { + LOG_DIST ("Could not check console: %1", GetLastError()); + } + + LOG_DIST ("%1 console events", num); if (num) { #endif string s; @@ -370,6 +377,8 @@ idle () getline (cin, s); device = "/dev/" + s; + LOG_DIST ("Here we go writing %1 to %2", dcp_path, device); + #ifdef DCPOMATIC_LINUX polkit_authority = polkit_authority_get_sync (0, 0); PolkitSubject* subject = polkit_unix_process_new (getppid()); @@ -386,6 +395,31 @@ idle () int main () { + /* XXX: this is a hack, but I expect we'll need logs and I'm not sure if there's + * a better place to put them. + */ + dcpomatic_log.reset(new FileLog(config_path() / "dist_writer.log")); + dcpomatic_log->set_types (dcpomatic_log->types() | LogEntry::TYPE_DIST); + LOG_DIST_NC("dcpomatic_dist_writer started"); + +#ifdef DCPOMATIC_WINDOWS + FreeConsole (); + AllocConsole (); + + HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); + int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT); + FILE* hf_out = _fdopen(hCrt, "w"); + setvbuf(hf_out, NULL, _IONBF, 1); + *stdout = *hf_out; + + HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); + LOG_DIST ("handle_in is %1", reinterpret_cast(handle_in)); + hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT); + FILE* hf_in = _fdopen(hCrt, "r"); + setvbuf(hf_in, NULL, _IONBF, 128); + *stdin = *hf_in; +#endif + Glib::RefPtr ml = Glib::MainLoop::create (); Glib::signal_timeout().connect(sigc::ptr_fun(&idle), 500); ml->run (); -- 2.30.2