// MemMapProxyLib.cpp
//
///////////////////////////////////////////////////////////////////////////////
/**
* @author Tomer Petel, based on MemMapProxyLib code from Stanely Wang
* @version 1.0
*/
#include <windows.h>
#include <tchar.h>
#include <process.h>
#include "StandByDetector.h"
// thread id
UINT uThreadId;
// cache for the JNIEnv* pointer
JNIEnv* g_pEnv = NULL;
// cache for the JavaVM* pointer
JavaVM* g_pJvm = NULL;
// cache for the a generic pointer
jobject g_jobj = NULL;
//do we want to allow the standby?:
jboolean g_allowStandby=true;
// cache for the instance handle
HINSTANCE hInstance;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void RegisterWindowClass();
unsigned WINAPI CreateWndThread(LPVOID);
void Callback();
void ErrorHandler(LPCTSTR);
BOOL APIENTRY DllMain(HINSTANCE hinstDll, DWORD dwReasion, LPVOID lpReserved) {
if(dwReasion == DLL_PROCESS_ATTACH) {
hInstance = hinstDll;
RegisterWindowClass();
}
return TRUE;
}
void RegisterWindowClass() {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = _T("Stand By Detector window");
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
if (Msg ==WM_POWERBROADCAST)
{
if (wParam==PBT_APMQUERYSUSPEND)
{
Callback();
return (g_allowStandby ? TRUE:BROADCAST_QUERY_DENY);
}
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
unsigned WINAPI CreateWndThread(LPVOID pThreadParam) {
HANDLE hWnd = CreateWindow(_T("Stand By Detector window"), NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if(hWnd == NULL) {
MessageBox(NULL, _T("Stand By Detector:Failed create Stand By Detecor window"), "Failed", MB_OK | MB_ICONERROR);
return 0;
}
jint nSize = 1;
jint nVms;
jint nStatus = JNI_GetCreatedJavaVMs(&g_pJvm, nSize, &nVms);
if(nStatus == 0) {
nStatus = g_pJvm->AttachCurrentThread(reinterpret_cast<void**>(&g_pEnv), NULL);
if(nStatus != 0) ErrorHandler(_T("Stand By Detector:Can not attach thread"));
}
else {
ErrorHandler(_T("Stand By Detector:Can not get the jvm"));
}
MSG Msg;
while(GetMessage(&Msg, 0, 0, 0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
JNIEXPORT jboolean JNICALL Java_com_ha_common_windows_StandByDetector_init
(JNIEnv * pEnv, jobject jobj) {
HANDLE hThread;
hThread = (HANDLE)_beginthreadex(NULL, 0, &CreateWndThread, NULL, 0, &uThreadId);
if(!hThread)
{
MessageBox(NULL, _T("Stand By Detector:Fail creating thread"), NULL, MB_OK);
return false;
}
g_jobj = pEnv->NewGlobalRef(jobj);
return true;
}
JNIEXPORT void JNICALL Java_com_ha_common_windows_StandByDetector_destroy
(JNIEnv * pEnv, jobject) {
if(g_jobj) pEnv->DeleteGlobalRef(g_jobj);
PostThreadMessage(uThreadId, WM_QUIT, 0, 0);
}
JNIEXPORT void JNICALL Java_com_ha_common_windows_StandByDetector_setAllowStandby
(JNIEnv * pEnv, jobject jobj, jboolean allow) {
g_allowStandby=allow;
}
void Callback() {
if(g_pEnv == NULL || g_jobj == NULL) return;
jclass cls = g_pEnv->GetObjectClass(g_jobj);
jmethodID mid = g_pEnv->GetMethodID(cls, "fireStandByRequested", "()V");
g_pEnv->CallVoidMethod(g_jobj, mid, NULL);
}
void ErrorHandler(LPCTSTR pszErrorMessage) {
MessageBox(NULL, pszErrorMessage, _T("Error"), MB_OK | MB_ICONERROR);
}