Przeglądaj źródła

#IQRV #comment [ResourceWatcher] 添加搜狗输入法安装信息的告警

gifur 4 lat temu
rodzic
commit
0fcc31a0b7

+ 3 - 1
Module/mod_ResourceWatcher/CMakeLists.txt

@@ -42,7 +42,8 @@ add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
 if(MSVC)
     set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ws2_32 mbnapi_uuid pdh)
 else()
-    set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_LIBS} libpublicFun)
+    target_link_directories(${MODULE_NAME} PRIVATE ${CONAN_LIB_DIRS_SOGOULIB})
+    set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_LIBS} libpublicFun ${CONAN_LIBS_SOGOULIB})
 endif(MSVC)
 
 target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})  
@@ -51,6 +52,7 @@ target_include_directories(${MODULE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
     ${MODULE_BASE_DIR}/mod_cardswiper
     ${DevHeadPath}
     ${OTHER_LIB_BASE_DIR}/libpublicFun
+    ${CONAN_INCLUDE_DIRS_SOGOULIB}
 )
 
 deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 251 - 0
Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp

@@ -8,6 +8,73 @@
 #include "fileutil.h"
 #include "iniutil.h"
 
+#if defined(RVC_OS_LINUX)
+#include "SogouVersion.h"
+#include <winpr/sysinfo.h>
+#endif //RVC_OS_LINUX
+
+struct SogouRunVersionInfo 
+{
+	CSimpleStringA strInstallDir;
+	CSimpleStringA strVersion;
+	SogouRunVersionInfo():strInstallDir(true),strVersion(true){}
+
+	CSimpleStringA ToString() const {
+		CSimpleStringA result(true);
+		if(!strInstallDir.IsNullOrEmpty()) {
+			result += strInstallDir;
+			result += "#";
+		}
+		if(!strVersion.IsNullOrEmpty()) {
+			result += strVersion;
+		}
+		return result;
+	}
+};
+
+struct SogouInstallStateInfo 
+{
+	DWORD dwInstalledStatus;
+	CSimpleStringA strInstallDate;
+
+	SogouInstallStateInfo():dwInstalledStatus(-1),strInstallDate(true){}
+
+	CSimpleStringA ToString() const {
+		CSimpleStringA result(true);
+		if(!strInstallDate.IsNullOrEmpty()) {
+			result += strInstallDate;
+			result += "#";
+		}
+		result += CSimpleStringA::Format("%u", dwInstalledStatus);
+		return result;
+	}
+
+	CSmallDateTime GetInstallTime() {
+		if(!strInstallDate.IsNullOrEmpty()) {
+			DWORD dwSecsSince1970(0);
+			sscanf_s(strInstallDate.GetData(), "%u", &dwSecsSince1970);
+			dwSecsSince1970 -= 946656000; // 2000-1970
+			return CSmallDateTime(dwSecsSince1970);
+		}
+		return CSmallDateTime::BeginTime;
+	}
+};
+
+struct SogouInstallInfo 
+{
+	SogouInstallStateInfo state;
+	SogouRunVersionInfo program;
+
+	CSimpleStringA Stringfy() const 
+	{
+		return (state.ToString() + "||" + program.ToString());
+	}
+
+	bool IsInstalledSuccess() const {
+		return (state.dwInstalledStatus == 0);
+	}
+};
+
 void ResourceWatcherServiceSession::Handle_Fetch(
     SpReqAnsContext<ResourceWatcherService_Fetch_Req, ResourceWatcherService_Fetch_Ans>::Pointer ctx)
 {
@@ -155,6 +222,190 @@ void ResourceWatcherEntity::GetNetworkInfo(SpReqAnsContext<ResourceWatcherServic
     ctx->Answer(Error_Succeed);
 }
 
+#if defined(RVC_OS_WIN)
+//1: 32bit process running at 64bit platform
+//0: 
+static int Is32R64Platform()
+{
+    static int isWow64 = -1;
+    typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+    if (isWow64 == -1) {
+        BOOL bIsWow64 = FALSE;
+        LPFN_ISWOW64PROCESS fnIsWow64Process =
+            (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
+
+        if (NULL != fnIsWow64Process) {
+            if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
+                Dbg("detect is running with 64bit or not failed: %u", GetLastError());
+                return -1;
+            } else {
+                isWow64 = bIsWow64 ? 1 : 0;
+            }
+        }
+    }
+
+    return isWow64;
+}
+
+static bool GetRegistValue(HKEY hKey, LPCTSTR lpcszParam,
+                           DWORD* pDwValue, CHAR* pSzValue, const DWORD* pDwSizeOfSz)
+{
+    if (pDwValue != NULL) {
+        DWORD dwType = REG_DWORD;
+        DWORD dwValue = 0;
+        DWORD dwSize = sizeof(DWORD);
+        LONG lResult = RegQueryValueExA(hKey, lpcszParam, NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
+        if (lResult == ERROR_SUCCESS) {
+            Dbg("Value of \"%s\": %d", lpcszParam, dwValue);
+            *pDwValue = dwValue;
+            return true;
+
+        } else {
+            Dbg("RegQueryValueEx for \"%s\" error, result=%ld.", lpcszParam, lResult);
+            return false;
+        }
+    } else if (pSzValue != NULL) {
+        DWORD dwType = REG_SZ;
+        DWORD dwSize = MAX_PATH * sizeof(CHAR);
+        TCHAR szValue[MAX_PATH + 1] = { 0 };
+        LONG lResult = RegQueryValueEx(hKey, lpcszParam, NULL, &dwType, (LPBYTE)szValue, &dwSize);
+        if (lResult == ERROR_SUCCESS) {
+            Dbg("Value of \"%s\": %s", lpcszParam, szValue);
+            strcpy_s(pSzValue, *pDwSizeOfSz, szValue);
+            return true;
+        } else {
+            Dbg("RegQueryValueEx for \"InstallTime\" error, result=%ld.", lResult);
+            return false;
+        }
+    }
+    Dbg("invalid param for \"%s\"", lpcszParam);
+    return false;
+}
+
+static LONG GetSogouInstallState(SogouInstallStateInfo& info)
+{
+    HKEY hKey;
+    LONG lResult = -1;
+    DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
+    lResult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\SogouPCIme", 0, dwFlag, &hKey);
+    if (lResult == ERROR_SUCCESS) {
+        DWORD dwValue = (DWORD)-1;
+        const bool res1 = GetRegistValue(hKey, "InstallFlag", &dwValue, NULL, NULL);
+        if (res1) {
+            info.dwInstalledStatus = dwValue;
+        }
+        TCHAR szValue[MAX_PATH + 1] = { 0 };
+        DWORD dwLength = MAX_PATH;
+        //1970 0x83AA7E80
+        const bool res2 = GetRegistValue(hKey, "InstallTime", NULL, szValue, &dwLength);
+        if (res2) {
+            info.strInstallDate = szValue;
+            Dbg("InstallTime: %s", info.GetInstallTime().ToTimeString().GetData());
+        }
+        if (res1 && res2) {
+            lResult = 0;
+        } else {
+            lResult = -1;
+        }
+    } else {
+        Dbg("%s::RegOpenKeyEx error, Result=%ld.", __FUNCTION__, lResult);
+    }
+    RegCloseKey(hKey);
+    return lResult;
+}
+
+static LONG GetSogouExecuteInfo(SogouRunVersionInfo& info, BOOL f32bit = TRUE)
+{
+    HKEY hKey;
+    LONG lResult = -1;
+    PVOID oldValue = NULL;
+    Wow64DisableWow64FsRedirection(&oldValue);
+    DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
+    lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                           f32bit ? "SOFTWARE\\SogouPCIme" : "SOFTWARE\\WOW6432Node\\SogouPCIme", 0, dwFlag, &hKey);
+    if (lResult == ERROR_SUCCESS) {
+        TCHAR szVersion[MAX_PATH + 1] = { 0 }, szDefault[MAX_PATH + 1] = { 0 };
+        DWORD dwLength = MAX_PATH;
+        const bool res1 = GetRegistValue(hKey, "Version", NULL, szVersion, &dwLength);
+        if (res1) info.strVersion = szVersion;
+        const bool res2 = GetRegistValue(hKey, "", NULL, szDefault, &dwLength);
+        if (res2) info.strInstallDir = szDefault;
+        if (res1 && res2) {
+            lResult = 0;
+        } else {
+            lResult = -1;
+        }
+    } else {
+        Dbg("%s::RegOpenKeyEx(32bit=%d) error, Result=%ld.", __FUNCTION__, f32bit, lResult);
+    }
+    RegCloseKey(hKey);
+    Wow64RevertWow64FsRedirection(oldValue);
+    return lResult;
+}
+
+#endif //RVC_OS_WIN
+
+ErrorCodeEnum ResourceWatcherEntity::DoCheckInstallStateJob()
+{
+    LOG_FUNCTION();
+
+    CSmartPointer<IEntityFunction> spFunction = GetFunction();
+    CSmartPointer<IConfigInfo> spConfig;
+    ErrorCodeEnum err = spFunction->OpenConfig(Config_Run, spConfig);
+
+    BOOL fNeedAlarm = TRUE;
+    SogouInstallInfo info;
+
+#if defined(RVC_OS_WIN)
+    GetSogouInstallState(info.state);
+    BOOL is32Bit = Is64BitPlatform() ? FALSE : TRUE;
+    if (ERROR_FILE_NOT_FOUND == GetSogouExecuteInfo(info.program, is32Bit))
+        GetSogouExecuteInfo(info.program, !is32Bit);
+#else
+    info.state.dwInstalledStatus = Sogou_GetInstallStatus();
+    info.state.strInstallDate = Sogou_GetInstallTime();
+    info.program.strInstallDir = Sogou_GetInstallPath();
+    info.program.strVersion = Sogou_GetVersion();
+    Dbg("%d, %s, %s, %s", info.state.dwInstalledStatus, info.state.strInstallDate.GetData(), info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
+#endif //RVC_OS_WIN
+
+    CSimpleStringA strLastRecord(true);
+    err = spConfig->ReadConfigValue("SogouInput", "LastInstalledRecord", strLastRecord);
+    if (strLastRecord.IsNullOrEmpty() || info.Stringfy().Compare(strLastRecord) != 0) {
+        spConfig->WriteConfigValue("SogouInput", "LastInstalledRecord", info.Stringfy());
+        fNeedAlarm = TRUE;
+    } else {
+        //Report info per day.
+        int nLastRecordTime = 0;
+        err = spConfig->ReadConfigValueInt("SogouInput", "LastReportTime", nLastRecordTime);
+        SYSTEMTIME stTaskTime = CSmallDateTime(nLastRecordTime).ToSystemTime();
+        Dbg("Last Sogou install check time: %04d-%02d-%02d %02d:%02d:%02d",
+            stTaskTime.wYear, stTaskTime.wMonth, stTaskTime.wDay,
+            stTaskTime.wHour, stTaskTime.wMinute, stTaskTime.wSecond);
+        SYSTEMTIME stNow = {};
+        GetLocalTime(&stNow);
+        if (nLastRecordTime > 0 && stTaskTime.wYear == stNow.wYear
+            && stTaskTime.wMonth == stNow.wMonth && stTaskTime.wDay == stNow.wDay) {
+            //The Same Day
+            fNeedAlarm = FALSE;
+        } else {
+            fNeedAlarm = TRUE;
+        }
+    }
+
+    if (fNeedAlarm) {
+        const DWORD dwUserCode = info.IsInstalledSuccess() ? LOG_ERR_SOGOU_INPUT_INSTALLED : LOG_ERR_SOGOU_INPUT_NOTINSTALLED;
+        LogWarn(Severity_Middle, Error_DataCheck, dwUserCode, info.Stringfy());
+        spConfig->WriteConfigValue("SogouInput", "LastReportTime",
+                                   CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow()));
+    } else {
+        Dbg("Do not Report.");
+    }
+
+    return Error_Succeed;
+}
+
+
 
 SP_BEGIN_ENTITY_MAP()
 SP_ENTITY(ResourceWatcherEntity)

+ 39 - 5
Module/mod_ResourceWatcher/mod_ResourceWatcher.h

@@ -6,6 +6,10 @@
 
 class ResourceWatcherEntity;
 
+#define ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE 1
+#define ENT_TIMERINTERVAL_CHECK_SOGOU_INPUT_INSTALLED_STATE 60 * 1000
+
+
 class ResourceWatcherServiceSession : public ResourceWatcherService_ServerSessionBase
 {
 public:
@@ -37,7 +41,7 @@ private:
 	ResourceWatcherEntity* m_pEntity;
 };
 
-class ResourceWatcherEntity : public CEntityBase, public IBroadcastListener
+class ResourceWatcherEntity : public CEntityBase, public IBroadcastListener, public ITimerListener
 {
 public:
 	ResourceWatcherEntity() {}
@@ -67,7 +71,9 @@ public:
             if (!StaticInfo.strMachineType.Compare("RVC.Pad", true)) {
                 errorCode = spEntityFunction->SubscribeBroadcast("CardSwiper", NULL, this, m_uiCardSwiperStatusListener);
                 if (errorCode != Error_Succeed) {
-                    LOG_TRACE("Subscribe CardSwiper evt failed 0x%x");
+                    LOG_TRACE("Subscribe CardSwiper evt failed 0x%x", errorCode);
+				pTransactionContext->SendAnswer(errorCode);
+				return;
                 }
                 Dbg("SubScribe CardSwiper status broadcast suc.");
             }
@@ -79,12 +85,16 @@ public:
 	void OnStarted()
 	{
 		m_fsm.AfterInit();
+		CSmartPointer<IEntityFunction> spEntityFunction = GetFunction();
+		spEntityFunction->SetTimer(ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE,
+			this, ENT_TIMERINTERVAL_CHECK_SOGOU_INPUT_INSTALLED_STATE);
 	}
 
+
 	/*ignore*/
 	virtual void OnPrePause(CSmartPointer<ITransactionContext> pTransactionContext)
 	{
-		//m_fsm.TryToConnect();
+		OnTimeout(ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE);
 		pTransactionContext->SendAnswer(Error_Succeed);
 	}
 
@@ -183,8 +193,7 @@ public:
 #endif //_MSC_VER
 
 private:
-		void OnCardSwiperConnectStatus(const char *pszEntityName, DWORD dwMessageId, 
-			DWORD dwMessageSignature, CardSwiper::ConnectStatus &evt)
+		void OnCardSwiperConnectStatus(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, CardSwiper::ConnectStatus &evt)
 		{
 			Dbg("OnCardSwiperConnectStatus %d", evt.status);
 			QueryCardSwiper cardswiperStatus;
@@ -193,6 +202,31 @@ private:
 			SpSendBroadcast(GetFunction(), SP_MSG_OF(QueryCardSwiper), SP_MSG_SIG_OF(QueryCardSwiper),
 				cardswiperStatus);
 		}
+		ErrorCodeEnum DoCheckInstallStateJob();
+
+		void OnTimeout(DWORD dwTimerID) 
+		{
+			if(dwTimerID == ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE) {
+
+				CSimpleStringA strState;
+				auto err = GetFunction()->GetSysVar("UIState",strState);
+
+				if(TRUE || err == Error_Succeed && strState == "M"){
+					Dbg("to check Sogou input install state...");
+					if(Error_Succeed == DoCheckInstallStateJob()) {
+						GetFunction()->KillTimer(ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE);
+					}
+
+				} else {
+
+					Dbg("Get UIState result: %d, %s", err, strState.GetData());
+				}
+
+			} else {
+
+				Dbg("Unkonwn timer id: %u", dwTimerID);
+			}
+		}
 
 private:
 	ResourceWatcherFSM m_fsm;

+ 4 - 1
addin/cmake/DependencyConanFiles.cmake

@@ -72,7 +72,10 @@ else()
 			#libpictureplayer libvideorender
 			SDL2/2.0.12@LR04.02_ThirdParty/dynamic
 			#mod_screenshot
-			libX11/1.6@LR04.02_ThirdParty/testing)
+			libX11/1.6@LR04.02_ThirdParty/testing
+			#mod_resourceWatcher
+			sogoulib/2021.1008.01@LR04.02_VendorLib/testing
+			)
 
 	if(PACK_AS_DEB_PKG)
 		list(APPEND CONAN_CURPLATFORM_LIB_NAMES cefclient_const/1.0@LR04.02_ThirdParty/testing)