diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2016-12-16 09:23:50 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2016-12-19 10:07:43 +0000 |
commit | 8fd5468ca2210d7e6bd515698f264e41368819fd (patch) | |
tree | cee88796ab54b4b1939c0d5a66f3a9f6ef700e42 | |
parent | b4fc0df834412de5b25b105a2141968d53d37df2 (diff) | |
download | qtactiveqt-8fd5468ca2210d7e6bd515698f264e41368819fd.tar.gz |
Rewrite qaxserver_main.cpp to use CommandLineToArgvW()
Rewrite the command line processing to use QStrings constructed
from the return value of CommandLineToArgvW().
This ensures that arguments with blanks are processed correctly
and fixes the invocation of .exe targets with spaces via idc
using the -dumpidl option and removes the dependency on
the qWinMain() function exported from QtCore.
Task-number: QTBUG-55332
Change-Id: I2d6cc11f2bff30027664707d03a75650d724a4f9
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r-- | src/activeqt/control/control.pro | 2 | ||||
-rw-r--r-- | src/activeqt/control/qaxservermain.cpp | 85 |
2 files changed, 60 insertions, 27 deletions
diff --git a/src/activeqt/control/control.pro b/src/activeqt/control/control.pro index 6409112..e55bdab 100644 --- a/src/activeqt/control/control.pro +++ b/src/activeqt/control/control.pro @@ -23,6 +23,8 @@ SOURCES = qaxaggregated.cpp \ qaxmain.cpp \ ../shared/qaxtypes.cpp +LIBS += -lshell32 + MODULE = axserver MODULE_DEFINES = QAXSERVER MODULE_CONFIG = idcidl force_import_plugins diff --git a/src/activeqt/control/qaxservermain.cpp b/src/activeqt/control/qaxservermain.cpp index 7aec11d..c54f7ef 100644 --- a/src/activeqt/control/qaxservermain.cpp +++ b/src/activeqt/control/qaxservermain.cpp @@ -43,6 +43,8 @@ #include "qaxfactory.h" +#include <string.h> + #include <qt_windows.h> QT_BEGIN_NAMESPACE @@ -173,8 +175,6 @@ bool qax_stopServer() return true; } -extern void qWinMain(HINSTANCE, HINSTANCE, LPSTR, int, int &, QVector<char *> &); - QT_END_NAMESPACE #if defined(QT_NEEDS_QMAIN) @@ -184,8 +184,47 @@ int qMain(int, char **); extern "C" int main(int, char **); #endif +static inline QStringList commandLineArguments() +{ + QStringList result; + int size; + if (wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &size)) { + result.reserve(size); + wchar_t **argvEnd = argv + size; + for (wchar_t **a = argv; a < argvEnd; ++a) + result.append(QString::fromWCharArray(*a)); + LocalFree(argv); + } + return result; +} -EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, int nShowCmd) +static inline bool matchesOption(const QString &arg, const char *option) +{ + return (arg.startsWith(QLatin1Char('/')) || arg.startsWith(QLatin1Char('-'))) + && arg.rightRef(arg.size() - 1).compare(QLatin1String(option), Qt::CaseInsensitive) == 0; +} + +namespace { +struct Arg { + explicit Arg(const QStringList &args) + { + argv.reserve(args.size() + 1); + for (const QString &a : args) + argv.append(_strdup(a.toLocal8Bit().constData())); + argv.append(nullptr); + } + + ~Arg() + { + for (int i = 0, last = argv.size() - 1; i < last; ++i) + free(argv.at(i)); + } + + QVector<char *> argv; +}; +} // namespace + +EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR, int /* nShowCmd */) { QT_USE_NAMESPACE @@ -193,66 +232,58 @@ EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, GetModuleFileName(0, qAxModuleFilename, MAX_PATH); qAxInstance = hInstance; - QByteArray cmdParam = QString::fromWCharArray(GetCommandLine()).toLocal8Bit(); - QList<QByteArray> cmds = cmdParam.split(' '); - QByteArray unprocessed; + const QStringList cmds = commandLineArguments(); + QStringList unprocessed; + unprocessed.reserve(cmds.size()); int nRet = 0; bool run = true; bool runServer = false; for (int i = 0; i < cmds.count(); ++i) { - QByteArray cmd = cmds.at(i).toLower(); - if (cmd == "-activex" || cmd == "/activex" || cmd == "-embedding" || cmd == "/embedding") { + const QString &cmd = cmds.at(i); + if (matchesOption(cmd, "activex") || matchesOption(cmd, "embedding")) { runServer = true; - } else if (cmd == "-unregserver" || cmd == "/unregserver") { + } else if (matchesOption(cmd, "unregserver")) { nRet = UpdateRegistry(false); run = false; break; - } else if (cmd == "-regserver" || cmd == "/regserver") { + } else if (matchesOption(cmd, "regserver")) { nRet = UpdateRegistry(true); run = false; break; - } else if (cmd == "-dumpidl" || cmd == "/dumpidl") { + } else if (matchesOption(cmd, "dumpidl")) { ++i; if (i < cmds.count()) { - QByteArray outfile = cmds.at(i); + const QString &outfile = cmds.at(i); ++i; - QByteArray version; - if (i < cmds.count() && (cmds.at(i) == "-version" || cmds.at(i) == "/version")) { + QString version; + if (i < cmds.count() && matchesOption(cmds.at(i), "version")) { ++i; if (i < cmds.count()) version = cmds.at(i); else - version = "1.0"; + version = QStringLiteral("1.0"); } - nRet = DumpIDL(QString::fromLatin1(outfile.constData()), QString::fromLatin1(version.constData())); + nRet = DumpIDL(outfile, version); } else { qWarning("Wrong commandline syntax: <app> -dumpidl <idl file> [-version <x.y.z>]"); } run = false; break; } else { - unprocessed += cmds.at(i) + ' '; + unprocessed.append(cmds.at(i)); } } if (run) { if (SUCCEEDED(CoInitialize(0))) { { - struct Arg { - int c; - QVector<char*> v; - - Arg() : v(8) {} - ~Arg() { Q_FOREACH (char *arg, v) free(arg); } - } arg; - - qWinMain(hInstance, hPrevInstance, unprocessed.data(), nShowCmd, arg.c, arg.v); + Arg args(unprocessed); qAxInit(); if (runServer) QAxFactory::startServer(); - nRet = ::main(arg.c, arg.v.data()); + nRet = ::main(args.argv.size() - 1, args.argv.data()); QAxFactory::stopServer(); qAxCleanup(); } |