📄 nled-driver.cpp
字号:
#include <windows.h>
#include <Pmpolicy.h>
#include <nled.h>
#include "logger.h"
#include "nled-driver.h"
#ifdef __cplusplus
extern "C"{
#endif
#define NLED_DRV_FN L"nleddrvr.dll"
#define _GET_PROC_PTR(procType, procName) \
if (!pfn##procName) { \
_LOG(L"Loading func '%s'\n", L#procName); \
pfn##procName = (procType)GetProcAddress(g_hDrvLib, L#procName); \
}
//\
//_LOG(L"Calling func '%s'\n", L#procName);
#define GET_PROC_PTR(procType, procName) \
_GET_PROC_PTR(procType, procName); \
if (!pfn##procName) { \
_LOG(L"Error loading func '%s'\n", L#procName); \
}
#define GET_PROC_PTR_RZERO(procType, procName) \
_GET_PROC_PTR(procType, procName); \
if (!pfn##procName) { \
_LOG(L"Error loading func '%s'\n", L#procName); \
return 0; \
}
#define GET_PROC_PTR_RNOTH(procType, procName) \
_GET_PROC_PTR(procType, procName); \
if (!pfn##procName) { \
_LOG(L"Error loading func '%s'\n", L#procName); \
return; \
}
typedef struct shared_tag
{
CRITICAL_SECTION lock;
DWORD dwContext;
DWORD nledNum;
DWORD pulseThreadId;
TCHAR szPulseScript[2048];
} SharedMem, *PSharedMem;
HANDLE shmem_map = 0;
PSharedMem shmem_dll = 0;
HMODULE g_hDrvLib;
HANDLE event_VibratePulse = 0;
PFN_INIT pfnInit;
PFN_DEINIT pfnDeinit;
PFN_IOCONTROL pfnIOControl;
PFN_POWERDOWN pfnPowerDown;
PFN_POWERUP pfnPowerUp;
PFN_OPEN pfnOpen;
PFN_CLOSE pfnClose;
int FetchIntFromStr(LPCTSTR szStr, int len, int* pos)
{
int res = 0;
TCHAR buf[2] = L"0";
while (*pos < len)
{
TCHAR c = szStr[*pos];
if (iswdigit(c))
{
buf[0] = c;
res = res*10 + _wtoi(buf);
(*pos)++;
}
else
{
(*pos)--;
break;
}
}
return res;
}
static void SetVibrate(int state)
{
if (!pfnIOControl) return;
NLED_SETTINGS_INFO nled;
ZeroMemory(&nled, sizeof(NLED_SETTINGS_INFO));
nled.LedNum = shmem_dll->nledNum;
nled.OffOnBlink = state;
BOOL ret = pfnIOControl(shmem_dll->dwContext, IOCTL_NLED_SETDEVICE, (PUCHAR)&nled, sizeof(nled), 0, 0, 0);
_LOG(L"SetVibrate: %d => %d\n", state, ret);
}
DWORD PulseThreadProc(LPVOID lpParameter)
{
GET_PROC_PTR_RZERO(PFN_IOCONTROL, IOControl);
TCHAR* script = 0;
_LOG(L"Entering PulseThread\n");
while (WaitForSingleObject(event_VibratePulse, INFINITE) == WAIT_OBJECT_0)
{
_LOG(L"PulseThread: event\n");
EnterCriticalSection(&shmem_dll->lock);
int i = 0;
int maxlen = sizeof(shmem_dll->szPulseScript)/sizeof(TCHAR);
int len = wcslen(shmem_dll->szPulseScript);
if (len < maxlen)
{
script = new TCHAR[len+1];
wcscpy(script, shmem_dll->szPulseScript);
}
else
{
len = 0;
script = new TCHAR[2];
wcscpy(script, L"");
}
LeaveCriticalSection(&shmem_dll->lock);
if (len < 1)
{
ResetEvent(event_VibratePulse);
SetVibrate(1);
}
while (i < len)
{
if (WaitForSingleObject(event_VibratePulse, 0) != WAIT_OBJECT_0) break;
switch (script[i])
{
case 'v':
{
i++;
int v = FetchIntFromStr(script, len, &i);
SetVibrate(1);
Sleep(v);
SetVibrate(0);
}
break;
case 'w':
{
i++;
int v = FetchIntFromStr(script, len, &i);
Sleep(v);
}
break;
}
i++;
}
}
_LOG(L"Leaving PulseThread\n");
return 0;
}
BOOL ReadPulseScript()
{
HKEY hKey;
BOOL ret = FALSE;
EnterCriticalSection(&shmem_dll->lock);
shmem_dll->szPulseScript[0] = 0;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\HtcExtFun", 0, 0, &hKey) == ERROR_SUCCESS)
{
DWORD vType = 0;
DWORD vSize = sizeof(shmem_dll->szPulseScript);
if (RegQueryValueEx(hKey, L"VibrateScript", 0, &vType, (LPBYTE)&(shmem_dll->szPulseScript), &vSize)==ERROR_SUCCESS)
{
ret = TRUE;
}
RegCloseKey(hKey);
}
LeaveCriticalSection(&shmem_dll->lock);
_LOG(L"PulseScript is %s\n", shmem_dll->szPulseScript);
return ret;
}
DWORD Init(PVOID Context)
{
GET_PROC_PTR_RZERO(PFN_INIT, Init);
return pfnInit(Context);
}
BOOL Deinit(DWORD dwContext)
{
GET_PROC_PTR_RZERO(PFN_DEINIT, Deinit);
return pfnDeinit(dwContext);
}
BOOL IOControl(DWORD dwContext, DWORD Ioctl, PUCHAR pInBuf, DWORD InBufLen, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred)
{
GET_PROC_PTR_RZERO(PFN_IOCONTROL, IOControl);
BOOL ret = FALSE;
if (Ioctl == IOCTL_NLED_SETDEVICE && pInBuf && InBufLen == sizeof(NLED_SETTINGS_INFO))
{
NLED_SETTINGS_INFO *nled = (NLED_SETTINGS_INFO*)pInBuf;
if (nled->LedNum == shmem_dll->nledNum)
{
if (nled->OffOnBlink == 1)
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"System\\State\\Phone", 0, 0, &hKey) == ERROR_SUCCESS)
{
DWORD status = 0;
DWORD vType;
DWORD vSize = sizeof(DWORD);
if (RegQueryValueEx(hKey, L"Status", 0, &vType, (LPBYTE)&status, &vSize)==ERROR_SUCCESS)
{
_LOG(L"Phone status is %08X\n", status);
if ((status & 0x10000) && !(status & 0x20000000))
{
ReadPulseScript();
EnterCriticalSection(&shmem_dll->lock);
shmem_dll->dwContext = dwContext;
LeaveCriticalSection(&shmem_dll->lock);
SetEvent(event_VibratePulse);
ret = TRUE;
}
}
RegCloseKey(hKey);
}
}
if (!ret) ResetEvent(event_VibratePulse);
}
}
if (!ret) ret = pfnIOControl(dwContext, Ioctl, pInBuf, InBufLen, pOutBuf, OutBufLen, pdwBytesTransferred);
return ret;
}
VOID PowerDown(DWORD dwContext)
{
GET_PROC_PTR_RNOTH(PFN_POWERDOWN, PowerDown);
return pfnPowerDown(dwContext);
}
VOID PowerUp(DWORD dwContext)
{
GET_PROC_PTR_RNOTH(PFN_POWERUP, PowerUp);
return pfnPowerUp(dwContext);
}
DWORD Open(DWORD Context, DWORD Access, DWORD ShareMode)
{
GET_PROC_PTR_RZERO(PFN_OPEN, Open);
return pfnOpen(Context, Access, ShareMode);
}
BOOL Close(DWORD dwContext)
{
GET_PROC_PTR_RZERO(PFN_CLOSE, Close);
return pfnClose(dwContext);
}
static bool deleteCriticalSection;
extern "C" HINSTANCE LoadDriver(LPCWSTR lpszFileName);//defined in pkfuncs.h
BOOL NledDrvDllEntry(HANDLE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
BOOL ReturnCode = TRUE;
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
_LOG(L"Process attach\n");
DisableThreadLibraryCalls((HMODULE) hinstDll);
g_hDrvLib = LoadDriver(NLED_DRV_FN);
GET_PROC_PTR_RZERO(PFN_POWERDOWN, PowerDown);
if (g_hDrvLib)
{
event_VibratePulse = CreateEvent(0, TRUE, FALSE, L"nledpx/pulse");
shmem_map = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(SharedMem), L"nledpx/shmem");
if (!shmem_map) ReturnCode = FALSE;
else
{
bool doInit = (GetLastError()!=ERROR_ALREADY_EXISTS);
shmem_dll = (PSharedMem)MapViewOfFile(shmem_map, FILE_MAP_WRITE, 0, 0, 0);
if (!shmem_dll) ReturnCode = FALSE;
else
{
if (doInit)
{
ZeroMemory(shmem_dll, sizeof(SharedMem));
deleteCriticalSection = true;
InitializeCriticalSection(&(shmem_dll->lock));
shmem_dll->nledNum = 1;
CreateThread(0, 0, PulseThreadProc, 0, 0, &(shmem_dll->pulseThreadId));
}
else
deleteCriticalSection = false;
}
}
ReadPulseScript();
}
else
{
ReturnCode = FALSE;
}
break;
case DLL_PROCESS_DETACH:
_LOG(L"Process detach\n");
ReturnCode = FreeLibrary(g_hDrvLib);
if (deleteCriticalSection)
{
DeleteCriticalSection(&(shmem_dll->lock));
PostThreadMessage(shmem_dll->pulseThreadId, WM_QUIT, 0, 0);
}
if (shmem_dll) UnmapViewOfFile(shmem_dll);
if (shmem_map) CloseHandle(shmem_map);
if (event_VibratePulse) CloseHandle(event_VibratePulse);
break;
}
_LOG(L"DllEntry ret: %d\n", ReturnCode);
return ( ReturnCode );
}
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
return NledDrvDllEntry(hinstDLL, dwReason, lpvReserved);
}
#ifdef __cplusplus
}
#endif //ifdef __cplusplus
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -