Replace WinRing0 with PawnIO for SMBus and Super-IO access on Windows

Commits squashed, files cleaned up, and rebased by Adam Honse <calcprogrammer1@gmail.com>
master
Stephen Horvath 12 months ago committed by Adam Honse
parent a1449d99cf
commit 30a250c7df

@ -199,7 +199,6 @@ HEADERS +=
serial_port/find_usb_serial_port.h \
serial_port/serial_port.h \
StringUtils.h \
super_io/super_io.h \
SuspendResume/SuspendResume.h \
AutoStart/AutoStart.h \
KeyboardLayoutManager/KeyboardLayoutManager.h \
@ -266,7 +265,6 @@ SOURCES +=
net_port/net_port.cpp \
serial_port/serial_port.cpp \
StringUtils.cpp \
super_io/super_io.cpp \
AutoStart/AutoStart.cpp \
KeyboardLayoutManager/KeyboardLayoutManager.cpp \
RGBController/RGBController.cpp \
@ -330,10 +328,11 @@ win32:QMAKE_CXXFLAGS += /utf-8
win32:INCLUDEPATH += \
dependencies/display-library/include \
dependencies/hidapi-win/include \
dependencies/winring0/include \
dependencies/libusb-1.0.27/include \
dependencies/mbedtls-3.2.1/include \
dependencies/NVFC \
dependencies/PawnIO \
i2c_smbus/Windows \
wmi/ \
win32:SOURCES += $$CONTROLLER_CPP_WINDOWS
@ -341,11 +340,10 @@ win32:SOURCES += $$CONTROLLER_CPP_WINDOWS
win32:SOURCES += \
dependencies/hueplusplus-1.2.0/src/WinHttpHandler.cpp \
dependencies/NVFC/nvapi.cpp \
i2c_smbus/i2c_smbus_amdadl.cpp \
i2c_smbus/i2c_smbus_i801.cpp \
i2c_smbus/i2c_smbus_nct6775.cpp \
i2c_smbus/i2c_smbus_nvapi.cpp \
i2c_smbus/i2c_smbus_piix4.cpp \
i2c_smbus/Windows/i2c_smbus_amdadl.cpp \
i2c_smbus/Windows/i2c_smbus_nvapi.cpp \
i2c_smbus/Windows/i2c_smbus_pawnio.cpp \
super_io/super_io_pawnio.cpp \
scsiapi/scsiapi_windows.c \
serial_port/find_usb_serial_port_win.cpp \
SuspendResume/SuspendResume_Windows.cpp \
@ -359,12 +357,12 @@ win32:HEADERS +=
dependencies/display-library/include/adl_defines.h \
dependencies/display-library/include/adl_sdk.h \
dependencies/display-library/include/adl_structures.h \
dependencies/winring0/include/OlsApi.h \
dependencies/NVFC/nvapi.h \
i2c_smbus/i2c_smbus_i801.h \
i2c_smbus/i2c_smbus_nct6775.h \
i2c_smbus/i2c_smbus_nvapi.h \
i2c_smbus/i2c_smbus_piix4.h \
dependencies/PawnIO/PawnIOLib.h \
i2c_smbus/Windows/i2c_smbus_amdadl.h \
i2c_smbus/Windows/i2c_smbus_nvapi.h \
i2c_smbus/Windows/i2c_smbus_pawnio.h \
super_io/super_io_pawnio.h \
wmi/wmi.h \
AutoStart/AutoStart-Windows.h \
SuspendResume/SuspendResume_Windows.h \
@ -373,17 +371,16 @@ win32:contains(QMAKE_TARGET.arch, x86_64) {
LIBS += \
-lws2_32 \
-liphlpapi \
-L"$$PWD/dependencies/winring0/x64/" -lWinRing0x64 \
-L"$$PWD/dependencies/libusb-1.0.27/VS2019/MS64/dll" -llibusb-1.0 \
-L"$$PWD/dependencies/hidapi-win/x64/" -lhidapi \
-L"$$PWD/dependencies/mbedtls-3.2.1/lib/x64/" -lmbedcrypto -lmbedtls -lmbedx509 \
-L"$$PWD/dependencies/PawnIO/" -lPawnIOLib \
}
win32:contains(QMAKE_TARGET.arch, x86) {
LIBS += \
-lws2_32 \
-liphlpapi \
-L"$$PWD/dependencies/winring0/Win32/" -lWinRing0 \
-L"$$PWD/dependencies/libusb-1.0.27/VS2019/MS32/dll" -llibusb-1.0 \
-L"$$PWD/dependencies/hidapi-win/x86/" -lhidapi \
-L"$$PWD/dependencies/mbedtls-3.2.1/lib/x86/" -lmbedcrypto -lmbedtls -lmbedx509 \
@ -403,6 +400,11 @@ win32:DEFINES +=
win32:RC_ICONS += \
qt/OpenRGB.ico
win32:DISTFILES += \
dependencies/PawnIO/modules/SmbusPIIX4.bin \
dependencies/PawnIO/modules/SmbusI801.bin \
dependencies/PawnIO/modules/LpcIO.bin
#-----------------------------------------------------------------------------------------------#
# Windows GitLab CI Configuration #
#-----------------------------------------------------------------------------------------------#
@ -424,10 +426,12 @@ win32:UI_DIR = _intermediate_$$DESTDIR/.ui
#-----------------------------------------------------------------------------------------------#
win32:contains(QMAKE_TARGET.arch, x86_64) {
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/libusb-1.0.27/VS2019/MS64/dll/libusb-1.0.dll)\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/hidapi-win/x64/hidapi.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/PawnIOLib.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/SmbusPIIX4.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/SmbusI801.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/LpcIO.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
@ -435,9 +439,6 @@ win32:contains(QMAKE_TARGET.arch, x86_64) {
}
win32:contains(QMAKE_TARGET.arch, x86) {
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/Win32/WinRing0.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/Win32/WinRing0.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/libusb-1.0.27/VS2019/MS32/dll/libusb-1.0.dll)\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/hidapi-win/x86/hidapi.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
@ -462,14 +463,16 @@ contains(QMAKE_PLATFORM, linux) {
HEADERS += \
dependencies/NVFC/nvapi.h \
i2c_smbus/i2c_smbus_linux.h \
i2c_smbus/Linux/i2c_smbus_linux.h \
AutoStart/AutoStart-Linux.h \
SPDAccessor/EE1004Accessor_Linux.h \
SPDAccessor/SPD5118Accessor_Linux.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
super_io/super_io.h \
INCLUDEPATH += \
dependencies/NVFC \
i2c_smbus/Linux \
/usr/include/mbedtls/ \
LIBS += \
@ -516,7 +519,7 @@ contains(QMAKE_PLATFORM, linux) {
SOURCES += \
dependencies/hueplusplus-1.2.0/src/LinHttpHandler.cpp \
dependencies/NVFC/nvapi.cpp \
i2c_smbus/i2c_smbus_linux.cpp \
i2c_smbus/Linux/i2c_smbus_linux.cpp \
scsiapi/scsiapi_linux.c \
serial_port/find_usb_serial_port_linux.cpp \
AutoStart/AutoStart-Linux.cpp \
@ -524,6 +527,7 @@ contains(QMAKE_PLATFORM, linux) {
SPDAccessor/SPD5118Accessor_Linux.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
startup/main_FreeBSD_Linux_MacOS.cpp \
super_io/super_io.cpp \
#-------------------------------------------------------------------------------------------#
# Set up install paths #
@ -599,6 +603,7 @@ contains(QMAKE_PLATFORM, freebsd) {
HEADERS += \
AutoStart/AutoStart-FreeBSD.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
super_io/super_io.h \
HEADERS -= \
Controllers/SeagateController/RGBController_Seagate.h \
@ -648,6 +653,7 @@ contains(QMAKE_PLATFORM, freebsd) {
AutoStart/AutoStart-FreeBSD.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
startup/main_FreeBSD_Linux_MacOS.cpp \
super_io/super_io.cpp \
SOURCES -= \
Controllers/SeagateController/RGBController_Seagate.cpp \
@ -750,6 +756,10 @@ macx:contains(QMAKE_HOST.arch, arm64) {
SOURCES += \
scsiapi/scsiapi_macos.c \
super_io/super_io.cpp \
HEADERS += \
super_io/super_io.h \
LIBS += \
-L/opt/homebrew/lib \
@ -761,20 +771,23 @@ macx:contains(QMAKE_HOST.arch, arm64) {
macx:contains(QMAKE_HOST.arch, x86_64) {
INCLUDEPATH += \
dependencies/macUSPCIO \
i2c_smbus/MacOS \
/usr/local/include \
/usr/local/homebrew/include \
SOURCES += \
i2c_smbus/i2c_smbus_i801.cpp \
i2c_smbus/i2c_smbus_nct6775.cpp \
i2c_smbus/i2c_smbus_piix4.cpp \
i2c_smbus/MacOS/i2c_smbus_i801.cpp \
i2c_smbus/MacOS/i2c_smbus_nct6775.cpp \
i2c_smbus/MacOS/i2c_smbus_piix4.cpp \
scsiapi/scsiapi_macos.c \
super_io/super_io.cpp \
HEADERS += \
dependencies/macUSPCIO/macUSPCIOAccess.h \
i2c_smbus/i2c_smbus_i801.h \
i2c_smbus/i2c_smbus_nct6775.h \
i2c_smbus/i2c_smbus_piix4.h \
i2c_smbus/MacOS/i2c_smbus_i801.h \
i2c_smbus/MacOS/i2c_smbus_nct6775.h \
i2c_smbus/MacOS/i2c_smbus_piix4.h \
super_io/super_io.h \
LIBS += \
-L/usr/local/lib \

@ -132,8 +132,7 @@ This project interacts directly with hardware using reverse engineered protocols
## Projects Used
* OpenRGB directly relies upon these projects.
* WinRing0: https://openlibsys.org/
* PawnIO: https://pawnio.eu/
* libusb: https://github.com/libusb/libusb
* hidapi: https://github.com/libusb/hidapi
* libe131: https://github.com/hhromic/libe131

Binary file not shown.

@ -0,0 +1,75 @@
// PawnIOLib - Library and tooling source to be used with PawnIO.
// Copyright (C) 2023 namazso <admin@namazso.eu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef PAWNIOLIB_LIBRARY_H
#define PAWNIOLIB_LIBRARY_H
#ifdef PawnIOLib_EXPORTS
#define PAWNIO_EXPORT __declspec(dllexport)
#else
#define PAWNIO_EXPORT __declspec(dllimport)
#endif
#define PAWNIOAPI EXTERN_C PAWNIO_EXPORT HRESULT STDAPICALLTYPE
/// Get PawnIOLib version.
///
/// @p version A pointer to a ULONG which receives the version.
/// @return A HRESULT.
PAWNIOAPI pawnio_version(PULONG version);
/// Open a PawnIO executor.
///
/// @p handle A handle to the executor, or NULL.
/// @return A HRESULT.
PAWNIOAPI pawnio_open(PHANDLE handle);
/// Load a PawnIO blob.
///
/// @p handle Handle from @c pawnio_open.
/// @p blob Blob to load.
/// @p size Size of blob.
/// @return A HRESULT.
PAWNIOAPI pawnio_load(HANDLE handle, const UCHAR* blob, SIZE_T size);
/// Executes a function from the loaded blob.
///
/// @p handle Handle from @c pawnio_open.
/// @p name Function name to execute.
/// @p in Input buffer.
/// @p in_size Input buffer count.
/// @p out Output buffer.
/// @p out_size Output buffer count.
/// @p return_size Entries written in out_size.
/// @return A HRESULT.
PAWNIOAPI pawnio_execute(
HANDLE handle,
PCSTR name,
const ULONG64* in,
SIZE_T in_size,
PULONG64 out,
SIZE_T out_size,
PSIZE_T return_size
);
/// Close a PawnIO executor.
///
/// @p handle Handle from @c pawnio_open.
/// @return A HRESULT.
PAWNIOAPI pawnio_close(HANDLE handle);
#endif //PAWNIOLIB_LIBRARY_H

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,580 +0,0 @@
//-----------------------------------------------------------------------------
// Author : hiyohiyo
// Mail : hiyohiyo@crystalmark.info
// Web : http://openlibsys.org/
// License : The modified BSD license
//
// Copyright 2007-2009 OpenLibSys.org. All rights reserved.
//-----------------------------------------------------------------------------
// for WinRing0 1.3.x
#pragma once
/******************************************************************************
**
** DLL Information
**
******************************************************************************/
//-----------------------------------------------------------------------------
// GetDllStatus
//-----------------------------------------------------------------------------
DWORD // DLL Status, defined OLS_DLL_****
WINAPI GetDllStatus();
//-----------------------------------------------------------------------------
// GetDllVersion
//-----------------------------------------------------------------------------
DWORD // DLL Version, defined OLS_VERSION
WINAPI GetDllVersion(
PBYTE major, // major version
PBYTE minor, // minor version
PBYTE revision, // revision
PBYTE release // release/build
);
//-----------------------------------------------------------------------------
// GetDriverVersion
//-----------------------------------------------------------------------------
DWORD // Device Driver Version, defined OLS_DRIVER_VERSION
WINAPI GetDriverVersion(
PBYTE major, // major version
PBYTE minor, // minor version
PBYTE revision, // revision
PBYTE release // release/build
);
//-----------------------------------------------------------------------------
// GetDriverType
//-----------------------------------------------------------------------------
DWORD // Device Driver Type, defined OLS_DRIVER_TYPE_****
WINAPI GetDriverType();
//-----------------------------------------------------------------------------
// InitializeOls
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI InitializeOls();
//-----------------------------------------------------------------------------
// DeinitializeOls
//-----------------------------------------------------------------------------
VOID WINAPI DeinitializeOls();
/******************************************************************************
**
** CPU
**
******************************************************************************/
//-----------------------------------------------------------------------------
// IsCpuid
//-----------------------------------------------------------------------------
BOOL // TRUE: support CPUID instruction, FALSE: not support CPUID instruction
WINAPI IsCpuid();
//-----------------------------------------------------------------------------
// IsMsr
//-----------------------------------------------------------------------------
BOOL // TRUE: support MSR(Model-Specific Register), FALSE: not support MSR
WINAPI IsMsr();
//-----------------------------------------------------------------------------
// IsTsc
//-----------------------------------------------------------------------------
BOOL // TRUE: support TSC(Time Stamp Counter), FALSE: not support TSC
WINAPI IsTsc();
//-----------------------------------------------------------------------------
// Rdmsr
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdmsr(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdmsrTx(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdmsrPx(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Wrmsr
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Wrmsr(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// WrmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WrmsrTx(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// WrmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WrmsrPx(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Rdpmc
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdpmc(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdpmcTx(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdpmcPx(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Cpuid
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Cpuid(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx
);
//-----------------------------------------------------------------------------
// CpuidTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI CpuidTx(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx,
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// CpuidPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI CpuidPx(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx,
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Rdtsc
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdtsc(
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdtscTx(
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdtscPx(
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Hlt
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Hlt();
//-----------------------------------------------------------------------------
// HltTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI HltTx(
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// HltPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI HltTx(
DWORD_PTR processAffinityMask
);
/******************************************************************************
**
** I/O
**
******************************************************************************/
//-----------------------------------------------------------------------------
// ReadIoPortByte
//-----------------------------------------------------------------------------
BYTE // Read Value
WINAPI ReadIoPortByte(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortWord
//-----------------------------------------------------------------------------
WORD // Read Value
WINAPI ReadIoPortWord(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortDword
//-----------------------------------------------------------------------------
DWORD // Read Value
WINAPI ReadIoPortDword(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortByteEx(
WORD port, // I/O port address
PBYTE value // Read Value
);
//-----------------------------------------------------------------------------
// ReadIoPortWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortWordEx(
WORD port, // I/O port address
PWORD value // Read Value
);
//-----------------------------------------------------------------------------
// ReadIoPortDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortDwordEx(
WORD port, // I/O port address
PDWORD value // Read Value
);
//-----------------------------------------------------------------------------
// WriteIoPortByte
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortByte(
WORD port, // I/O port address
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortDword
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortDword(
WORD port, // I/O port address
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortWord
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortWord(
WORD port, // I/O port address
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortByteEx(
WORD port, // I/O port address
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortWordEx(
WORD port, // I/O port address
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortDwordEx(
WORD port, // I/O port address
DWORD value // Write Value
);
/******************************************************************************
**
** PCI
**
******************************************************************************/
// pciAddress
// 0- 2: Function Number
// 3- 7: Device Number
// 8-15: PCI Bus Number
// 16-31: Reserved
// 0xFFFFFFFF : Error
//-----------------------------------------------------------------------------
// SetPciMaxBusNo
//-----------------------------------------------------------------------------
VOID
WINAPI SetPciMaxBusIndex(
BYTE max // Max PCI Bus to Scan
);
//-----------------------------------------------------------------------------
// ReadPciConfigByte
//-----------------------------------------------------------------------------
BYTE // Read Value
WINAPI ReadPciConfigByte(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigWord
//-----------------------------------------------------------------------------
WORD // Read Value
WINAPI ReadPciConfigWord(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigDword
//-----------------------------------------------------------------------------
DWORD // Read Value
WINAPI ReadPciConfigDword(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigByteEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PBYTE value // Read Value
);
//-----------------------------------------------------------------------------
// ReadPciConfigWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigWordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PWORD value // Read Value
);
//-----------------------------------------------------------------------------
// ReadPciConfigDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigDwordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PDWORD value // Read Value
);
//-----------------------------------------------------------------------------
// WritePciConfigByte
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigByte(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigWord
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigWord(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigDword
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigDword(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigByteEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigWordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigDwordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// FindPciDeviceById
//-----------------------------------------------------------------------------
DWORD // pciAddress, 0xFFFFFFFF: failure
WINAPI FindPciDeviceById(
WORD vendorId, // Vendor ID
WORD deviceId, // Device ID
BYTE index // Index
);
//-----------------------------------------------------------------------------
// FindPciDeviceByClass
//-----------------------------------------------------------------------------
DWORD // pciAddress, 0xFFFFFFFF: failure
WINAPI FindPciDeviceByClass(
BYTE baseClass, // Base Class
BYTE subClass, // Sub Class
BYTE programIf, // Program Interface
BYTE index // Index
);
/******************************************************************************
**
** Memory (Special API)
**
******************************************************************************/
#ifdef _PHYSICAL_MEMORY_SUPPORT
//-----------------------------------------------------------------------------
// ReadDmiMemory
//-----------------------------------------------------------------------------
DWORD // Read size(byte), 0: failure
WINAPI ReadDmiMemory(
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
//-----------------------------------------------------------------------------
// ReadPhysicalMemory
//-----------------------------------------------------------------------------
DWORD // Read size(byte), 0: failure
WINAPI ReadPhysicalMemory(
DWORD_PTR address, // Physical Memory Address
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
//-----------------------------------------------------------------------------
// WritePhysicalMemory
//-----------------------------------------------------------------------------
DWORD // Write size(byte), 0: failure
WINAPI WritePhysicalMemory(
DWORD_PTR address, // Physical Memory Address
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_i801.cpp |
| |
| i801 SMBUS driver for Windows |
| i801 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 29 Jan 2019 |
| Portions based on Linux source code |
@ -10,47 +10,22 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "i2c_smbus_i801.h"
#include "ResourceManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#include "wmi.h"
#elif _MACOSX_X86_X64
#include "macUSPCIOAccess.h"
#endif
#include "Detector.h"
#include "i2c_smbus_i801.h"
#include "LogManager.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
using namespace std::chrono_literals;
i2c_smbus_i801::i2c_smbus_i801()
{
#ifdef _WIN32
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#endif
}
i2c_smbus_i801::~i2c_smbus_i801()
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
/* Return negative errno on error. */
@ -519,22 +494,8 @@ int i2c_smbus_i801::i801_wait_intr()
s32 i2c_smbus_i801::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = i801_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@ -543,103 +504,6 @@ s32 i2c_smbus_i801::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u8
return -1;
}
#ifdef _WIN32
bool i2c_smbus_i801_detect()
{
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, i801 I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HRESULT hres;
Wmi wmi;
// Query WMI for Win32_PnPSignedDriver entries with names matching "SMBUS" or "SM BUS"
// These devices may be browsed under Device Manager -> System Devices
std::vector<QueryObj> q_res_PnPSignedDriver;
hres = wmi.query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'", q_res_PnPSignedDriver);
if (hres)
{
LOG_INFO("WMI query failed, i801 I2C bus detection aborted");
return(false);
}
// For each detected SMBus adapter, try enumerating it as either AMD or Intel
for (QueryObj &i : q_res_PnPSignedDriver)
{
// Intel SMBus controllers do show I/O resources in Device Manager
// Analysis of many Intel boards has shown that Intel SMBus adapter I/O space varies between boards
// We can query Win32_PnPAllocatedResource entries and look up the PCI device ID to find the allocated I/O space
// Intel SMBus adapters use the i801 driver
if ((i["Manufacturer"].find("Intel") != std::string::npos)
|| (i["Manufacturer"].find("INTEL") != std::string::npos))
{
std::string rgx1 = ".+" + q_res_PnPSignedDriver[0]["DeviceID"].substr(4, 33) + ".+";
AdditionalFilters filters;
filters.emplace("Dependent", rgx1);
filters.emplace("Antecedent", ".*Port.*");
std::vector<QueryObj> q_res_PNPAllocatedResource;
hres = wmi.query("SELECT * FROM Win32_PnPAllocatedResource", q_res_PNPAllocatedResource, &filters);
std::regex rgx2(".*StartingAddress=\"(\\d+)\".*");
std::smatch matches;
// Query the StartingAddress for the matching device ID and use it to enumerate the bus
if (!q_res_PNPAllocatedResource.empty() && std::regex_search(q_res_PNPAllocatedResource[0]["Antecedent"], matches, rgx2))
{
unsigned int IORangeStart = std::stoi(matches[1].str());
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
DWORD pciAddress = FindPciDeviceById(ven_id, dev_id, 0);
if(pciAddress == 0xFFFFFFFF)
{
continue;
}
uint8_t host_config = (uint8_t)ReadPciConfigWord(pciAddress, SMBHSTCFG);
if ((host_config & SMBHSTCFG_HST_EN) == 0)
{
continue;
}
bus = new i2c_smbus_i801();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strcpy(bus->device_name, i["Description"].c_str());
((i2c_smbus_i801 *)bus)->i801_smba = IORangeStart;
ResourceManager::get()->RegisterI2CBus(bus);
}
}
}
return(true);
}
#elif _MACOSX_X86_X64
bool i2c_smbus_i801_detect()
{
if(!GetMacUSPCIODriverStatus())
@ -675,6 +539,4 @@ bool i2c_smbus_i801_detect()
return(true);
}
#endif
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_i801_detect);

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_i801.h |
| |
| i801 SMBUS driver for Windows |
| i801 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 29 Jan 2019 |
| Portions based on Linux source code |
@ -14,10 +14,6 @@
#include "i2c_smbus.h"
#ifdef _WIN32
#include <Windows.h>
#endif
/* BIT shifting macro */
#define BIT(x) ( 1 << x )
@ -87,10 +83,6 @@
#define SMBHSTCFG 0x040
#define SMBHSTCFG_HST_EN BIT(0)
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_i801 : public i2c_smbus_interface
{
public:
@ -109,8 +101,4 @@ private:
int i801_wait_intr();
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE global_smbus_access_handle = NULL;
#endif
};

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_nct6775.cpp |
| |
| Nuvoton NCT67xx SMBUS driver for Windows |
| Nuvoton NCT67xx SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 19 May 2019 |
| |
@ -9,14 +9,11 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "macUSPCIOAccess.h"
#include "Detector.h"
#include "i2c_smbus_nct6775.h"
#include "LogManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#elif _MACOSX_X86_X64
#include "macUSPCIOAccess.h"
#endif
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "super_io.h"
@ -25,29 +22,10 @@ using namespace std::chrono_literals;
i2c_smbus_nct6775::i2c_smbus_nct6775()
{
#ifdef _WIN32
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#endif
}
i2c_smbus_nct6775::~i2c_smbus_nct6775()
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
s32 i2c_smbus_nct6775::nct6775_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data)
@ -223,22 +201,8 @@ s32 i2c_smbus_nct6775::nct6775_access(u16 addr, char read_write, u8 command, int
s32 i2c_smbus_nct6775::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = nct6775_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@ -249,19 +213,11 @@ s32 i2c_smbus_nct6775::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/,
bool i2c_smbus_nct6775_detect()
{
#ifdef _WIN32
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, nct6775 I2C bus detection aborted");
return(false);
}
#elif _MACOSX_X86_X64
if(!GetMacUSPCIODriverStatus())
{
LOG_INFO("macUSPCIO is not loaded, nct6775 I2C bus detection aborted");
return(false);
}
#endif
i2c_smbus_interface* bus;
int sioaddr = 0x2E;

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_nct6775.h |
| |
| Nuvoton NCT67xx SMBUS driver for Windows |
| Nuvoton NCT67xx SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 19 May 2019 |
| |
@ -12,9 +12,6 @@
#pragma once
#include "i2c_smbus.h"
#ifdef _WIN32
#include <Windows.h>
#endif
#define SMBHSTDAT (0 + nct6775_smba)
#define SMBBLKSZ (1 + nct6775_smba)
@ -50,10 +47,6 @@
/* Other settings */
#define NCT6775_MAX_RETRIES 400
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_nct6775: public i2c_smbus_interface
{
public:
@ -65,8 +58,4 @@ private:
s32 nct6775_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE global_smbus_access_handle = NULL;
#endif
};

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4.cpp |
| |
| PIIX4 SMBUS driver for Windows |
| PIIX4 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 08 Aug 2018 |
| Portions based on Linux source code |
@ -10,17 +10,13 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <unistd.h>
#include "macUSPCIOAccess.h"
#include "Detector.h"
#include "i2c_smbus_piix4.h"
#include "LogManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#include "wmi.h"
#elif _MACOSX_X86_X64
#include <unistd.h>
#include "macUSPCIOAccess.h"
#include "pci_ids.h"
#endif
#include "ResourceManager.h"
#include "SettingsManager.h"
@ -33,43 +29,12 @@ i2c_smbus_piix4::i2c_smbus_piix4()
{
amd_smbus_reduce_cpu = drivers_settings["amd_smbus_reduce_cpu"].get<bool>();
}
#ifdef _WIN32
if(amd_smbus_reduce_cpu)
{
delay_timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if(delay_timer == NULL) // high resolution timer not supported
{
delay_timer = CreateWaitableTimer(NULL, TRUE, NULL); // create regular timer instead
}
}
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#else
delay_timer = amd_smbus_reduce_cpu;
#endif
}
i2c_smbus_piix4::~i2c_smbus_piix4()
{
#ifdef _WIN32
if(delay_timer != NULL)
{
CloseHandle(delay_timer);
}
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
//Logic adapted from piix4_transaction() in i2c-piix4.c
@ -105,21 +70,8 @@ int i2c_smbus_piix4::piix4_transaction()
| if this bit is set. Note that there may be moderate latency before the transaction begins and the Host Busy bit |
| gets set. |
\*---------------------------------------------------------------------------------------------------------------*/
#ifdef _WIN32
if(delay_timer != NULL)
{
LARGE_INTEGER retry_delay;
retry_delay.QuadPart = RETRY_DELAY_US * -10;
temp = 0;
do
{
SetWaitableTimer(delay_timer, &retry_delay, 0, NULL, NULL, FALSE);
WaitForSingleObject(delay_timer, INFINITE);
temp = ReadIoPortByte(SMBHSTSTS);
}
while((++timeout < MAX_TIMEOUT) && ((temp & 0x03) != 0x02));
}
#else
if(delay_timer)
{
do
@ -129,7 +81,6 @@ int i2c_smbus_piix4::piix4_transaction()
}
while((++timeout < MAX_TIMEOUT) && ((temp & 0x03) != 0x02));
}
#endif
else
{
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);
@ -282,22 +233,8 @@ s32 i2c_smbus_piix4::piix4_access(u16 addr, char read_write, u8 command, int siz
s32 i2c_smbus_piix4::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = piix4_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@ -305,79 +242,7 @@ s32 i2c_smbus_piix4::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u
{
return -1;
}
#ifdef _WIN32
bool i2c_smbus_piix4_detect()
{
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, piix4 I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HRESULT hres;
Wmi wmi;
// Query WMI for Win32_PnPSignedDriver entries with names matching "SMBUS" or "SM BUS"
// These devices may be browsed under Device Manager -> System Devices
std::vector<QueryObj> q_res_PnPSignedDriver;
hres = wmi.query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'", q_res_PnPSignedDriver);
if (hres)
{
LOG_INFO("WMI query failed, piix4 I2C bus detection aborted");
return(false);
}
// For each detected SMBus adapter, try enumerating it as either AMD or Intel
for (QueryObj &i : q_res_PnPSignedDriver)
{
// AMD SMBus controllers do not show any I/O resources allocated in Device Manager
// Analysis of many AMD boards has shown that AMD SMBus controllers have two adapters with fixed I/O spaces at 0x0B00 and 0x0B20
// AMD SMBus adapters use the PIIX4 driver
if (i["Manufacturer"].find("Advanced Micro Devices, Inc") != std::string::npos)
{
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
bus = new i2c_smbus_piix4();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strcpy(bus->device_name, i["Description"].c_str());
strcat(bus->device_name, " at 0x0B00");
((i2c_smbus_piix4 *)bus)->piix4_smba = 0x0B00;
ResourceManager::get()->RegisterI2CBus(bus);
bus = new i2c_smbus_piix4();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
((i2c_smbus_piix4 *)bus)->piix4_smba = 0x0B20;
strcpy(bus->device_name, i["Description"].c_str());
strcat(bus->device_name, " at 0x0B20");
ResourceManager::get()->RegisterI2CBus(bus);
}
}
return(true);
}
#elif _MACOSX_X86_X64
bool i2c_smbus_piix4_detect()
{
if(!GetMacUSPCIODriverStatus())
@ -419,6 +284,5 @@ bool i2c_smbus_piix4_detect()
return(true);
}
#endif
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_piix4_detect);

@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4.h |
| |
| PIIX4 SMBUS driver for Windows |
| PIIX4 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 08 Aug 2018 |
| Portions based on Linux source code |
@ -13,9 +13,6 @@
#pragma once
#include "i2c_smbus.h"
#ifdef _WIN32
#include "windows.h"
#endif
// PIIX4 SMBus address offsets
#define SMBHSTSTS (0 + piix4_smba)
@ -41,10 +38,6 @@
#define PIIX4_WORD_DATA 0x0C
#define PIIX4_BLOCK_DATA 0x14
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_piix4 : public i2c_smbus_interface
{
public:
@ -57,10 +50,6 @@ private:
s32 piix4_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE delay_timer = NULL;
HANDLE global_smbus_access_handle = NULL;
#else
bool delay_timer;
#endif
};

@ -0,0 +1,558 @@
/*---------------------------------------------------------*\
| i2c_smbus_pawnio.cpp |
| |
| PawnIO SMBUS driver for Windows |
| |
| Stephen Horvath (Steve-Tech) 04 May 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <string>
#include "Detector.h"
#include "i2c_smbus_pawnio.h"
#include "LogManager.h"
#include "PawnIOLib.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "wmi.h"
std::unordered_map<std::string, int> i2c_smbus_pawnio::using_handle;
i2c_smbus_pawnio::i2c_smbus_pawnio(HANDLE handle, std::string name)
{
/*-----------------------------------------------------*\
| Get driver settings |
\*-----------------------------------------------------*/
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
/*-----------------------------------------------------*\
| Get shared SMBus access setting |
\*-----------------------------------------------------*/
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
/*-----------------------------------------------------*\
| Create global SMBus mutex if enabled |
\*-----------------------------------------------------*/
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
/*-----------------------------------------------------*\
| Store bus information |
| TODO: Remove name field once all drivers use the same |
| ioctl names |
\*-----------------------------------------------------*/
this->handle = handle;
this->name = name;
using_handle[name]++;
}
i2c_smbus_pawnio::~i2c_smbus_pawnio()
{
/*-----------------------------------------------------*\
| Close global SMBus mutex |
\*-----------------------------------------------------*/
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
/*-----------------------------------------------------*\
| TODO: find a way to do this without name field |
\*-----------------------------------------------------*/
if(--using_handle[name] == 0 && pawnio_close(handle))
{
LOG_ERROR("PawnIO failed to close");
}
}
s32 i2c_smbus_pawnio::pawnio_read(u8 addr, char /*read_write*/, u8 command, int size, i2c_smbus_data* data)
{
SIZE_T return_size;
switch(size)
{
case I2C_SMBUS_BYTE:
{
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {addr};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
/*---------------------------------------------*\
| Execute PawnIO read_byte ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_byte").c_str(), in, in_size, out, out_size, &return_size);
data->byte = (u8)out[0];
return(status ? -EIO : 0);
}
case I2C_SMBUS_BYTE_DATA:
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {addr, command};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
/*---------------------------------------------*\
| Execute PawnIO read_byte_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_byte_data").c_str(), in, in_size, out, out_size, &return_size);
data->byte = (u8)out[0];
return(status ? -EIO : 0);
}
case I2C_SMBUS_WORD_DATA:
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {addr, command};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
/*---------------------------------------------*\
| Execute PawnIO read_word_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_word_data").c_str(), in, in_size, out, out_size, &return_size);
data->word = (u16)out[0];
return(status ? -EIO : 0);
}
case I2C_SMBUS_BLOCK_DATA:
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {addr, command};
/*---------------------------------------------*\
| Calculate output data buffer size |
| Pawn only deals with 64-bit cells, divide by |
| 8 to convert bytes to qwords. |
| The first cell is also the length. |
\*---------------------------------------------*/
const SIZE_T out_size = 1 + (I2C_SMBUS_BLOCK_MAX / 8);
ULONG64 out[out_size];
/*---------------------------------------------*\
| Execute PawnIO read_block_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_block_data").c_str(), in, in_size, out, out_size, &return_size);
if(status)
{
return(-EIO);
}
if(out[0] == 0 || out[0] > I2C_SMBUS_BLOCK_MAX)
{
return(-EPROTO);
}
/*---------------------------------------------*\
| Unpack bytes from 64bit Pawn cells |
\*---------------------------------------------*/
u8 *out_bytes = (u8*)(&out[1]);
memcpy(&data->block[1], out_bytes, out[0]);
return(0);
}
default:
return(-EOPNOTSUPP);
}
}
s32 i2c_smbus_pawnio::pawnio_write(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
SIZE_T return_size;
switch(size)
{
case I2C_SMBUS_QUICK:
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {addr, (u8)read_write};
/*---------------------------------------------*\
| Execute PawnIO write_quick ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_quick").c_str(), in, in_size, NULL, 0, &return_size);
return(status ? -EIO : 0);
}
case I2C_SMBUS_BYTE:
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {addr, data->byte};
/*---------------------------------------------*\
| Execute PawnIO write_byte ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_byte").c_str(), in, in_size, NULL, 0, &return_size);
return(status ? -EIO : 0);
}
case I2C_SMBUS_BYTE_DATA:
{
const SIZE_T in_size = 3;
ULONG64 in[in_size] = {addr, command, data->byte};
/*---------------------------------------------*\
| Execute PawnIO write_byte_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_byte_data").c_str(), in, in_size, NULL, 0, &return_size);
return(status ? -EIO : 0);
}
case I2C_SMBUS_WORD_DATA:
{
const SIZE_T in_size = 3;
ULONG64 in[in_size] = {addr, command, data->word};
/*---------------------------------------------*\
| Execute PawnIO write_word_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_word_data").c_str(), in, in_size, NULL, 0, &return_size);
return(status ? -EIO : 0);
}
case I2C_SMBUS_BLOCK_DATA:
{
SIZE_T len = data->block[0];
if(len == 0 || len > I2C_SMBUS_BLOCK_MAX)
{
return -EINVAL;
}
const SIZE_T in_size = 3 + (I2C_SMBUS_BLOCK_MAX/8);
ULONG64 in[3 + (I2C_SMBUS_BLOCK_MAX/8)] = {addr, command, len};
/*---------------------------------------------*\
| Pack bytes into 64bit Pawn cells |
\*---------------------------------------------*/
u8 *in_bytes = (u8*)&in[3];
memcpy(in_bytes, &data->block[1], len);
/*---------------------------------------------*\
| Execute PawnIO write_block_data ioctl |
\*---------------------------------------------*/
HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_block_data").c_str(), in, in_size, NULL, 0, &return_size);
return(status ? -EIO : 0);
}
default:
return(-EOPNOTSUPP);
}
}
s32 i2c_smbus_pawnio::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
int status = -ENXIO;
if(read_write && size != I2C_SMBUS_QUICK) {
status = pawnio_read(addr, read_write, command, size, data);
}
else
{
status = pawnio_write(addr, read_write, command, size, data);
}
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
return(status);
}
s32 i2c_smbus_pawnio::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u8* /*data*/)
{
return(-1);
}
// TODO: Find a better place for this function
HRESULT i2c_smbus_pawnio::start_pawnio(std::string filename, PHANDLE phandle)
{
char exePath[MAX_PATH];
HANDLE handle;
HRESULT status;
/*-----------------------------------------------------*\
| Open PawnIO driver |
\*-----------------------------------------------------*/
status = pawnio_open(phandle);
/*-----------------------------------------------------*\
| Check result |
\*-----------------------------------------------------*/
if(status)
{
if(status == E_ACCESSDENIED)
{
LOG_ERROR("Permission Denied, PawnIO initialization aborted");
}
else
{
LOG_ERROR("Could not open PawnIO, PawnIO initialization aborted");
}
return(status);
}
handle = *phandle;
/*-----------------------------------------------------*\
| Get the path of the executable |
\*-----------------------------------------------------*/
if(!GetModuleFileNameA(NULL, exePath, MAX_PATH))
{
LOG_ERROR("Failed to get executable path, PawnIO initialization aborted");
return E_FAIL;
}
/*-----------------------------------------------------*\
| Construct the path to `filename` in the executable's |
| directory |
\*-----------------------------------------------------*/
std::filesystem::path exeDir = std::filesystem::path(exePath).parent_path();
std::filesystem::path filePath = exeDir / filename;
/*-----------------------------------------------------*\
| Check if the file exists |
\*-----------------------------------------------------*/
if(!std::filesystem::exists(filePath))
{
LOG_ERROR("Failed to find %s in the executable's directory, PawnIO initialization aborted", filename.c_str());
return(E_FAIL);
}
/*-----------------------------------------------------*\
| Open the file |
\*-----------------------------------------------------*/
std::ifstream file(filePath, std::ios::binary);
if(!file.is_open())
{
LOG_ERROR("Failed to open %s, PawnIO initialization aborted", filename.c_str());
return(E_FAIL);
}
/*-----------------------------------------------------*\
| Read the contents of the file into a vector of bytes |
\*-----------------------------------------------------*/
std::vector<char> blob((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
/*-----------------------------------------------------*\
| Close the file |
\*-----------------------------------------------------*/
file.close();
/*-----------------------------------------------------*\
| Load the file into PawnIO |
\*-----------------------------------------------------*/
status = pawnio_load(handle, reinterpret_cast<const UCHAR*>(blob.data()), blob.size());
/*-----------------------------------------------------*\
| Check if the load was successful |
\*-----------------------------------------------------*/
if(status)
{
LOG_ERROR("Failed to load %s, PawnIO initialization aborted", filename.c_str());
return(status);
}
/*-----------------------------------------------------*\
| Log a message and return OK if PawnIO successfully |
| opened |
\*-----------------------------------------------------*/
LOG_INFO("PawnIO initialized");
return(S_OK);
}
s32 piix4_port_sel(HANDLE pawnio_handle, s32 port)
{
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)port};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status;
/*-----------------------------------------------------*\
| Execute PIIX4 port_sel ioctl |
\*-----------------------------------------------------*/
status = pawnio_execute(pawnio_handle, "ioctl_piix4_port_sel", in, in_size, out, 1, &return_size);
return(status ? -EIO : 0);
}
bool i2c_smbus_pawnio_detect()
{
ULONG dll_version;
if(pawnio_version(&dll_version))
{
LOG_INFO("PawnIO is not loaded, PawnIO I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HRESULT hres;
Wmi wmi;
HANDLE pawnio_handle;
/*-----------------------------------------------------*\
| Query WMI for Win32_PnPSignedDriver entries with |
| names matching "SMBUS" or "SM BUS". These devices |
| may be browsed under Device Manager -> System Devices |
\*-----------------------------------------------------*/
std::vector<QueryObj> q_res_PnPSignedDriver;
hres = wmi.query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'", q_res_PnPSignedDriver);
if(hres)
{
LOG_INFO("WMI query failed, I2C bus detection aborted");
return(false);
}
/*-----------------------------------------------------*\
| For each detected SMBus adapter, try enumerating it |
| as either AMD (piix4) or Intel (i801) |
\*-----------------------------------------------------*/
for(QueryObj &i : q_res_PnPSignedDriver)
{
/*-------------------------------------------------*\
| Intel SMBus controllers do show I/O resources in |
| Device Manager. Analysis of many Intel boards |
| has shown that Intel SMBus adapter I/O space |
| varies between boards. We can query |
| Win32_PnPAllocatedResource entries and look up |
| the PCI device ID to find the allocated I/O space.|
| |
| Intel SMBus adapters use the i801 driver |
\*-------------------------------------------------*/
if((i["Manufacturer"].find("Intel") != std::string::npos)
|| (i["Manufacturer"].find("INTEL") != std::string::npos))
{
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
/*---------------------------------------------*\
| Create bus |
\*---------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusI801.bin", &pawnio_handle) != S_OK)
{
return(false);
}
bus = new i2c_smbus_pawnio(pawnio_handle, "i801");
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name);
ResourceManager::get()->RegisterI2CBus(bus);
}
/*-------------------------------------------------*\
| AMD SMBus adapters use the PIIX4 driver |
\*-------------------------------------------------*/
else if(i["Manufacturer"].find("Advanced Micro Devices, Inc") != std::string::npos)
{
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
/*---------------------------------------------*\
| Create primary bus |
\*---------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) != S_OK)
{
return(false);
}
/*---------------------------------------------*\
| Select port 0 |
\*---------------------------------------------*/
piix4_port_sel(pawnio_handle, 0);
bus = new i2c_smbus_pawnio(pawnio_handle, "piix4");
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name);
strncat(bus->device_name, " port 0", sizeof bus->device_name);
ResourceManager::get()->RegisterI2CBus(bus);
/*---------------------------------------------*\
| Create secondary bus |
\*---------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) != S_OK)
{
return(false);
}
/*---------------------------------------------*\
| Select port 1 |
\*---------------------------------------------*/
piix4_port_sel(pawnio_handle, 1);
bus = new i2c_smbus_pawnio(pawnio_handle, "piix4");
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name);
strncat(bus->device_name, " port 1", sizeof bus->device_name);
ResourceManager::get()->RegisterI2CBus(bus);
}
}
return(true);
}
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_pawnio_detect);

@ -0,0 +1,42 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4_pawnio.h |
| |
| PawnIO PIIX4 SMBUS driver for Windows |
| |
| Stephen Horvath (Steve-Tech) 21 Apr 2025 |
| Based on original OpenRGB PIIX4 source code |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <unordered_map>
#include "windows.h"
#include "i2c_smbus.h"
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
class i2c_smbus_pawnio : public i2c_smbus_interface
{
public:
static std::unordered_map<std::string, int> using_handle;
i2c_smbus_pawnio(HANDLE handle, std::string name);
~i2c_smbus_pawnio();
static HRESULT start_pawnio(std::string filename, PHANDLE phandle);
private:
s32 pawnio_read(u8 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 pawnio_write(u8 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
HANDLE global_smbus_access_handle;
std::string name;
HANDLE handle;
};

@ -520,83 +520,6 @@ static void WaitWhileServerOnline(NetworkServer* srv)
}
/*---------------------------------------------------------*\
| InstallWinRing0 |
| |
| Install SMBus Driver WinRing0, If not already installed |
| (Win32) |
\*---------------------------------------------------------*/
void InstallWinRing0()
{
/*-----------------------------------------------------*\
| Driver final location usually |
| C:\windows\system32\drivers\WinRing0x64.sys |
\*-----------------------------------------------------*/
TCHAR winring0_install_location[MAX_PATH];
uint system_path_length = GetSystemDirectory(winring0_install_location, MAX_PATH);
std::string winring0_filename = "WinRing0.sys";
BOOL bIsWow64 = false;
#if _WIN64
winring0_filename = "WinRing0x64.sys";
#else
BOOL (*fnIsWow64Process)(HANDLE, PBOOL) = (BOOL (__cdecl *)(HANDLE, PBOOL))GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if (fnIsWow64Process)
{
fnIsWow64Process(GetCurrentProcess(),&bIsWow64);
}
if(bIsWow64)
{
winring0_filename = "WinRing0x64.sys";
}
#endif
std::strncat(winring0_install_location, "\\drivers\\", MAX_PATH - system_path_length - 1);
std::strncat(winring0_install_location, winring0_filename.c_str(), MAX_PATH - system_path_length - 10);
std::string driver_name = winring0_filename.substr(0, winring0_filename.size() - 4); // driver name: WinRing0 or WinRing0x64
SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (manager)
{
PVOID wow64_fsredirection_OldValue = NULL;
if(bIsWow64)
{
Wow64DisableWow64FsRedirection(&wow64_fsredirection_OldValue);
}
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(winring0_install_location) && GetLastError()==ERROR_FILE_NOT_FOUND)
{
char module_path_buffer[MAX_PATH];
GetModuleFileNameA(NULL, module_path_buffer, MAX_PATH);
std::string::size_type exe_loc = std::string(module_path_buffer).find_last_of("\\/");
std::string driver_source_path = std::string(module_path_buffer).substr(0, exe_loc + 1) + winring0_filename;
CopyFile(driver_source_path.c_str(), winring0_install_location, true);
}
if(bIsWow64)
{
Wow64RevertWow64FsRedirection(wow64_fsredirection_OldValue);
}
SC_HANDLE service = OpenService(manager, driver_name.c_str(), SERVICE_ALL_ACCESS);
if(!service)
{
std::string service_sys_path = "System32\\Drivers\\" + winring0_filename;
service = CreateService(manager,
driver_name.c_str(),
driver_name.c_str(),
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
service_sys_path.c_str(),
NULL,
NULL,
NULL,
NULL,
NULL);
}
CloseServiceHandle(service);
CloseServiceHandle(manager);
}
}
/*---------------------------------------------------------*\
| common_main |
| |
| Common entry functionality after determining whether we |
@ -632,11 +555,6 @@ static int common_main(int argc, char* argv[])
InitializeTimerResolutionThread->detach();
/*-----------------------------------------------------*\
| Install SMBus Driver WinRing0 |
\*-----------------------------------------------------*/
InstallWinRing0();
/*-----------------------------------------------------*\
| Initialize ResourceManager |
\*-----------------------------------------------------*/
ResourceManager::get()->Initialize(

@ -10,11 +10,9 @@
\*---------------------------------------------------------*/
#include "super_io.h"
#include "super_io_pawnio.h"
#ifdef _WIN32
#include <Windows.h>
#include "OlsApi.h"
#elif _MACOSX_X86_X64
#if _MACOSX_X86_X64
#include "macUSPCIOAccess.h"
#else
#include <unistd.h>
@ -34,7 +32,7 @@ int dev_port_fd;
void superio_enter(int ioreg)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, 0x87);
WriteIoPortByte(ioreg, 0x87);
#else
@ -71,7 +69,7 @@ void superio_enter(int ioreg)
void superio_outb(int ioreg, int reg, int val)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, reg);
WriteIoPortByte(ioreg + 1, val);
#else
@ -106,7 +104,7 @@ void superio_outb(int ioreg, int reg, int val)
int superio_inb(int ioreg, int reg)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, reg);
return ReadIoPortByte(ioreg + 1);
#else

@ -9,6 +9,8 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
/******************************************************************************************\
* *
* Nuvoton Super IO constants *

@ -0,0 +1,120 @@
/*---------------------------------------------------------*\
| super_io_pawnio.cpp |
| |
| Functions for interfacing with Super-IO using PawnIO |
| |
| Stephen Horvath (Steve-Tech) 05 May 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "super_io_pawnio.h"
#include <Windows.h>
#include "PawnIOLib.h"
#include "i2c_smbus_pawnio.h"
static HANDLE pawnio_handle = NULL;
static int pawnio_chip_type = 0;
static int addr_to_pawnio(int addr)
{
switch (addr)
{
case 0x2E:
return 0;
case 0x4E:
return 1;
default:
return -1;
}
}
/******************************************************************************************\
* *
* pawnio_superio_enter *
* *
* Put the Super IO chip into Extended Function Mode *
* *
\******************************************************************************************/
void superio_enter(int ioreg)
{
HRESULT status;
SIZE_T return_size;
if (pawnio_handle == NULL)
{
status = i2c_smbus_pawnio::start_pawnio("superio", &pawnio_handle);
if (status != S_OK)
{
// TODO: Figure out how to handle errors
return;
}
}
if (pawnio_chip_type == 0)
{
int in_reg = addr_to_pawnio(ioreg);
if (in_reg == -1) {
return;
}
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)in_reg};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
status = pawnio_execute(pawnio_handle, "ioctl_detect", in, in_size, out, out_size, &return_size);
if (status != S_OK || out[0] == 0)
{
return;
}
pawnio_chip_type = (int)out[0];
}
pawnio_execute(pawnio_handle, "ioctl_enter", NULL, 0, NULL, 0, &return_size);
}
/******************************************************************************************\
* *
* pawnio_superio_outb *
* *
* Write a byte to the Super IO configuration register *
* *
\******************************************************************************************/
void superio_outb([[maybe_unused]] int ioreg, int reg, int val)
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {(ULONG64)reg, (ULONG64)val};
SIZE_T return_size;
pawnio_execute(pawnio_handle, "ioctl_write", in, in_size, NULL, 0, &return_size);
}
/******************************************************************************************\
* *
* pawnio_superio_inb *
* *
* Read a byte from the Super IO configuration register *
* *
\******************************************************************************************/
int superio_inb([[maybe_unused]] int ioreg, int reg)
{
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)reg};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status = pawnio_execute(pawnio_handle, "ioctl_read", in, in_size, out, out_size, &return_size);
if (status != S_OK)
{
return -1;
}
return (int)out[0];
}

@ -0,0 +1,18 @@
/*---------------------------------------------------------*\
| super_io_pawnio.h |
| |
| Functions for interfacing with Super-IO using PawnIO |
| |
| Stephen Horvath (Steve-Tech) 05 May 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
void superio_enter(int ioreg);
void superio_outb(int ioreg, int reg, int val);
int superio_inb(int ioreg, int reg);
Loading…
Cancel
Save