| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019 |
- #include "stdafx.h"
- #include "SpBase.h"
- #include "SpIni.h"
- #include "download.h"
- #include <fileutil.h>
- #include <memutil.h>
- #include "RVCComm.h"
- #include "scew.h"
- #include <string>
- #ifdef RVC_OS_WIN
- #include <WinCrypt.h>
- #else
- #include <sys/stat.h>
- #include <errno.h>
- #include <iconv.h>
- #endif // RVC_OS_WIN
- using namespace std;
- static __inline int char2hex(char c)
- {
- if (c >= '0' && c<= '9')
- return c-'0';
- else if (c >= 'A' && c <= 'F')
- return c-'A' +10;
- else if (c >= 'a' && c <= 'f')
- return c-'a' +10;
- else
- assert(0);
- return 0;
- }
- //废弃方法
- static void parse_md5_hex(const char *str, char md5[16])
- {
- int i;
- for (i = 0; i < 16; ++i) {
- int h = char2hex(str[2*i]);
- int l = char2hex(str[2*i+1]);
- md5[i] = (h << 4) | l;
- }
- }
- static void parse_SM3_hex(const char *str, char md5[32])
- {
- int i;
- for (i = 0; i < 32; ++i) {
- int h = char2hex(str[2*i]);
- int l = char2hex(str[2*i+1]);
- md5[i] = (h << 4) | l;
- }
- }
- char* ConvertUtf8ToGBK(char* strUtf8)
- {
- #ifdef RVC_OS_WIN
- int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
- WCHAR* wszGBK = new WCHAR[len + 1];
- memset(wszGBK, 0, len * 2 + 2);
- MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len);
- len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
- char* szGBK = new char[len + 1];
- memset(szGBK, 0, len + 1);
- WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
- delete[] wszGBK;
- return szGBK;
- #else
- return NULL;
- #endif // RVC_OS_WIN
- }
- char* ConvertGBKToUtf8(char* gbk, int *n)
- {
- #ifdef RVC_OS_WIN
- int len = MultiByteToWideChar(CP_ACP, 0, gbk, -1, NULL, 0);
- WCHAR* wszGBK = new WCHAR[len + 1];
- memset(wszGBK, 0, len * 2 + 2);
- MultiByteToWideChar(CP_ACP, 0, gbk, -1, wszGBK, len);
-
- len = WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, NULL, 0, NULL, NULL);
- char* szUtf8 = new char[len + 1];
- memset(szUtf8, 0, len + 1);
- WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, szUtf8, len, NULL, NULL);
- delete[] wszGBK;
- *n = len - 1;
- return szUtf8;
- #else:
- return NULL;
- #endif
-
- }
- #ifdef RVC_OS_WIN
- #else
- unsigned char* GBKToUTF8(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;
- }
- char* UTF8ToGBK(const char* string) {
- iconv_t cd;
- const char* from_encoding = "UTF-8";
- size_t result = 0;
- if (string == NULL)
- return NULL;
- cd = iconv_open("CP936", from_encoding);
- if (cd == (iconv_t)-1)
- return NULL;
- //准备转换字符串
- char* inbuf = const_cast<char*>(string);
- size_t inlen = strlen(inbuf);
- size_t outlen = inlen * 4;
- char* outbuf = (char*)malloc(inlen * 4);
- char* in = inbuf;
- char* out = outbuf;
- if (outbuf) {
- memset(outbuf, 0, inlen * 4);
- iconv(cd, &in, &inlen, &out, &outlen);
- }
- iconv_close(cd);
- if (result == (size_t)-1) {
- free(outbuf);
- outbuf = NULL;
- }
- return outbuf;
- }
- int changeFileAtt(const char* path)
- {
- 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 //RVC_OS_WIN
- static download_file_t *parse_file_object(scew_element *elem)
- {
- download_file_t *file = ZALLOC_T(download_file_t);
- if (file) {
- scew_attribute *attr = scew_element_attribute_by_name(elem, "Name");
- if (attr) {
- const char *str = scew_attribute_value(attr);
- if (str) {
- #ifdef RVC_OS_WIN
- char *pGBK = ConvertUtf8ToGBK((char*)str);
- strncpy(file->name, pGBK, sizeof(file->name)-1);
- delete[] pGBK;
- #else
- char* outGBkStr = UTF8ToGBK(str);
- if (outGBkStr == NULL) {
- Dbg("UTF8ToGBK get GBK str is null,xml string : %s", str);
- goto on_error;//直接报错
- }
- strncpy(file->name, (const char*)outGBkStr, sizeof(file->name) - 1);
- free(outGBkStr);
- #endif
- } else {
- goto on_error;
- }
- } else {
- goto on_error;
- }
- attr = scew_element_attribute_by_name(elem, "Length");
- if (attr) {
- const char *str = scew_attribute_value(attr);
- if (str) {
- file->length = atoi(str);
- } else {
- goto on_error;
- }
- } else {
- goto on_error;
- }
- attr = scew_element_attribute_by_name(elem, "MD5");
- if (attr) {
- const char *str = scew_attribute_value(attr);
- if (str) {
- //采用新国密SM3解析接口
- //parse_md5_hex(str, file->md5);
- //Dbg("MD5:%s",str);
- parse_SM3_hex(str,file->md5);
- } else {
- goto on_error;
- }
- } else {
- goto on_error;
- }
- }
- return file;
- on_error:
- if (file) {
- free(file);
- }
- return NULL;
- }
- array_header_t* download_parse_filelist1(const char *xml, int n)
- {
- scew_reader *reader = NULL;
- scew_parser *parser = NULL;
- scew_tree *tree = NULL;
- array_header_t *arr = NULL;
- scew_element *root;
- scew_error code;
- scew_list* lst = NULL;
-
- reader = scew_reader_buffer_create(xml, n);
- if (!reader) {
- Dbg("create scew buffer reader!");
- goto on_error;
- }
- parser = scew_parser_create();
- tree = scew_parser_load(parser, reader);
- if (!tree) {
- code = scew_error_code();
- if (code == scew_error_expat) {
- enum XML_Error expat_code = scew_error_expat_code(parser);
- Dbg("scew parse error:%d, line:%d column:%d %s", expat_code, scew_error_expat_line(parser),
- scew_error_expat_column(parser), scew_error_expat_string(expat_code));
- }
-
- //Dbg("parser xml failed! xml=%s", xml);
- goto on_error;
- }
- root = scew_tree_root(tree);
- if (!root) {
- //Dbg("does not have root element!xml=%s", xml);
- goto on_error;
- }
- lst = scew_element_children(root);
- if (lst) {
- arr = array_make(scew_list_size(lst), sizeof(download_file_t*));
- for (scew_list *it = scew_list_first(lst); it; it = scew_list_next(it)) {
- scew_element *elem = (scew_element*)scew_list_data(it);
- download_file_t *file = parse_file_object(elem);
- if (file) {
- ARRAY_PUSH(arr, download_file_t*) = file;
- } else {
- Dbg("parse file object failed!");
- }
- }
- }
- on_error:
- if (tree) {
- scew_tree_free(tree);
- }
- if (parser) {
- scew_parser_free(parser);
- }
- if (reader) {
- scew_reader_close(reader);
- }
- return arr;
- }
- array_header_t* download_parse_filelist(const char *xml, int n)
- {
- char *pBuf = new char[n+1];
- memset(pBuf, 0, n+1);
- memcpy(pBuf, xml, n);
-
- int nLen = 0;
- #ifdef RVC_OS_WIN
- char* pUtf8 = ConvertGBKToUtf8(pBuf, &nLen);
- #else
- unsigned char* tempStr = GBKToUTF8((const char*)pBuf);
- if (tempStr == NULL) {
- Dbg("get utf8 str is null,xml string : %s",pBuf);
- delete[] pBuf;
- return NULL;//直接报错
- }
- int tempLen = strlen((const char*)tempStr);
- char* pUtf8 = new char[tempLen + 1];
- memset(pUtf8, 0, tempLen + 1);
- memcpy(pUtf8, (const char*)tempStr, tempLen);
- free(tempStr);
- nLen = strlen(pUtf8);
- #endif // RVC_OS_WIN
- auto arr = download_parse_filelist1(pUtf8, nLen);
- if (arr == NULL)
- {
- Dbg("xml string : %s", pBuf);
- }
- delete[] pBuf;
- delete[] pUtf8;
- return arr;
- }
- void download_free_filelist(array_header_t* arr)
- {
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
- free(file);
- }
- free(arr);
- }
- }
- //废弃方法
- static int download_get_file_md5(const char *path, char md5[16])
- {
- #ifdef RVC_OS_WIN
- HCRYPTPROV hCryptProv;
- if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) {
- int rc = Error_Unexpect;
- HCRYPTHASH hHash;
- if (CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) {
- HANDLE hFile = CreateFileA(path, FILE_GENERIC_READ,
- FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile != INVALID_HANDLE_VALUE) {
- char tmp[8192];
- DWORD dwBytesRead;
- BOOL bRet;
- do {
- bRet = ReadFile(hFile, tmp, sizeof(tmp), &dwBytesRead, NULL);
- if (bRet) {
- CryptHashData(hHash, (LPBYTE)tmp, dwBytesRead, 0);
- }
- } while (bRet && dwBytesRead > 0);
- CloseHandle(hFile);
- DWORD dwLen = 16;
- CryptGetHashParam(hHash, HP_HASHVAL, (LPBYTE)&md5[0], &dwLen, 0);
- rc = Error_Succeed;
- }
- else {
- Dbg("file open failed, may be %s does not exist! GetLastError:%d", path, GetLastError());
- }
- CryptDestroyHash(hHash);
- }
- else {
- Dbg("create hash failed!GetLastError:%d", GetLastError());
- }
- CryptReleaseContext(hCryptProv, 0);
- return (ErrorCodeEnum)rc;
- }
- else {
- Dbg("acquire ctx failed!GetLastError:%d", GetLastError());
- return Error_Unexpect;
- }
- #else
- //等国密版本
- #endif // RVC_OS_WIN
- return Error_Unexpect;
-
- }
- static int new_download_get_file_md5(const char *path, BYTE md5[32])
- {
- if(path==NULL){
- Dbg("file path is null");
- return -1;
- }
- int nlen = strlen(path);
- char* pchar = new char[nlen+1];
- strcpy(pchar,path);
- try
- {
- if(SM3File(pchar,md5)){
- delete pchar;
- return 0;
- }else{
- delete pchar;
- Dbg("下载文件sm3国密加密失败,file=%s",path);
- return -1;
- }
- }
- catch (...)
- {
- delete pchar;
- Dbg("下载文件sm3国密加密异常失败,file=%s",path);
- return -2;
- }
-
- }
- //废弃方法
- //int download_check_filelist(const char *base_dir, array_header_t* arr)
- //{
- // int i;
- // char tmp[MAX_PATH];
- // assert(base_dir);
- // assert(arr);
- // i = 0;
- // while (i < arr->nelts) {
- // download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
- // assert(file);
- // sprintf(tmp, "%s\\%s", base_dir, file->name);
- //#ifdef RVC_OS_WIN
- // WIN32_FILE_ATTRIBUTE_DATA attr_data;
- // if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
- // if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) {
- // char md5[16];
- // int rc = download_get_file_md5(tmp, md5);
- // if (rc == 0) {
- // if (memcmp(md5, file->md5, 16) == 0) { // already have remove this file
- // Dbg("file %s the same, remove it!", file->name);
- // ARRAY_DEL(arr, i, download_file_t*);
- // free(file);
- // }
- // else {
- // ++i;
- // }
- // }
- // else {
- // ++i;
- // }
- // }
- // else {
- // ++i;
- // }
- // }
- // else {
- // ++i;
- // }
- //#endif // RVC_OS_WIN
- //
- //
- // }
- // return 0;
- //}
- int new_download_check_filelist(const char *base_dir, array_header_t* arr,download_file_t *downloadFile){
- int ret=0; //表示下载的文件在文件列表里不存在
- int i;
- char tmp[MAX_PATH];
- assert(base_dir);
- assert(arr);
- i = 0;
- while (i<arr->nelts){
- download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
- assert(file);
- Dbg("download_check_filelist request downloadFile->name:[%s] ,fileList->name : [%s]", downloadFile->name, (const char*)file->name);
- if (strcmp((const char* )downloadFile->name, (const char*)file->name) == 0) {
- sprintf(tmp, "%s%s%s", base_dir, SPLIT_SLASH_STR, downloadFile->name);
- #ifdef RVC_OS_WIN
- WIN32_FILE_ATTRIBUTE_DATA attr_data;
- if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
- if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) {
- //char md5[16];
- BYTE md5[32];
- int rc = new_download_get_file_md5(tmp, md5);
- if(rc==0){
- //if (memcmp(md5, file->md5, 16) == 0) {
- if (memcmp(md5, file->md5, 32) == 0) {
- //文件长度,md5完全相同,告知下载完成
- Dbg("file %s the same, remove it!", file->name);
- ret = 2;
- break;
- }else{
- //md5不相等,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5, file->md5, 16);
- memcpy(downloadFile->md5, file->md5, 32);
- break;
- }
- }else{
- //获取md5报错,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5,file->md5,16);
- memcpy(downloadFile->md5,file->md5,32);
- break;
- }
- }else{
- //文件长度不相同,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5,file->md5,16);
- memcpy(downloadFile->md5,file->md5,32);
- break;
- }
- }else{
- //获取不到文件,需要下载
- Dbg("file is not exist , fileName is [%s]", (LPCSTR)tmp);
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5,file->md5,16);
- memcpy(downloadFile->md5,file->md5,32);
- break;
- }
- #else
- struct stat attr_of_src;
- if (lstat(tmp, &attr_of_src) == 0)
- {
- if (attr_of_src.st_size== file->length) {
- //char md5[16];
- BYTE md5[32];
- int rc = new_download_get_file_md5(tmp, md5);
- if (rc == 0) {
- //if (memcmp(md5, file->md5, 16) == 0) {
- if (memcmp(md5, file->md5, 32) == 0) {
- //文件长度,md5完全相同,告知下载完成
- Dbg("file %s the same, remove it!", file->name);
- ret = 2;
- break;
- }
- else {
- //md5不相等,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5, file->md5, 16);
- memcpy(downloadFile->md5, file->md5, 32);
- break;
- }
- }
- else {
- //获取md5报错,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5, file->md5, 16);
- memcpy(downloadFile->md5, file->md5, 32);
- break;
- }
- }
- else {
- //文件长度不相同,需要下载
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5, file->md5, 16);
- memcpy(downloadFile->md5, file->md5, 32);
- break;
- }
- }
- else
- {
- //获取不到文件,需要下载
- Dbg("file is not exist , fileName is [%s]", (const char*)tmp);
- ret = 1;
- downloadFile->length = file->length;
- //memcpy(downloadFile->md5, file->md5, 16);
- memcpy(downloadFile->md5, file->md5, 32);
- break;
- }
- #endif
- }
- else {
- i++;
- }
-
- }
- return ret;
- }
- //SM3Byte is 16 or 32
- //SM3_len is 32 or 64
- char* SM3_Str (BYTE * SM3Byte, int SM3_len)
- {
- if(SM3Byte == NULL){
- return NULL;
- }
- int i;
- char* file_SM3 = (char*)malloc((SM3_len + 1) * sizeof(char));
- if(file_SM3 == NULL)
- {
- fprintf(stderr, "SM3 malloc failed.\n");
- return NULL;
- }
- memset(file_SM3, 0, (SM3_len + 1));
- if(SM3_len == 32)
- {
- for(i=0; i<16; i++)
- {
- sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);
- }
- }
- else if(SM3_len == 64)
- {
- for(i=0; i<32; i++)
- {
- sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);
- }
- }
- else
- {
- free(file_SM3);
- return NULL;
- }
- return file_SM3;
- }
- int download_check_MD5(download_storage_t *storage,download_file_t *dfile){
- int ret=0;
- //char md5[16];
- BYTE md5[32]={0};
- //计算sm3的加密时间
- CSmallDateTime beginT = CSmallDateTime::GetNow();
- int rc = new_download_get_file_md5(storage->temp_path, md5);//计算出临时文件md5值
- CSmallDateTime endT = CSmallDateTime::GetNow();
- Dbg("下载文件国密获取的SM3耗时%d秒",(DWORD)(endT-beginT));
-
- if(rc==0){
- //试着打印已下载文件的SM3的16进制值
- char* fSM3 = SM3_Str(md5,64);
- if(fSM3!=NULL){
- Dbg("下载文件国密获取的SM3=%s",fSM3);
- free(fSM3);
- }
- //if (memcmp(md5, dfile->md5, 16) == 0) {
- if (memcmp(md5, dfile->md5, 32) == 0) {
- //下载临时文件和文件列表md5一致
- ret=0;
- }else{
- //下载临时文件和文件列表md5不一致,需要下载
- Dbg("下载文件SM3值和服务器文件SM3值不同,需要重新下载");
- ret=1;
- }
- }else{
- //获取临时文件md5报错
- ret=2;
- }
- return ret;
- }
- int download_delete_file(const char *base_dir,download_file_t *downloadFile){
- char tmp[MAX_PATH];
- assert(base_dir);
- sprintf(tmp, "%s%s%s", base_dir, SPLIT_SLASH_STR, downloadFile->name);
- FILE * fh = fopen(tmp,"r");
- if(fh == NULL)
- {
- return 1;
- }else{
- fclose(fh);//先关闭文件
- #ifdef RVC_OS_WIN
- if (DeleteFileA(tmp)) {
- Dbg("same download file [%s] delete success ", (LPCSTR)tmp);
- return 1;
- }
- else {
- DWORD err = GetLastError();
- char* pErrmsg = strerror((int)err);
- Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (LPCSTR)tmp, err, (LPCSTR)pErrmsg);
- return 0;
- }
- #else
- if (remove(tmp)==0) {
- Dbg("same download file [%s] delete success ", (const char*)tmp);
- return 1;
- }
- else {
- char* pErrmsg = strerror(errno);
- Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (const char*)tmp, errno, (const char*)pErrmsg);
- return 0;
- }
- #endif // RVC_OS_WIN
-
- }
- }
- #if 0
- int download_get_storage_block_id(const char *base_dir, download_file_t *file, int *block_id)
- {
- char temp_path[MAX_PATH];
- char info_path[MAX_PATH];
- //sprintf(temp_path, "%s\\%s.temp", base_dir, file->name);
- sprintf(temp_path, "%s\\%s.info", base_dir, file->name);
- return 0;
- }
- #endif
- typedef struct storage_info_t {
- int block_id;
- //char md5[16];
- char md5[32];
- int length;
- }storage_info_t;
- download_storage_t *download_storage_open(const char *base_dir, download_file_t *file)
- {
- if (base_dir && file) {
- download_storage_t *storage = ZALLOC_T(download_storage_t);//清零初始化
- #ifdef RVC_OS_WIN
- if (storage) {
- sprintf(storage->temp_path, "%s%s%s.temp", base_dir, SPLIT_SLASH_STR, file->name);//临时内容文件
- sprintf(storage->info_path, "%s%s%s.info", base_dir, SPLIT_SLASH_STR, file->name);//控制信息文件
- storage->info_handle = INVALID_HANDLE_VALUE;
- storage->temp_handle = INVALID_HANDLE_VALUE;
- storage->length = file->length;
- storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (storage->info_handle == INVALID_HANDLE_VALUE) {
- storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (storage->info_handle != INVALID_HANDLE_VALUE) {
- storage_info_t info;
- DWORD dwLen;
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- FlushFileBuffers(storage->info_handle);
- }
- } else {
- storage_info_t info;
- DWORD dwLen;
- BOOL bRet = ReadFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- if (bRet && dwLen == sizeof(info)) {
- //if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
- if (info.length == file->length && memcmp(info.md5, file->md5, 32) == 0) {
- // 续传
- storage->offset_block_id = info.block_id;
- } else {
- // 文件已改变,重新传输
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- FlushFileBuffers(storage->info_handle);
- }
- } else {
- //新文件,新传输
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- FlushFileBuffers(storage->info_handle);
- }
- }
- if (storage->info_handle != INVALID_HANDLE_VALUE) {
- if (storage->offset_block_id) {
- //续传
- storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
- FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- } else {
- //重新传输,用create_always 清除之前的内容文件
- storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
- FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- }
- if (storage->temp_handle != INVALID_HANDLE_VALUE) {
- if (storage->offset_block_id) {
- //续传,则偏移内容文件游标
- SetFilePointer(storage->temp_handle, storage->offset_block_id<<15, NULL, FILE_BEGIN);
- }
- } else {
- //打开不了内容文件,则关闭
- download_storage_close(storage,false,false);//关闭
- storage = NULL;
- }
- }else{
- //打开并且创建不了文件则返回null;
- free(storage);
- storage=NULL;
- }
- }
- #else
- if (storage) {
- sprintf(storage->temp_path, "%s%s%s.temp", base_dir,SPLIT_SLASH_STR, file->name);//临时内容文件
- sprintf(storage->info_path, "%s%s%s.info", base_dir, SPLIT_SLASH_STR, file->name);//控制信息文件
- storage->info_handle = NULL;
- storage->temp_handle = NULL;
- storage->length = file->length;
- //storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- storage->info_handle = fopen(storage->info_path, "rb+");//如文件不存在则创建它,二进制方式打开
- if (storage->info_handle == NULL) {
- //storage->info_handle = CreateFileA(storage->info_path, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- //if (storage->info_handle != INVALID_HANDLE_VALUE) {
- // storage_info_t info;
- // DWORD dwLen;
- // info.length = file->length;
- // //memcpy(info.md5, file->md5, 16);
- // memcpy(info.md5, file->md5, 32);
- // info.block_id = 0;
- // WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- // FlushFileBuffers(storage->info_handle);
- //}
- //试着再次创建文件
- storage->info_handle = fopen(storage->info_path, "wb+");//如文件不存在则创建它,二进制方式打开
- if (storage->info_handle != NULL) {
- storage_info_t info;
- DWORD dwLen;
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
- fwrite(&info, sizeof(info), 1, storage->info_handle);
- fflush(storage->info_handle);
- }
- }
- else {
- storage_info_t info;
- DWORD dwLen;
- //BOOL bRet = ReadFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- int readCount = fread(&info,sizeof(info),1,storage->info_handle);
- if (readCount!=0) {
- //if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
- if (info.length == file->length && memcmp(info.md5, file->md5, 32) == 0) {
- // 续传
- storage->offset_block_id = info.block_id;
- }
- else {
- // 文件已改变,重新传输
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- //WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- //FlushFileBuffers(storage->info_handle);
- fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
- fwrite(&info, sizeof(info), 1, storage->info_handle);
- fflush(storage->info_handle);
- }
- }
- else {
- //新文件,新传输
- info.length = file->length;
- //memcpy(info.md5, file->md5, 16);
- memcpy(info.md5, file->md5, 32);
- info.block_id = 0;
- //WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
- //FlushFileBuffers(storage->info_handle);
- fseek(storage->info_handle, 0, SEEK_SET);//设置到起始位置
- fwrite(&info, sizeof(info), 1, storage->info_handle);
- fflush(storage->info_handle);
- }
- }
- if (storage->info_handle != NULL) {
- if (storage->offset_block_id) {
- //续传
- //storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
- // FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- storage->temp_handle = fopen(storage->temp_path,"ab+");//保留之前的内容
- }
- else {
- //storage->temp_handle = CreateFileA(storage->temp_path, GENERIC_ALL,
- // FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- storage->temp_handle = fopen(storage->temp_path, "wb+");//重新传输,用wb+ 清除之前的内容文件
- }
- if (storage->temp_handle != NULL) {
- if (storage->offset_block_id) {
- //续传,则偏移内容文件游标
- //SetFilePointer(storage->temp_handle, storage->offset_block_id << 15, NULL, FILE_BEGIN);
- fseek(storage->temp_handle, storage->offset_block_id << 15, SEEK_SET);
- }
- }
- else {
- //打开不了内容文件,则关闭
- download_storage_close(storage, false, false);//关闭
- storage = NULL;
- }
- }
- else {
- //打开并且创建不了文件则返回null;
- free(storage);
- storage = NULL;
- }
- }
- #endif // RVC_OS_WIN
- return storage;
- } else {
- return NULL;
- }
- }
- //renameFlag:下载完是否改名称,deleteFlag:删除临时文件
- void download_storage_close(download_storage_t *storage,bool renameFlag,bool deleteFlag)
- {
- #ifdef RVC_OS_WIN
- if (storage) {
- if (storage->info_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(storage->info_handle);
- storage->info_handle = INVALID_HANDLE_VALUE;
- }
- if (storage->temp_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(storage->temp_handle);
- storage->temp_handle = INVALID_HANDLE_VALUE;
- }
- if (renameFlag) {
- if (storage->offset_block_id << 15 >= storage->length) {
- char tmp[MAX_PATH];
- strcpy(tmp, storage->temp_path);
- tmp[strlen(tmp) - 5] = 0;
- /*CopyFileA(storage->temp_path, tmp, TRUE);
- DeleteFileA(storage->temp_path);*/
- MoveFileA(storage->temp_path, tmp);
- DeleteFileA(storage->info_path);
- }
- }
- if (deleteFlag) {
- DeleteFileA(storage->temp_path);
- DeleteFileA(storage->info_path);
- }
- free(storage);
- }
- #else
- if (storage) {
- if (storage->info_handle != NULL) {
- fclose(storage->info_handle);
- storage->info_handle = NULL;
- }
- if (storage->temp_handle != NULL) {
- fclose(storage->temp_handle);
- storage->temp_handle = NULL;
- }
- if (renameFlag) {
- if (storage->offset_block_id << 15 >= storage->length) {
- char tmp[MAX_PATH];
- strcpy(tmp, storage->temp_path);
- tmp[strlen(tmp) - 5] = 0;
- /*CopyFileA(storage->temp_path, tmp, TRUE);
- DeleteFileA(storage->temp_path);*/
- //MoveFileA(storage->temp_path, tmp);
- rename(storage->temp_path, tmp);
- changeFileAtt((const char*)tmp);
- remove(storage->info_path);
- //DeleteFileA(storage->info_path);
- }
- }
- if (deleteFlag) {
- //DeleteFileA(storage->temp_path);
- //DeleteFileA(storage->info_path);
- remove(storage->temp_path);
- remove(storage->info_path);
- }
- free(storage);
- }
- #endif // RVC_OS_WIN
- }
- int download_storage_update(download_storage_t *storage, char *buf, int n)
- {
- assert(storage);
- #ifdef RVC_OS_WIN
- DWORD dwLen;
- WriteFile(storage->temp_handle, buf, n, &dwLen, NULL);
- FlushFileBuffers(storage->temp_handle);
- storage->offset_block_id++;
- SetFilePointer(storage->info_handle, 0, NULL, FILE_BEGIN);
- WriteFile(storage->info_handle, &storage->offset_block_id, 4, &dwLen, NULL); // 只更新块号字段
- FlushFileBuffers(storage->info_handle);
- #else
- fwrite(buf, n, 1, storage->temp_handle);
- fflush(storage->temp_handle);
- storage->offset_block_id++;
- fseek(storage->info_handle, 0, SEEK_SET);
- fwrite(&storage->offset_block_id, 4, 1, storage->info_handle);
- fflush(storage->info_handle);
- #endif // RVC_OS_WIN
- return 0;
- }
|