Browse Source

Z991239-3622 #comment feat: uos从Download下获取最近修改的搜狗包

陈纪林80310970 3 years ago
parent
commit
27070b0c7d

+ 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})

+ 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_

+ 226 - 128
Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp

@@ -15,6 +15,8 @@
 #include <winpr/sysinfo.h>
 #endif //RVC_OS_LINUX
 
+#include "XUnZipZilb.h"
+
 #include "publicFunExport.h"
 #include <map>
 #include <regex.h>
@@ -415,6 +417,68 @@ 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);
@@ -423,16 +487,13 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
 
     if (ctx->Req.type == 1) {//安装搜狗输入法
         bool zipFind = false;
-
-        long hFile = -1;
         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]不存在!");
@@ -449,9 +510,9 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                     struct stat buf;
                     int ret = 0;
                     memset(&buf, 0x00, sizeof(buf));
-                    ret = stat(tmpName.GetData(), &buf);
+                    ret = stat(CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadDirPath.GetData(), dirp->d_name).GetData(), &buf);
 
-                    if (tmpName.IsStartWith("win-sogou", true) && tmpName.IsEndWith(".zip", true) && buf.st_mtim.tv_sec > newestWrite)
+                    if (tmpName.IsStartWith("uos-sogou", true) && tmpName.IsEndWith(".zip", true) && buf.st_mtim.tv_sec > newestWrite)
                     {
                         if (ret != 0)
                         {
@@ -465,143 +526,180 @@ void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWat
                         }
                     }
                 }
-            }
-        }
 
