summaryrefslogtreecommitdiffhomepage
path: root/windows/driverlogic/src/version.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'windows/driverlogic/src/version.cpp')
-rw-r--r--windows/driverlogic/src/version.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/windows/driverlogic/src/version.cpp b/windows/driverlogic/src/version.cpp
new file mode 100644
index 0000000000..d7394e224b
--- /dev/null
+++ b/windows/driverlogic/src/version.cpp
@@ -0,0 +1,125 @@
+#include "stdafx.h"
+#include "version.h"
+#include "device.h"
+#include <setupapi.h>
+#include <initguid.h>
+#include <devpkey.h>
+#include <libcommon/string.h>
+#include <libcommon/memory.h>
+#include <stdexcept>
+
+DRIVER_UPGRADE_STATUS
+EvaluateDriverUpgrade
+(
+ const std::wstring &existingVersion,
+ const std::wstring &proposedVersion
+)
+{
+ //
+ // "x.y.z.a"
+ //
+
+ using namespace common::string;
+
+ auto et = Tokenize(existingVersion, L".");
+ auto pt = Tokenize(proposedVersion, L".");
+
+ auto items = min(et.size(), pt.size());
+
+ for (auto index = 0; index < items; ++index)
+ {
+ auto ev = wcstoul(et[index].c_str(), nullptr, 10);
+ auto pv = wcstoul(pt[index].c_str(), nullptr, 10);
+
+ if (pv > ev)
+ {
+ return DRIVER_UPGRADE_STATUS::WOULD_UPGRADE;
+ }
+
+ if (ev > pv)
+ {
+ return DRIVER_UPGRADE_STATUS::WOULD_DOWNGRADE;
+ }
+ }
+
+ if (pt.size() > et.size())
+ {
+ return DRIVER_UPGRADE_STATUS::WOULD_UPGRADE;
+ }
+
+ if (et.size() > pt.size())
+ {
+ return DRIVER_UPGRADE_STATUS::WOULD_DOWNGRADE;
+ }
+
+ return DRIVER_UPGRADE_STATUS::WOULD_INSTALL_SAME_VERSION;
+}
+
+std::wstring
+InfGetDriverVersion
+(
+ const std::wstring &filePath
+)
+{
+ auto infHandle = SetupOpenInfFileW(filePath.c_str(), nullptr, INF_STYLE_WIN4, nullptr);
+
+ if (infHandle == INVALID_HANDLE_VALUE)
+ {
+ throw std::runtime_error("SetupOpenInfFileW()");
+ }
+
+ common::memory::ScopeDestructor dtor;
+
+ dtor += [infHandle]()
+ {
+ SetupCloseInfFile(infHandle);
+ };
+
+ INFCONTEXT infContext { 0 };
+
+ auto status = SetupFindFirstLineW(infHandle, L"Version", L"DriverVer", &infContext);
+
+ if (status == FALSE)
+ {
+ throw std::runtime_error("SetupFindFirstLineW()");
+ }
+
+ DWORD requiredSize;
+
+ //
+ // This is a multi-value key.
+ // 0 = key, 1 = driver date
+ //
+ const DWORD VersionFieldIndex = 2;
+
+ status = SetupGetStringFieldW(&infContext, VersionFieldIndex, nullptr, 0, &requiredSize);
+
+ if (status == FALSE || requiredSize < 2)
+ {
+ throw std::runtime_error("SetupGetStringFieldW()");
+ }
+
+ std::vector<wchar_t> buffer(requiredSize);
+
+ status = SetupGetStringFieldW(&infContext, VersionFieldIndex,
+ &buffer[0], static_cast<DWORD>(buffer.size()), nullptr);
+
+ if (status == FALSE)
+ {
+ throw std::runtime_error("SetupGetStringFieldW()");
+ }
+
+ // Remove null terminator.
+ buffer.resize(requiredSize - 1);
+
+ return buffer.data();
+}
+
+std::wstring
+GetDriverVersion
+(
+ const EnumeratedDevice &device
+)
+{
+ return GetDeviceStringProperty(device.deviceInfoSet, device.deviceInfo, &DEVPKEY_Device_DriverVersion);
+}