⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nled-driver.cpp

📁 Windows Mobile NLED driver proxy. Created for customization of incoming call ring vibration. While
💻 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 + -