-        Dbg("to install sogou input...");
-        const bool doNotStartup(true); //安装后是否启动搜狗输入法服务,据搜狗反馈,不能通过root权限启动Sogou输入法
-        CSimpleStringA strInstallPkgPath;
-        tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
-        if (tmpResult != 0) {
-            tmpMsg = CSimpleStringA::Format("指定位置找不到输入法安装包");
-        } else {
-            tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
-            if (tmpResult != Error_Succeed) {
-                tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
-                tmpResult = Error_NotExist;
-            } else {
-                CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
-                if (ExistsFileA(strRunIniFilePath)) {
-                    char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
-                    CSimpleStringA strInstallScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + p);
-                    toolkit_free(p);
-                    Dbg("install script file: %s", strInstallScriptFile.GetData());
-                    if (ExistsFileA(strInstallScriptFile)) {
-                        char app[MAX_PATH] = { '\0' };
-                        sprintf(app, "bash %s", strInstallScriptFile.GetData());
-                        tmpResult = RunShellScript(app);
+                if (zipFind)
+                {
+                    if (UnzipPack(newSogouPath.GetData()) != Error_Succeed)
+                    {
+                        tmpResult = Error_Unexpect;
+                        tmpMsg = CSimpleStringA::Format("解压搜狗安装包失败!");
+                    }
+                    else
+                    {
+                        Dbg("to install sogou input...");
+                        const bool doNotStartup(true); //安装后是否启动搜狗输入法服务,据搜狗反馈,不能通过root权限启动Sogou输入法
+                        CSimpleStringA strInstallPkgPath;
+                        //tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
+
+                        newSogouPath = newSogouPath.SubString(0, newSogouPath.GetLength() - 4);
+                        strInstallPkgPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s",
+                            strTempDirPath.GetData(), newSogouPath.GetData());
                         if (tmpResult != 0) {
-                            tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
-                        } 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());
+                            tmpMsg = CSimpleStringA::Format("指定位置找不到输入法安装包");
+                        }
+                        else {
+                            tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
+                            if (tmpResult != Error_Succeed) {
+                                tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
                                 tmpResult = Error_NotExist;
-                            } else {
-                                Sleep(1000);
-                                do {
-                                    char app[MAX_PATH] = { '\0' };
-                                    tk_process_t* process = NULL;
-                                    tk_process_option_t option;
-                                    option.exit_cb = NULL;
-                                    option.file = NULL;
-                                    option.flags = 0;
-#if 0
-                                    auto users = GetUserNameList(true);
-                                    if (users.size() == 1) {
-                                        sprintf(app, "su -m -p -c \"bash %s\" %s", strStartupScriptFile.GetData(), users[0].c_str());
-                                    } else {
-                                        for (auto it = users.cbegin(); it != users.cend(); ++it) {
-                                            Dbg("user:%s", it->c_str());
+                            }
+                            else {
+                                CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
+                                if (ExistsFileA(strRunIniFilePath)) {
+                                    char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
+                                    CSimpleStringA strInstallScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + p);
+                                    toolkit_free(p);
+                                    Dbg("install script file: %s", strInstallScriptFile.GetData());
+                                    if (ExistsFileA(strInstallScriptFile)) {
+                                        char app[MAX_PATH] = { '\0' };
+                                        sprintf(app, "bash %s", strInstallScriptFile.GetData());
+                                        tmpResult = RunShellScript(app);
+                                        if (tmpResult != 0) {
+                                            tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
                                         }
-                                        sprintf(app, "bash %s", strStartupScriptFile.GetData());
-                                    }
+                                        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 {
+                                                Sleep(1000);
+                                                do {
+                                                    char app[MAX_PATH] = { '\0' };
+                                                    tk_process_t* process = NULL;
+                                                    tk_process_option_t option;
+                                                    option.exit_cb = NULL;
+                                                    option.file = NULL;
+                                                    option.flags = 0;
+#if 0
+                                                    auto users = GetUserNameList(true);
+                                                    if (users.size() == 1) {
+                                                        sprintf(app, "su -m -p -c \"bash %s\" %s", strStartupScriptFile.GetData(), users[0].c_str());
+                                                    }
+                                                    else {
+                                                        for (auto it = users.cbegin(); it != users.cend(); ++it) {
+                                                            Dbg("user:%s", it->c_str());
+                                                        }
+                                                        sprintf(app, "bash %s", strStartupScriptFile.GetData());
+                                                    }
 #else
-                                    sprintf(app, "bash %s", strStartupScriptFile.GetData());
+                                                    sprintf(app, "bash %s", strStartupScriptFile.GetData());
 #endif
-                                    option.params = app;
-                                    const int res = process_spawn(&option, &process);
-                                    if (0 == res) {
-                                        FREE(process);
-                                        Dbg("execute {%s} suc", app);
-                                    } else {
-                                        tmpMsg = CSimpleStringA::Format("执行 '%s' 失败:%s", app, toolkit_strerror(res));
-                                        tmpResult = Error_Process;
+                                                    option.params = app;
+                                                    const int res = process_spawn(&option, &process);
+                                                    if (0 == res) {
+                                                        FREE(process);
+                                                        Dbg("execute {%s} suc", app);
+                                                    }
+                                                    else {
+                                                        tmpMsg = CSimpleStringA::Format("执行 '%s' 失败:%s", app, toolkit_strerror(res));
+                                                        tmpResult = Error_Process;
+                                                    }
+                                                } while (false);
+                                            }
+                                        }
+                                    }
+                                    else {
+                                        tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
+                                        tmpResult = Error_NotExist;
                                     }
-                                } while (false);
+                                }
+                                else {
+                                    tmpMsg = CSimpleStringA::Format("%s 文件不存在,请检查安装包完整性", strRunIniFilePath.GetData());
+                                    tmpResult = Error_NotExist;
+                                }
+                            }
+                        }
+                        if (tmpResult == Error_Succeed) {
+                            Sleep(1500);
+                            const CSimpleStringA strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "result.log";
+                            do
+                            {
+                                const int maxTimes = 5;
+                                int curTimes = 0;
+                                while (!ExistsFileA(strResultLogFilePath) && curTimes < maxTimes) {
+                                    Sleep(1500);
+                                    curTimes++;
+                                }
+                            } while (false);
+
+                            if (!ExistsFileA(strResultLogFilePath)) {
+                                tmpResult = Error_NotExist;
+                                tmpMsg = CSimpleStringA::Format("安装成功标志文件不存在!");
+                            }
+                            else {
+                                FILE* pResultLog = fopen(strResultLogFilePath, "r");
+                                if (pResultLog == NULL) {
+                                    tmpResult = Error_IO;
+                                    tmpMsg = CSimpleStringA::Format("打开安装成功标志文件失败!%s", strerror(errno));
+                                }
+                                else {
+                                    char szTmp[1024] = { '\0' };
+                                    int nRead = fread(szTmp, 1, sizeof(szTmp), pResultLog);
+                                    int installResult(-1);
+                                    char installMsg[256] = { '\0' };
+                                    sscanf(szTmp, "result=%d&msg=%s", &installResult, installMsg);
+                                    fclose(pResultLog);
+
+                                    if (installResult != 0) {
+                                        tmpResult = Error_Unexpect;
+                                        tmpMsg = CSimpleStringA::Format("%s", szTmp);
+                                    }
+                                    else {
+                                        SogouInstallInfo info;
+                                        info.state.dwInstalledStatus = Sogou_GetInstallStatus();
+                                        info.state.strInstallDate = Sogou_GetInstallTime();
+                                        info.program.strInstallDir = Sogou_GetInstallPath();
+                                        info.program.strVersion = Sogou_GetVersion();
+                                        const int maxTimes = 5;
+                                        int curTimes = 0;
+                                        while (!doNotStartup && info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
+                                            Sleep(1200);
+                                            info.program.strVersion = Sogou_GetVersion();
+                                            curTimes++;
+                                        }
+                                        Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
+                                        Dbg("%d, %s, %s, %s"
+                                            , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
+                                            , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
+
+                                        if (!info.IsInstalledSuccess()) {
+                                            tmpResult = Error_FailVerify;
+                                            tmpMsg = CSimpleStringA::Format("检测安装状态失败!");
+                                        }
+                                        else {
+                                            ctx->Ans.path = info.program.strInstallDir;
+                                            ctx->Ans.reserverd1 = info.program.strVersion;
+                                            ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
+                                        }
+                                    }
+                                }
                             }
                         }
-                    } else {
-                        tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
-                        tmpResult = Error_NotExist;
                     }
-                } else {
-                    tmpMsg = CSimpleStringA::Format("%s 文件不存在,请检查安装包完整性", strRunIniFilePath.GetData());
+                }
+                else
+                {
                     tmpResult = Error_NotExist;
+                    tmpMsg = CSimpleStringA::Format("在路径[%s]下未找到搜狗安装包!", strDownloadDirPath.GetData());
                 }
             }
