//--------------------------------------------------------------------------// //--------------------------------------------------------------------------// Font::CacheEntry* Font::find_cached(const String &msg){ Hash_t hash =gen_hash( (const byte*)&m_position, sizeof(m_position) ); hash =gen_hash(msg, hash); for(Cache::iterator it=m_cache.begin(); it!=m_cache.end();++it){ if( it->hash == hash ) return &*it; } return NULL; }
//--------------------------------------------------------------------------// //--------------------------------------------------------------------------// Font::CacheEntry* Font::cache(const String &msg){ m_cache.push_back( CacheEntry() ); CacheEntry &ce=m_cache.back(); ce.hash =gen_hash( (const byte*)&m_position, sizeof(m_position) ); ce.hash =gen_hash(msg, ce.hash); ce.lastUsed =m_counter; ce.vertCount =msg.length()*4; ce.verts =new Vertex[ce.vertCount]; m_cacheUpdated =false; return &ce; }
int tsht_remove(TSHTable *ht, char *str, void **datum) { unsigned long hash; H_Entry *p, *q; int found = 0; pthread_mutex_lock(&(ht->lock)); hash = gen_hash(str, ht->size); p = ht->table[hash].first; q = NULL; while (p != NULL) { if (strcmp(str, p->key) == 0) { found++; break; } q = p; p = q->next; } if (found) { *datum = p->datum; if (q == NULL) ht->table[hash].first = p->next; else q->next = p->next; ht->nelements--; mem_free((void *)p->key); mem_free((void *)p); } pthread_mutex_unlock(&(ht->lock)); return found; }
/* * This function tries to find a running server for the proxy <px> following * the URL parameter hash method. It looks for a specific parameter in the * URL and hashes it to compute the server ID. This is useful to optimize * performance by avoiding bounces between servers in contexts where sessions * are shared but cookies are not usable. If the parameter is not found, NULL * is returned. If any server is found, it will be returned. If no valid server * is found, NULL is returned. */ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len) { unsigned int hash = 0; const char *start, *end; const char *p; const char *params; int plen; /* when tot_weight is 0 then so is srv_count */ if (px->lbprm.tot_weight == 0) return NULL; if ((p = memchr(uri, '?', uri_len)) == NULL) return NULL; p++; uri_len -= (p - uri); plen = px->url_param_len; params = p; while (uri_len > plen) { /* Look for the parameter name followed by an equal symbol */ if (params[plen] == '=') { if (memcmp(params, px->url_param_name, plen) == 0) { /* OK, we have the parameter here at <params>, and * the value after the equal sign, at <p> * skip the equal symbol */ p += plen + 1; start = end = p; uri_len -= plen + 1; while (uri_len && *end != '&') { uri_len--; end++; } hash = gen_hash(px, start, (end - start)); if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) hash = full_hash(hash); if (px->lbprm.algo & BE_LB_LKUP_CHTREE) return chash_get_server_hash(px, hash); else return map_get_server_hash(px, hash); } } /* skip to next parameter */ p = memchr(params, '&', uri_len); if (!p) return NULL; p++; uri_len -= (p - params); params = p; } return NULL; }
void scanDataFileBefore(HTree* tree, int bucket, const char* path, time_t before) { MFile *f = open_mfile(path); if (f == NULL) return; fprintf(stderr, "scan datafile %s before %ld\n", path, before); char *p = f->addr, *end = f->addr + f->size; int broken = 0; while (p < end) { DataRecord *r = decode_record(p, end-p, false); if (r != NULL) { if (r->tstamp >= before ){ break; } uint32_t pos = p - f->addr; p += record_length(r); r = decompress_record(r); uint16_t hash = gen_hash(r->value, r->vsz); if (r->version > 0){ uint16_t hash = gen_hash(r->value, r->vsz); ht_add2(tree, r->key, r->ksz, pos | bucket, hash, r->version); }else{ ht_remove2(tree, r->key, r->ksz); } free_record(r); } else { broken ++; if (broken > 40960) { // 10M fprintf(stderr, "unexpected broken data in %s at %ld\n", path, p - f->addr - broken * PADDING); break; } p += PADDING; } } close_mfile(f); }
void *tsht_lookup(TSHTable *ht, char *str) { unsigned long hash; H_Entry *p; pthread_mutex_lock(&(ht->lock)); hash = gen_hash(str, ht->size); p = ht->table[hash].first; while (p != NULL) { if (strcmp(str, p->key) == 0) { pthread_mutex_unlock(&(ht->lock)); return p->datum; } p = p->next; } pthread_mutex_unlock(&(ht->lock)); return NULL; }
char *hs_get(HStore *store, char *key, int *vlen, uint32_t *flag) { if (!key || !store) return NULL; if (key[0] == '@'){ char *r = hs_list(store, key+1); if (r) *vlen = strlen(r); *flag = 0; return r; } bool info = false; if (key[0] == '?'){ info = true; key ++; } int index = get_index(store, key); DataRecord *r = bc_get(store->bitcasks[index], key); if (r == NULL){ return NULL; } char *res = NULL; if (info){ res = malloc(256); if (!res) { free_record(r); return NULL; } uint16_t hash = 0; if (r->version > 0){ hash = gen_hash(r->value, r->vsz); } *vlen = snprintf(res, 255, "%d %u %u %u %u", r->version, hash, r->flag, r->vsz, r->tstamp); *flag = 0; }else if (r->version > 0){ res = record_value(r); r->value = NULL; *vlen = r->vsz; *flag = r->flag; } free_record(r); return res; }
/* RDP Cookie HASH. */ struct server *get_server_rch(struct session *s) { unsigned int hash = 0; struct proxy *px = s->be; unsigned long len; int ret; struct sample smp; int rewind; /* tot_weight appears to mean srv_count */ if (px->lbprm.tot_weight == 0) return NULL; memset(&smp, 0, sizeof(smp)); b_rew(s->req.buf, rewind = s->req.buf->o); ret = fetch_rdp_cookie_name(s, &smp, px->hh_name, px->hh_len); len = smp.data.str.len; b_adv(s->req.buf, rewind); if (ret == 0 || (smp.flags & SMP_F_MAY_CHANGE) || len == 0) return NULL; /* note: we won't hash if there's only one server left */ if (px->lbprm.tot_used == 1) goto hash_done; /* Found a the hh_name in the headers. * we will compute the hash based on this value ctx.val. */ hash = gen_hash(px, smp.data.str.str, len); if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) hash = full_hash(hash); hash_done: if (px->lbprm.algo & BE_LB_LKUP_CHTREE) return chash_get_server_hash(px, hash); else return map_get_server_hash(px, hash); }
/* * This function tries to find a running server for the proxy <px> following * the URI hash method. In order to optimize cache hits, the hash computation * ends at the question mark. Depending on the number of active/backup servers, * it will either look for active servers, or for backup servers. * If any server is found, it will be returned. If no valid server is found, * NULL is returned. * * This code was contributed by Guillaume Dallaire, who also selected this hash * algorithm out of a tens because it gave him the best results. * */ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len) { unsigned int hash = 0; int c; int slashes = 0; const char *start, *end; if (px->lbprm.tot_weight == 0) return NULL; /* note: we won't hash if there's only one server left */ if (px->lbprm.tot_used == 1) goto hash_done; if (px->uri_len_limit) uri_len = MIN(uri_len, px->uri_len_limit); start = end = uri; while (uri_len--) { c = *end; if (c == '/') { slashes++; if (slashes == px->uri_dirs_depth1) /* depth+1 */ break; } else if (c == '?' && !px->uri_whole) break; end++; } hash = gen_hash(px, start, (end - start)); if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) hash = full_hash(hash); hash_done: if (px->lbprm.algo & BE_LB_LKUP_CHTREE) return chash_get_server_hash(px, hash); else return map_get_server_hash(px, hash); }
int tsht_insert(TSHTable *ht, char *str, void *datum, void **old) { unsigned long hash; H_Entry *p; pthread_mutex_lock(&(ht->lock)); hash = gen_hash(str, ht->size); p = ht->table[hash].first; while (p != NULL) { if (strcmp(str, p->key) == 0) { *old = p->datum; p->datum = datum; pthread_mutex_unlock(&(ht->lock)); return 1; } p = p->next; } p = (H_Entry *)mem_alloc(sizeof(H_Entry)); if (p != NULL) { char *s = strdup(str); if (s == NULL) { mem_free((void *)p); pthread_mutex_unlock(&(ht->lock)); return 0; } p->key = s; p->datum = datum; p->next = ht->table[hash].first; ht->table[hash].first = p; ht->nelements++; pthread_mutex_unlock(&(ht->lock)); *old = NULL; return 1; } pthread_mutex_unlock(&(ht->lock)); return 0; }
void miner_gen_nonce2_work(struct mm_work *mw, uint32_t nonce2, struct work *work) { uint8_t merkle_root[32], merkle_sha[64]; uint32_t *data32, *swap32, tmp32; int i; tmp32 = bswap_32(nonce2); memcpy(mw->coinbase + mw->nonce2_offset, (uint8_t *)(&tmp32), sizeof(uint32_t)); work->nonce2 = nonce2; gen_hash(mw->coinbase, merkle_root, mw->coinbase_len); memcpy(merkle_sha, merkle_root, 32); for (i = 0; i < mw->nmerkles; i++) { memcpy(merkle_sha + 32, mw->merkles[i], 32); gen_hash(merkle_sha, merkle_root, 64); memcpy(merkle_sha, merkle_root, 32); } data32 = (uint32_t *)merkle_sha; swap32 = (uint32_t *)merkle_root; flip32(swap32, data32); memcpy(mw->header + mw->merkle_offset, merkle_root, 32); debug32("D: Work nonce2: %08x\n", work->nonce2); calc_midstate(mw, work); uint8_t work_t[44]; #ifdef HW_PRE_CALC uint8_t work_t[] = { 0x05, 0x4e, 0x53, 0xc3, 0xc4, 0xd4, 0xba, 0x3e, 0x65, 0x40, 0x99, 0x4f, 0x06, 0x67, 0x91, 0x31, 0xa7, 0x2d, 0x66, 0xaa, 0x68, 0x4f, 0x0e, 0xdb, 0xc3, 0x6d, 0x95, 0x8a, 0x46, 0x6e, 0x4d, 0xb2, 0x1c, 0x26, 0x52, 0xfb, 0x52, 0xa0, 0x26, 0xf4, 0x19, 0x06, 0x12, 0x42}; #endif memcpy(work_t, work->data, 44); rev(work_t, 32); rev(work_t + 32, 12); memcpy(work->data, work_t, 44); #ifdef HW_PRE_CALC calc_prepare(work, work_t); memcpy((uint8_t *)(&tmp32), work->a1, 4); debug32("%08x,", tmp32); memcpy((uint8_t *)(&tmp32), work->a0, 4); debug32("%08x,", tmp32); memcpy((uint8_t *)(&tmp32), work->e2, 4); debug32("%08x,", tmp32); memcpy((uint8_t *)(&tmp32), work->e1, 4); debug32("%08x,", tmp32); memcpy((uint8_t *)(&tmp32), work->e0, 4); debug32("%08x,", tmp32); memcpy((uint8_t *)(&tmp32), work->a2, 4); debug32("%08x", tmp32); debug32("\n"); #endif calc_prepare1(work, work->data); memcpy((uint8_t *)(&tmp32), work->a1, 4); memcpy((uint8_t *)(&tmp32), work->a0, 4); memcpy((uint8_t *)(&tmp32), work->e2, 4); memcpy((uint8_t *)(&tmp32), work->e1, 4); memcpy((uint8_t *)(&tmp32), work->e0, 4); memcpy((uint8_t *)(&tmp32), work->a2, 4); }
/* * This function tries to find a running server for the proxy <px> following * the Header parameter hash method. It looks for a specific parameter in the * URL and hashes it to compute the server ID. This is useful to optimize * performance by avoiding bounces between servers in contexts where sessions * are shared but cookies are not usable. If the parameter is not found, NULL * is returned. If any server is found, it will be returned. If no valid server * is found, NULL is returned. */ struct server *get_server_hh(struct session *s) { unsigned int hash = 0; struct http_txn *txn = &s->txn; struct proxy *px = s->be; unsigned int plen = px->hh_len; unsigned long len; struct hdr_ctx ctx; const char *p; const char *start, *end; /* tot_weight appears to mean srv_count */ if (px->lbprm.tot_weight == 0) return NULL; ctx.idx = 0; /* if the message is chunked, we skip the chunk size, but use the value as len */ http_find_header2(px->hh_name, plen, b_ptr(s->req.buf, -http_hdr_rewind(&txn->req)), &txn->hdr_idx, &ctx); /* if the header is not found or empty, let's fallback to round robin */ if (!ctx.idx || !ctx.vlen) return NULL; /* note: we won't hash if there's only one server left */ if (px->lbprm.tot_used == 1) goto hash_done; /* Found a the hh_name in the headers. * we will compute the hash based on this value ctx.val. */ len = ctx.vlen; p = (char *)ctx.line + ctx.val; if (!px->hh_match_domain) { hash = gen_hash(px, p, len); } else { int dohash = 0; p += len; /* special computation, use only main domain name, not tld/host * going back from the end of string, start hashing at first * dot stop at next. * This is designed to work with the 'Host' header, and requires * a special option to activate this. */ end = p; while (len) { if (dohash) { /* Rewind the pointer until the previous char * is a dot, this will allow to set the start * position of the domain. */ if (*(p - 1) == '.') break; } else if (*p == '.') { /* The pointer is rewinded to the dot before the * tld, we memorize the end of the domain and * can enter the domain processing. */ end = p; dohash = 1; } p--; len--; } start = p; hash = gen_hash(px, start, (end - start)); } if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) hash = full_hash(hash); hash_done: if (px->lbprm.algo & BE_LB_LKUP_CHTREE) return chash_get_server_hash(px, hash); else return map_get_server_hash(px, hash); }
/* * this does the same as the previous server_ph, but check the body contents */ struct server *get_server_ph_post(struct session *s) { unsigned int hash = 0; struct http_txn *txn = &s->txn; struct channel *req = &s->req; struct http_msg *msg = &txn->req; struct proxy *px = s->be; unsigned int plen = px->url_param_len; unsigned long len = http_body_bytes(msg); const char *params = b_ptr(req->buf, -http_data_rewind(msg)); const char *p = params; const char *start, *end; if (len == 0) return NULL; if (px->lbprm.tot_weight == 0) return NULL; while (len > plen) { /* Look for the parameter name followed by an equal symbol */ if (params[plen] == '=') { if (memcmp(params, px->url_param_name, plen) == 0) { /* OK, we have the parameter here at <params>, and * the value after the equal sign, at <p> * skip the equal symbol */ p += plen + 1; start = end = p; len -= plen + 1; while (len && *end != '&') { if (unlikely(!HTTP_IS_TOKEN(*p))) { /* if in a POST, body must be URI encoded or it's not a URI. * Do not interpret any possible binary data as a parameter. */ if (likely(HTTP_IS_LWS(*p))) /* eol, uncertain uri len */ break; return NULL; /* oh, no; this is not uri-encoded. * This body does not contain parameters. */ } len--; end++; /* should we break if vlen exceeds limit? */ } hash = gen_hash(px, start, (end - start)); if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) hash = full_hash(hash); if (px->lbprm.algo & BE_LB_LKUP_CHTREE) return chash_get_server_hash(px, hash); else return map_get_server_hash(px, hash); } } /* skip to next parameter */ p = memchr(params, '&', len); if (!p) return NULL; p++; len -= (p - params); params = p; } return NULL; }
bool bc_set(Bitcask *bc, const char* key, char* value, int vlen, int flag, int version) { if (version < 0 && vlen > 0 || vlen > MAX_RECORD_SIZE) { fprintf(stderr, "invalid set cmd \n"); return false; } bool suc = false; pthread_mutex_lock(&bc->write_lock); int oldv = 0, ver = version; Item *it = ht_get(bc->tree, key); if (it != NULL) { oldv = it->ver; } if (version == 0 && oldv > 0) // replace { ver = oldv + 1; } else if (version == 0 && oldv <= 0) // add { ver = -oldv + 1; } else if (version < 0 && oldv <= 0) // delete, not exist { goto SET_FAIL; } else if (version == -1) // delete { ver = - abs(oldv) - 1; } else if (abs(version) <= abs(oldv)) // sync { goto SET_FAIL; } else // sync { ver = version; } uint16_t hash = gen_hash(value, vlen); if (ver < 0) hash = 0; if (NULL != it && hash == it->hash) { DataRecord *r = bc_get(bc, key); if (r != NULL && r->flag == flag && vlen == r->vsz && memcmp(value, r->value, vlen) == 0) { if (version != 0) { // update version if (it->pos & 0xff == bc->curr) { ht_add(bc->curr_tree, key, it->pos, it->hash, ver); } ht_add(bc->tree, key, it->pos, it->hash, ver); } suc = true; free_record(r); goto SET_FAIL; } if (r != NULL) free_record(r); } int klen = strlen(key); DataRecord *r = (DataRecord*)malloc(sizeof(DataRecord) + klen); r->ksz = klen; memcpy(r->key, key, klen); r->vsz = vlen; r->value = value; r->free_value = false; r->flag = flag; r->version = ver; r->tstamp = time(NULL); int rlen; char *rbuf = encode_record(r, &rlen); if (rbuf == NULL || (rlen & 0xff) != 0) { fprintf(stderr, "encode_record() failed with %d\n", rlen); if (rbuf != NULL) free(rbuf); goto SET_FAIL; } pthread_mutex_lock(&bc->buffer_lock); // record maybe larger than buffer if (bc->wbuf_curr_pos + rlen > bc->wbuf_size) { pthread_mutex_unlock(&bc->buffer_lock); bc_flush(bc, 0, 0); pthread_mutex_lock(&bc->buffer_lock); while (rlen > bc->wbuf_size) { bc->wbuf_size *= 2; free(bc->write_buffer); bc->write_buffer = (char*)malloc(bc->wbuf_size); } if (bc->wbuf_start_pos + bc->wbuf_size > MAX_BUCKET_SIZE) { bc_rotate(bc); } } memcpy(bc->write_buffer + bc->wbuf_curr_pos, rbuf, rlen); int pos = (bc->wbuf_start_pos + bc->wbuf_curr_pos) | bc->curr; bc->wbuf_curr_pos += rlen; pthread_mutex_unlock(&bc->buffer_lock); ht_add(bc->curr_tree, key, pos, hash, ver); ht_add(bc->tree, key, pos, hash, ver); suc = true; free(rbuf); free_record(r); SET_FAIL: pthread_mutex_unlock(&bc->write_lock); if (it != NULL) free(it); return suc; }
/* DDS3.2.3: Authenticate */ int main(int argc, char *argv[]) { struct http_vars *vars; struct barcode_hash_entry *bcentry; struct barcode bc; char bchash[HASH_BITS+1]; struct electorate *elecs, *i; PGconn *conn; int ppcode; /* Our own failure function */ set_cgi_bailout(); /* Can be called on slave as well as master */ conn = connect_db_port("evacs", get_database_port()); if (!conn) bailout("Could not open database connection\n"); /* Copy barcode ascii code from POST arguments */ vars = cgi_get_arguments(); strncpy(bc.ascii, http_string(vars, "barcode"), sizeof(bc.ascii)-1); bc.ascii[sizeof(bc.ascii)-1] = '\0'; http_free(vars); /* Extract data and checksum from ascii */ if (!bar_decode_ascii(&bc)) cgi_error_response(ERR_BARCODE_MISREAD); /* Hash the barcode to look up in the table */ gen_hash(bchash, bc.data, sizeof(bc.data)); bcentry = get_bhash_table(conn, bchash); if (!bcentry) { PQfinish(conn); fprintf(stderr, "Barcode `%s' not found\n", bc.ascii); cgi_error_response(ERR_BARCODE_AUTHENTICATION_FAILED); } /* DDS3.2.4: Check Unused */ if (bcentry->used) { PQfinish(conn); fprintf(stderr, "Barcode `%s' already used\n", bc.ascii); cgi_error_response(ERR_BARCODE_USED); } ppcode = SQL_singleton_int(conn,"SELECT polling_place_code " "FROM server_parameter;"); if (ppcode < 0) { PQfinish(conn); cgi_error_response(ERR_SERVER_INTERNAL); } if (ppcode != bcentry->ppcode) { PQfinish(conn); cgi_error_response(ERR_BARCODE_PP_INCORRECT); } elecs = get_electorates(conn); for (i = elecs; i; i = i->next) { if (i->code == bcentry->ecode) { /* Found it! */ vars = create_response(conn, i); free_electorates(elecs); PQfinish(conn); cgi_good_response(vars); } } /* Should never happen */ free_electorates(elecs); PQfinish(conn); bailout("Barcode electorate %u not found\n", bcentry->ecode); }
/* 封包索引目录提取函数 */ static int QLIE_pack_extract_directory(struct package *pkg, struct package_directory *pkg_dir) { pack_tailer_t pack_tailer; hash_header_t *hash_header; my_hash_entry_t *my_index_buffer; BYTE buf[0x440]; u32 key; BYTE *hash_index; unsigned int i; DWORD hash_index_length, index_buffer_length; int ret; int pack_ver, hash_ver; BYTE *p; if (pkg->pio->readvec(pkg, &pack_tailer, sizeof(pack_tailer), 0 - sizeof(pack_tailer), IO_SEEK_END)) return -CUI_EREADVEC; if (!strncmp(pack_tailer.magic, "FilePackVer3.0", 16)) pack_ver = 3; else if (!strncmp(pack_tailer.magic, "FilePackVer2.0", 16)) pack_ver = 2; else if (!strncmp(pack_tailer.magic, "FilePackVer1.0", 16)) pack_ver = 1; if (pack_ver == 3 || pack_ver == 2) { if (pkg->pio->readvec(pkg, buf, sizeof(buf), 0 - sizeof(buf), IO_SEEK_END)) return -CUI_EREADVEC; if (pack_ver == 3) { key = gen_hash((WORD *)&buf[0x24], 256) & 0x0fffffff; decode((DWORD *)buf, 32, key);// 计算出校验和 } else if (pack_ver == 2) decode((DWORD *)buf, 32, 0);// 计算出校验和 } u32 hash_size = 0; if (pkg->lst) { if (pkg->pio->open(pkg->lst, IO_READONLY)) return -CUI_EOPEN; if (pkg->pio->length_of(pkg->lst, &hash_size)) { pkg->pio->close(pkg->lst); return -CUI_ELEN; } hash_header = (hash_header_t *)malloc(hash_size * 2); if (!hash_header) { pkg->pio->close(pkg->lst); return -CUI_EMEM; } if (pkg->pio->read(pkg->lst, hash_header, hash_size)) { free(hash_header); pkg->pio->close(pkg->lst); return -CUI_EREAD; } memcpy((BYTE *)hash_header + hash_size, hash_header, hash_size); pkg->pio->close(pkg->lst); } else if (pack_ver != 1) { hash_size = *(u32 *)&buf[32]; hash_header = (hash_header_t *)malloc(hash_size); if (!hash_header) return -CUI_EMEM; if (pkg->pio->seek(pkg, 0 - (sizeof(buf) + hash_size), IO_SEEK_END)) { free(hash_header); return -CUI_ESEEK; } if (pkg->pio->read(pkg, hash_header, hash_size)) { free(hash_header); return -CUI_EREAD; } } if (!hash_size) goto no_hash; if (!strncmp(hash_header->magic, "HashVer1.3", sizeof(hash_header->magic))) hash_ver = 13; else if (!strncmp(hash_header->magic, "HashVer1.2", sizeof(hash_header->magic))) hash_ver = 12; else { free(hash_header); return -CUI_EMATCH; } retry: decode((DWORD *)(hash_header + 1), hash_header->data_length, 0x428); ret = pack_decompress(&hash_index, &hash_index_length, (pack_compr_t *)(hash_header + 1), hash_header->data_length); if (ret) { if (pack_ver == 1 && !new_pack_ver1) { new_pack_ver1 = 1; memcpy(hash_header, (BYTE *)hash_header + hash_size, hash_size); goto retry; } free(hash_header); return ret; } index_buffer_length = sizeof(my_hash_entry_t) * hash_header->hash_index_entries; my_index_buffer = (my_hash_entry_t *)malloc(index_buffer_length); if (!my_index_buffer) { free(hash_index); free(hash_header); return -CUI_EMEM; } /* 这个表的具体作用不明 */ p = hash_index; for (i = 0; i < hash_header->hash_index_entries; i++) { u16 n = *(u16 *)p; p += 2; for (u16 j = 0; j < n; ++j) { u16 name_length; u32 offset_lo, offset_hi; name_length = *(u16 *)p; p += 2; strncpy(my_index_buffer[i].name, (char *)p, name_length); my_index_buffer[i].name[name_length] = 0; p += name_length; offset_lo = *(u32 *)p; p += 4; offset_hi = *(u32 *)p; p += 4; if (hash_ver == 13) { my_index_buffer[i].hash = *(u32 *)p; p += 4; my_index_buffer[i].index_entries_offset = (u64)(offset_lo) | (u64)(offset_hi) << 32; } //printf("%s: hash %x @ %08x%08x\n", my_index_buffer[i].name, my_index_buffer[i].hash, offset_hi, offset_lo); } } free(hash_index); free(hash_header); no_hash: if (pkg->pio->seek(pkg, pack_tailer.index_offset_lo, IO_SEEK_SET)) { free(my_index_buffer); return -CUI_ESEEK; } my_entry_t *index_buffer = (my_entry_t *)malloc(sizeof(my_entry_t) * pack_tailer.index_entries); if (!index_buffer) { free(my_index_buffer); return -CUI_EMEM; } for (i = 0; i < pack_tailer.index_entries; ++i) { u16 name_length; BYTE dec; u32 offset_lo, offset_hi; if (pkg->pio->read(pkg, &name_length, sizeof(name_length))) break; if (pkg->pio->read(pkg, index_buffer[i].name, name_length)) break; if (pack_ver == 3) dec = name_length + (key ^ 0x3e); else if (pack_ver == 2) dec = name_length + (0xc4 ^ 0x3e); else if (!new_pack_ver1) dec = name_length + (0xc4 ^ 0x3e); else dec = 0xc4 ^ 0x3e; for (unsigned int k = 0; k < name_length; ++k) index_buffer[i].name[k] ^= (((k + 1) ^ dec) + (k + 1)); index_buffer[i].name[k] = 0; if (pkg->pio->read(pkg, &offset_lo, sizeof(offset_lo))) break; if (pkg->pio->read(pkg, &offset_hi, sizeof(offset_hi))) break; if (pkg->pio->read(pkg, &index_buffer[i].comprlen, sizeof(index_buffer[i].comprlen))) break; if (pkg->pio->read(pkg, &index_buffer[i].uncomprlen, sizeof(index_buffer[i].uncomprlen))) break; if (pkg->pio->read(pkg, &index_buffer[i].is_compressed, sizeof(index_buffer[i].is_compressed))) break; if (pkg->pio->read(pkg, &index_buffer[i].is_encoded, sizeof(index_buffer[i].is_encoded))) break; if (new_pack_ver1) index_buffer[i].hash = 0; else { if (pkg->pio->read(pkg, &index_buffer[i].hash, sizeof(index_buffer[i].hash))) break; } index_buffer[i].offset = (u64)offset_lo | ((u64)offset_hi << 32); if (pack_ver == 3) index_buffer[i].key = key; else if (pack_ver == 2 || pack_ver == 1) index_buffer[i].key = 0; // printf("%s: hash %x %d / %d @ %08x%08x\n", index_buffer[i].name, index_buffer[i].hash, index_buffer[i].comprlen, // index_buffer[i].uncomprlen, offset_hi, offset_lo); } if (i != pack_tailer.index_entries) { free(index_buffer); return -CUI_EREAD; } pkg_dir->index_entries = pack_tailer.index_entries; pkg_dir->directory = index_buffer; pkg_dir->directory_length = sizeof(my_entry_t) * pack_tailer.index_entries; pkg_dir->index_entry_length = sizeof(my_entry_t); package_set_private(pkg, pack_ver); return 0; }
/* 封包资源提取函数 */ static int QLIE_pack_extract_resource(struct package *pkg, struct package_resource *pkg_res) { BYTE *compr, *uncompr, **act_data; DWORD comprlen, uncomprlen, act_data_len; my_entry_t *my_entry; comprlen = pkg_res->raw_data_length; compr = (BYTE *)malloc(comprlen); if (!compr) return -CUI_EMEM; if (pkg->pio->readvec(pkg, compr, comprlen, pkg_res->offset, IO_SEEK_SET)) { free(compr); return -CUI_EREADVEC; } if (pkg_res->flags & PKG_RES_FLAG_RAW) { pkg_res->raw_data = compr; return 0; } my_entry = (my_entry_t *)pkg_res->actual_index_entry; if (my_entry->hash) { if (gen_hash((WORD *)compr, comprlen) != my_entry->hash) { free(compr); return -CUI_EMATCH; } } int pack_ver = (int)package_get_private(pkg); if (my_entry->is_encoded) decode((DWORD *)compr, comprlen, my_entry->key); if (my_entry->is_compressed) { int ret = pack_decompress(&uncompr, &uncomprlen, (pack_compr_t *)compr, comprlen); free(compr); compr = NULL; if (ret) return ret; act_data = &uncompr; act_data_len = uncomprlen; } else { uncompr = NULL; uncomprlen = 0; act_data = &compr; act_data_len = comprlen; } if (!strncmp("ARGBSaveData1", (char *)*act_data, 17)) { argb_header_t *argb_header = (argb_header_t *)*act_data; BYTE *argb_data; uncomprlen = argb_header->length; argb_data = (BYTE *)malloc(uncomprlen); if (!argb_data) { free(act_data); return -CUI_EMEM; } memcpy(argb_data, argb_header + 1, uncomprlen); free(*act_data); *act_data = NULL; uncompr = argb_data; pkg_res->flags |= PKG_RES_FLAG_APEXT; pkg_res->replace_extension = _T(".bmp"); } #if 0 if (!strncmp("ABMP7", (char *)act_data, 8)) { int ret; BYTE *ret_data; DWORD ret_data_len; ret = abmp7_decompress(&ret_data, &ret_data_len, act_data, act_data_len); if (ret) { free(act_data); return ret; } free(act_data); uncompr = ret_data; uncomprlen = ret_data_len; if (!memcmp(uncompr, "\x89PNG", 4)) { pkg_res->flags |= PKG_RES_FLAG_APEXT; pkg_res->replace_extension = _T(".png"); } else if (!memcmp(uncompr, "BM", 2)) { pkg_res->flags |= PKG_RES_FLAG_APEXT; pkg_res->replace_extension = _T(".bmp"); } } else if (!strncmp("abmp10", (char *)act_data, 8)) { int ret; BYTE *ret_data; DWORD ret_data_len; ret = abmp10_decompress(&ret_data, &ret_data_len, act_data, act_data_len); if (ret) { free(act_data); return ret; } free(act_data); uncompr = ret_data; uncomprlen = ret_data_len; if (!memcmp(uncompr, "\x89PNG", 4)) { pkg_res->flags |= PKG_RES_FLAG_APEXT; pkg_res->replace_extension = _T(".png"); } else if (!memcmp(uncompr, "BM", 2)) { pkg_res->flags |= PKG_RES_FLAG_APEXT; pkg_res->replace_extension = _T(".bmp"); } } #endif pkg_res->raw_data = compr; pkg_res->actual_data = uncompr; pkg_res->actual_data_length = uncomprlen; return 0; }