Kaynağa Gözat

Merge branch 'cjl_BrowserCacheClean_003st1' into feature_unionlog

陈良瑜80374463 3 yıl önce
ebeveyn
işleme
4118b7704f

+ 10 - 0
Module/mod_ResourceWatcher/CMakeLists.txt

@@ -18,6 +18,8 @@ set(${MODULE_PREFIX}_SRCS
     EventLogW.cpp
     mod_ResourceWatcher.cpp
     ResourceWatcherFSM.cpp
+    XUnZipZilb.cpp
+	XUnZipZilb.h
 )
 
 else()
@@ -34,6 +36,8 @@ set(${MODULE_PREFIX}_SRCS
 
     mod_ResourceWatcher.cpp
     ResourceWatcherFSM.cpp
+    XUnZipZilb.cpp
+	XUnZipZilb.h
 )
 
 endif(MSVC)
@@ -56,6 +60,12 @@ target_include_directories(${MODULE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
     ${OTHER_LIB_BASE_DIR}/libpublicFun
     ${CONAN_INCLUDE_DIRS_SOGOULIB}
     ${OTHER_LIB_BASE_DIR}/libRestfulFunc
+    ${CONAN_INCLUDE_DIRS_ZLIB}
 )
+target_link_directories(${MODULE_NAME} PRIVATE ${CONAN_LIB_DIRS_ZLIB})
 
+# 添加实体需要依赖的其他共享库(包括系统库):连接器包含的包
+set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_ALL_LIBS} ${CONAN_PKG_LIBS_ZLIB})
+
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})  
 deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 36 - 0
Module/mod_ResourceWatcher/ResourceWatcher.xml

@@ -231,6 +231,8 @@
       <req>
         <!---1: 搜狗输入法-->
         <param name="mode" type="int" />
+		<param name="reserved1" type="int" />
+		<param name="reserved2" type="int" />
       </req>
       <res>
         <!--1:已安装-->
@@ -247,6 +249,8 @@
       <req>
         <!---1: 搜狗输入法-->
         <param name="type" type="int" />
+		<param name="reserved1" type="int" />
+		<param name="reserved2" type="int" />
       </req>
       <res>
         <param name="result" type="int" />
@@ -303,6 +307,38 @@
       </res>
     </twoway>
 
+		<!--第三方软件手工启动接口-->
+		<twoway  name="RestartThirdPartyProgram" overlap="true">
+			<req>
+				<!---1: 搜狗输入法-->
+				<param name="type" type="int" />
+				<param name="reserved1" type="int" />
+				<param name="reserved2" type="int" />
+			</req>
+			<res>
+				<param name="result" type="int" />
+				<param name="msg" type="string"/>
+				<param name="reserverd1" type="string"/>
+				<param name="reserverd2" type="string"/>
+			</res>
+		</twoway>
+
+		<!--第三方软件进程检测接口-->
+		<twoway  name="ProcessDetectThirdPartyProgram" overlap="true">
+			<req>
+				<!---1: 搜狗输入法-->
+				<param name="type" type="int" />
+				<param name="reserved1" type="int" />
+				<param name="reserved2" type="int" />
+			</req>
+			<res>
+				<param name="result" type="int" />
+				<param name="msg" type="string"/>
+				<param name="reserverd1" type="string"/>
+				<param name="reserverd2" type="string"/>
+			</res>
+		</twoway>
+
 		<!--文件清理接口-->
 		<twoway  name="FilesClean" overlap="true">
 			<req>

+ 0 - 4
Module/mod_ResourceWatcher/ResourceWatcherFSM.cpp

@@ -4373,10 +4373,6 @@ void ResourceWatcherFSM::GetMainLinkStatus()
     {
         Dbg("Main Link disconnected [%s].", mainLink);
     }
-    else
-    {
-        Dbg("Main Link is connected [%s].", mainLink);
-    }
     
     mainDetect.mainLinkStatus = curStatus;
     mainDetect.reversed1 = 0;

+ 58 - 0
Module/mod_ResourceWatcher/ResourceWatcher_client_g.h

@@ -555,6 +555,64 @@ public:
 		return Error;
 	}
 