-        }
-        if (tmpResult == Error_Succeed) {
-            Sleep(1500);
-            const CSimpleStringA strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "result.log";
-            do 
+            else
             {
-                const int maxTimes = 5;
-                int curTimes = 0;
-                while (!ExistsFileA(strResultLogFilePath) && curTimes < maxTimes) {
-                    Sleep(1500);
-                    curTimes++;
-                }
-            } while (false);
-
-            if (!ExistsFileA(strResultLogFilePath)) {
                 tmpResult = Error_NotExist;
-                tmpMsg = CSimpleStringA::Format("安装成功标志文件不存在!");
-            } else {
-                FILE* pResultLog = fopen(strResultLogFilePath, "r");
-                if (pResultLog == NULL) {
-                    tmpResult = Error_IO;
-                    tmpMsg = CSimpleStringA::Format("打开安装成功标志文件失败!%s", strerror(errno));
-                } else {
-                    char szTmp[1024] = {'\0'};
-                    int nRead = fread(szTmp, 1, sizeof(szTmp), pResultLog);
-                    int installResult(-1);
-                    char installMsg[256] = { '\0' };
-                    sscanf(szTmp, "result=%d&msg=%s", &installResult, installMsg);
-                    fclose(pResultLog);
-
-                    if (installResult != 0) {
-                        tmpResult = Error_Unexpect;
-                        tmpMsg = CSimpleStringA::Format("%s", szTmp);
-                    } else {
-                        SogouInstallInfo info;
-                        info.state.dwInstalledStatus = Sogou_GetInstallStatus();
-                        info.state.strInstallDate = Sogou_GetInstallTime();
-                        info.program.strInstallDir = Sogou_GetInstallPath();
-                        info.program.strVersion = Sogou_GetVersion();
-                        const int maxTimes = 5;
-                        int curTimes = 0;
-                        while (!doNotStartup && info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
-                            Sleep(1200);
-                            info.program.strVersion = Sogou_GetVersion();
-                            curTimes++;
-                        }
-                        Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
-                        Dbg("%d, %s, %s, %s"
-                            , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
-                            , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
-
-                        if (!info.IsInstalledSuccess()) {
-                            tmpResult = Error_FailVerify;
-                            tmpMsg = CSimpleStringA::Format("检测安装状态失败!");
-                        } else {
-                            ctx->Ans.path = info.program.strInstallDir;
-                            ctx->Ans.reserverd1 = info.program.strVersion;
-                            ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
-                        }
-                    }
-                }
+                tmpMsg = CSimpleStringA::Format("打开[Downloads]目录失败!");
             }
         }
     } else if (ctx->Req.type == 2) {//安装花了钱的字体

+ 3 - 0
Module/mod_ResourceWatcher/mod_ResourceWatcher.h

@@ -344,6 +344,9 @@ private:
 		ErrorCodeEnum RunShellScript(LPCTSTR cmdline);
 		std::string DoCheckCertainProcessStatus(const CAutoArray<CSimpleStringA>& pName);
 
+		ErrorCodeEnum GetUnzipTempDir(CSimpleStringA& strUnzipDir);
+		ErrorCodeEnum UnzipPack(const char* unZipPackName);
+
 private:
 	ResourceWatcherFSM m_fsm;
 	CUUID m_uiCardSwiperStatusListener;