Various windows hacks.
[dcpomatic.git] / src / tools / dcpomatic_dist_writer.cc
index 08e5a109ea74c626ccad5281bd2ad3c06af2c5cd..7f76c9ba44f48c7fbe808028f499553e18b7d317 100644 (file)
@@ -23,8 +23,9 @@
 #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 <lwext4/file_dev.h>
 #include <lwext4/ext4_mbr.h>
 #include <lwext4/ext4_fs.h>
 #include <lwext4/ext4_mkfs.h>
@@ -32,17 +33,35 @@ extern "C" {
 #include <lwext4/ext4_debug.h>
 #include <lwext4/ext4.h>
 }
-#ifndef WIN32
+
+#ifdef DCPOMATIC_POSIX
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <linux/fs.h>
 #endif
+
+#ifdef DCPOMATIC_OSX
+#undef nil
+#endif
+
+#ifdef DCPOMATIC_LINUX
+#include <linux/fs.h>
 #include <polkit/polkit.h>
+extern "C" {
+#include <lwext4/file_dev.h>
+}
+#include <poll.h>
+#endif
+
+#ifdef DCPOMATIC_WINDOWS
+extern "C" {
+#include <lwext4/file_windows.h>
+}
+#endif
+
 #include <glibmm.h>
 #include <unistd.h>
 #include <sys/types.h>
-#include <poll.h>
 #include <boost/filesystem.hpp>
 #include <iostream>
 
@@ -51,7 +70,9 @@ using std::cin;
 using std::min;
 using std::string;
 
+#ifdef DCPOMATIC_LINUX
 static PolkitAuthority* polkit_authority = 0;
+#endif
 static boost::filesystem::path dcp_path;
 static std::string device;
 static uint64_t const block_size = 4096;
@@ -205,6 +226,7 @@ copy (boost::filesystem::path from, boost::filesystem::path to, uint64_t& total_
 static
 void
 write ()
+try
 {
 //     ext4_dmask_set (DEBUG_ALL);
 
@@ -218,7 +240,7 @@ write ()
        info.journal = false;
 
 #ifdef WIN32
-       file_windows_name_set(WINDOWS_DRIVE);
+       file_windows_name_set(device.c_str());
        struct ext4_blockdev* bd = file_windows_dev_get();
 #else
        file_dev_name_set (device.c_str());
@@ -246,7 +268,7 @@ write ()
                throw CopyError ("Failed to write MBR", r);
        }
 
-#ifdef WIN32
+#ifdef DCPOMATIC_WINDOWS
        struct ext4_mbr_bdevs bdevs;
        r = ext4_mbr_scan (bd, &bdevs);
        if (r != EOK) {
@@ -254,12 +276,16 @@ write ()
        }
 
        file_windows_partition_set (bdevs.partitions[0].part_offset, bdevs.partitions[0].part_size);
-#else
+#endif
+
+#ifdef DCPOMATIC_LINUX
        /* Re-read the partition table */
        int fd = open(device.c_str(), O_RDONLY);
        ioctl(fd, BLKRRPART, NULL);
        close(fd);
+#endif
 
+#ifdef DCPOMATIC_POSIX
        string partition = device;
        /* XXX: don't know if this logic is sensible */
        if (partition.size() > 0 && isdigit(partition[partition.length() - 1])) {
@@ -302,35 +328,46 @@ write ()
 
        cout << DIST_WRITER_OK "\n";
        cout.flush ();
+} catch (CopyError& e) {
+       cout << DIST_WRITER_ERROR "\n" << e.message() << "\n" << e.number() << "\n";
+       cout.flush ();
+} catch (VerifyError& e) {
+       cout << DIST_WRITER_ERROR "\n" << e.message() << "\n" << e.number() << "\n";
+       cout.flush ();
 }
 
+#ifdef DCPOMATIC_LINUX
 static
 void
 polkit_callback (GObject *, GAsyncResult* res, gpointer)
 {
        PolkitAuthorizationResult* result = polkit_authority_check_authorization_finish (polkit_authority, res, 0);
        if (result && polkit_authorization_result_get_is_authorized(result)) {
-               try {
-                       write ();
-               } catch (CopyError& e) {
-                       cout << DIST_WRITER_ERROR "\n" << e.message() << "\n" << e.number() << "\n";
-                       cout.flush ();
-               } catch (VerifyError& e) {
-                       cout << DIST_WRITER_ERROR "\n" << e.message() << "\n" << e.number() << "\n";
-                       cout.flush ();
-               }
+               write ();
        }
        if (result) {
                g_object_unref (result);
        }
 }
+#endif
 
 bool
 idle ()
 {
+#ifdef DCPOMATIC_POSIX
        struct pollfd input[1] = { { fd: 0, events: POLLIN, revents: 0 } };
        int const r = poll (input, 1, 0);
        if (r > 0 && (input[0].revents & POLLIN)) {
+#else
+       DWORD num;
+       LOG_DIST ("now handle in is %1", reinterpret_cast<uint64_t>(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;
                getline (cin, s);
                if (s.empty()) {
@@ -340,11 +377,17 @@ 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());
                polkit_authority_check_authorization (
                        polkit_authority, subject, "com.dcpomatic.write-drive", 0, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, 0, polkit_callback, 0
                        );
+#else
+               write ();
+#endif
        }
        return true;
 }
@@ -352,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<uint64_t>(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<Glib::MainLoop> ml = Glib::MainLoop::create ();
        Glib::signal_timeout().connect(sigc::ptr_fun(&idle), 500);
        ml->run ();