From e998bd0b3f95e92f82f52256e0c086dc1030b7fa Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Tue, 12 Dec 2017 12:15:33 +0400
Subject: [PATCH] Parse command line natively on Windows.

Use CommandLineToArgvW() so that unicode arguments are preserved.
This will fix path arguments with unicode symbols in them.
---
 Telegram/SourceFiles/core/launcher.cpp        | 37 ++++++++++---------
 Telegram/SourceFiles/core/launcher.h          |  8 ++++
 .../SourceFiles/platform/win/launcher_win.cpp | 19 ++++++++++
 .../SourceFiles/platform/win/launcher_win.h   |  4 ++
 4 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp
index 731aa1aee4..c059159764 100644
--- a/Telegram/SourceFiles/core/launcher.cpp
+++ b/Telegram/SourceFiles/core/launcher.cpp
@@ -26,20 +26,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 #include "application.h"
 
 namespace Core {
-namespace {
-
-QStringList ReadArguments(int argc, char *argv[]) {
-	Expects(argc >= 0);
-
-	auto result = QStringList();
-	result.reserve(argc);
-	for (auto i = 0; i != argc; ++i) {
-		result.push_back(fromUtf8Safe(argv[i]));
-	}
-	return result;
-}
-
-} // namespace
 
 std::unique_ptr<Launcher> Launcher::Create(int argc, char *argv[]) {
 	return std::make_unique<Platform::Launcher>(argc, argv);
@@ -47,12 +33,14 @@ std::unique_ptr<Launcher> Launcher::Create(int argc, char *argv[]) {
 
 Launcher::Launcher(int argc, char *argv[])
 : _argc(argc)
-, _argv(argv)
-, _arguments(ReadArguments(argc, argv)) {
-	prepareSettings();
+, _argv(argv) {
 }
 
 void Launcher::init() {
+	_arguments = readArguments(_argc, _argv);
+
+	prepareSettings();
+
 	QCoreApplication::setApplicationName(qsl("TelegramDesktop"));
 
 #ifndef OS_MAC_OLD
@@ -103,6 +91,21 @@ int Launcher::exec() {
 	return result;
 }
 
+QStringList Launcher::readArguments(int argc, char *argv[]) const {
+	Expects(argc >= 0);
+
+	if (const auto native = readArgumentsHook(argc, argv)) {
+		return *native;
+	}
+
+	auto result = QStringList();
+	result.reserve(argc);
+	for (auto i = 0; i != argc; ++i) {
+		result.push_back(fromUtf8Safe(argv[i]));
+	}
+	return result;
+}
+
 QString Launcher::argumentsString() const {
 	return _arguments.join(' ');
 }
diff --git a/Telegram/SourceFiles/core/launcher.h b/Telegram/SourceFiles/core/launcher.h
index a16a85c643..2348d1646f 100644
--- a/Telegram/SourceFiles/core/launcher.h
+++ b/Telegram/SourceFiles/core/launcher.h
@@ -45,12 +45,20 @@ private:
 	void prepareSettings();
 	void processArguments();
 
+	QStringList readArguments(int argc, char *argv[]) const;
+	virtual base::optional<QStringList> readArgumentsHook(
+			int argc,
+			char *argv[]) const {
+		return base::none;
+	}
+
 	void init();
 	virtual void initHook() {
 	}
 
 	virtual bool launchUpdater(UpdaterLaunch action) = 0;
 
+
 	int _argc;
 	char **_argv;
 	QStringList _arguments;
diff --git a/Telegram/SourceFiles/platform/win/launcher_win.cpp b/Telegram/SourceFiles/platform/win/launcher_win.cpp
index cf8f81f06c..3419998f04 100644
--- a/Telegram/SourceFiles/platform/win/launcher_win.cpp
+++ b/Telegram/SourceFiles/platform/win/launcher_win.cpp
@@ -23,10 +23,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 #include "core/crash_reports.h"
 #include "platform/platform_specific.h"
 
+#include <windows.h>
 #include <shellapi.h>
 
 namespace Platform {
 
+base::optional<QStringList> Launcher::readArgumentsHook(
+		int argc,
+		char *argv[]) const {
+	auto count = 0;
+	if (const auto list = CommandLineToArgvW(GetCommandLine(), &count)) {
+		const auto guard = gsl::finally([&] { LocalFree(list); });
+		if (count > 0) {
+			auto result = QStringList();
+			result.reserve(count);
+			for (auto i = 0; i != count; ++i) {
+				result.push_back(QString::fromWCharArray(list[i]));
+			}
+			return result;
+		}
+	}
+	return base::none;
+}
+
 bool Launcher::launchUpdater(UpdaterLaunch action) {
 	if (cExeName().isEmpty()) {
 		return false;
diff --git a/Telegram/SourceFiles/platform/win/launcher_win.h b/Telegram/SourceFiles/platform/win/launcher_win.h
index 3d5079934c..95c01301e9 100644
--- a/Telegram/SourceFiles/platform/win/launcher_win.h
+++ b/Telegram/SourceFiles/platform/win/launcher_win.h
@@ -29,6 +29,10 @@ public:
 	using Core::Launcher::Launcher;
 
 private:
+	base::optional<QStringList> readArgumentsHook(
+		int argc,
+		char *argv[]) const override;
+
 	bool launchUpdater(UpdaterLaunch action) override;
 
 	bool launch(