/* * Class: org_chm4j_ChmFile * Method: entries * Signature: (Ljava/lang/String;I)[Lorg/chm4j/ChmEntry; */ JNIEXPORT jobjectArray JNICALL Java_org_chm4j_ChmFile_entries (JNIEnv *env, jobject jobj, jstring jfilename, jstring jpath, jint flags) { // opens the file const char *filename = (*env)->GetStringUTFChars(env, jfilename, 0); struct chmFile* cFile = chm_open(filename); if(cFile == NULL) { J_ThrowException(env, "java/io/IOException", "failed to open the file"); return NULL; } (*env)->ReleaseStringUTFChars(env, jfilename, filename); // creates java list jobject list = J_CreateList(env); if(list == NULL) { // close the file chm_close(cFile); J_ThrowException(env, "java/io/IOException", "failed to create entries list"); return NULL; } // initializes context ENUM_CONTEXT* context = (ENUM_CONTEXT*) malloc(sizeof(ENUM_CONTEXT)); if(context == NULL) { // close the file chm_close(cFile); J_ThrowException(env, "java/io/IOException", "failed to create entries context"); return NULL; } context->env = env; context->file = jobj; context->list = list; // enumerates entries const char *path = (*env)->GetStringUTFChars(env, jpath, NULL); int enumres = chm_enumerate_dir(cFile, path, (int) flags, listEntries, context); (*env)->ReleaseStringUTFChars(env, jpath, path); free(context); // closes the file chm_close(cFile); if(enumres != 1) { J_ThrowException(env, "java/io/IOException", "failed to list entries"); return NULL; } // returns a java array jobjectArray array = J_ListToArray(env, list); return array; }
int main(int c, char **v) { struct chmFile *h; struct extract_context ec; if (c < 3) { fprintf(stderr, "usage: %s <chmfile> <outdir>\n", v[0]); exit(1); } h = chm_open(v[1]); if (h == NULL) { fprintf(stderr, "failed to open %s\n", v[1]); exit(1); } printf("%s:\n", v[1]); ec.base_path = v[2]; if (! chm_enumerate(h, CHM_ENUMERATE_ALL, _extract_callback, (void *)&ec)) printf(" *** ERROR ***\n"); chm_close(h); return 0; }
long extract_chm(const char *filename, const char *base_path) { struct chmFile *handle; struct extract_context ec; handle = chm_open(filename); if (handle == NULL) { fprintf(stderr, "Cannot open chmfile: %s", filename); return -1; } ec.base_path = base_path; if (!chm_enumerate(handle, CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_SPECIAL, _extract_callback, (void *)&ec)) { fprintf(stderr, "Extract chmfile failed: %s", filename); } chm_close(handle); return 0; }
extern u32 fs_chm_to_menu(const char *chmfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor) { int fid; struct chmFile *chm; t_fs_chm_enum cenum; if (menu_renew(&g_menu) == NULL) { return 0; } fid = freq_enter_hotzone(); chm = chm_open(chmfile); if (chm == NULL) { freq_leave(fid); return 0; } add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor); cenum.icolor = icolor; cenum.selicolor = selicolor; cenum.selrcolor = selrcolor; cenum.selbcolor = selbcolor; chm_enumerate(chm, CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES, chmEnum, (void *) &cenum); chm_close(chm); freq_leave(fid); return g_menu->size; }
static void release_chm(ITSProtocol *This) { if(This->chm_file) { chm_close(This->chm_file); This->chm_file = NULL; } This->offset = 0; }
/* * Class: org_chm4j_ChmEntry * Method: readContent * Signature: (Ljava/lang/String;Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_org_chm4j_ChmEntry_readContent (JNIEnv *env, jobject jobj, jstring jfilename, jstring jpath) { // opens the file const char *filename = (*env)->GetStringUTFChars(env, jfilename, 0); struct chmFile* cFile = chm_open(filename); (*env)->ReleaseStringUTFChars(env, jfilename, filename); if(cFile == NULL) { J_ThrowException(env, "java/io/IOException", "failed to open the file"); return NULL; } // resolves entry struct chmUnitInfo cUnit; const char *path = (*env)->GetStringUTFChars(env, jpath, NULL); int res = chm_resolve_object(cFile, path, &cUnit); (*env)->ReleaseStringUTFChars(env, jpath, path); if(res != CHM_RESOLVE_SUCCESS) { // close the file chm_close(cFile); J_ThrowException(env, "java.io.IOException", "failed to resolve entry"); return NULL; } // retrieves entry content unsigned char* buf = (unsigned char*) malloc(sizeof(unsigned char) * cUnit.length); if(buf == NULL) { // close the file chm_close(cFile); J_ThrowException(env, "java.io.IOException", "failed to allocate buffer"); return NULL; } jlong nbRead = (jlong) chm_retrieve_object(cFile, &cUnit, buf, 0, cUnit.length); // close the file chm_close(cFile); // creates and fills java byte array jbyteArray data = (*env)->NewByteArray(env, nbRead); if(nbRead > 0) { (*env)->SetByteArrayRegion(env, data, 0, nbRead, buf); } free(buf); return data; }
static ULONG WINAPI ITSS_IStorageImpl_Release( IStorage* iface) { ITSS_IStorageImpl *This = impl_from_IStorage(iface); ULONG ref = InterlockedDecrement(&This->ref); if (ref == 0) { chm_close(This->chmfile); HeapFree(GetProcessHeap(), 0, This); ITSS_UnlockModule(); } return ref; }
static void chmfile_file_info(ChmFile *chmfile) { struct chmFile *cfd; cfd = chm_open(chmfile->filename); if (cfd == NULL) { g_error(_("Can not open chm file %s."), chmfile->filename); return; } chmfile_system_info(cfd, chmfile); chmfile_windows_info(cfd, chmfile); /* Convert book title to UTF-8 */ if (chmfile->title != NULL && chmfile->encoding != NULL) { gchar *title_utf8; title_utf8 = g_convert(chmfile->title, -1, "UTF-8", chmfile->encoding, NULL, NULL, NULL); g_free(chmfile->title); chmfile->title = title_utf8; } /* Convert filename to UTF-8 */ if (chmfile->hhc != NULL && chmfile->encoding != NULL) { gchar *filename_utf8; filename_utf8 = convert_filename_to_utf8(chmfile->hhc, chmfile->encoding); g_free(chmfile->hhc); chmfile->hhc = filename_utf8; } if (chmfile->hhk != NULL && chmfile->encoding != NULL) { gchar *filename_utf8; filename_utf8 = convert_filename_to_utf8(chmfile->hhk, chmfile->encoding); g_free(chmfile->hhk); chmfile->hhk = filename_utf8; } chm_close(cfd); }
static bool extract_fd(const char* path, const char* base_path) { fd_reader_ctx ctx; if (!fd_reader_init(&ctx, path)) { fprintf(stderr, "failed to open %s\n", path); return false; } chm_file f; bool ok = chm_parse(&f, fd_reader, &ctx); if (!ok) { fprintf(stderr, "chm_parse() failed\n"); fd_reader_close(&ctx); return false; } printf("%s:\n", path); ok = extract(&f, base_path); chm_close(&f); fd_reader_close(&ctx); return ok; }
int main (int argc, char *argv[]) { struct chmFile *handle; if (argc < 2) { fprintf(stderr, "Oops: nothing to do!\n"); exit(1); } handle = chm_open(argv[1]); if (NULL == handle) { fprintf( stderr, "Oops: something's wrong...\n"); exit(2); } do_something_useful_with(handle); chm_close(handle); return 0; }
char * chm_parse(char * chmdata,int chmdatalen,char * filename,int * outlen) { struct chmFile *h = chm_mem(chmdata,chmdatalen); if (h == NULL) { fprintf(stderr, "failed to open %s\n", filename); exit(1); } struct chmfile getfile; memset(&getfile,0,sizeof(struct chmfile)); getfile.filename = filename; if (! chm_enumerate(h, CHM_ENUMERATE_ALL, _print_ui, &getfile)) { printf(" *** ERROR ***\n"); } *outlen = getfile.len; chm_close(h); //printf("%s",getfile.data); return getfile.data; }
static gboolean extract_chm(const gchar *filename, ChmFile *chmfile) { struct chmFile *handle; struct extract_context ec; handle = chm_open(filename); if (handle == NULL) { g_message(_("cannot open chmfile: %s"), filename); return FALSE; } ec.base_path = (const char *)chmfile->dir; if (!chm_enumerate(handle, CHM_ENUMERATE_NORMAL, _extract_callback, (void *)&ec)) { g_message(_("Extract chmfile failed: %s"), filename); return FALSE; } chm_close(handle); return TRUE; }
static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { ITSProtocol *This = impl_from_IInternetProtocol(iface); BINDINFO bindinfo; DWORD bindf = 0, len; LPWSTR file_name, mime, object_name, p; LPCWSTR ptr; struct chmFile *chm_file; struct chmUnitInfo chm_object; int res; HRESULT hres; static const WCHAR separator[] = {':',':',0}; TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); ptr = skip_schema(szUrl); if(!ptr) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } ReleaseBindInfo(&bindinfo); len = strlenW(ptr)+3; file_name = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); memcpy(file_name, ptr, len*sizeof(WCHAR)); hres = UrlUnescapeW(file_name, NULL, &len, URL_UNESCAPE_INPLACE); if(FAILED(hres)) { WARN("UrlUnescape failed: %08x\n", hres); HeapFree(GetProcessHeap(), 0, file_name); return hres; } p = strstrW(file_name, separator); if(!p) { WARN("invalid url\n"); HeapFree(GetProcessHeap(), 0, file_name); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } *p = 0; chm_file = chm_openW(file_name); if(!chm_file) { WARN("Could not open chm file\n"); HeapFree(GetProcessHeap(), 0, file_name); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } object_name = p+2; len = strlenW(object_name); if(*object_name != '/' && *object_name != '\\') { memmove(object_name+1, object_name, (len+1)*sizeof(WCHAR)); *object_name = '/'; len++; } if(object_name[len-1] == '/') object_name[--len] = 0; for(p=object_name; *p; p++) { if(*p == '\\') *p = '/'; } remove_dot_segments(object_name); TRACE("Resolving %s\n", debugstr_w(object_name)); memset(&chm_object, 0, sizeof(chm_object)); res = chm_resolve_object(chm_file, object_name, &chm_object); if(res != CHM_RESOLVE_SUCCESS) { WARN("Could not resolve chm object\n"); HeapFree(GetProcessHeap(), 0, file_name); chm_close(chm_file); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, strrchrW(object_name, '/')+1); /* FIXME: Native doesn't use FindMimeFromData */ hres = FindMimeFromData(NULL, object_name, NULL, 0, NULL, 0, &mime, 0); HeapFree(GetProcessHeap(), 0, file_name); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } release_chm(This); /* Native leaks handle here */ This->chm_file = chm_file; This->chm_object = chm_object; hres = IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE, chm_object.length, chm_object.length); if(FAILED(hres)) { WARN("ReportData failed: %08x\n", hres); release_chm(This); return report_result(pOIProtSink, hres); } hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL); return report_result(pOIProtSink, hres); }
ChmDoc::~ChmDoc() { chm_close(chmHandle); }