Files
CarlMonitor/LibreHardwareMonitor-0.9.4/InpOut/inpout32drv.cpp
2025-04-07 07:44:27 -07:00

692 lines
15 KiB
C++

/***********************************************************************\
* *
* InpOut32drv.cpp *
* *
* The entry point for the InpOut DLL *
* Provides the 32 and 64bit implementation of InpOut32 DLL to install *
* and call the appropriate driver and write directly to hardware ports. *
* *
* Written by Phillip Gibbons (Highrez.co.uk) *
* Based on orriginal, written by Logix4U (www.logix4u.net) *
* *
\***********************************************************************/
#include "stdafx.h"
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include "hwinterfacedrv.h"
#include "resource.h"
int inst32();
int inst64();
int start(LPCTSTR pszDriver);
//First, lets set the DRIVERNAME depending on our configuraiton.
#define DRIVERNAMEx64 _T("inpoutx64\0")
#define DRIVERNAMEi386 _T("inpout32\0")
char str[10];
int vv;
HANDLE hdriver=NULL;
TCHAR path[MAX_PATH];
HINSTANCE hmodule;
SECURITY_ATTRIBUTES sa;
int sysver;
int Opendriver(BOOL bX64);
void Closedriver(void);
BOOL APIENTRY DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hmodule = hModule;
BOOL bx64 = IsXP64Bit();
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
sysver = SystemVersion();
if(sysver==2)
{
Opendriver(bx64);
}
}
break;
case DLL_PROCESS_DETACH:
{
if(sysver==2)
{
Closedriver();
}
}
break;
}
return TRUE;
}
/***********************************************************************/
void Closedriver(void)
{
if (hdriver)
{
OutputDebugString(_T("Closing InpOut driver...\n"));
CloseHandle(hdriver);
hdriver=NULL;
}
}
void _stdcall Out32(short PortAddress, short data)
{
{
switch(sysver)
{
case 1:
#ifdef _M_IX86
_outp( PortAddress,data); //Will ONLY compile on i386 architecture
#endif
break;
case 2:
unsigned int error;
DWORD BytesReturned;
BYTE Buffer[3]={NULL};
unsigned short* pBuffer;
pBuffer = (unsigned short *)&Buffer[0];
*pBuffer = LOWORD(PortAddress);
Buffer[2] = LOBYTE(data);
error = DeviceIoControl(hdriver,
IOCTL_WRITE_PORT_UCHAR,
&Buffer,
3,
NULL,
0,
&BytesReturned,
NULL);
break;
}
}
}
/*********************************************************************/
short _stdcall Inp32(short PortAddress)
{
{
BYTE retval(0);
switch(sysver)
{
case 1:
#ifdef _M_IX86
retval = _inp(PortAddress);
#endif
return retval;
break;
case 2:
unsigned int error;
DWORD BytesReturned;
unsigned char Buffer[3]={NULL};
unsigned short * pBuffer;
pBuffer = (unsigned short *)&Buffer;
*pBuffer = LOWORD(PortAddress);
Buffer[2] = 0;
error = DeviceIoControl(hdriver,
IOCTL_READ_PORT_UCHAR,
&Buffer,
2,
&Buffer,
1,
&BytesReturned,
NULL);
if (error==0)
{
DWORD dwError = GetLastError();
TCHAR tszError[255];
_stprintf_s(tszError, 255, _T("Error %d\n"), dwError);
OutputDebugString(tszError);
}
//Do this to ensure only the first byte is returned, we dont really want to return a short as were only reading a byte.
//but we also dont want to change the InpOut interface!
UCHAR ucRes = (UCHAR)Buffer[0];
return ucRes;
break;
}
}
return 0;
}
/*********************************************************************/
int Opendriver(BOOL bX64)
{
OutputDebugString(_T("Attempting to open InpOut driver...\n"));
TCHAR szFileName[MAX_PATH] = {NULL};
_stprintf_s(szFileName, MAX_PATH, _T("\\\\.\\%s"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386);
hdriver = CreateFile(szFileName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hdriver == INVALID_HANDLE_VALUE)
{
if(start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386))
{
if (bX64)
inst64(); //Install the x64 driver
else
inst32(); //Install the i386 driver
int nResult = start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386);
if (nResult == ERROR_SUCCESS)
{
hdriver = CreateFile(szFileName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hdriver != INVALID_HANDLE_VALUE)
{
OutputDebugString(_T("Successfully opened "));
OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386);
OutputDebugString(_T(" driver\n"));
return 0;
}
}
else
{
TCHAR szMsg[MAX_PATH] = {NULL};
_stprintf_s(szMsg, MAX_PATH, _T("Unable to open %s driver. Error code %d.\n"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386, nResult);
OutputDebugString(szMsg);
//RemoveDriver();
}
}
return 1;
}
OutputDebugString(_T("Successfully opened "));
OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386);
OutputDebugString(_T(" driver\n"));
return 0;
}
/***********************************************************************/
int inst32()
{
TCHAR szDriverSys[MAX_PATH];
_tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEi386);
_tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0"));
SC_HANDLE Mgr;
SC_HANDLE Ser;
GetSystemDirectory(path, MAX_PATH);
HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUT32), _T("bin"));
if(hResource)
{
HGLOBAL binGlob = LoadResource(hmodule, hResource);
if(binGlob)
{
void *binData = LockResource(binGlob);
if(binData)
{
HANDLE file;
_tcscat_s(path, sizeof(path), _T("\\Drivers\\"));
_tcscat_s(path, sizeof(path), szDriverSys);
file = CreateFile(path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL);
if (file && file != INVALID_HANDLE_VALUE)
{
DWORD size, written;
size = SizeofResource(hmodule, hResource);
WriteFile(file, binData, size, &written, NULL);
CloseHandle(file);
}
else
{
//Error
}
}
}
}
Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS);
if (Mgr == NULL)
{ //No permission to create service
if (GetLastError() == ERROR_ACCESS_DENIED)
{
return 5; // error access denied
}
}
else
{
TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0");
_tcscat_s(szFullPath, MAX_PATH, szDriverSys);
Ser = CreateService (Mgr,
DRIVERNAMEi386,
DRIVERNAMEi386,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szFullPath,
NULL,
NULL,
NULL,
NULL,
NULL
);
}
CloseServiceHandle(Ser);
CloseServiceHandle(Mgr);
return 0;
}
int inst64()
{
TCHAR szDriverSys[MAX_PATH];
_tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEx64);
_tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0"));
SC_HANDLE Mgr;
SC_HANDLE Ser;
GetSystemDirectory(path, MAX_PATH);
HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUTX64), _T("bin"));
if(hResource)
{
HGLOBAL binGlob = LoadResource(hmodule, hResource);
if(binGlob)
{
void *binData = LockResource(binGlob);
if(binData)
{
HANDLE file;
_tcscat_s(path, sizeof(path), _T("\\Drivers\\"));
_tcscat_s(path, sizeof(path), szDriverSys);
PVOID OldValue;
DisableWOW64(&OldValue);
file = CreateFile(path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL);
if(file && file != INVALID_HANDLE_VALUE)
{
DWORD size, written;
size = SizeofResource(hmodule, hResource);
WriteFile(file, binData, size, &written, NULL);
CloseHandle(file);
}
else
{
//error
}
RevertWOW64(&OldValue);
}
}
}
Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS);
if (Mgr == NULL)
{ //No permission to create service
if (GetLastError() == ERROR_ACCESS_DENIED)
{
return 5; // error access denied
}
}
else
{
TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0");
_tcscat_s(szFullPath, MAX_PATH, szDriverSys);
Ser = CreateService (Mgr,
DRIVERNAMEx64,
DRIVERNAMEx64,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szFullPath,
NULL,
NULL,
NULL,
NULL,
NULL
);
}
CloseServiceHandle(Ser);
CloseServiceHandle(Mgr);
return 0;
}
/**************************************************************************/
int start(LPCTSTR pszDriver)
{
SC_HANDLE Mgr;
SC_HANDLE Ser;
Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS);
if (Mgr == NULL)
{ //No permission to create service
if (GetLastError() == ERROR_ACCESS_DENIED)
{
Mgr = OpenSCManager (NULL, NULL, GENERIC_READ);
Ser = OpenService(Mgr, pszDriver, GENERIC_EXECUTE);
if (Ser)
{ // we have permission to start the service
if(!StartService(Ser,0,NULL))
{
CloseServiceHandle (Ser);
return 4; // we could open the service but unable to start
}
}
}
}
else
{// Successfuly opened Service Manager with full access
Ser = OpenService(Mgr, pszDriver, SERVICE_ALL_ACCESS);
if (Ser)
{
if(!StartService(Ser,0,NULL))
{
CloseServiceHandle (Ser);
return 3; // opened the Service handle with full access permission, but unable to start
}
else
{
CloseServiceHandle (Ser);
return 0;
}
}
}
return 1;
}
BOOL _stdcall IsInpOutDriverOpen()
{
sysver = SystemVersion();
if (sysver==2)
{
if (hdriver!=INVALID_HANDLE_VALUE && hdriver != NULL)
return TRUE;
}
else if (sysver==1)
{
return TRUE;
}
return FALSE;
}
UCHAR _stdcall DlPortReadPortUchar (USHORT port)
{
UCHAR retval(0);
switch(sysver)
{
case 1:
#ifdef _M_IX86
retval = _inp((USHORT)port);
#endif
return retval;
break;
case 2:
unsigned int error;
DWORD BytesReturned;
BYTE Buffer[3]={NULL};
unsigned short * pBuffer;
pBuffer = (unsigned short *)&Buffer;
*pBuffer = port;
Buffer[2] = 0;
error = DeviceIoControl(hdriver,
IOCTL_READ_PORT_UCHAR,
&Buffer,
sizeof(Buffer),
&Buffer,
sizeof(Buffer),
&BytesReturned,
NULL);
return((UCHAR)Buffer[0]);
break;
}
return 0;
}
void _stdcall DlPortWritePortUchar (USHORT port, UCHAR Value)
{
switch(sysver)
{
case 1:
#ifdef _M_IX86
_outp((UINT)port,Value); //Will ONLY compile on i386 architecture
#endif
break;
case 2:
unsigned int error;
DWORD BytesReturned;
BYTE Buffer[3]={NULL};
unsigned short * pBuffer;
pBuffer = (unsigned short *)&Buffer[0];
*pBuffer = port;
Buffer[2] = Value;
error = DeviceIoControl(hdriver,
IOCTL_WRITE_PORT_UCHAR,
&Buffer,
sizeof(Buffer),
NULL,
0,
&BytesReturned,
NULL);
break;
}
}
USHORT _stdcall DlPortReadPortUshort (USHORT port)
{
if (sysver!=2)
return 0;
ULONG retval(0);
unsigned int error;
DWORD BytesReturned;
unsigned short sPort=port;
error = DeviceIoControl(hdriver,
IOCTL_READ_PORT_USHORT,
&sPort,
sizeof(unsigned short),
&sPort,
sizeof(unsigned short),
&BytesReturned,
NULL);
return(sPort);
}
void _stdcall DlPortWritePortUshort (USHORT port, USHORT Value)
{
if (sysver!=2)
return;
unsigned int error;
DWORD BytesReturned;
BYTE Buffer[5]={NULL};
unsigned short * pBuffer;
pBuffer = (unsigned short *)&Buffer[0];
*pBuffer = LOWORD(port);
*(pBuffer+1) = Value;
error = DeviceIoControl(hdriver,
IOCTL_WRITE_PORT_USHORT,
&Buffer,
sizeof(Buffer),
NULL,
0,
&BytesReturned,
NULL);
}
ULONG _stdcall DlPortReadPortUlong(ULONG port)
{
if (sysver!=2)
return 0;
ULONG retval(0);
unsigned int error;
DWORD BytesReturned;
unsigned long lPort=port;
PULONG ulBuffer;
ulBuffer = (PULONG)&lPort;
ULONG test = ulBuffer[0];
error = DeviceIoControl(hdriver,
IOCTL_READ_PORT_ULONG,
&lPort,
sizeof(unsigned long),
&lPort,
sizeof(unsigned long),
&BytesReturned,
NULL);
return(lPort);
}
void _stdcall DlPortWritePortUlong (ULONG port, ULONG Value)
{
if (sysver!=2)
return;
unsigned int error;
DWORD BytesReturned;
BYTE Buffer[8] = {NULL};
unsigned long* pBuffer;
pBuffer = (unsigned long*)&Buffer[0];
*pBuffer = port;
*(pBuffer+1) = Value;
error = DeviceIoControl(hdriver,
IOCTL_WRITE_PORT_ULONG,
&Buffer,
sizeof(Buffer),
NULL,
0,
&BytesReturned,
NULL);
}
// Support functions for WinIO
PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle)
{
PBYTE pbLinAddr;
tagPhys32Struct Phys32Struct;
DWORD dwBytesReturned;
if (sysver!=2)
return false;
Phys32Struct.dwPhysMemSizeInBytes = dwPhysSize;
Phys32Struct.pvPhysAddress = pbPhysAddr;
if (!DeviceIoControl(hdriver, IOCTL_WINIO_MAPPHYSTOLIN, &Phys32Struct,
sizeof(tagPhys32Struct), &Phys32Struct, sizeof(tagPhys32Struct),
&dwBytesReturned, NULL))
return NULL;
else
{
#ifdef _M_X64
pbLinAddr = (PBYTE)((LONGLONG)Phys32Struct.pvPhysMemLin + (LONGLONG)pbPhysAddr - (LONGLONG)Phys32Struct.pvPhysAddress);
#else
pbLinAddr = (PBYTE)((DWORD)Phys32Struct.pvPhysMemLin + (DWORD)pbPhysAddr - (DWORD)Phys32Struct.pvPhysAddress);
#endif
*pPhysicalMemoryHandle = Phys32Struct.PhysicalMemoryHandle;
}
return pbLinAddr;
}
BOOL _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr)
{
tagPhys32Struct Phys32Struct;
DWORD dwBytesReturned;
if (sysver!=2)
return false;
Phys32Struct.PhysicalMemoryHandle = PhysicalMemoryHandle;
Phys32Struct.pvPhysMemLin = pbLinAddr;
if (!DeviceIoControl(hdriver, IOCTL_WINIO_UNMAPPHYSADDR, &Phys32Struct,
sizeof(tagPhys32Struct), NULL, 0, &dwBytesReturned, NULL))
return false;
return true;
}
BOOL _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal)
{
PDWORD pdwLinAddr;
HANDLE PhysicalMemoryHandle;
if (sysver!=2)
return false;
pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle);
if (pdwLinAddr == NULL)
return false;
*pdwPhysVal = *pdwLinAddr;
UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr);
return true;
}
BOOL _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal)
{
PDWORD pdwLinAddr;
HANDLE PhysicalMemoryHandle;
if (sysver!=2)
return false;
pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle);
if (pdwLinAddr == NULL)
return false;
*pdwLinAddr = dwPhysVal;
UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr);
return true;
}