From b16af78142b3c82c85631fc2e9fa3385030a7e5e Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Sun, 8 Jul 2018 12:37:24 +0200 Subject: [PATCH] Load SimConnect dynamically at runtime. Previously the FSX/P3D driver tried to link a very specific SimConnect version from the Windows Assembly cache. This caused issues with machines which did not have this specific version of SimConnect in the assembly cache since drivers refused to load without much information. Having a different version of SimConnect in the assembly cache or even in the bin folder did not help. To fix this problem, SimConnect is now loaded and resolved manually at runtime. This allows to try loading different versions from the assembly cache or prefer to load the shipped one. For this, the manifests are linked into the binary's resource section and activated manually before loading. This has the positive effect, that loading errors can be handled by code instead of raising a cryptic error and aborting. --- mkspecs/features/libraries.pri | 43 +++ src/plugins/simulator/fsx/fsx.pro | 21 +- .../fsxcommon/SimConnect_RTM.manifest | 8 + .../fsxcommon/SimConnect_SP1.manifest | 8 + .../fsxcommon/SimConnect_XPack.manifest | 8 + src/plugins/simulator/fsxcommon/fsxcommon.pro | 8 +- src/plugins/simulator/fsxcommon/simconnect.rc | 3 + .../fsxcommon/simconnectdatadefinition.cpp | 1 + .../simulator/fsxcommon/simconnectsymbols.cpp | 300 ++++++++++++++++++ .../simulator/fsxcommon/simconnectsymbols.h | 20 ++ .../fsxcommon/simulatorfsxcommon.cpp | 2 + src/plugins/simulator/fsxconfig/fsxconfig.pro | 22 +- src/plugins/simulator/fsxp3d.pri | 30 -- src/plugins/simulator/fsxp3d_include.pri | 15 - src/plugins/simulator/p3d/p3d.pro | 24 +- src/plugins/simulator/p3dconfig/p3dconfig.pro | 21 +- .../testblacksimpluginfsxp3d.pro | 11 +- .../testblacksimpluginfsxp3dmain.cpp | 4 + .../testsimconnectsymbols.cpp | 34 ++ .../testsimconnectsymbols.h | 38 +++ 20 files changed, 559 insertions(+), 62 deletions(-) create mode 100644 src/plugins/simulator/fsxcommon/SimConnect_RTM.manifest create mode 100644 src/plugins/simulator/fsxcommon/SimConnect_SP1.manifest create mode 100644 src/plugins/simulator/fsxcommon/SimConnect_XPack.manifest create mode 100644 src/plugins/simulator/fsxcommon/simconnect.rc create mode 100644 src/plugins/simulator/fsxcommon/simconnectsymbols.cpp create mode 100644 src/plugins/simulator/fsxcommon/simconnectsymbols.h delete mode 100644 src/plugins/simulator/fsxp3d.pri delete mode 100644 src/plugins/simulator/fsxp3d_include.pri create mode 100644 tests/blacksimpluginfsxp3d/testsimconnectsymbols.cpp create mode 100644 tests/blacksimpluginfsxp3d/testsimconnectsymbols.h diff --git a/mkspecs/features/libraries.pri b/mkspecs/features/libraries.pri index f3c5fadc6..370ec4f41 100644 --- a/mkspecs/features/libraries.pri +++ b/mkspecs/features/libraries.pri @@ -6,6 +6,49 @@ unix:!macx { LIBS += -Wl,-rpath-link,$$DestRoot/lib -Wl,-rpath-link,$$[QT_INSTALL_LIBS] } +simulatorfsxcommon { + addStaticLibraryDependency(simulatorfsxcommon) + LIBS += -lsimulatorfsxcommon +} + +simulatorfscommon { + addStaticLibraryDependency(simulatorfscommon) + LIBS += -lsimulatorfscommon +} + +simulatorplugincommon { + addStaticLibraryDependency(simulatorplugincommon) + LIBS += -lsimulatorplugincommon +} + +fsuipc { + addStaticLibraryDependency(fsuipc) + LIBS += -lfsuipc +} + +simconnect { + DEFINES += SIMCONNECT_H_NOMANIFEST + + equals(WORD_SIZE,64) { + INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/P3D-v4.1 + LIBS *= -L$$EXTERNALS_LIB_DIR/P3D-v4.1 + LIBS *= -lAdvapi32 + LIBS += -ldxguid -lole32 + # ole32 only needed for P3D on WIN64 systems, LNK2019: unresolved external symbol __imp_CoTaskMemFree referenced in function + # ldxguid are DirectX guid numbers + CONFIG(debug, debug|release): LIBS *= -lSimConnectDebug + else: LIBS *= -lSimConnect + } + equals(WORD_SIZE,32) { + INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/FSX-XPack + # LIBS *= -L$$EXTERNALS_LIB_DIR/FSX-XPack + } + + RC_FILE = $$SourceRoot/src/plugins/simulator/fsxcommon/simconnect.rc + + msvc: QMAKE_LFLAGS *= /ignore:4099 +} + blackgui { addLibraryDependency(blackgui) LIBS *= -lblackgui diff --git a/src/plugins/simulator/fsx/fsx.pro b/src/plugins/simulator/fsx/fsx.pro index 49a7895b9..674fcfdea 100644 --- a/src/plugins/simulator/fsx/fsx.pro +++ b/src/plugins/simulator/fsx/fsx.pro @@ -1,11 +1,30 @@ load(common_pre) +QT += core dbus widgets network + +TEMPLATE = lib + +CONFIG += plugin shared +CONFIG += blackconfig blackmisc blackcore blackgui +CONFIG += simulatorfsxcommon simulatorfscommon simulatorplugincommon fsuipc simconnect + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src +DESTDIR = $$DestRoot/bin/plugins/simulator + SOURCES += *.cpp HEADERS += *.h REQUIRES += contains(BLACK_CONFIG,FSX) TARGET = simulatorfsx DISTFILES += simulatorfsx.json -include(../fsxp3d.pri) + +win32 { + dlltarget.path = $$PREFIX/bin/plugins/simulator + INSTALLS += dlltarget +} else { + target.path = $$PREFIX/bin/plugins/simulator + INSTALLS += target +} load(common_post) diff --git a/src/plugins/simulator/fsxcommon/SimConnect_RTM.manifest b/src/plugins/simulator/fsxcommon/SimConnect_RTM.manifest new file mode 100644 index 000000000..7891458b0 --- /dev/null +++ b/src/plugins/simulator/fsxcommon/SimConnect_RTM.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/plugins/simulator/fsxcommon/SimConnect_SP1.manifest b/src/plugins/simulator/fsxcommon/SimConnect_SP1.manifest new file mode 100644 index 000000000..5ccece959 --- /dev/null +++ b/src/plugins/simulator/fsxcommon/SimConnect_SP1.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/plugins/simulator/fsxcommon/SimConnect_XPack.manifest b/src/plugins/simulator/fsxcommon/SimConnect_XPack.manifest new file mode 100644 index 000000000..71af031ca --- /dev/null +++ b/src/plugins/simulator/fsxcommon/SimConnect_XPack.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/plugins/simulator/fsxcommon/fsxcommon.pro b/src/plugins/simulator/fsxcommon/fsxcommon.pro index cde2e2cf9..26dde0ebe 100644 --- a/src/plugins/simulator/fsxcommon/fsxcommon.pro +++ b/src/plugins/simulator/fsxcommon/fsxcommon.pro @@ -10,7 +10,7 @@ HEADERS += *.h FORMS += *.ui CONFIG += staticlib -CONFIG += blackconfig blackmisc blackcore blackgui +CONFIG += blackconfig blackmisc blackcore blackgui simconnect DEPENDPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src @@ -18,9 +18,11 @@ DESTDIR = $$DestRoot/lib LIBS += -lsimulatorfscommon -lfsuipc -lsimulatorplugincommon -include(../fsxp3d_include.pri) - addStaticLibraryDependency(fsuipc) addStaticLibraryDependency(simulatorplugincommon) +OTHER_FILES += \ + *.manifest \ + *.rc + load(common_post) diff --git a/src/plugins/simulator/fsxcommon/simconnect.rc b/src/plugins/simulator/fsxcommon/simconnect.rc new file mode 100644 index 000000000..cebcdeaa3 --- /dev/null +++ b/src/plugins/simulator/fsxcommon/simconnect.rc @@ -0,0 +1,3 @@ +101 24 "SimConnect_RTM.manifest" +102 24 "SimConnect_SP1.manifest" +103 24 "SimConnect_XPack.manifest" diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp index b28586339..03f7cef2f 100644 --- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp +++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp @@ -8,6 +8,7 @@ */ #include "simconnectdatadefinition.h" +#include "simconnectsymbols.h" #include "blackmisc/aviation/aircraftparts.h" #include "blackmisc/aviation/aircraftenginelist.h" #include "blackmisc/logmessage.h" diff --git a/src/plugins/simulator/fsxcommon/simconnectsymbols.cpp b/src/plugins/simulator/fsxcommon/simconnectsymbols.cpp new file mode 100644 index 000000000..965d0b3d4 --- /dev/null +++ b/src/plugins/simulator/fsxcommon/simconnectsymbols.cpp @@ -0,0 +1,300 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "simconnectsymbols.h" +#include "blackmisc/logmessage.h" +#include +#include +#include +#include + +using namespace BlackMisc; + +#ifdef Q_OS_WIN64 + +bool loadAndResolveSimConnect(bool manifestProbing) +{ + Q_UNUSED(manifestProbing); + return true; +} + +#else + +typedef HRESULT(__stdcall *PfnSimConnect_Open)(HANDLE *, LPCSTR, HWND, DWORD, HANDLE, DWORD); +typedef HRESULT(__stdcall *PfnSimConnect_Close)(HANDLE); +typedef HRESULT(__stdcall *PfnSimConnect_AddToDataDefinition)(HANDLE, SIMCONNECT_DATA_DEFINITION_ID, const char *, const char *, SIMCONNECT_DATATYPE, float, DWORD); +typedef HRESULT(__stdcall *PfnSimConnect_Text)(HANDLE, SIMCONNECT_TEXT_TYPE, float, SIMCONNECT_CLIENT_EVENT_ID, DWORD, void *); +typedef HRESULT(__stdcall *PfnSimConnect_CallDispatch)(HANDLE, DispatchProc, void *); +typedef HRESULT(__stdcall *PfnSimConnect_WeatherSetModeCustom)(HANDLE); +typedef HRESULT(__stdcall *PfnSimConnect_WeatherSetModeGlobal)(HANDLE); +typedef HRESULT(__stdcall *PfnSimConnect_WeatherSetObservation)(HANDLE, DWORD, const char *); +typedef HRESULT(__stdcall *PfnSimConnect_TransmitClientEvent)(HANDLE, SIMCONNECT_OBJECT_ID, SIMCONNECT_CLIENT_EVENT_ID, DWORD, SIMCONNECT_NOTIFICATION_GROUP_ID, SIMCONNECT_EVENT_FLAG); +typedef HRESULT(__stdcall *PfnSimConnect_SetClientData)(HANDLE, SIMCONNECT_CLIENT_DATA_ID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID, SIMCONNECT_CLIENT_DATA_SET_FLAG, DWORD, DWORD, void *); +typedef HRESULT(__stdcall *PfnSimConnect_RequestDataOnSimObject)(HANDLE, SIMCONNECT_DATA_REQUEST_ID, SIMCONNECT_DATA_DEFINITION_ID, SIMCONNECT_OBJECT_ID, SIMCONNECT_PERIOD, SIMCONNECT_DATA_REQUEST_FLAG, DWORD, DWORD, DWORD); +typedef HRESULT(__stdcall *PfnSimConnect_RequestClientData)(HANDLE, SIMCONNECT_CLIENT_DATA_ID, SIMCONNECT_DATA_REQUEST_ID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID, SIMCONNECT_CLIENT_DATA_PERIOD, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG, DWORD, DWORD, DWORD); +typedef HRESULT(__stdcall *PfnSimConnect_SubscribeToSystemEvent)(HANDLE, SIMCONNECT_CLIENT_EVENT_ID, const char *); +typedef HRESULT(__stdcall *PfnSimConnect_MapClientEventToSimEvent)(HANDLE, SIMCONNECT_CLIENT_EVENT_ID, const char *); +typedef HRESULT(__stdcall *PfnSimConnect_SubscribeToFacilities)(HANDLE, SIMCONNECT_FACILITY_LIST_TYPE, SIMCONNECT_DATA_REQUEST_ID); +typedef HRESULT(__stdcall *PfnSimConnect_GetLastSentPacketID)(HANDLE, DWORD *); +typedef HRESULT(__stdcall *PfnSimConnect_AIRemoveObject)(HANDLE, SIMCONNECT_OBJECT_ID, SIMCONNECT_DATA_REQUEST_ID); +typedef HRESULT(__stdcall *PfnSimConnect_SetDataOnSimObject)(HANDLE, SIMCONNECT_DATA_DEFINITION_ID, SIMCONNECT_OBJECT_ID, SIMCONNECT_DATA_SET_FLAG, DWORD, DWORD, void *); +typedef HRESULT(__stdcall *PfnSimConnect_AIReleaseControl)(HANDLE, SIMCONNECT_OBJECT_ID, SIMCONNECT_DATA_REQUEST_ID); +typedef HRESULT(__stdcall *PfnSimConnect_AICreateNonATCAircraft)(HANDLE, const char *, const char *, SIMCONNECT_DATA_INITPOSITION, SIMCONNECT_DATA_REQUEST_ID); +typedef HRESULT(__stdcall *PfnSimConnect_AICreateSimulatedObject)(HANDLE, const char *, SIMCONNECT_DATA_INITPOSITION, SIMCONNECT_DATA_REQUEST_ID); +typedef HRESULT(__stdcall *PfnSimConnect_MapClientDataNameToID)(HANDLE, const char *, SIMCONNECT_CLIENT_DATA_ID); +typedef HRESULT(__stdcall *PfnSimConnect_CreateClientData)(HANDLE, SIMCONNECT_CLIENT_DATA_ID, DWORD, SIMCONNECT_CREATE_CLIENT_DATA_FLAG); +typedef HRESULT(__stdcall *PfnSimConnect_AddToClientDataDefinition)(HANDLE, SIMCONNECT_CLIENT_DATA_DEFINITION_ID, DWORD, DWORD, float, DWORD); + +//! The SimCOnnect Symbols +//! \private @{ +struct SimConnectSymbols +{ + PfnSimConnect_Open SimConnect_Open = nullptr; + PfnSimConnect_Close SimConnect_Close = nullptr; + PfnSimConnect_AddToDataDefinition SimConnect_AddToDataDefinition = nullptr; + PfnSimConnect_Text SimConnect_Text = nullptr; + PfnSimConnect_CallDispatch SimConnect_CallDispatch = nullptr; + PfnSimConnect_WeatherSetModeCustom SimConnect_WeatherSetModeCustom = nullptr; + PfnSimConnect_WeatherSetModeGlobal SimConnect_WeatherSetModeGlobal = nullptr; + PfnSimConnect_WeatherSetObservation SimConnect_WeatherSetObservation = nullptr; + PfnSimConnect_TransmitClientEvent SimConnect_TransmitClientEvent = nullptr; + PfnSimConnect_SetClientData SimConnect_SetClientData = nullptr; + PfnSimConnect_RequestDataOnSimObject SimConnect_RequestDataOnSimObject = nullptr; + PfnSimConnect_RequestClientData SimConnect_RequestClientData = nullptr; + PfnSimConnect_SubscribeToSystemEvent SimConnect_SubscribeToSystemEvent = nullptr; + PfnSimConnect_MapClientEventToSimEvent SimConnect_MapClientEventToSimEvent = nullptr; + PfnSimConnect_SubscribeToFacilities SimConnect_SubscribeToFacilities = nullptr; + PfnSimConnect_GetLastSentPacketID SimConnect_GetLastSentPacketID = nullptr; + PfnSimConnect_AIRemoveObject SimConnect_AIRemoveObject = nullptr; + PfnSimConnect_SetDataOnSimObject SimConnect_SetDataOnSimObject = nullptr; + PfnSimConnect_AIReleaseControl SimConnect_AIReleaseControl = nullptr; + PfnSimConnect_AICreateNonATCAircraft SimConnect_AICreateNonATCAircraft = nullptr; + PfnSimConnect_AICreateSimulatedObject SimConnect_AICreateSimulatedObject = nullptr; + PfnSimConnect_MapClientDataNameToID SimConnect_MapClientDataNameToID = nullptr; + PfnSimConnect_CreateClientData SimConnect_CreateClientData = nullptr; + PfnSimConnect_AddToClientDataDefinition SimConnect_AddToClientDataDefinition = nullptr; +}; +//! @ } + +SimConnectSymbols gSymbols; + +QString getLastErrorMsg() +{ + LPWSTR bufPtr = nullptr; + DWORD err = GetLastError(); + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, 0, (LPWSTR)&bufPtr, 0, NULL); + const QString result = (bufPtr) ? QString::fromUtf16((const ushort *)bufPtr).trimmed() : QString("Unknown Error %1").arg(err); + LocalFree(bufPtr); + return result; +} + +bool loadAndResolveSimConnect(bool manifestProbing) +{ + QLibrary simConnectDll; + simConnectDll.setFileName("SimConnect.dll"); + simConnectDll.setLoadHints(QLibrary::PreventUnloadHint); + + if (manifestProbing) + { + HMODULE hInst = nullptr; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)loadAndResolveSimConnect, &hInst); + wchar_t szModuleName[MAX_PATH]; + GetModuleFileName(hInst, szModuleName, MAX_PATH); + + std::array resourceNumbers = {{ 101U, 102U, 103U }}; + + for (const auto resourceNumber : resourceNumbers) + { + ACTCTX actCtx; + memset(&actCtx, 0, sizeof(ACTCTX)); + actCtx.cbSize = sizeof(actCtx); + actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; + actCtx.lpSource = szModuleName; + actCtx.lpResourceName = MAKEINTRESOURCE(resourceNumber); + + HANDLE hActCtx; + hActCtx = CreateActCtx(&actCtx); + if (hActCtx != INVALID_HANDLE_VALUE) + { + ULONG_PTR lpCookie = 0; + if (ActivateActCtx(hActCtx, &lpCookie)) + { + simConnectDll.load(); + DeactivateActCtx(0, lpCookie); + if (simConnectDll.isLoaded()) { break; } + } + } + ReleaseActCtx(hActCtx); + } + } + + // Try once without activation context + if (!simConnectDll.isLoaded()) + { + simConnectDll.load(); + } + + if (simConnectDll.isLoaded()) + { + gSymbols.SimConnect_Open = reinterpret_cast(simConnectDll.resolve("SimConnect_Open")); + gSymbols.SimConnect_Close = (PfnSimConnect_Close) simConnectDll.resolve("SimConnect_Close"); + + gSymbols.SimConnect_AddToDataDefinition = reinterpret_cast(simConnectDll.resolve("SimConnect_AddToDataDefinition")); + gSymbols.SimConnect_Text = reinterpret_cast(simConnectDll.resolve("SimConnect_Text")); + gSymbols.SimConnect_CallDispatch = reinterpret_cast(simConnectDll.resolve("SimConnect_CallDispatch")); + gSymbols.SimConnect_WeatherSetModeCustom = reinterpret_cast(simConnectDll.resolve("SimConnect_WeatherSetModeCustom")); + gSymbols.SimConnect_WeatherSetModeGlobal = reinterpret_cast(simConnectDll.resolve("SimConnect_WeatherSetModeGlobal")); + gSymbols.SimConnect_WeatherSetObservation = reinterpret_cast(simConnectDll.resolve("SimConnect_WeatherSetObservation")); + gSymbols.SimConnect_TransmitClientEvent = reinterpret_cast(simConnectDll.resolve("SimConnect_TransmitClientEvent")); + gSymbols.SimConnect_SetClientData = reinterpret_cast(simConnectDll.resolve("SimConnect_SetClientData")); + gSymbols.SimConnect_RequestDataOnSimObject = reinterpret_cast(simConnectDll.resolve("SimConnect_RequestDataOnSimObject")); + gSymbols.SimConnect_RequestClientData = reinterpret_cast(simConnectDll.resolve("SimConnect_RequestClientData")); + gSymbols.SimConnect_SubscribeToSystemEvent = reinterpret_cast(simConnectDll.resolve("SimConnect_SubscribeToSystemEvent")); + gSymbols.SimConnect_MapClientEventToSimEvent = reinterpret_cast(simConnectDll.resolve("SimConnect_MapClientEventToSimEvent")); + gSymbols.SimConnect_SubscribeToFacilities = reinterpret_cast(simConnectDll.resolve("SimConnect_SubscribeToFacilities")); + gSymbols.SimConnect_GetLastSentPacketID = reinterpret_cast(simConnectDll.resolve("SimConnect_GetLastSentPacketID")); + gSymbols.SimConnect_AIRemoveObject = reinterpret_cast(simConnectDll.resolve("SimConnect_AIRemoveObject")); + gSymbols.SimConnect_SetDataOnSimObject = reinterpret_cast(simConnectDll.resolve("SimConnect_SetDataOnSimObject")); + gSymbols.SimConnect_AIReleaseControl = reinterpret_cast(simConnectDll.resolve("SimConnect_AIReleaseControl")); + gSymbols.SimConnect_AICreateNonATCAircraft = reinterpret_cast(simConnectDll.resolve("SimConnect_AICreateNonATCAircraft")); + gSymbols.SimConnect_AICreateSimulatedObject = reinterpret_cast(simConnectDll.resolve("SimConnect_AICreateSimulatedObject")); + gSymbols.SimConnect_MapClientDataNameToID = reinterpret_cast(simConnectDll.resolve("SimConnect_MapClientDataNameToID")); + gSymbols.SimConnect_CreateClientData = reinterpret_cast(simConnectDll.resolve("SimConnect_CreateClientData")); + gSymbols.SimConnect_AddToClientDataDefinition = reinterpret_cast(simConnectDll.resolve("SimConnect_AddToClientDataDefinition")); + } + + return true; +} + +SIMCONNECTAPI SimConnect_Open(HANDLE *phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex) +{ + return gSymbols.SimConnect_Open(phSimConnect, szName, hWnd, UserEventWin32, hEventHandle, ConfigIndex); +} + +SIMCONNECTAPI SimConnect_Close(HANDLE hSimConnect) +{ + return gSymbols.SimConnect_Close(hSimConnect); +} + +SIMCONNECTAPI SimConnect_AddToDataDefinition(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, const char *DatumName, const char *UnitsName, SIMCONNECT_DATATYPE DatumType, float fEpsilon, DWORD DatumID) +{ + return gSymbols.SimConnect_AddToDataDefinition(hSimConnect, DefineID, DatumName, UnitsName, DatumType, fEpsilon, DatumID); +} + +SIMCONNECTAPI SimConnect_Text(HANDLE hSimConnect, SIMCONNECT_TEXT_TYPE type, float fTimeSeconds, SIMCONNECT_CLIENT_EVENT_ID EventID, DWORD cbUnitSize, void *pDataSet) +{ + return gSymbols.SimConnect_Text(hSimConnect, type, fTimeSeconds, EventID, cbUnitSize, pDataSet); +} + +SIMCONNECTAPI SimConnect_CallDispatch(HANDLE hSimConnect, DispatchProc pfcnDispatch, void *pContext) +{ + return gSymbols.SimConnect_CallDispatch(hSimConnect, pfcnDispatch, pContext); +} + +SIMCONNECTAPI SimConnect_WeatherSetModeCustom(HANDLE hSimConnect) +{ + return gSymbols.SimConnect_WeatherSetModeCustom(hSimConnect); +} + +SIMCONNECTAPI SimConnect_WeatherSetModeGlobal(HANDLE hSimConnect) +{ + return gSymbols.SimConnect_WeatherSetModeGlobal(hSimConnect); +} + +SIMCONNECTAPI SimConnect_WeatherSetObservation(HANDLE hSimConnect, DWORD Seconds, const char *szMETAR) +{ + return gSymbols.SimConnect_WeatherSetObservation(hSimConnect, Seconds, szMETAR); +} + +SIMCONNECTAPI SimConnect_TransmitClientEvent(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_CLIENT_EVENT_ID EventID, DWORD dwData, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_EVENT_FLAG Flags) +{ + return gSymbols.SimConnect_TransmitClientEvent(hSimConnect, ObjectID, EventID, dwData, GroupID, Flags); +} + +SIMCONNECTAPI SimConnect_SetClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, SIMCONNECT_CLIENT_DATA_SET_FLAG Flags, DWORD dwReserved, DWORD cbUnitSize, void *pDataSet) +{ + return gSymbols.SimConnect_SetClientData(hSimConnect, ClientDataID, DefineID, Flags, dwReserved, cbUnitSize, pDataSet); +} + +SIMCONNECTAPI SimConnect_RequestDataOnSimObject(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_PERIOD Period, SIMCONNECT_DATA_REQUEST_FLAG Flags, DWORD origin, DWORD interval, DWORD limit) +{ + return gSymbols.SimConnect_RequestDataOnSimObject(hSimConnect, RequestID, DefineID, ObjectID, Period, Flags, origin, interval, limit); +} + +SIMCONNECTAPI SimConnect_RequestClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, SIMCONNECT_CLIENT_DATA_PERIOD Period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG Flags, DWORD origin, DWORD interval, DWORD limit) +{ + return gSymbols.SimConnect_RequestClientData(hSimConnect, ClientDataID, RequestID, DefineID, Period, Flags, origin, interval, limit); +} + +SIMCONNECTAPI SimConnect_SubscribeToSystemEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char *SystemEventName) +{ + return gSymbols.SimConnect_SubscribeToSystemEvent(hSimConnect, EventID, SystemEventName); +} + +SIMCONNECTAPI SimConnect_MapClientEventToSimEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char *EventName) +{ + return gSymbols.SimConnect_MapClientEventToSimEvent(hSimConnect, EventID, EventName); +} + +SIMCONNECTAPI SimConnect_SubscribeToFacilities(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID RequestID) +{ + return gSymbols.SimConnect_SubscribeToFacilities(hSimConnect, type, RequestID); +} + +SIMCONNECTAPI SimConnect_GetLastSentPacketID(HANDLE hSimConnect, DWORD *pdwError) +{ + return gSymbols.SimConnect_GetLastSentPacketID(hSimConnect, pdwError); +} + +SIMCONNECTAPI SimConnect_AIRemoveObject(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_REQUEST_ID RequestID) +{ + return gSymbols.SimConnect_AIRemoveObject(hSimConnect, ObjectID, RequestID); +} + +SIMCONNECTAPI SimConnect_SetDataOnSimObject(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_SET_FLAG Flags, DWORD ArrayCount, DWORD cbUnitSize, void *pDataSet) +{ + return gSymbols.SimConnect_SetDataOnSimObject(hSimConnect, DefineID, ObjectID, Flags, ArrayCount, cbUnitSize, pDataSet); +} + +SIMCONNECTAPI SimConnect_AIReleaseControl(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_REQUEST_ID RequestID) +{ + return gSymbols.SimConnect_AIReleaseControl(hSimConnect, ObjectID, RequestID); +} + +SIMCONNECTAPI SimConnect_AICreateNonATCAircraft(HANDLE hSimConnect, const char *szContainerTitle, const char *szTailNumber, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID) +{ + return gSymbols.SimConnect_AICreateNonATCAircraft(hSimConnect, szContainerTitle, szTailNumber, InitPos, RequestID); +} + +SIMCONNECTAPI SimConnect_AICreateSimulatedObject(HANDLE hSimConnect, const char *szContainerTitle, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID) +{ + return gSymbols.SimConnect_AICreateSimulatedObject(hSimConnect, szContainerTitle, InitPos, RequestID); +} + +SIMCONNECTAPI SimConnect_MapClientDataNameToID(HANDLE hSimConnect, const char *szClientDataName, SIMCONNECT_CLIENT_DATA_ID ClientDataID) +{ + return gSymbols.SimConnect_MapClientDataNameToID(hSimConnect, szClientDataName, ClientDataID); +} + +SIMCONNECTAPI SimConnect_CreateClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, DWORD dwSize, SIMCONNECT_CREATE_CLIENT_DATA_FLAG Flags) +{ + return gSymbols.SimConnect_CreateClientData(hSimConnect, ClientDataID, dwSize, Flags); +} + +SIMCONNECTAPI SimConnect_AddToClientDataDefinition(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, DWORD dwOffset, DWORD dwSizeOrType, float fEpsilon, DWORD DatumID) +{ + return gSymbols.SimConnect_AddToClientDataDefinition(hSimConnect, DefineID, dwOffset, dwSizeOrType, fEpsilon, DatumID); +} + +#endif + + diff --git a/src/plugins/simulator/fsxcommon/simconnectsymbols.h b/src/plugins/simulator/fsxcommon/simconnectsymbols.h new file mode 100644 index 000000000..416514765 --- /dev/null +++ b/src/plugins/simulator/fsxcommon/simconnectsymbols.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2018 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTSYMBOLS_H +#define BLACKSIMPLUGIN_FSXCOMMON_SIMCONNECTSYMBOLS_H + +//! Load and resolve SimConnect. +//! \param manifestProbing Set to true if you want to try loading from the assembly cache with manifests. +//! Otherwise the library in the bin folder will be loaded. +bool loadAndResolveSimConnect(bool manifestProbing); + +#endif // guard diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index b3ee7771c..7eb2ff3dc 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -8,6 +8,7 @@ */ #include "simulatorfsxcommon.h" +#include "simconnectsymbols.h" #include "blackcore/application.h" #include "blackmisc/network/textmessage.h" #include "blackmisc/simulation/fsx/simconnectutilities.h" @@ -2020,6 +2021,7 @@ namespace BlackSimPlugin constexpr int QueryInterval = 5 * 1000; // 5 seconds m_timer.setInterval(QueryInterval); m_timer.setObjectName(this->objectName().append(":m_timer")); + loadAndResolveSimConnect(true); connect(&m_timer, &QTimer::timeout, this, &CSimulatorFsxCommonListener::checkConnection); } diff --git a/src/plugins/simulator/fsxconfig/fsxconfig.pro b/src/plugins/simulator/fsxconfig/fsxconfig.pro index e74502fa1..c7e762927 100644 --- a/src/plugins/simulator/fsxconfig/fsxconfig.pro +++ b/src/plugins/simulator/fsxconfig/fsxconfig.pro @@ -1,11 +1,31 @@ load(common_pre) +QT += core dbus widgets network + +TEMPLATE = lib + +CONFIG += plugin shared +CONFIG += blackconfig blackmisc blackcore blackgui +CONFIG += simulatorfsxcommon simulatorfscommon simulatorplugincommon fsuipc simconnect + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src +DESTDIR = $$DestRoot/bin/plugins/simulator + SOURCES += *.cpp HEADERS += *.h REQUIRES += contains(BLACK_CONFIG,FSX) TARGET = simulatorfsxconfig DISTFILES += simulatorfsx.json -include(../fsxp3d.pri) + +win32 { + dlltarget.path = $$PREFIX/bin/plugins/simulator + INSTALLS += dlltarget +} else { + target.path = $$PREFIX/bin/plugins/simulator + INSTALLS += target +} + load(common_post) diff --git a/src/plugins/simulator/fsxp3d.pri b/src/plugins/simulator/fsxp3d.pri deleted file mode 100644 index 76ef02223..000000000 --- a/src/plugins/simulator/fsxp3d.pri +++ /dev/null @@ -1,30 +0,0 @@ -QT += core dbus widgets network - -TEMPLATE = lib - -CONFIG += plugin shared -CONFIG += blackconfig blackmisc blackcore blackgui - -DEPENDPATH += . $$SourceRoot/src -INCLUDEPATH += . $$SourceRoot/src -DESTDIR = $$DestRoot/bin/plugins/simulator - -LIBS += -lsimulatorfsxcommon -lsimulatorfscommon -lfsuipc -lsimulatorplugincommon - -include(fsxp3d_include.pri) - -addStaticLibraryDependency(simulatorfscommon) -addStaticLibraryDependency(simulatorfsxcommon) -addStaticLibraryDependency(fsuipc) -addStaticLibraryDependency(simulatorplugincommon) - -# Ignore linker warning about missing pdb files from Simconnect -msvc: QMAKE_LFLAGS *= /ignore:4099 - -win32 { - dlltarget.path = $$PREFIX/bin/plugins/simulator - INSTALLS += dlltarget -} else { - target.path = $$PREFIX/bin/plugins/simulator - INSTALLS += target -} diff --git a/src/plugins/simulator/fsxp3d_include.pri b/src/plugins/simulator/fsxp3d_include.pri deleted file mode 100644 index 2362b7789..000000000 --- a/src/plugins/simulator/fsxp3d_include.pri +++ /dev/null @@ -1,15 +0,0 @@ -equals(WORD_SIZE,64) { - INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/P3D-v4.1 - LIBS *= -L$$EXTERNALS_LIB_DIR/P3D-v4.1 - LIBS *= -lAdvapi32 - LIBS += -ldxguid -lole32 - # ole32 only needed for P3D on WIN64 systems, LNK2019: unresolved external symbol __imp_CoTaskMemFree referenced in function - # ldxguid are DirectX guid numbers - CONFIG(debug, debug|release): LIBS *= -lSimConnectDebug - else: LIBS *= -lSimConnect -} -equals(WORD_SIZE,32) { - INCLUDEPATH *= $$EXTERNALSROOT/common/include/simconnect/FSX-XPack - LIBS *= -L$$EXTERNALS_LIB_DIR/FSX-XPack - LIBS *= -lSimConnect -} diff --git a/src/plugins/simulator/p3d/p3d.pro b/src/plugins/simulator/p3d/p3d.pro index cdf616ac1..6f9592741 100644 --- a/src/plugins/simulator/p3d/p3d.pro +++ b/src/plugins/simulator/p3d/p3d.pro @@ -1,11 +1,33 @@ load(common_pre) +load(common_pre) + +QT += core dbus widgets network + +TEMPLATE = lib + +CONFIG += plugin shared +CONFIG += blackconfig blackmisc blackcore blackgui +CONFIG += simulatorfsxcommon simulatorfscommon simulatorplugincommon fsuipc simconnect + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src +DESTDIR = $$DestRoot/bin/plugins/simulator + SOURCES += *.cpp HEADERS += *.h REQUIRES += contains(BLACK_CONFIG,P3D) TARGET = simulatorp3d DISTFILES += simulatorp3d.json -include(../fsxp3d.pri) + +win32 { + dlltarget.path = $$PREFIX/bin/plugins/simulator + INSTALLS += dlltarget +} else { + target.path = $$PREFIX/bin/plugins/simulator + INSTALLS += target +} + load(common_post) diff --git a/src/plugins/simulator/p3dconfig/p3dconfig.pro b/src/plugins/simulator/p3dconfig/p3dconfig.pro index 5e01449b5..b68c556b2 100644 --- a/src/plugins/simulator/p3dconfig/p3dconfig.pro +++ b/src/plugins/simulator/p3dconfig/p3dconfig.pro @@ -1,11 +1,30 @@ load(common_pre) +QT += core dbus widgets network + +TEMPLATE = lib + +CONFIG += plugin shared +CONFIG += blackconfig blackmisc blackcore blackgui +CONFIG += simulatorfsxcommon simulatorfscommon simulatorplugincommon fsuipc simconnect + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src +DESTDIR = $$DestRoot/bin/plugins/simulator + SOURCES += *.cpp HEADERS += *.h REQUIRES += contains(BLACK_CONFIG,P3D) TARGET = simulatorp3dconfig DISTFILES += simulatorp3d.json -include(../fsxp3d.pri) + +win32 { + dlltarget.path = $$PREFIX/bin/plugins/simulator + INSTALLS += dlltarget +} else { + target.path = $$PREFIX/bin/plugins/simulator + INSTALLS += target +} load(common_post) diff --git a/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3d.pro b/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3d.pro index 10a4c1afb..dd003cf0f 100644 --- a/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3d.pro +++ b/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3d.pro @@ -8,6 +8,7 @@ TEMPLATE = app CONFIG += console CONFIG -= app_bundle CONFIG += blackmisc blackcore blackconfig blackgui +CONFIG += simulatorfsxcommon simulatorfscommon simulatorplugincommon fsuipc simconnect CONFIG += testcase CONFIG += no_testcase_installs @@ -17,16 +18,6 @@ HEADERS += *.h SOURCES += *.cpp DESTDIR = $$DestRoot/bin -LIBS *= -lsimulatorfsxcommon -lsimulatorfscommon -lfsuipc -lsimulatorplugincommon - -# include(../../src/plugins/simulator/fsxp3d.pri) -include(../../src/plugins/simulator/fsxp3d_include.pri) - -addStaticLibraryDependency(simulatorfscommon) -addStaticLibraryDependency(simulatorfsxcommon) -addStaticLibraryDependency(fsuipc) -addStaticLibraryDependency(simulatorplugincommon) - # Ignore linker warning about missing pdb files from Simconnect msvc: QMAKE_LFLAGS *= /ignore:4099 diff --git a/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3dmain.cpp b/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3dmain.cpp index c46e05b07..b0f1934a8 100644 --- a/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3dmain.cpp +++ b/tests/blacksimpluginfsxp3d/testblacksimpluginfsxp3dmain.cpp @@ -13,6 +13,7 @@ #include "testblacksimpluginfsxp3dmain.h" #include "testfsxp3dcommon.h" +#include "testsimconnectsymbols.h" #include "blackmisc/test/test.h" #include #include @@ -25,6 +26,9 @@ namespace BlackSimPluginFsxP3D int status = 0; { + CTestSimconnectSymbols simconnectSymbolsTest; + status |= test.exec(&simconnectSymbolsTest, "blacksimpluginfsxp3d_simconnectsymbols"); + CTestFsxP3DCommon commonTest; status |= test.exec(&commonTest, "blacksimpluginfsxp3d_fsxp3dcommon"); } diff --git a/tests/blacksimpluginfsxp3d/testsimconnectsymbols.cpp b/tests/blacksimpluginfsxp3d/testsimconnectsymbols.cpp new file mode 100644 index 000000000..40f2a2f81 --- /dev/null +++ b/tests/blacksimpluginfsxp3d/testsimconnectsymbols.cpp @@ -0,0 +1,34 @@ +/* Copyright (C) 2018 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \cond PRIVATE_TESTS + +/*! + * \file + * \ingroup testblacksimplugin + */ + +#include "testsimconnectsymbols.h" +#include "plugins/simulator/fsxcommon/simconnectsymbols.h" +#include "plugins/simulator/fsxcommon/simconnectwindows.h" +#include + +namespace BlackSimPluginFsxP3D +{ + void CTestSimconnectSymbols::resolveSymbols() + { + QVERIFY2(loadAndResolveSimConnect(false), "Could not load and resolve SimConnect library!"); + HANDLE hSimConnect; + SimConnect_Open(&hSimConnect, "Test", nullptr, 0, 0, 0); + SimConnect_Close(hSimConnect); + } + +} // ns + +//! \endcond diff --git a/tests/blacksimpluginfsxp3d/testsimconnectsymbols.h b/tests/blacksimpluginfsxp3d/testsimconnectsymbols.h new file mode 100644 index 000000000..54deac3eb --- /dev/null +++ b/tests/blacksimpluginfsxp3d/testsimconnectsymbols.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2018 + * swift project community / contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#ifndef BLACKSIMPLUGINFSXP3D_TESTSIMCONNECTSYMBOLS_H +#define BLACKSIMPLUGINFSXP3D_TESTSIMCONNECTSYMBOLS_H + +//! \cond PRIVATE_TESTS +//! \file +//! \ingroup testblacksimplugin + +#include + +namespace BlackSimPluginFsxP3D +{ + //! FSX/P3D common tests + class CTestSimconnectSymbols : public QObject + { + Q_OBJECT + + public: + //! Standard test case constructor + explicit CTestSimconnectSymbols(QObject *parent = nullptr) : QObject(parent) {} + + private slots: + //! Resolve SimConnect Symbols + void resolveSymbols(); + }; +} // namespace + +//! \endcond + +#endif // guard