download.cpp 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "download.h"
  5. #include <fileutil.h>
  6. #include <memutil.h>
  7. #include "RVCComm.h"
  8. #include "scew.h"
  9. #include <string>
  10. #ifdef RVC_OS_WIN
  11. #include <WinCrypt.h>
  12. #else
  13. #include <sys/stat.h>
  14. #include <errno.h>
  15. #include <iconv.h>
  16. #endif // RVC_OS_WIN
  17. using namespace std;
  18. static __inline int char2hex(char c)
  19. {
  20. if (c >= '0' && c<= '9')
  21. return c-'0';
  22. else if (c >= 'A' && c <= 'F')
  23. return c-'A' +10;
  24. else if (c >= 'a' && c <= 'f')
  25. return c-'a' +10;
  26. else
  27. assert(0);
  28. return 0;
  29. }
  30. //废弃方法
  31. static void parse_md5_hex(const char *str, char md5[16])
  32. {
  33. int i;
  34. for (i = 0; i < 16; ++i) {
  35. int h = char2hex(str[2*i]);
  36. int l = char2hex(str[2*i+1]);
  37. md5[i] = (h << 4) | l;
  38. }
  39. }
  40. static void parse_SM3_hex(const char *str, char md5[32])
  41. {
  42. int i;
  43. for (i = 0; i < 32; ++i) {
  44. int h = char2hex(str[2*i]);
  45. int l = char2hex(str[2*i+1]);
  46. md5[i] = (h << 4) | l;
  47. }
  48. }
  49. char* ConvertUtf8ToGBK(char* strUtf8)
  50. {
  51. #ifdef RVC_OS_WIN
  52. int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
  53. WCHAR* wszGBK = new WCHAR[len + 1];
  54. memset(wszGBK, 0, len * 2 + 2);
  55. MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len);
  56. len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
  57. char* szGBK = new char[len + 1];
  58. memset(szGBK, 0, len + 1);
  59. WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
  60. delete[] wszGBK;
  61. return szGBK;
  62. #else
  63. return NULL;
  64. #endif // RVC_OS_WIN
  65. }
  66. char* ConvertGBKToUtf8(char* gbk, int *n)
  67. {
  68. #ifdef RVC_OS_WIN
  69. int len = MultiByteToWideChar(CP_ACP, 0, gbk, -1, NULL, 0);
  70. WCHAR* wszGBK = new WCHAR[len + 1];
  71. memset(wszGBK, 0, len * 2 + 2);
  72. MultiByteToWideChar(CP_ACP, 0, gbk, -1, wszGBK, len);
  73. len = WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, NULL, 0, NULL, NULL);
  74. char* szUtf8 = new char[len + 1];
  75. memset(szUtf8, 0, len + 1);
  76. WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, szUtf8, len, NULL, NULL);
  77. delete[] wszGBK;
  78. *n = len - 1;
  79. return szUtf8;
  80. #else:
  81. return NULL;
  82. #endif
  83. }
  84. #ifdef RVC_OS_WIN
  85. #else
  86. unsigned char* GBKToUTF8(const char* string) {
  87. iconv_t cd;
  88. const char* from_encoding = "CP936";
  89. size_t result = 0;
  90. size_t string_length = 0;
  91. size_t string_utf8_size = 0;
  92. unsigned char* string_utf8 = NULL;
  93. unsigned char* string_utf8_ptr = NULL;
  94. if (string == NULL)
  95. return NULL;
  96. cd = iconv_open("UTF-8", from_encoding);
  97. if (cd == (iconv_t)-1)
  98. return NULL;
  99. string_length = strlen(string);
  100. string_utf8_size = string_length * 2;
  101. string_utf8 = (unsigned char*)malloc((int)(string_utf8_size + 1));
  102. string_utf8_ptr = string_utf8;
  103. if (string_utf8) {
  104. memset(string_utf8, 0, string_utf8_size + 1);
  105. result = iconv(cd, (char**)&string, &string_length,
  106. (char**)&string_utf8_ptr, &string_utf8_size);
  107. }
  108. iconv_close(cd);
  109. if (result == (size_t)-1) {
  110. free(string_utf8);
  111. string_utf8 = NULL;
  112. }
  113. return string_utf8;
  114. }
  115. char* UTF8ToGBK(const char* string) {
  116. iconv_t cd;
  117. const char* from_encoding = "UTF-8";
  118. size_t result = 0;
  119. if (string == NULL)
  120. return NULL;
  121. cd = iconv_open("CP936", from_encoding);
  122. if (cd == (iconv_t)-1)
  123. return NULL;
  124. //准备转换字符串
  125. char* inbuf = const_cast<char*>(string);
  126. size_t inlen = strlen(inbuf);
  127. size_t outlen = inlen * 4;
  128. char* outbuf = (char*)malloc(inlen * 4);
  129. char* in = inbuf;
  130. char* out = outbuf;
  131. if (outbuf) {
  132. memset(outbuf, 0, inlen * 4);
  133. iconv(cd, &in, &inlen, &out, &outlen);
  134. }
  135. iconv_close(cd);
  136. if (result == (size_t)-1) {
  137. free(outbuf);
  138. outbuf = NULL;
  139. }
  140. return outbuf;
  141. }
  142. int changeFileAtt(const char* path)
  143. {
  144. struct stat attr_of_del;
  145. if (lstat(path, &attr_of_del) == 0)
  146. {
  147. //修改为775属性
  148. mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
  149. if (chmod(path, f_attrib) != 0)
  150. {
  151. Dbg("set file attribute is fail,errno=%d, file=%s", errno, path);
  152. return -1;
  153. }
  154. return 0;
  155. }
  156. else {
  157. Dbg("get file attribute is fail,errno=%d, file=%s", errno, path);
  158. return -1;
  159. }
  160. }
  161. #endif //RVC_OS_WIN
  162. static download_file_t *parse_file_object(scew_element *elem)
  163. {
  164. download_file_t *file = ZALLOC_T(download_file_t);
  165. if (file) {
  166. scew_attribute *attr = scew_element_attribute_by_name(elem, "Name");
  167. if (attr) {
  168. const char *str = scew_attribute_value(attr);
  169. if (str) {
  170. #ifdef RVC_OS_WIN
  171. char *pGBK = ConvertUtf8ToGBK((char*)str);
  172. strncpy(file->name, pGBK, sizeof(file->name)-1);
  173. delete[] pGBK;
  174. #else
  175. char* outGBkStr = UTF8ToGBK(str);
  176. if (outGBkStr == NULL) {
  177. Dbg("UTF8ToGBK get GBK str is null,xml string : %s", str);
  178. goto on_error;//直接报错
  179. }
  180. strncpy(file->name, (const char*)outGBkStr, sizeof(file->name) - 1);
  181. free(outGBkStr);
  182. #endif
  183. } else {
  184. goto on_error;
  185. }
  186. } else {
  187. goto on_error;
  188. }
  189. attr = scew_element_attribute_by_name(elem, "Length");
  190. if (attr) {
  191. const char *str = scew_attribute_value(attr);
  192. if (str) {
  193. file->length = atoi(str);
  194. } else {
  195. goto on_error;
  196. }
  197. } else {
  198. goto on_error;
  199. }
  200. attr = scew_element_attribute_by_name(elem, "MD5");
  201. if (attr) {
  202. const char *str = scew_attribute_value(attr);
  203. if (str) {
  204. //采用新国密SM3解析接口
  205. //parse_md5_hex(str, file->md5);
  206. //Dbg("MD5:%s",str);
  207. parse_SM3_hex(str,file->md5);
  208. } else {
  209. goto on_error;
  210. }
  211. } else {
  212. goto on_error;
  213. }
  214. }
  215. return file;
  216. on_error:
  217. if (file) {
  218. free(file);
  219. }
  220. return NULL;
  221. }
  222. array_header_t* download_parse_filelist1(const char *xml, int n)
  223. {
  224. scew_reader *reader = NULL;
  225. scew_parser *parser = NULL;
  226. scew_tree *tree = NULL;
  227. array_header_t *arr = NULL;
  228. scew_element *root;
  229. scew_error code;
  230. scew_list* lst = NULL;
  231. reader = scew_reader_buffer_create(xml, n);
  232. if (!reader) {
  233. Dbg("create scew buffer reader!");
  234. goto on_error;
  235. }
  236. parser = scew_parser_create();
  237. tree = scew_parser_load(parser, reader);
  238. if (!tree) {
  239. code = scew_error_code();
  240. if (code == scew_error_expat) {
  241. enum XML_Error expat_code = scew_error_expat_code(parser);
  242. Dbg("scew parse error:%d, line:%d column:%d %s", expat_code, scew_error_expat_line(parser),
  243. scew_error_expat_column(parser), scew_error_expat_string(expat_code));
  244. }
  245. //Dbg("parser xml failed! xml=%s", xml);
  246. goto on_error;
  247. }
  248. root = scew_tree_root(tree);
  249. if (!root) {
  250. //Dbg("does not have root element!xml=%s", xml);
  251. goto on_error;
  252. }
  253. lst = scew_element_children(root);
  254. if (lst) {
  255. arr = array_make(scew_list_size(lst), sizeof(download_file_t*));
  256. for (scew_list *it = scew_list_first(lst); it; it = scew_list_next(it)) {
  257. scew_element *elem = (scew_element*)scew_list_data(it);
  258. download_file_t *file = parse_file_object(elem);
  259. if (file) {
  260. ARRAY_PUSH(arr, download_file_t*) = file;
  261. } else {
  262. Dbg("parse file object failed!");
  263. }
  264. }
  265. }
  266. on_error:
  267. if (tree) {
  268. scew_tree_free(tree);
  269. }
  270. if (parser) {
  271. scew_parser_free(parser);
  272. }
  273. if (reader) {
  274. scew_reader_close(reader);
  275. }
  276. return arr;
  277. }
  278. array_header_t* download_parse_filelist(const char *xml, int n)
  279. {
  280. char *pBuf = new char[n+1];
  281. memset(pBuf, 0, n+1);
  282. memcpy(pBuf, xml, n);
  283. int nLen = 0;
  284. #ifdef RVC_OS_WIN
  285. char* pUtf8 = ConvertGBKToUtf8(pBuf, &nLen);
  286. #else
  287. unsigned char* tempStr = GBKToUTF8((const char*)pBuf);
  288. if (tempStr == NULL) {
  289. Dbg("get utf8 str is null,xml string : %s",pBuf);
  290. delete[] pBuf;
  291. return NULL;//直接报错
  292. }
  293. int tempLen = strlen((const char*)tempStr);
  294. char* pUtf8 = new char[tempLen + 1];
  295. memset(pUtf8, 0, tempLen + 1);
  296. memcpy(pUtf8, (const char*)tempStr, tempLen);
  297. free(tempStr);
  298. nLen = strlen(pUtf8);
  299. #endif // RVC_OS_WIN
  300. auto arr = download_parse_filelist1(pUtf8, nLen);
  301. if (arr == NULL)
  302. {
  303. Dbg("xml string : %s", pBuf);
  304. }
  305. delete[] pBuf;
  306. delete[] pUtf8;
  307. return arr;
  308. }
  309. void download_free_filelist(array_header_t* arr)
  310. {
  311. if (arr) {
  312. int i;
  313. for (i = 0; i < arr->nelts; ++i) {
  314. download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
  315. free(file);
  316. }
  317. free(arr);
  318. }
  319. }
  320. //废弃方法
  321. static int download_get_file_md5(const char *path, char md5[16])
  322. {
  323. #ifdef RVC_OS_WIN
  324. HCRYPTPROV hCryptProv;
  325. if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) {
  326. int rc = Error_Unexpect;
  327. HCRYPTHASH hHash;
  328. if (CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) {
  329. HANDLE hFile = CreateFileA(path, FILE_GENERIC_READ,
  330. FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  331. if (hFile != INVALID_HANDLE_VALUE) {
  332. char tmp[8192];
  333. DWORD dwBytesRead;
  334. BOOL bRet;
  335. do {
  336. bRet = ReadFile(hFile, tmp, sizeof(tmp), &dwBytesRead, NULL);
  337. if (bRet) {
  338. CryptHashData(hHash, (LPBYTE)tmp, dwBytesRead, 0);
  339. }
  340. } while (bRet && dwBytesRead > 0);
  341. CloseHandle(hFile);
  342. DWORD dwLen = 16;
  343. CryptGetHashParam(hHash, HP_HASHVAL, (LPBYTE)&md5[0], &dwLen, 0);
  344. rc = Error_Succeed;
  345. }
  346. else {
  347. Dbg("file open failed, may be %s does not exist! GetLastError:%d", path, GetLastError());
  348. }
  349. CryptDestroyHash(hHash);
  350. }
  351. else {
  352. Dbg("create hash failed!GetLastError:%d", GetLastError());
  353. }
  354. CryptReleaseContext(hCryptProv, 0);
  355. return (ErrorCodeEnum)rc;
  356. }
  357. else {
  358. Dbg("acquire ctx failed!GetLastError:%d", GetLastError());
  359. return Error_Unexpect;
  360. }
  361. #else
  362. //等国密版本
  363. #endif // RVC_OS_WIN
  364. return Error_Unexpect;
  365. }
  366. static int new_download_get_file_md5(const char *path, BYTE md5[32])
  367. {
  368. if(path==NULL){
  369. Dbg("file path is null");
  370. return -1;
  371. }
  372. int nlen = strlen(path);
  373. char* pchar = new char[nlen+1];
  374. strcpy(pchar,path);
  375. try
  376. {
  377. if(SM3File(pchar,md5)){
  378. delete pchar;
  379. return 0;
  380. }else{
  381. delete pchar;
  382. Dbg("下载文件sm3国密加密失败,file=%s",path);
  383. return -1;
  384. }
  385. }
  386. catch (...)
  387. {
  388. delete pchar;
  389. Dbg("下载文件sm3国密加密异常失败,file=%s",path);
  390. return -2;
  391. }
  392. }
  393. //废弃方法
  394. //int download_check_filelist(const char *base_dir, array_header_t* arr)
  395. //{
  396. // int i;
  397. // char tmp[MAX_PATH];
  398. // assert(base_dir);
  399. // assert(arr);
  400. // i = 0;
  401. // while (i < arr->nelts) {
  402. // download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
  403. // assert(file);
  404. // sprintf(tmp, "%s\\%s", base_dir, file->name);
  405. //#ifdef RVC_OS_WIN
  406. // WIN32_FILE_ATTRIBUTE_DATA attr_data;
  407. // if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
  408. // if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) {
  409. // char md5[16];
  410. // int rc = download_get_file_md5(tmp, md5);
  411. // if (rc == 0) {
  412. // if (memcmp(md5, file->md5, 16) == 0) { // already have remove this file
  413. // Dbg("file %s the same, remove it!", file->name);
  414. // ARRAY_DEL(arr, i, download_file_t*);
  415. // free(file);
  416. // }
  417. // else {
  418. // ++i;
  419. // }
  420. // }
  421. // else {
  422. // ++i;
  423. // }
  424. // }
  425. // else {
  426. // ++i;
  427. // }
  428. // }
  429. // else {
  430. // ++i;
  431. // }
  432. //#endif // RVC_OS_WIN
  433. //
  434. //
  435. // }
  436. // return 0;
  437. //}
  438. int new_download_check_filelist(const char *base_dir, array_header_t* arr,download_file_t *downloadFile){
  439. int ret=0; //表示下载的文件在文件列表里不存在
  440. int i;
  441. char tmp[MAX_PATH];
  442. assert(base_dir);
  443. assert(arr);
  444. i = 0;
  445. while (i<arr->nelts){
  446. download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
  447. assert(file);
  448. Dbg("download_check_filelist request downloadFile->name:[%s] ,fileList->name : [%s]", downloadFile->name, (const char*)file->name);
  449. if (strcmp((const char* )downloadFile->name, (const char*)file->name) == 0) {
  450. sprintf(tmp, "%s%s%s", base_dir, SPLIT_SLASH_STR, downloadFile->name);
  451. #ifdef RVC_OS_WIN
  452. WIN32_FILE_ATTRIBUTE_DATA attr_data;
  453. if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
  454. if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) {
  455. //char md5[16];
  456. BYTE md5[32];
  457. int rc = new_download_get_file_md5(tmp, md5);
  458. if(rc==0){
  459. //if (memcmp(md5, file->md5, 16) == 0) {
  460. if (memcmp(md5, file->md5, 32) == 0) {
  461. //文件长度,md5完全相同,告知下载完成
  462. Dbg("file %s the same, remove it!", file->name);
  463. ret = 2;
  464. break;
  465. }else{
  466. //md5不相等,需要下载
  467. ret = 1;
  468. downloadFile->length = file->length;
  469. //memcpy(downloadFile->md5, file->md5, 16);
  470. memcpy(downloadFile->md5, file->md5, 32);
  471. break;
  472. }
  473. }else{
  474. //获取md5报错,需要下载
  475. ret = 1;
  476. downloadFile->length = file->length;
  477. //memcpy(downloadFile->md5,file->md5,16);
  478. memcpy(downloadFile->md5,file->md5,32);
  479. break;
  480. }
  481. }else{
  482. //文件长度不相同,需要下载
  483. ret = 1;
  484. downloadFile->length = file->length;
  485. //memcpy(downloadFile->md5,file->md5,16);
  486. memcpy(downloadFile->md5,file->md5,32);
  487. break;
  488. }
  489. }else{
  490. //获取不到文件,需要下载
  491. Dbg("file is not exist , fileName is [%s]", (LPCSTR)tmp);
  492. ret = 1;
  493. downloadFile->length = file->length;
  494. //memcpy(downloadFile->md5,file->md5,16);
  495. memcpy(downloadFile->md5,file->md5,32);
  496. break;
  497. }
  498. #else
  499. struct stat attr_of_src;
  500. if (lstat(tmp, &attr_of_src) == 0)
  501. {
  502. if (attr_of_src.st_size== file->length) {
  503. //char md5[16];
  504. BYTE md5[32];
  505. int rc = new_download_get_file_md5(tmp, md5);
  506. if (rc == 0) {
  507. //if (memcmp(md5, file->md5, 16) == 0) {
  508. if (memcmp(md5, file->md5, 32) == 0) {
  509. //文件长度,md5完全相同,告知下载完成
  510. Dbg("file %s the same, remove it!", file->name);
  511. ret = 2;
  512. break;
  513. }
  514. else {
  515. //md5不相等,需要下载
  516. ret = 1;
  517. downloadFile->length = file->length;
  518. //memcpy(downloadFile->md5, file->md5, 16);
  519. memcpy(downloadFile->md5, file->md5, 32);
  520. break;
  521. }
  522. }
  523. else {
  524. //获取md5报错,需要下载
  525. ret = 1;
  526. downloadFile->length = file->length;
  527. //memcpy(downloadFile->md5, file->md5, 16);
  528. memcpy(downloadFile->md5, file->md5, 32);
  529. break;
  530. }
  531. }
  532. else {
  533. //文件长度不相同,需要下载
  534. ret = 1;
  535. downloadFile->length = file->length;
  536. //memcpy(downloadFile->md5, file->md5, 16);
  537. memcpy(downloadFile->md5, file->md5, 32);
  538. break;
  539. }
  540. }
  541. else
  542. {
  543. //获取不到文件,需要下载
  544. Dbg("file is not exist , fileName is [%s]", (const char*)tmp);
  545. ret = 1;
  546. downloadFile->length = file->length;
  547. //memcpy(downloadFile->md5, file->md5, 16);
  548. memcpy(downloadFile->md5, file->md5, 32);
  549. break;
  550. }
  551. #endif
  552. }
  553. else {
  554. i++;
  555. }
  556. }
  557. return ret;
  558. }
  559. //SM3Byte is 16 or 32
  560. //SM3_len is 32 or 64
  561. char* SM3_Str (BYTE * SM3Byte, int SM3_len)
  562. {
  563. if(SM3Byte == NULL){
  564. return NULL;
  565. }
  566. int i;
  567. char* file_SM3 = (char*)malloc((SM3_len + 1) * sizeof(char));
  568. if(file_SM3 == NULL)
  569. {
  570. fprintf(stderr, "SM3 malloc failed.\n");
  571. return NULL;
  572. }
  573. memset(file_SM3, 0, (SM3_len + 1));
  574. if(SM3_len == 32)
  575. {
  576. for(i=0; i<16; i++)
  577. {
  578. sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);
  579. }
  580. }
  581. else if(SM3_len == 64)
  582. {
  583. for(i=0; i<32; i++)
  584. {
  585. sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);
  586. }
  587. }
  588. else
  589. {
  590. free(file_SM3);
  591. return NULL;
  592. }
  593. return file_SM3;
  594. }
  595. int download_check_MD5(download_storage_t *storage,download_file_t *dfile){
  596. int ret=0;
  597. //char md5[16];
  598. BYTE md5[32]={0};
  599. //计算sm3的加密时间
  600. CSmallDateTime beginT = CSmallDateTime::GetNow();
  601. int rc = new_download_get_file_md5(storage->temp_path, md5);//计算出临时文件md5值
  602. CSmallDateTime endT = CSmallDateTime::GetNow();
  603. Dbg("下载文件国密获取的SM3耗时%d秒",(DWORD)(endT-beginT));
  604. if(rc==0){
  605. //试着打印已下载文件的SM3的16进制值
  606. char* fSM3 = SM3_Str(md5,64);
  607. if(fSM3!=NULL){
  608. Dbg("下载文件国密获取的SM3=%s",fSM3);
  609. free(fSM3);
  610. }
  611. //if (memcmp(md5, dfile->md5, 16) == 0) {
  612. if (memcmp(md5, dfile->md5, 32) == 0) {
  613. //下载临时文件和文件列表md5一致
  614. ret=0;
  615. }else{
  616. //下载临时文件和文件列表md5不一致,需要下载
  617. Dbg("下载文件SM3值和服务器文件SM3值不同,需要重新下载");
  618. ret=1;
  619. }
  620. }else{
  621. //获取临时文件md5报错
  622. ret=2;
  623. }
  624. return ret;
  625. }
  626. int download_delete_file(const char *base_dir,download_file_t *downloadFile){
  627. char tmp[MAX_PATH];
  628. assert(base_dir);
  629. sprintf(tmp, "%s%s%s", base_dir, SPLIT_SLASH_STR, downloadFile->name);
  630. FILE * fh = fopen(tmp,"r");
  631. if(fh == NULL)
  632. {
  633. return 1;
  634. }else{
  635. fclose(fh);//先关闭文件
  636. #ifdef RVC_OS_WIN
  637. if (DeleteFileA(tmp)) {
  638. Dbg("same download file [%s] delete success ", (LPCSTR)tmp);
  639. return 1;
  640. }
  641. else {
  642. DWORD err = GetLastError();
  643. char* pErrmsg = strerror((int)err);
  644. Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (LPCSTR)tmp, err, (LPCSTR)pErrmsg);
  645. return 0;
  646. }
  647. #else
  648. if (remove(tmp)==0) {
  649. Dbg("same download file [%s] delete success ", (const char*)tmp);
  650. return 1;
  651. }
  652. else {
  653. char* pErrmsg = strerror(errno);
  654. Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (const char*)tmp, errno, (const char*)pErrmsg);
  655. return 0;
  656. }
  657. #endif // RVC_OS_WIN
  658. }
  659. }
  660. #if 0
  661. int download_get_storage_block_id(const char *base_dir, download_file_t *file, int *block_id)
  662. {
  663. char temp_path[MAX_PATH];
  664. char info_path[MAX_PATH];
  665. //sprintf(temp_path, "%s\\%s.temp", base_dir, file->name);
  666. sprintf(temp_path, "%s\\%s.info", base_dir, file->name);
  667. return 0;
  668. }
  669. #endif
  670. typedef struct storage_info_t {
  671. int block_id;
  672. //char md5[16];
  673. char md5[32];
  674. int length;
  675. }storage_info_t;
  676. download_storage_t *download_storage_open(const char *base_dir, download_file_t *file)
  677. {
  678. if (base_dir && file) {
  679. download_storage_t *storage = ZALLOC_T(download_storage_t);//清零初始化
  680. #ifdef RVC_OS_WIN
  681. if (storage) {
  682. sprintf(storage->temp_path, "%s%s%s.temp", base_dir, SPLIT_SLASH_STR, file->name);//临时内容文件
  683. sprintf(storage->info_path, "%s%s%s.info", base_dir, SPLIT_SLASH_STR, file->name);//控制信息文件
  684. storage->info_handle = INVALID_HANDLE_VALUE;
  685. storage->temp_handle = INVALID_HANDLE_VALUE;
  686. storage->length = file->length;
  687. storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  688. if (storage->info_handle == INVALID_HANDLE_VALUE) {
  689. storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  690. if (storage->info_handle != INVALID_HANDLE_VALUE) {
  691. storage_info_t info;
  692. DWORD dwLen;
  693. info.length = file->length;
  694. //memcpy(info.md5, file->md5, 16);
  695. memcpy(info.md5, file->md5, 32);
  696. info.block_id = 0;
  697. WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  698. FlushFileBuffers(storage->info_handle);
  699. }
  700. } else {
  701. storage_info_t info;
  702. DWORD dwLen;
  703. BOOL bRet = ReadFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  704. if (bRet && dwLen == sizeof(info)) {
  705. //if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
  706. if (info.length == file->length && memcmp(info.md5, file->md5, 32) == 0) {
  707. // 续传
  708. storage->offset_block_id = info.block_id;
  709. } else {
  710. // 文件已改变,重新传输
  711. info.length = file->length;
  712. //memcpy(info.md5, file->md5, 16);
  713. memcpy(info.md5, file->md5, 32);
  714. info.block_id = 0;
  715. WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  716. FlushFileBuffers(storage->info_handle);
  717. }
  718. } else {
  719. //新文件,新传输
  720. info.length = file->length;
  721. //memcpy(info.md5, file->md5, 16);
  722. memcpy(info.md5, file->md5, 32);
  723. info.block_id = 0;
  724. WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  725. FlushFileBuffers(storage->info_handle);
  726. }
  727. }
  728. if (storage->info_handle != INVALID_HANDLE_VALUE) {
  729. if (storage->offset_block_id) {
  730. //续传
  731. storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
  732. FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  733. } else {
  734. //重新传输,用create_always 清除之前的内容文件
  735. storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
  736. FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  737. }
  738. if (storage->temp_handle != INVALID_HANDLE_VALUE) {
  739. if (storage->offset_block_id) {
  740. //续传,则偏移内容文件游标
  741. SetFilePointer(storage->temp_handle, storage->offset_block_id<<15, NULL, FILE_BEGIN);
  742. }
  743. } else {
  744. //打开不了内容文件,则关闭
  745. download_storage_close(storage,false,false);//关闭
  746. storage = NULL;
  747. }
  748. }else{
  749. //打开并且创建不了文件则返回null;
  750. free(storage);
  751. storage=NULL;
  752. }
  753. }
  754. #else
  755. if (storage) {
  756. sprintf(storage->temp_path, "%s%s%s.temp", base_dir,SPLIT_SLASH_STR, file->name);//临时内容文件
  757. sprintf(storage->info_path, "%s%s%s.info", base_dir, SPLIT_SLASH_STR, file->name);//控制信息文件
  758. storage->info_handle = NULL;
  759. storage->temp_handle = NULL;
  760. storage->length = file->length;
  761. //storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  762. storage->info_handle = fopen(storage->info_path, "rb+");//如文件不存在则创建它,二进制方式打开
  763. if (storage->info_handle == NULL) {
  764. //storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  765. //if (storage->info_handle != INVALID_HANDLE_VALUE) {
  766. // storage_info_t info;
  767. // DWORD dwLen;
  768. // info.length = file->length;
  769. // //memcpy(info.md5, file->md5, 16);
  770. // memcpy(info.md5, file->md5, 32);
  771. // info.block_id = 0;
  772. // WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  773. // FlushFileBuffers(storage->info_handle);
  774. //}
  775. //试着再次创建文件
  776. storage->info_handle = fopen(storage->info_path, "wb+");//如文件不存在则创建它,二进制方式打开
  777. if (storage->info_handle != NULL) {
  778. storage_info_t info;
  779. DWORD dwLen;
  780. info.length = file->length;
  781. //memcpy(info.md5, file->md5, 16);
  782. memcpy(info.md5, file->md5, 32);
  783. info.block_id = 0;
  784. fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
  785. fwrite(&info, sizeof(info), 1, storage->info_handle);
  786. fflush(storage->info_handle);
  787. }
  788. }
  789. else {
  790. storage_info_t info;
  791. DWORD dwLen;
  792. //BOOL bRet = ReadFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  793. int readCount = fread(&info,sizeof(info),1,storage->info_handle);
  794. if (readCount!=0) {
  795. //if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
  796. if (info.length == file->length && memcmp(info.md5, file->md5, 32) == 0) {
  797. // 续传
  798. storage->offset_block_id = info.block_id;
  799. }
  800. else {
  801. // 文件已改变,重新传输
  802. info.length = file->length;
  803. //memcpy(info.md5, file->md5, 16);
  804. memcpy(info.md5, file->md5, 32);
  805. info.block_id = 0;
  806. //WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  807. //FlushFileBuffers(storage->info_handle);
  808. fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
  809. fwrite(&info, sizeof(info), 1, storage->info_handle);
  810. fflush(storage->info_handle);
  811. }
  812. }
  813. else {
  814. //新文件,新传输
  815. info.length = file->length;
  816. //memcpy(info.md5, file->md5, 16);
  817. memcpy(info.md5, file->md5, 32);
  818. info.block_id = 0;
  819. //WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
  820. //FlushFileBuffers(storage->info_handle);
  821. fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
  822. fwrite(&info, sizeof(info), 1, storage->info_handle);
  823. fflush(storage->info_handle);
  824. }
  825. }
  826. if (storage->info_handle != NULL) {
  827. if (storage->offset_block_id) {
  828. //续传
  829. //storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
  830. // FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  831. storage->temp_handle = fopen(storage->temp_path,"ab+");//保留之前的内容
  832. }
  833. else {
  834. //storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
  835. // FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  836. storage->temp_handle = fopen(storage->temp_path, "wb+");//重新传输,用wb+ 清除之前的内容文件
  837. }
  838. if (storage->temp_handle != NULL) {
  839. if (storage->offset_block_id) {
  840. //续传,则偏移内容文件游标
  841. //SetFilePointer(storage->temp_handle, storage->offset_block_id << 15, NULL, FILE_BEGIN);
  842. fseek(storage->temp_handle, storage->offset_block_id << 15, SEEK_SET);
  843. }
  844. }
  845. else {
  846. //打开不了内容文件,则关闭
  847. download_storage_close(storage, false, false);//关闭
  848. storage = NULL;
  849. }
  850. }
  851. else {
  852. //打开并且创建不了文件则返回null;
  853. free(storage);
  854. storage = NULL;
  855. }
  856. }
  857. #endif // RVC_OS_WIN
  858. return storage;
  859. } else {
  860. return NULL;
  861. }
  862. }
  863. //renameFlag:下载完是否改名称,deleteFlag:删除临时文件
  864. void download_storage_close(download_storage_t *storage,bool renameFlag,bool deleteFlag)
  865. {
  866. #ifdef RVC_OS_WIN
  867. if (storage) {
  868. if (storage->info_handle != INVALID_HANDLE_VALUE) {
  869. CloseHandle(storage->info_handle);
  870. storage->info_handle = INVALID_HANDLE_VALUE;
  871. }
  872. if (storage->temp_handle != INVALID_HANDLE_VALUE) {
  873. CloseHandle(storage->temp_handle);
  874. storage->temp_handle = INVALID_HANDLE_VALUE;
  875. }
  876. if (renameFlag) {
  877. if (storage->offset_block_id << 15 >= storage->length) {
  878. char tmp[MAX_PATH];
  879. strcpy(tmp, storage->temp_path);
  880. tmp[strlen(tmp) - 5] = 0;
  881. /*CopyFileA(storage->temp_path, tmp, TRUE);
  882. DeleteFileA(storage->temp_path);*/
  883. MoveFileA(storage->temp_path, tmp);
  884. DeleteFileA(storage->info_path);
  885. }
  886. }
  887. if (deleteFlag) {
  888. DeleteFileA(storage->temp_path);
  889. DeleteFileA(storage->info_path);
  890. }
  891. free(storage);
  892. }
  893. #else
  894. if (storage) {
  895. if (storage->info_handle != NULL) {
  896. fclose(storage->info_handle);
  897. storage->info_handle = NULL;
  898. }
  899. if (storage->temp_handle != NULL) {
  900. fclose(storage->temp_handle);
  901. storage->temp_handle = NULL;
  902. }
  903. if (renameFlag) {
  904. if (storage->offset_block_id << 15 >= storage->length) {
  905. char tmp[MAX_PATH];
  906. strcpy(tmp, storage->temp_path);
  907. tmp[strlen(tmp) - 5] = 0;
  908. /*CopyFileA(storage->temp_path, tmp, TRUE);
  909. DeleteFileA(storage->temp_path);*/
  910. //MoveFileA(storage->temp_path, tmp);
  911. rename(storage->temp_path, tmp);
  912. changeFileAtt((const char*)tmp);
  913. remove(storage->info_path);
  914. //DeleteFileA(storage->info_path);
  915. }
  916. }
  917. if (deleteFlag) {
  918. //DeleteFileA(storage->temp_path);
  919. //DeleteFileA(storage->info_path);
  920. remove(storage->temp_path);
  921. remove(storage->info_path);
  922. }
  923. free(storage);
  924. }
  925. #endif // RVC_OS_WIN
  926. }
  927. int download_storage_update(download_storage_t *storage, char *buf, int n)
  928. {
  929. assert(storage);
  930. #ifdef RVC_OS_WIN
  931. DWORD dwLen;
  932. WriteFile(storage->temp_handle, buf, n, &dwLen, NULL);
  933. FlushFileBuffers(storage->temp_handle);
  934. storage->offset_block_id++;
  935. SetFilePointer(storage->info_handle, 0, NULL, FILE_BEGIN);
  936. WriteFile(storage->info_handle, &storage->offset_block_id, 4, &dwLen, NULL); // 只更新块号字段
  937. FlushFileBuffers(storage->info_handle);
  938. #else
  939. fwrite(buf, n, 1, storage->temp_handle);
  940. fflush(storage->temp_handle);
  941. storage->offset_block_id++;
  942. fseek(storage->info_handle, 0, SEEK_SET);
  943. fwrite(&storage->offset_block_id, 4, 1, storage->info_handle);
  944. fflush(storage->info_handle);
  945. #endif // RVC_OS_WIN
  946. return 0;
  947. }