diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20e83544..85d34b64 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,6 +54,12 @@ jobs: cmake -G 'Visual Studio 17 2022' -A x64 -DQUIC_TLS=${{ matrix.tls }} -DQUIC_BUILD_SHARED=${{ matrix.shared }} .. cmake --build . --config Release cmake --install . --config Release + - name: Build Windows Installer + if: runner.os == 'Windows' + run: | + cd build + & 'C:/Program Files (x86)/WiX Toolset v3.11/bin/candle.exe' ../src/installer.wxs -o src/Release/quicreach.wixobj + & 'C:/Program Files (x86)/WiX Toolset v3.11/bin/light.exe' -b src/Release -o src/Release/quicreach.msi src/Release/quicreach.wixobj - name: Upload uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: @@ -63,6 +69,7 @@ jobs: build/**/*.dll build/**/quicreach build/**/quicreach.exe + build/**/quicreach.msi - name: Test (Linux) if: runner.os == 'Linux' run: /usr/local/lib/quicreach outlook-evergreen.office.com,www.cloudflare.com,www.google.com --req-all --stats diff --git a/.gitignore b/.gitignore index a7678abc..433a83eb 100644 --- a/.gitignore +++ b/.gitignore @@ -349,3 +349,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# VSCode folder +.vscode/ diff --git a/src/installer.wxs b/src/installer.wxs new file mode 100644 index 00000000..593b9539 --- /dev/null +++ b/src/installer.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/quicreach.cpp b/src/quicreach.cpp index d35b2435..ec9ebdf7 100644 --- a/src/quicreach.cpp +++ b/src/quicreach.cpp @@ -16,6 +16,8 @@ #include #include "domains.hpp" +#define QUICREACH_VERSION "1.1.0" + #ifdef _WIN32 #define QUIC_CALL __cdecl #else @@ -97,6 +99,24 @@ void IncStat( _Inout_ _Interlocked_operand_ uint32_t volatile &Addend) { #endif } +void AddHostName(const char* arg) { + // Parse hostname(s), treating '*' as all top-level domains. + if (!strcmp(arg, "*")) { + for (auto Domain : TopDomains) { + Config.HostNames.push_back(Domain); + } + } else { + char* HostName = (char*)arg; + do { + char* End = strchr(HostName, ','); + if (End) *End = 0; + Config.HostNames.push_back(HostName); + if (!End) break; + HostName = End + 1; + } while (true); + } +} + bool ParseConfig(int argc, char **argv) { if (argc < 2 || !strcmp(argv[1], "-?") || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { printf("usage: quicreach [options...]\n" @@ -110,29 +130,16 @@ bool ParseConfig(int argc, char **argv) { " -r, --req-all Require all hostnames to succeed\n" " -s, --stats Print connection statistics\n" " -u, --unsecure Allows unsecure connections\n" + " -v, --version Prints out the version\n" ); return false; } - // Parse hostname(s), treating '*' as all top-level domains. - if (!strcmp(argv[1], "*")) { - for (auto Domain : TopDomains) { - Config.HostNames.push_back(Domain); - } - } else { - char* HostName = (char*)argv[1]; - do { - char* End = strchr(HostName, ','); - if (End) *End = 0; - Config.HostNames.push_back(HostName); - if (!End) break; - HostName = End + 1; - } while (true); - } + for (int i = 1; i < argc; ++i) { + if (argv[i][0] != '-') { + AddHostName(argv[i]); - // Parse options. - for (int i = 2; i < argc; ++i) { - if (!strcmp(argv[i], "--alpn") || !strcmp(argv[i], "-a")) { + } else if (!strcmp(argv[i], "--alpn") || !strcmp(argv[i], "-a")) { if (++i >= argc) { printf("Missing ALPN string\n"); return false; } Config.Alpn = argv[i]; @@ -163,6 +170,9 @@ bool ParseConfig(int argc, char **argv) { } else if (!strcmp(argv[i], "--unsecure") || !strcmp(argv[i], "-u")) { Config.CredFlags |= QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION; + + } else if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) { + printf("quicreach " QUICREACH_VERSION "\n"); } } @@ -332,7 +342,7 @@ bool TestReachability() { int QUIC_CALL main(int argc, char **argv) { - if (!ParseConfig(argc, argv)) return 1; + if (!ParseConfig(argc, argv) || Config.HostNames.empty()) return 1; MsQuic = new (std::nothrow) MsQuicApi(); if (QUIC_FAILED(MsQuic->GetInitStatus())) {