+	ErrorCodeEnum RestartThirdPartyProgram(ResourceWatcherService_RestartThirdPartyProgram_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(ResourceWatcherService_Method_RestartThirdPartyProgram, ResourceWatcherService_MethodSignature_RestartThirdPartyProgram, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum RestartThirdPartyProgram(ResourceWatcherService_RestartThirdPartyProgram_Req &Req, ResourceWatcherService_RestartThirdPartyProgram_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = RestartThirdPartyProgram(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum RestartThirdPartyProgram(ResourceWatcherService_RestartThirdPartyProgram_Req &Req, ResourceWatcherService_RestartThirdPartyProgram_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = RestartThirdPartyProgram(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum ProcessDetectThirdPartyProgram(ResourceWatcherService_ProcessDetectThirdPartyProgram_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(ResourceWatcherService_Method_ProcessDetectThirdPartyProgram, ResourceWatcherService_MethodSignature_ProcessDetectThirdPartyProgram, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum ProcessDetectThirdPartyProgram(ResourceWatcherService_ProcessDetectThirdPartyProgram_Req &Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = ProcessDetectThirdPartyProgram(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum ProcessDetectThirdPartyProgram(ResourceWatcherService_ProcessDetectThirdPartyProgram_Req &Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = ProcessDetectThirdPartyProgram(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
 	ErrorCodeEnum FilesClean(ResourceWatcherService_FilesClean_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
 	{
 		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();

+ 64 - 2
Module/mod_ResourceWatcher/ResourceWatcher_def_g.h

@@ -28,6 +28,8 @@ namespace ResourceWatcher {
 #define ResourceWatcherService_Method_GetTerminalVersionList 12
 #define ResourceWatcherService_Method_ManipulateVersion 13
 #define ResourceWatcherService_Method_UninstallThirdPartyProgram 14
+#define ResourceWatcherService_Method_RestartThirdPartyProgram 15
+#define ResourceWatcherService_Method_ProcessDetectThirdPartyProgram 16
 #define ResourceWatcherService_Method_FilesClean 17
 
 #define ResourceWatcherService_MethodSignature_Fetch -1944912560
@@ -46,6 +48,8 @@ namespace ResourceWatcher {
 #define ResourceWatcherService_MethodSignature_GetTerminalVersionList -504582702
 #define ResourceWatcherService_MethodSignature_ManipulateVersion -313717631
 #define ResourceWatcherService_MethodSignature_UninstallThirdPartyProgram -2137706699
+#define ResourceWatcherService_MethodSignature_RestartThirdPartyProgram -534704262
+#define ResourceWatcherService_MethodSignature_ProcessDetectThirdPartyProgram -1692430185
 #define ResourceWatcherService_MethodSignature_FilesClean 624348486
 
 struct ResourceWatcherService_Fetch_Req
@@ -352,10 +356,12 @@ struct ResourceWatcherService_GetNetworkInfo_Ans
 struct ResourceWatcherService_GetThirdPartyInstallState_Req
 {
 	int mode;
+	int reserved1;
+	int reserved2;
 
 	void Serialize(SpBuffer &Buf)
 	{
-		auto & buf = Buf & mode;
+		auto & buf = Buf & mode & reserved1 & reserved2;
 	}
 
 };
@@ -380,10 +386,12 @@ struct ResourceWatcherService_GetThirdPartyInstallState_Ans
 struct ResourceWatcherService_InstallThirdPartyProgram_Req
 {
 	int type;
+	int reserved1;
+	int reserved2;
 
 	void Serialize(SpBuffer &Buf)
 	{
-		auto & buf = Buf & type;
+		auto & buf = Buf & type & reserved1 & reserved2;
 	}
 
 };
@@ -489,6 +497,60 @@ struct ResourceWatcherService_UninstallThirdPartyProgram_Ans
 
 };
 
+struct ResourceWatcherService_RestartThirdPartyProgram_Req
+{
+	int type;
+	int reserved1;
+	int reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & type & reserved1 & reserved2;
+	}
+
+};
+
+struct ResourceWatcherService_RestartThirdPartyProgram_Ans
+{
+	int result;
+	CSimpleStringA msg;
+	CSimpleStringA reserverd1;
+	CSimpleStringA reserverd2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result & msg & reserverd1 & reserverd2;
+	}
+
+};
+
+struct ResourceWatcherService_ProcessDetectThirdPartyProgram_Req
+{
+	int type;
+	int reserved1;
+	int reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & type & reserved1 & reserved2;
+	}
+
+};
+
+struct ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans
+{
+	int result;
+	CSimpleStringA msg;
+	CSimpleStringA reserverd1;
+	CSimpleStringA reserverd2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result & msg & reserverd1 & reserverd2;
+	}
+
+};
+
 struct ResourceWatcherService_FilesClean_Req
 {
 	int type;

+ 50 - 0
Module/mod_ResourceWatcher/ResourceWatcher_server_g.h

@@ -142,6 +142,20 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case ResourceWatcherService_Method_RestartThirdPartyProgram:
+			if (dwSignature == ResourceWatcherService_MethodSignature_RestartThirdPartyProgram) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ResourceWatcherService_Method_ProcessDetectThirdPartyProgram:
+			if (dwSignature == ResourceWatcherService_MethodSignature_ProcessDetectThirdPartyProgram) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		case ResourceWatcherService_Method_FilesClean:
 			if (dwSignature == ResourceWatcherService_MethodSignature_FilesClean) {
 				bOverlap = true;
@@ -240,6 +254,16 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case ResourceWatcherService_Method_RestartThirdPartyProgram:
+			if (dwSignature != ResourceWatcherService_MethodSignature_RestartThirdPartyProgram) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ResourceWatcherService_Method_ProcessDetectThirdPartyProgram:
+			if (dwSignature != ResourceWatcherService_MethodSignature_ProcessDetectThirdPartyProgram) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		case ResourceWatcherService_Method_FilesClean:
 			if (dwSignature != ResourceWatcherService_MethodSignature_FilesClean) {
 				Error = Error_MethodSignatureFailed;
@@ -332,6 +356,16 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_RestartThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req, ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_ProcessDetectThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void Handle_FilesClean(SpReqAnsContext<ResourceWatcherService_FilesClean_Req, ResourceWatcherService_FilesClean_Ans>::Pointer ctx)
 	{
 	/// override by user
@@ -497,6 +531,22 @@ public:
 						Handle_UninstallThirdPartyProgram(ctx);
 					}
 					break;
+				case ResourceWatcherService_Method_RestartThirdPartyProgram:
+					{
+						SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req,ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req,ResourceWatcherService_RestartThirdPartyProgram_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_RestartThirdPartyProgram(ctx);
+					}
+					break;
+				case ResourceWatcherService_Method_ProcessDetectThirdPartyProgram:
+					{
+						SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req,ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req,ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_ProcessDetectThirdPartyProgram(ctx);
+					}
+					break;
 				case ResourceWatcherService_Method_FilesClean:
 					{
 						SpReqAnsContext<ResourceWatcherService_FilesClean_Req,ResourceWatcherService_FilesClean_Ans>::Pointer ctx;

+ 699 - 0
Module/mod_ResourceWatcher/XUnZipZilb.cpp

@@ -0,0 +1,699 @@
+#include "XUnZipZilb.h"
+#include "libtoolkit/path.h"
+#include "fileutil.h"
+#include <string.h>
+#ifdef RVC_OS_WIN
+#else
+#include <iconv.h>
+#include <sys/stat.h>
+#include <errno.h>
+#endif // RVC_OS_WIN
+#define ZIP_ZILP_MAX_FILENAME 512
+#define ZIP_ZILP_READ_SIZE 4096
+
+#define ZIP_ZILP_HOST_SYSTEM(VERSION_MADEBY)  ((uint8_t)(VERSION_MADEBY >> 8))
+#define ZIP_ZILP_HOST_SYSTEM_MSDOS            (0)
+#define ZIP_ZILP_HOST_SYSTEM_UNIX             (3)
+#define ZIP_ZILP_HOST_SYSTEM_WINDOWS_NTFS     (10)
+#define ZIP_ZILP_HOST_SYSTEM_RISCOS           (13)
+#define ZIP_ZILP_HOST_SYSTEM_OSX_DARWIN       (19)
+
+int UnZipToDir(string zipFileName, string destDirPath)
+{
+	Dbg("zipFileName %s destDirPath %s", zipFileName.c_str(), destDirPath.c_str());
+	unzFile zfile = unzOpen(zipFileName.c_str());
+	if (zfile == NULL)
+	{
+		Dbg("could open zipFile (%s)", zipFileName.c_str());
+		return -1;
+	}
+	//create directory
+	if (!ExistsDirA(destDirPath.c_str())) {
+		if (!CreateDirA(destDirPath.c_str(), true)) {
+			Dbg("create temp unzip root dir fail: %s",destDirPath.c_str());
+			return -1;
+		}
+	}
+	unz_global_info global_info;
+	if (unzGetGlobalInfo(zfile, &global_info) != UNZ_OK)
+	{
+		Dbg("could not read file global info (%s)", zipFileName.c_str());
+		unzClose(zfile);
+		return -1;
+	}
+	for (int i = 0; i < global_info.number_entry; i++) {
+		if (unZipCurrentFile(zfile, destDirPath) != UNZ_OK) {
+			Dbg("unzip fail %s", zipFileName.c_str());
+			unzClose(zfile);
+			return -1;
+		}
+		if ((i + 1) < global_info.number_entry) {
+			int ret = unzGoToNextFile(zfile);
+			if (ret != UNZ_OK) {
+				Dbg("error %d with zipfile in unzGoToNextFile", ret);
+				unzClose(zfile);
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+//int unZipCurrentFile(zipFile zf, string destDirPath)
+//{
+//	unz_file_info file_info;
+//	char zipFilename[ZIP_ZILP_MAX_FILENAME];
+//	memset(zipFilename, 0, ZIP_ZILP_MAX_FILENAME);
+//	
+//	string newFileName = "";
+//	bool isDir = false;
+//	if (unzGetCurrentFileInfo(zf, &file_info, zipFilename, ZIP_ZILP_MAX_FILENAME, NULL, 0, NULL, 0) != UNZ_OK)
+//	{
+//		Dbg("could not read file info");
+//		return -1;
+//	}
+//#ifdef RVC_OS_WIN
+//	if (is_str_utf8(zipFilename)) {
+//		//Dbg("file name is UTF8");
+//		newFileName = utf8_to_gbk(zipFilename);
+//	}
+//	else {
+//		//Dbg("file name is GBK");
+//		newFileName = zipFilename;
+//	}
+//#else
+//	if (!is_str_utf8(zipFilename)) {
+//		//Dbg("file name is GBK");
+//		//newFileName = gbk_to_utf8(zipFilename);
+//		unsigned char* tempName = utf8_string_create((const char*)zipFilename);
+//		if (tempName == NULL) {
+//			Dbg("get utf8 str is null");
+//			return -1;
+//		}
+//		newFileName = (const char*)tempName;
+//		free(tempName);
+//	}
+//	else {
+//		//Dbg("file name is UTF8");
+//		newFileName = zipFilename;
+//	}
+//#endif // RVC_OS_WIN
+//	Dbg("unZipCurrentFile newFileName %s", newFileName.c_str());
+//	string filestr = newFileName;
+//	//判断是文件还是文件夹
+//
+//	if (filestr.substr(filestr.length() - 1, 1) == "/") {
+//		isDir = true;
+//	}
+//
+//	if (isDir)
+//	{   //创建文件夹
+//		string dirPath = destDirPath + SPLIT_SLASH_STR + newFileName;
+//		Dbg("creating directory: %s", dirPath.c_str());
+//		if (!CreateDirA(dirPath.c_str(), true))
+//		{
+//			Dbg("creating directory fail: dirPath(%s) zipFileName(%s)", dirPath.c_str(), newFileName.c_str());
+//			return -1;
+//		}
+//	}
+//	else
+//	{   //打开zip里面的文件
+//		string fileNamePath = destDirPath + SPLIT_SLASH_STR + newFileName;
+//		Dbg("creating file:%s", fileNamePath.c_str());
+//
+//		//先创建文件的父文件夹
+//		int pos = fileNamePath.find_last_of(SPLIT_SLASH);
+//		string newFileDirPath(fileNamePath.substr(0, pos));
+//		//Dbg("creating dir:%s", newFileDirPath.c_str());
+//		if (!CreateDirA(newFileDirPath.c_str(), true)) {
+//			Dbg("creating zip file dir fail: dirPath(%s)", newFileDirPath.c_str());
+//			return -1;
+//		}
+//
+//		if (unzOpenCurrentFile(zf) != UNZ_OK)
+//		{
+//			Dbg("could not open zip file ,%s", newFileName);
+//			return -1;
+//		}
+//		// Open a file to write out the data.
+//		FILE* out = fopen(fileNamePath.c_str(), "wb");
+//
+//		if (out == NULL)
+//		{
+//			Dbg("could not open destination file, %s", fileNamePath.c_str());
+//			unzCloseCurrentFile(zf);
+//			return -1;
+//		}
+//
+//		int err = UNZ_OK;
+//		unsigned char * read_buffer= new unsigned char[ZIP_ZILP_READ_SIZE];
+//		memset(read_buffer, 0, ZIP_ZILP_READ_SIZE);
+//		do
+//		{
+//			err = unzReadCurrentFile(zf, read_buffer, ZIP_ZILP_READ_SIZE);
+//			if (err < 0)
+//			{
+//				Dbg("error %d with zipfile in unzReadCurrentFile", err);
+//				break;
+//			}
+//
+//			// Write data to file.
+//			if (err > 0)
+//			{
+//				if (fwrite(read_buffer, err, 1, out) != 1) {
+//					Dbg("error in writing extracted file");
+//					err = UNZ_ERRNO;
+//					break;
+//				}
+//			}
+//		} while (err > 0);
+//
+//		delete[] read_buffer;//删除临时对象
+//
+//		if (out!=NULL) {
+//			if (fclose(out)!=0) {
+//				Dbg("fclose new file from zip fail, %s", fileNamePath.c_str());
+//				unzCloseCurrentFile(zf);
+//				return -1;
+//			}
+//		}
+//
+//		if (err == UNZ_OK) {
+//			//正常结束
+//			err = unzCloseCurrentFile(zf);
+//			if (err != UNZ_OK) {
+//				Dbg("error %d with zipfile in unzCloseCurrentFile", err);
+//				return -1;
+//			}
+//			if (changeUnZipFileAtt(fileNamePath.c_str())!=0) {
+//				return -1;
+//			}
+//			return 0;
+//		}
+//		else {
+//			//异常结束
+//			unzCloseCurrentFile(zf); /* don't lose the error */
+//			return -1;
+//		}
+//	}
+//	return 0;
+//}
+
+int unZipCurrentFile(zipFile zf, string destDirPath)
+{
+	unz_file_info file_info;
+	char zipFilename[ZIP_ZILP_MAX_FILENAME];
+	memset(zipFilename, 0, ZIP_ZILP_MAX_FILENAME);
+	
+	string newFileName = "";
+	bool isDir = false;
+	if (unzGetCurrentFileInfo(zf, &file_info, zipFilename, ZIP_ZILP_MAX_FILENAME, NULL, 0, NULL, 0) != UNZ_OK)
+	{
+		Dbg("could not read file info");
+		return -1;
+	}
+	//转码
+#ifdef RVC_OS_WIN
+	if (is_str_utf8(zipFilename)) {
+		//Dbg("file name is UTF8");
+		newFileName = utf8_to_gbk(zipFilename);
+	}
+	else {
+		//Dbg("file name is GBK");
+		newFileName = zipFilename;
+	}
+#else
+	if (!is_str_utf8(zipFilename)) {
+		//Dbg("file name is GBK");
+		//newFileName = gbk_to_utf8(zipFilename);
+		unsigned char* tempName = utf8_string_create((const char*)zipFilename);
+		if (tempName == NULL) {
+			Dbg("get utf8 str is null");
+			return -1;
+		}
+		newFileName = (const char*)tempName;
+		free(tempName);
+	}
+	else {
+		//Dbg("file name is UTF8");
+		newFileName = zipFilename;
+	}
+#endif // RVC_OS_WIN
+
+	Dbg("unZipCurrentFile newFileName %s", newFileName.c_str());
+	string filestr = newFileName;
+	//判断是文件还是文件夹
+
+	if (filestr.substr(filestr.length() - 1, 1) == "/") {
+		isDir = true;
+	}
+
+	//替换newFileName字符串中的'/'到对应平台路径
+#ifdef RVC_OS_WIN
+	size_t fi = newFileName.find("/");//判断是否有"/"
+	if (fi != string::npos) {
+		if (!replacePlace(newFileName, "/", "\\")) {
+			Dbg("replaceInPlace zip fileName fail:zipFileName(%s)", newFileName.c_str());
+			return -1;
+		}
+	}
+#else
+	size_t fi = newFileName.find("\\");//判断是否有"\\"
+	if (fi != string::npos) {
+		if (!replacePlace(newFileName, "\\", "/")) {
+			Dbg("replaceInPlace zip fileName fail:zipFileName(%s)", newFileName.c_str());
+			return -1;
+		}
+	}
+#endif // DEBUG
+
+	if (isDir)
+	{   //创建文件夹
+		string dirPath = destDirPath + SPLIT_SLASH_STR + newFileName;
+		Dbg("creating directory: %s", dirPath.c_str());
+		if (!CreateDirA(dirPath.c_str(), true))
+		{
+			Dbg("creating directory fail: dirPath(%s) zipFileName(%s)", dirPath.c_str(), newFileName.c_str());
+			return -1;
+		}
+	}
+	else
+	{   //打开zip里面的文件
+		string fileNamePath = destDirPath + SPLIT_SLASH_STR + newFileName;
+		Dbg("creating file:%s", fileNamePath.c_str());
+
+		//先创建文件的父文件夹
+		int pos = fileNamePath.find_last_of(SPLIT_SLASH);
+		string newFileDirPath(fileNamePath.substr(0, pos));
+
+		if (!CreateDirA(newFileDirPath.c_str(), true)) {
+			Dbg("creating zip file dir fail: dirPath(%s)", newFileDirPath.c_str());
+			return -1;
+		}
+
+		if (unzOpenCurrentFile(zf) != UNZ_OK)
+		{
+			Dbg("could not open zip file ,%s", newFileName);
+			return -1;
+		}
+
+		bool isSymlink = false;
+#ifdef RVC_OS_WIN
+		isSymlink = false;//windows 默认不创建链接文件
+		//if (entry_is_symlink(file_info) == 0) {
+		//	isSymlink = true;
+		//	printf("entry is link file, %s\n", newFileName.c_str());
+		//}
+#else
+		isSymlink = false;//linux 默认不创建链接文件
+		//if (entry_is_symlink(file_info) == 0) {
+		//	isSymlink = true;
+		//	Dbg("entry is link file, %s\n", newFileName.c_str());
+		//}
+#endif
+
+		// Open a file to write out the data.
+		int saveSucc = 0;
+
+		if (isSymlink) {
+			//链接文件
+			saveSucc = saveSymlink(zf, fileNamePath);
+		}
+		else {
+			//一般文件
+			saveSucc = saveNormalFile(zf, fileNamePath);
+		}
+
+		if (saveSucc == 0) {
+			//正常结束
+			int err = unzCloseCurrentFile(zf);
+			if (err != UNZ_OK) {
+				Dbg("zipfile  unzCloseCurrentFile is %d", err);
+				return -1;
+			}
+			//文件赋权
+			if (changeUnZipFileAtt(fileNamePath.c_str()) != 0) {
+				return -1;
+			}
+			return 0;
+		}
+		else {
+			//保存异常
+			unzCloseCurrentFile(zf); /* don't lose the error */
+			return -1;
+		}
+	}
+	return 0;
+}
+
+bool is_str_utf8(const char* str)
+{
+	unsigned int nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节  
+	unsigned char chr = *str;
+	bool bAllAscii = true;
+
+	for (unsigned int i = 0; str[i] != '\0'; ++i) {
+		chr = *(str + i);
+		//判断是否ASCII编码,如果不是,说明有可能是UTF8,ASCII用7位编码,最高位标记为0,0xxxxxxx 
+		if (nBytes == 0 && (chr & 0x80) != 0) {
+			bAllAscii = false;
+		}
+
+		if (nBytes == 0) {
+			//如果不是ASCII码,应该是多字节符,计算字节数  
+			if (chr >= 0x80) {
+
+				if (chr >= 0xFC && chr <= 0xFD) {
+					nBytes = 6;
+				}
+				else if (chr >= 0xF8) {
+					nBytes = 5;
+				}
+				else if (chr >= 0xF0) {
+					nBytes = 4;
+				}
+				else if (chr >= 0xE0) {
+					nBytes = 3;
+				}
+				else if (chr >= 0xC0) {
+					nBytes = 2;
+				}
+				else {
+					return false;
+				}
+
+				nBytes--;
+			}
+		}
+		else {
+			//多字节符的非首字节,应为 10xxxxxx 
+			if ((chr & 0xC0) != 0x80) {
+				return false;
+			}
+			//减到为零为止
+			nBytes--;
+		}
+	}
+
+	//违返UTF8编码规则 
+	if (nBytes != 0) {
+		return false;
+	}
+
+	if (bAllAscii) { //如果全部都是ASCII, 也是UTF8
+		return true;
+	}
+
+	return true;
+}
+
+int changeUnZipFileAtt(const char* path)
+{
+#ifdef RVC_OS_WIN
+	return 0;//windows 默认返回成功
+#else
+	struct stat attr_of_del;
+	if (lstat(path, &attr_of_del) == 0)
+	{
+		//修改为775属性
+		mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
+		if (chmod(path, f_attrib) != 0)
+		{
+			Dbg("set file attribute is fail,errno=%d, file=%s", errno, path);
+			return -1;
+		}
+		return 0;
+	}
+	else {
+		Dbg("get file attribute is fail,errno=%d, file=%s", errno, path);
+		return -1;
+	}
+#endif
+}
+
+bool replacePlace(string& str, string const& replaceThis, string const& withThis)
+{
+	bool replaced = false;
+	size_t i = str.find(replaceThis);
+	while (i != string::npos) {
+		replaced = true;
+		str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
+		if (i < str.size() - withThis.size())
+			i = str.find(replaceThis, i + withThis.size());
+		else
+			i = string::npos;
+	}
+	return replaced;
+}
+
+int saveNormalFile(zipFile zf, string savePath) {
+	// Open a file to write out the data.
+	FILE* out = fopen(savePath.c_str(), "wb");
+
+	if (out == NULL)
+	{
+		Dbg("could not open destination file, %s", savePath.c_str());
+		return -1;
+	}
+
+	int err = 0;
+	unsigned char* read_buffer = new unsigned char[ZIP_ZILP_READ_SIZE];
+	memset(read_buffer, 0, ZIP_ZILP_READ_SIZE);
+	do
+	{
+		err = unzReadCurrentFile(zf, read_buffer, ZIP_ZILP_READ_SIZE);
+		if (err < 0)
+		{
+			Dbg("zipfile in unzReadCurrentFile is fail:%d", err);
+			err = -1;
+			break;
+		}
+		if (err > 0)
+		{
+			// Write data to file.
+			if (fwrite(read_buffer, err, 1, out) != 1) {
+				Dbg("writing extracted normal file is fail");
+				err = -1;
+				break;
+			}
+			else {
+				//及时写入缓存数据
+				if (fflush(out) != 0) {
+					Dbg("fflush extracted normal file is fail");
+					err = -1;
+					break;
+				}
+			}
+		}
+		if (err == 0) {
+			//已经到结尾
+			break;
+		}
+	} while (true);
+
+	delete[] read_buffer;//删除临时对象
+
+	if (out != NULL) {
+		if (fclose(out) != 0) {
+			Dbg("fclose normal file fail");
+			return -1;
+		}
+	}
+	return err;
+}
+
+int saveSymlink(zipFile zf, string savePath) {
+	//链接文件
+	char* srcPath = new char[4096];//链接的原地址路径
+	memset(srcPath, 0, 4096);
+	string destPath = savePath;//新地址
+
+	unsigned char* readStr = new unsigned char[512];
+	memset(readStr, 0, 512);
+
+	int err = 0;
+	int copy = 0;
+	do
+	{
+		err = unzReadCurrentFile(zf, readStr, 512);
+		if (err < 0)
+		{
+			Dbg("zipfile in unzReadCurrentFile is fail:%d", err);
+			err = -1;
+			break;
+		}
+		// Write data to file.
+		if (err > 0)
+		{
+			if ((copy + err) <= 4096) {
+				memcpy(srcPath + copy, readStr, err);
+				copy += err;
+			}
+			else {
+				Dbg("link content len over 4096 ,check zipfile in unzReadCurrentFile, %s ", savePath.c_str());
+				err = -1;
+				break;
+			}
+		}
+		if (err == 0) {
+			//已经到结尾
+			break;
+		}
+	} while (true);
+
+	delete[] readStr;
+
+	if (err == 0) {
+		err = os_make_symlink((const char*)srcPath, destPath.c_str());
+		delete[] srcPath; //删除临时对象
+		return err;
+	}
+	else {
+		delete[] srcPath;//删除临时对象
+		return -1;
+	}
+	return 0;
+}
+
+int entry_is_symlink(unz_file_info file_info)
+{
+	uint32_t posix_attrib = 0;
+	uint8_t system = ZIP_ZILP_HOST_SYSTEM(file_info.version);
+	int32_t err = 0;
+
+	err = zip_attrib_convert(system, file_info.external_fa, ZIP_ZILP_HOST_SYSTEM_UNIX, &posix_attrib);
+	if (err == 0) {
+		if ((posix_attrib & 0170000) == 0120000) /* S_ISLNK */
+			return 0;
+	}
+
+	return -1;
+}
+
+int zip_attrib_convert(uint8_t src_sys, uint32_t src_attrib, uint8_t target_sys, uint32_t* target_attrib)
+{
+	if (target_attrib == NULL)
+		return -1;
+
+	*target_attrib = 0;
+
+	if ((src_sys == ZIP_ZILP_HOST_SYSTEM_MSDOS) || (src_sys == ZIP_ZILP_HOST_SYSTEM_WINDOWS_NTFS)) {
+		if ((target_sys == ZIP_ZILP_HOST_SYSTEM_MSDOS) || (target_sys == ZIP_ZILP_HOST_SYSTEM_WINDOWS_NTFS)) {
+			*target_attrib = src_attrib;
+			return 0;
+		}
+		if ((target_sys == ZIP_ZILP_HOST_SYSTEM_UNIX) || (target_sys == ZIP_ZILP_HOST_SYSTEM_OSX_DARWIN) || (target_sys == ZIP_ZILP_HOST_SYSTEM_RISCOS))
+			return zip_attrib_win32_to_posix(src_attrib, target_attrib);
+	}
+	else if ((src_sys == ZIP_ZILP_HOST_SYSTEM_UNIX) || (src_sys == ZIP_ZILP_HOST_SYSTEM_OSX_DARWIN) || (src_sys == ZIP_ZILP_HOST_SYSTEM_RISCOS)) {
+		if ((target_sys == ZIP_ZILP_HOST_SYSTEM_UNIX) || (target_sys == ZIP_ZILP_HOST_SYSTEM_OSX_DARWIN) || (target_sys == ZIP_ZILP_HOST_SYSTEM_RISCOS)) {
+			/* If high bytes are set, it contains unix specific attributes */
+			if ((src_attrib >> 16) != 0)
+				src_attrib >>= 16;
+
+			*target_attrib = src_attrib;
+			return 0;
+		}
+		if ((target_sys == ZIP_ZILP_HOST_SYSTEM_MSDOS) || (target_sys == ZIP_ZILP_HOST_SYSTEM_WINDOWS_NTFS))
+			return zip_attrib_posix_to_win32(src_attrib, target_attrib);
+	}
+
+	return -2;
+}
+
+int zip_attrib_posix_to_win32(uint32_t posix_attrib, uint32_t* win32_attrib)
+{
+	if (win32_attrib == NULL)
+		return -1;
+
+	*win32_attrib = 0;
+
+	/* S_IWUSR | S_IWGRP | S_IWOTH | S_IXUSR | S_IXGRP | S_IXOTH */
+	if ((posix_attrib & 0000333) == 0 && (posix_attrib & 0000444) != 0)
+		*win32_attrib |= 0x01;      /* FILE_ATTRIBUTE_READONLY */
+	/* S_IFLNK */
+	if ((posix_attrib & 0170000) == 0120000)
+		*win32_attrib |= 0x400;     /* FILE_ATTRIBUTE_REPARSE_POINT */
+	/* S_IFDIR */
+	else if ((posix_attrib & 0170000) == 0040000)
+		*win32_attrib |= 0x10;      /* FILE_ATTRIBUTE_DIRECTORY */
+	/* S_IFREG */
+	else
+		*win32_attrib |= 0x80;      /* FILE_ATTRIBUTE_NORMAL */
+
+	return 0;
+}
+
+int zip_attrib_win32_to_posix(uint32_t win32_attrib, uint32_t* posix_attrib)
+{
+	if (posix_attrib == NULL)
+		return -1;
+
+	*posix_attrib = 0000444;        /* S_IRUSR | S_IRGRP | S_IROTH */
+	/* FILE_ATTRIBUTE_READONLY */
+	if ((win32_attrib & 0x01) == 0)
+		*posix_attrib |= 0000222;   /* S_IWUSR | S_IWGRP | S_IWOTH */
+	/* FILE_ATTRIBUTE_REPARSE_POINT */
+	if ((win32_attrib & 0x400) == 0x400)
+		*posix_attrib |= 0120000;   /* S_IFLNK */
+	/* FILE_ATTRIBUTE_DIRECTORY */
+	else if ((win32_attrib & 0x10) == 0x10)
+		*posix_attrib |= 0040111;   /* S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH */
+	else
+		*posix_attrib |= 0100000;   /* S_IFREG */
+
+	return 0;
+}
+
+int os_make_symlink(const char* srcPath, const char* target_path) {
+#ifdef RVC_OS_WIN
+	return 0;//暂不实现,暂时写入后缀名是link的文件
+#else
+	if (symlink(srcPath, target_path) != 0) {
+		Dbg("symlink fail,errno = %d", errno);
+		return -1;
+	}
+	return 0;
+#endif // RVC_OS_WIN
+}
+
+#ifdef RVC_OS_WIN
+#else
+unsigned char* utf8_string_create(const char* string) {
+	iconv_t cd;
+	const char* from_encoding = "CP936";
+	size_t result = 0;
+	size_t string_length = 0;
+	size_t string_utf8_size = 0;
+	unsigned char* string_utf8 = NULL;
+	unsigned char* string_utf8_ptr = NULL;
+
+	if (string == NULL)
+		return NULL;
+
+	cd = iconv_open("UTF-8", from_encoding);
+	if (cd == (iconv_t)-1)
+		return NULL;
+
+	string_length = strlen(string);
+	string_utf8_size = string_length * 2;
+	string_utf8 = (unsigned char*)malloc((int)(string_utf8_size + 1));
+	string_utf8_ptr = string_utf8;
+
+	if (string_utf8) {
+		memset(string_utf8, 0, string_utf8_size + 1);
+
+		result = iconv(cd, (char**)&string, &string_length,
+			(char**)&string_utf8_ptr, &string_utf8_size);
+	}
+
+	iconv_close(cd);
+
+	if (result == (size_t)-1) {
+		free(string_utf8);
+		string_utf8 = NULL;
+	}
+	return string_utf8;
+}
+
+#endif //RVC_OS_WIN

+ 90 - 0
Module/mod_ResourceWatcher/XUnZipZilb.h

@@ -0,0 +1,90 @@
+#ifndef RVC_MOD_UPLOAD_XUNZIP_ZLIB_H_
+#define RVC_MOD_UPLOAD_XUNZIP_ZLIB_H_
+
+
+#include "SpBase.h"
+
+#ifdef RVC_OS_WIN
+
+#define ZLIB_WINAPI //win32 必须使用的宏
+
+#endif 
+
+#include "zip.h"
+#include "unzip.h"
+#include <iostream>
+#include <stdio.h>
+#include <string>
+#include <locale>
+#include <codecvt> 
+
+using namespace std;
+//GBK转UTF码类
+class chs_codecvt : public std::codecvt_byname<wchar_t, char, std::mbstate_t> {
+public:
+	//因不同平台,名称不同,故这里做转换,统一取出不同平台下面的GBK码
+#ifdef RVC_OS_WIN
+	chs_codecvt() : codecvt_byname("chs") { }//zh_CN.GBK or .936
+#else
+	chs_codecvt() : codecvt_byname("zh_CN.GBK") { }//.936
+#endif // RVC_OS_WIN
+};
+
+//src必须是UTF8否则抛异常
+static wstring utf8_to_wstr(const string& src)
+{
+	wstring_convert<codecvt_utf8<wchar_t>> converter;
+	return converter.from_bytes(src);
+}
+
+static string wstr_to_utf8(const wstring& src)
+{
+	wstring_convert<codecvt_utf8<wchar_t>> convert;
+	return convert.to_bytes(src);
+}
+
+static string utf8_to_gbk(const string& str)
+{
+	wstring wStr = utf8_to_wstr(str);//utf8转wstring
+	wstring_convert<chs_codecvt> converter;
+	return converter.to_bytes(wStr);//wstring转GBK
+}
+
+static string gbk_to_utf8(const string& str)
+{
+	wstring_convert<chs_codecvt> converter;
+	wstring wStr = converter.from_bytes(str);//GBK转wstring
+	return wstr_to_utf8(wStr);//wstring 转utf8
+}
+
+
+int UnZipToDir(string zipFileName, string destDirPath);
+
+int unZipCurrentFile(zipFile zf, string destDirPath);
+
+bool is_str_utf8(const char* str);
+
+int changeUnZipFileAtt(const char* path);
+
+bool replacePlace(string& str, string const& replaceThis, string const& withThis);
+
+int saveNormalFile(zipFile zf, string savePath);
+
+int saveSymlink(zipFile zf, string savePath);
+
+int entry_is_symlink(unz_file_info file_info);
+
+int zip_attrib_convert(uint8_t src_sys, uint32_t src_attrib, uint8_t target_sys, uint32_t* target_attrib);
+
+int zip_attrib_posix_to_win32(uint32_t posix_attrib, uint32_t* win32_attrib);
+
+int zip_attrib_win32_to_posix(uint32_t win32_attrib, uint32_t* posix_attrib);
+
+int os_make_symlink(const char* srcPath, const char* target_path);
+#ifdef RVC_OS_WIN
+#else
+unsigned char* utf8_string_create(const char* string);
+
+#endif // RVC_OS_WIN
+
+#endif //RVC_MOD_UPLOAD_XUNZIP_ZLIB_H_

+ 427 - 18
Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp

@@ -15,9 +15,13 @@
 #include <winpr/sysinfo.h>
 #endif //RVC_OS_LINUX
 
+#include "XUnZipZilb.h"
+
 #include "publicFunExport.h"
 #include <map>
 #include <regex.h>
+#include "../mod_healthmanager/HealthManager_client_g.h"
+using namespace HealthManager;
 
 struct SogouRunVersionInfo 
 {
@@ -182,6 +186,18 @@ void ResourceWatcherServiceSession::Handle_UninstallThirdPartyProgram(SpReqAnsCo
     m_pEntity->UninstallThirdPartyProgram(ctx);
 }
 
+void ResourceWatcherServiceSession::Handle_RestartThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req, ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx)
+{
+    LOG_FUNCTION();
+    m_pEntity->RestartThirdPartyProgram(ctx);
+}
+
+void ResourceWatcherServiceSession::Handle_ProcessDetectThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx)
+{
+    LOG_FUNCTION();
+    m_pEntity->ProcessDetectThirdPartyProgram(ctx);
+}
+
 void ResourceWatcherServiceSession::Handle_FilesClean(SpReqAnsContext<ResourceWatcherService_FilesClean_Req, ResourceWatcherService_FilesClean_Ans>::Pointer ctx)
 {
     LOG_FUNCTION();
@@ -409,26 +425,163 @@ ErrorCodeEnum SetFileExecutePriviledge(LPCTSTR lpcszDirOrFilePath)
     return result;
 }
 
+ErrorCodeEnum ResourceWatcherEntity::GetUnzipTempDir(CSimpleStringA& strUnzipDir)
+{
+    CSimpleStringA strDownloadsPath;
+    auto rc = GetFunction()->GetPath("Downloads", strDownloadsPath);
+    assert(rc == Error_Succeed);
+
+    strUnzipDir = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strDownloadsPath, strUnzipDir);
+    if (strUnzipDir.IsEndWith(".zip") || strUnzipDir.IsEndWith(".cab"))
+        strUnzipDir = strUnzipDir.SubString(0, strUnzipDir.GetLength() - 4);
+
+    return Error_Succeed;
+}
+
+ErrorCodeEnum ResourceWatcherEntity::UnzipPack(const char* unZipPackName)
+{
+    CSimpleStringA strDownloadsPath;
+    auto rc = GetFunction()->GetPath("Downloads", strDownloadsPath);
+    assert(rc == Error_Succeed);
+
+    CSimpleStringA strTempPath;
+    CSmartPointer<IEntityFunction> spFunction2 = GetFunction();
+    ErrorCodeEnum rc2 = spFunction2->GetPath("Temp", strTempPath);
+    assert(rc2 == Error_Succeed);
+
+    CSimpleStringA strUnzipPath;
+    strUnzipPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strTempPath.GetData(), unZipPackName);
+    if (strUnzipPath.IsEndWith(".zip") || strUnzipPath.IsEndWith(".cab"))
+    {
+        strUnzipPath = strUnzipPath.SubString(0, strUnzipPath.GetLength() - 4);
+    }
+
+    // 如目标目录存在,则先删除
+    if (ExistsDirA(strUnzipPath))
+    {
+        if (!RemoveDirRecursiveA(strUnzipPath)) {
+            LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("remove old unzip dir [%s] fail", strUnzipPath.GetData()));
+            return  Error_NotExist;
+        }
+    }
+    // 创建临时解压目录
+    CreateDirA(strUnzipPath.GetData(), false);
+
+    // 解压
+    CSimpleStringA strZipFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadsPath.GetData(), unZipPackName);
+    string zipFileStr = strZipFile.GetData();
+    string zipTempDir = strUnzipPath.GetData();
+
+    if (!ExistsFileA(strZipFile.GetData()))
+    {
+        LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("pack [%s] not exists", unZipPackName));
+        return  Error_NotExist;
+    }
+
+    if (UnZipToDir(zipFileStr, zipTempDir) != 0)
+    {
+        LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("unzip pack [%s] fail", unZipPackName));
+        return  Error_NotExist;
+    }
+    return Error_Succeed;
+}
+
+
 void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_InstallThirdPartyProgram_Req, ResourceWatcherService_InstallThirdPartyProgram_Ans>::Pointer ctx)
 {
     ErrorCodeEnum result(Error_Succeed);
     ErrorCodeEnum tmpResult(Error_Succeed);
     CSimpleStringA tmpMsg(true);
 
+    bool sogouInstalled = false;
     if (ctx->Req.type == 1) {//安装搜狗输入法
+        bool zipFind = false;
+        time_t newestWrite = 0;
+        CSimpleStringA newSogouPath(true);
+        CSimpleStringA strDownloadDirPath(true);
+        GetFunction()->GetPath("Downloads", strDownloadDirPath);
+        CSimpleStringA strTempDirPath(true);
+        GetFunction()->GetPath("Temp", strTempDirPath);
+
+        if (strDownloadDirPath.IsNullOrEmpty()) {
+            tmpResult = Error_Unexpect;
+            tmpMsg = CSimpleStringA::Format("搜狗安装包目录[Downloads]不存在!");
+        }
+        else
+        {
+            DIR* dp;
+            struct dirent* dirp;
+
+            if ((dp = opendir(strDownloadDirPath.GetData())) != NULL)
+            {
+                while ((dirp = readdir(dp)) != NULL) 
+                {
+                    CSimpleStringA tmpName(dirp->d_name);
+                    struct stat buf;
+                    int ret = 0;
+                    memset(&buf, 0x00, sizeof(buf));
+                    ret = stat(CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadDirPath.GetData(), dirp->d_name).GetData(), &buf);
+
+                    if (tmpName.IsStartWith("uos-sogou", true) && tmpName.IsEndWith(".zip", true) && buf.st_mtim.tv_sec > newestWrite)
+                    {
+                        if (ret != 0)
+                        {
+                            Dbg("获取文件[%s]状态信息出错。\n", tmpName.GetData());
+                        }
+                        else
+                        {
+                            newestWrite = buf.st_mtim.tv_sec;
+                            newSogouPath = CSimpleStringA(tmpName.GetData());
+                            zipFind = true;
+                        }
+                    }
+                }
+                if(!zipFind)
+                {
+                    tmpResult = Error_NotExist;
+                    tmpMsg = CSimpleStringA::Format("在路径[%s]下未找到搜狗安装包!", strDownloadDirPath.GetData());
+                }
+            }
+            else
+            {
+                tmpResult = Error_NotExist;
+                tmpMsg = CSimpleStringA::Format("打开[Downloads]目录失败!");
+            }
+        }
+
+        CSimpleStringA strInstallPkgPath;
+        if (zipFind)
+        {
+            if (UnzipPack(newSogouPath.GetData()) != Error_Succeed)
+            {
+                tmpResult = Error_Unexpect;
+                tmpMsg = CSimpleStringA::Format("解压搜狗安装包失败!");
+            }
+            else
+            {
+                newSogouPath = newSogouPath.SubString(0, newSogouPath.GetLength() - 4);
+                strInstallPkgPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s",
+                    strTempDirPath.GetData(), newSogouPath.GetData());
+            }
+        }
+        else
+        {
+            tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
+            if (tmpResult != 0) {
+                tmpMsg = tmpMsg + CSimpleStringA::Format(" 指定位置[%s]找不到输入法安装包", strInstallPkgPath.GetData());
+            }
+        }
 
         Dbg("to install sogou input...");
         const bool doNotStartup(true); //安装后是否启动搜狗输入法服务,据搜狗反馈,不能通过root权限启动Sogou输入法
-        CSimpleStringA strInstallPkgPath;
-        tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
-        if (tmpResult != 0) {
-            tmpMsg = CSimpleStringA::Format("指定位置找不到输入法安装包");
-        } else {
+        if(tmpResult == Error_Succeed)
+        {
             tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
             if (tmpResult != Error_Succeed) {
                 tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
                 tmpResult = Error_NotExist;
-            } else {
+            }
+            else {
                 CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
                 if (ExistsFileA(strRunIniFilePath)) {
                     char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
@@ -441,13 +594,15 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                         tmpResult = RunShellScript(app);
                         if (tmpResult != 0) {
                             tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
-                        } else if(!doNotStartup) {
+                        }
+                        else if (!doNotStartup) {
                             CSimpleStringA strStartupScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + "startup_service.sh");
                             Dbg("startup script file: %s", strStartupScriptFile.GetData());
                             if (!ExistsFileA(strStartupScriptFile)) {
                                 tmpMsg = CSimpleStringA::Format("%s 启动脚本文件不存在,请重启设备再次验证", strStartupScriptFile.GetData());
                                 tmpResult = Error_NotExist;
-                            } else {
+                            }
+                            else {
                                 Sleep(1000);
                                 do {
                                     char app[MAX_PATH] = { '\0' };
@@ -460,7 +615,8 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                                     auto users = GetUserNameList(true);
                                     if (users.size() == 1) {
                                         sprintf(app, "su -m -p -c \"bash %s\" %s", strStartupScriptFile.GetData(), users[0].c_str());
-                                    } else {
+                                    }
+                                    else {
                                         for (auto it = users.cbegin(); it != users.cend(); ++it) {
                                             Dbg("user:%s", it->c_str());
                                         }
@@ -474,18 +630,21 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                                     if (0 == res) {
                                         FREE(process);
                                         Dbg("execute {%s} suc", app);
-                                    } else {
+                                    }
+                                    else {
                                         tmpMsg = CSimpleStringA::Format("执行 '%s' 失败:%s", app, toolkit_strerror(res));
                                         tmpResult = Error_Process;
                                     }
                                 } while (false);
                             }
                         }
-                    } else {
+                    }
+                    else {
                         tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
                         tmpResult = Error_NotExist;
                     }
-                } else {
+                }
+                else {
                     tmpMsg = CSimpleStringA::Format("%s 文件不存在,请检查安装包完整性", strRunIniFilePath.GetData());
                     tmpResult = Error_NotExist;
                 }
@@ -494,7 +653,7 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
         if (tmpResult == Error_Succeed) {
             Sleep(1500);
             const CSimpleStringA strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "result.log";
-            do 
+            do
             {
                 const int maxTimes = 5;
                 int curTimes = 0;
@@ -507,13 +666,15 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
             if (!ExistsFileA(strResultLogFilePath)) {
                 tmpResult = Error_NotExist;
                 tmpMsg = CSimpleStringA::Format("安装成功标志文件不存在!");
-            } else {
+            }
+            else {
                 FILE* pResultLog = fopen(strResultLogFilePath, "r");
                 if (pResultLog == NULL) {
                     tmpResult = Error_IO;
                     tmpMsg = CSimpleStringA::Format("打开安装成功标志文件失败!%s", strerror(errno));
-                } else {
-                    char szTmp[1024] = {'\0'};
+                }
+                else {
+                    char szTmp[1024] = { '\0' };
                     int nRead = fread(szTmp, 1, sizeof(szTmp), pResultLog);
                     int installResult(-1);
                     char installMsg[256] = { '\0' };
@@ -523,7 +684,8 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                     if (installResult != 0) {
                         tmpResult = Error_Unexpect;
                         tmpMsg = CSimpleStringA::Format("%s", szTmp);
-                    } else {
+                    }
+                    else {
                         SogouInstallInfo info;
                         info.state.dwInstalledStatus = Sogou_GetInstallStatus();
                         info.state.strInstallDate = Sogou_GetInstallTime();
@@ -544,15 +706,20 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                         if (!info.IsInstalledSuccess()) {
                             tmpResult = Error_FailVerify;
                             tmpMsg = CSimpleStringA::Format("检测安装状态失败!");
-                        } else {
+                        }
+                        else {
                             ctx->Ans.path = info.program.strInstallDir;
                             ctx->Ans.reserverd1 = info.program.strVersion;
                             ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
+
+                            tmpMsg = tmpMsg + CSimpleStringA::Format(" 从[%s]安装搜狗输入法成功,设备即将重启。", strInstallPkgPath.GetData());
+                            sogouInstalled = true;
                         }
                     }
                 }
             }
         }
+
     } else if (ctx->Req.type == 2) {//安装花了钱的字体
 
         Dbg("to install cmb font input...%d", m_bInitMode);
@@ -622,6 +789,36 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
     ctx->Ans.result = tmpResult;
     ctx->Ans.msg = tmpMsg;
     ctx->Answer(result);
+
+    if (sogouInstalled)
+    {
+        HealthManagerService_ClientBase* m_pRWClient = new HealthManagerService_ClientBase(this);
+        ErrorCodeEnum eErr = m_pRWClient->Connect();
+
+        if (eErr != Error_Succeed) {
+            Dbg("HealthManager connected failed.");
+            m_pRWClient->SafeDelete();
+            m_pRWClient = NULL;
+        }
+        else
+        {
+            HealthManagerService_ControlTerminalLife_Req detReq;
+            HealthManagerService_ControlTerminalLife_Ans detAns;
+            detReq.cmdType = 4;
+            detReq.reason = 0;
+            eErr = m_pRWClient->ControlTerminalLife(detReq, detAns, 3000);
+            if (eErr == Error_Succeed)
+            {
+                // 系统重启事件
+                LogWarn(Severity_Middle, Error_Succeed, Event_Req_OS_Restart, "搜狗安装成功, 设备即将重启。");
+            }
+            else
+            {
+                LogWarn(Severity_Middle, Error_Unexpect, 0, "调用健康实体重启设备失败!");
+            }
+        }
+    }
+
     return;
 }
 
@@ -849,6 +1046,146 @@ void ResourceWatcherEntity::UninstallThirdPartyProgram(SpReqAnsContext<ResourceW
     return;
 }
 
+void ResourceWatcherEntity::RestartThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req, ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx)
+{
+    ErrorCodeEnum result(Error_Succeed);
+    ErrorCodeEnum tmpResult(Error_Succeed);
+
+    CSimpleStringA tmpMsg(true);
+
+    if (ctx->Req.type == 1) 
+    {//重启搜狗输入法
+        static int old_process_id[2] = { -1, -1 };
+        char* relate_processes[2] = { "sogouImeWebSrv", "sogouImeService" };
+
+        int count = 3;
+        alive_process_info processes[3];
+        memset(processes, 0, sizeof(processes));
+
+        osutil_detect_unique_app(relate_processes, array_size(relate_processes), &count, processes);
+
+        CAutoArray<CSimpleStringA> msgs(array_size(relate_processes));
+        int cnt(0);
+
+        for (int i = 0; i < array_size(relate_processes); ++i) 
+        {
+            int k = -1;
+            for (int j = 0; j < count; ++j) {
+                if (strcmp(processes[j].name, relate_processes[i]) == 0) {
+                    k = j;
+                    break;
+                }
+            }
+            if (k != -1)
+            {
+                cnt++;
+                old_process_id[k] = processes[k].pid;
+
+                std::string sucContent, failedContent;
+                CSimpleStringA strCmd = CSimpleStringA::Format("kill -9 %d", old_process_id[k]);
+                bool ret = SP::Module::Util::ShellExecute(strCmd.GetData(), sucContent, failedContent);
+                Dbg("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str());
+            }
+        }
+
+        if (cnt > 0)
+        {
+            Sleep(2000);
+
+            int newCount = 3;
+            int notSame = 0;
+            vector<CSimpleStringA> tKillmsg;
+            alive_process_info newProcesses[3];
+            memset(newProcesses, 0, sizeof(newProcesses));
+            osutil_detect_unique_app(relate_processes, array_size(relate_processes), &newCount, newProcesses);
+            for (int i = 0; i < array_size(relate_processes); ++i)
+            {
+                int k = -1;
+                for (int j = 0; j < count; ++j) {
+                    if (strcmp(newProcesses[j].name, relate_processes[i]) == 0) {
+                        k = j;
+                        break;
+                    }
+                }
+                if (k != -1)
+                {
+                    if (newProcesses[k].pid != old_process_id[k])
+                    {
+                        notSame++;
+                    }
+                    else
+                    {
+                        tmpResult = Error_Unexpect;
+                        CSimpleStringA tmsg = CSimpleStringA::Format("{杀死当前搜狗进程[%s]失败,pid[%d]。}", 
+                            newProcesses[k].name, newProcesses[k].pid);
+                        tKillmsg.push_back(tmsg);
+                    }
+                }
+            }
+            if (tKillmsg.size() != 0)
+            {
+                for (int i = 0; i < tKillmsg.size(); ++i)
+                {
+                    tmpMsg += tKillmsg[i];
+                }
+            }
+            else
+            {
+                tmpMsg = "已成功重启搜狗输入法进程。";
+            }
+        }
+        else
+        {
+            tmpMsg = "当前系统无搜狗进程,请确认已安装搜狗输入法,并重启计算机以尝试启动搜狗输入法!";
+            tmpResult = Error_Unexpect;
+        }
+    }
+    else
+    {
+        tmpResult = Error_NotSupport;
+        tmpMsg = CSimpleStringA::Format("接口调用参数错误。");
+    }
+
+    ctx->Ans.result = tmpResult;
+    ctx->Ans.msg = tmpMsg;
+
+    ctx->Answer(result);
+    return;
+}
+
+void ResourceWatcherEntity::ProcessDetectThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx)
+{
+    ErrorCodeEnum result(Error_Succeed);
+    ErrorCodeEnum tmpResult(Error_Succeed);
+
+    CSimpleStringA tmpMsg(true);
+    std::string res("");
+
+    if (ctx->Req.type == 1) {//检测搜狗输入法进程
+        CAutoArray<CSimpleStringA> pName(2);
+        pName[0] = "sogouImeWebSrv";
+        pName[1] = "sogouImeService";
+        res = DoCheckCertainProcessStatus(pName);
+
+        if (res.length() == 0)
+        {
+            tmpResult = Error_Failed;
+            tmpMsg = "Can't find Sogou Process.";
+        }
+        else
+        {
+            tmpMsg = CSimpleStringA::Format("%s", res.c_str());
+        }
+    }
+
+
+    ctx->Ans.result = tmpResult;
+    ctx->Ans.msg = tmpMsg;
+
+    ctx->Answer(result);
+    return;
+}
+
 #if defined(RVC_OS_WIN)
 //1: 32bit process running at 64bit platform
 //0: 
@@ -1298,6 +1635,77 @@ void ResourceWatcherEntity::OnSysVarEvent(const char* pszKey, const char* pszVal
 
 }
 
+}
+
+std::string ResourceWatcherEntity::DoCheckCertainProcessStatus(const CAutoArray<CSimpleStringA>& pName)
+{
+    int pSize = pName.GetCount();
+    /*static int old_process_id[pSize];
+    memset(old_process_id, -1, sizeof(old_process_id));*/
+    vector<int> old_process_id;
+    CAutoArray<CSimpleStringA> msgs;
+    alive_process_info* processes = new alive_process_info[pSize];
+    char** relate_processes = new char* [pSize];
+    int count = pSize;
+
+    for (int i = 0; i < pSize; ++i)
+    {
+        old_process_id.push_back(-1);
+
+        CSimpleStringA temp("");
+        msgs.Append(&temp, 0, 1);
+        relate_processes[i] = const_cast<char*>(pName[i].GetData());
+        Dbg("relate_process name: %s.", relate_processes[i]);
+    }
+    Dbg("COUNT = %d!", count);
+    osutil_detect_unique_app(relate_processes, pSize, &count, processes);
+
+    int cnt(0);
+    for (int i = 0; i < pSize; ++i) {
+        int k = -1;
+        for (int j = 0; j < count; ++j) {
+            if (strcmp(processes[j].name, relate_processes[i]) == 0) {
+                k = j;
+                break;
+            }
+        }
+
+        if (k != -1 && old_process_id[i] == -1) {
+            msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"pid\":%d}"
+                , relate_processes[i], processes[k].pid);
+            old_process_id[i] = processes[k].pid;
+
+        }
+        else if (k != -1 && (processes[k].pid != old_process_id[i])) {
+            msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
+                , relate_processes[i], old_process_id[i], processes[k].pid);
+            old_process_id[i] = processes[k].pid;
+
+        }
+        else if (k == -1 && old_process_id[i] != 0) {
+            msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
+                , relate_processes[i], old_process_id[i], 0);
+            old_process_id[i] = 0;
+        }
+    }
+
+    std::string uploadInfo("");
+    if (cnt > 0) {
+        if (cnt > 1) {
+            uploadInfo = "{";
+        }
+        for (int i = 0; i < cnt; ++i) {
+            if (i != 0) {
+                uploadInfo += ",";
+            }
+            uploadInfo += msgs[i].GetData();
+        }
+        if (cnt > 1) {
+            uploadInfo += "}";
+        }
+    }
+
+    return uploadInfo;
 void ResourceWatcherEntity::FilesClean(SpReqAnsContext<ResourceWatcherService_FilesClean_Req, ResourceWatcherService_FilesClean_Ans>::Pointer ctx)
 {
     ErrorCodeEnum result(Error_Succeed);
@@ -1325,6 +1733,7 @@ void ResourceWatcherEntity::FilesClean(SpReqAnsContext<ResourceWatcherService_Fi
     ctx->Answer(result);
 }
 
+
 SP_BEGIN_ENTITY_MAP()
 SP_ENTITY(ResourceWatcherEntity)
 SP_END_ENTITY_MAP()

+ 13 - 0
Module/mod_ResourceWatcher/mod_ResourceWatcher.h

@@ -56,6 +56,9 @@ public:
 
 	virtual void Handle_UninstallThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_UninstallThirdPartyProgram_Req, ResourceWatcherService_UninstallThirdPartyProgram_Ans>::Pointer ctx);
 
+	virtual void Handle_RestartThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req, ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx);
+
+	virtual void Handle_ProcessDetectThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req, ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx);
 	virtual void Handle_FilesClean(SpReqAnsContext<ResourceWatcherService_FilesClean_Req, ResourceWatcherService_FilesClean_Ans>::Pointer ctx);
 private:
 	ResourceWatcherEntity* m_pEntity;
@@ -271,6 +274,12 @@ public:
 
     void InstallThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_InstallThirdPartyProgram_Req, ResourceWatcherService_InstallThirdPartyProgram_Ans>::Pointer ctx);
 
+	void RestartThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_RestartThirdPartyProgram_Req,
+		ResourceWatcherService_RestartThirdPartyProgram_Ans>::Pointer ctx);
+
+	void ProcessDetectThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_ProcessDetectThirdPartyProgram_Req,
+		ResourceWatcherService_ProcessDetectThirdPartyProgram_Ans>::Pointer ctx);
+
 	void FilesClean(SpReqAnsContext<ResourceWatcherService_FilesClean_Req,
 		ResourceWatcherService_FilesClean_Ans>::Pointer ctx);
 
@@ -337,6 +346,10 @@ private:
 
 		ErrorCodeEnum GetSogouPkgDirPath(CSimpleStringA& strPkgPath);
 		ErrorCodeEnum RunShellScript(LPCTSTR cmdline);
+		std::string DoCheckCertainProcessStatus(const CAutoArray<CSimpleStringA>& pName);
+
+		ErrorCodeEnum GetUnzipTempDir(CSimpleStringA& strUnzipDir);
+		ErrorCodeEnum UnzipPack(const char* unZipPackName);
 
 private:
 	ResourceWatcherFSM m_fsm;