/****************************************************************** * HtmlHelpA (HHCTRL.OCX.14) */ HWND WINAPI HtmlHelpA(HWND caller, LPCSTR filename, UINT command, DWORD_PTR data) { WCHAR *wfile = NULL, *wdata = NULL; DWORD len; HWND result; if (filename) { len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 ); wfile = heap_alloc(len*sizeof(WCHAR)); MultiByteToWideChar( CP_ACP, 0, filename, -1, wfile, len ); } if (data) { switch(command) { case HH_ALINK_LOOKUP: case HH_DISPLAY_SEARCH: case HH_DISPLAY_TEXT_POPUP: case HH_GET_LAST_ERROR: case HH_GET_WIN_TYPE: case HH_KEYWORD_LOOKUP: case HH_SET_WIN_TYPE: case HH_SYNC: FIXME("structures not handled yet\n"); break; case HH_DISPLAY_INDEX: case HH_DISPLAY_TOPIC: case HH_DISPLAY_TOC: case HH_GET_WIN_HANDLE: case HH_SAFE_DISPLAY_TOPIC: len = MultiByteToWideChar( CP_ACP, 0, (const char*)data, -1, NULL, 0 ); wdata = heap_alloc(len*sizeof(WCHAR)); MultiByteToWideChar( CP_ACP, 0, (const char*)data, -1, wdata, len ); break; case HH_CLOSE_ALL: case HH_HELP_CONTEXT: case HH_INITIALIZE: case HH_PRETRANSLATEMESSAGE: case HH_TP_HELP_CONTEXTMENU: case HH_TP_HELP_WM_HELP: case HH_UNINITIALIZE: /* either scalar or pointer to scalar - do nothing */ break; default: FIXME("Unknown command: %s (%d)\n", command_to_string(command), command); break; } } result = HtmlHelpW( caller, wfile, command, wdata ? (DWORD_PTR)wdata : data ); heap_free(wfile); heap_free(wdata); return result; }
/* * The file size of a mach-o file is limited to 32 bits; this is because * this is the limit on the kalloc() of enough bytes for a mach_header and * the contents of its sizeofcmds, which is currently constrained to 32 * bits in the file format itself. We read into the kernel buffer the * commands section, and then parse it in order to parse the mach-o file * format load_command segment(s). We are only interested in a subset of * the total set of possible commands. If "map"==VM_MAP_NULL or * "thread"==THREAD_NULL, do not make permament VM modifications, * just preflight the parse. */ static load_return_t parse_machfile( uint8_t *vp, struct mach_header *header, off_t file_offset, off_t macho_size, int depth, int64_t aslr_offset, int64_t dyld_aslr_offset, load_result_t *result ) { uint32_t ncmds; struct load_command *lcp; struct dylinker_command *dlp = 0; integer_t dlarchbits = 0; void * control; load_return_t ret = LOAD_SUCCESS; caddr_t addr; vm_size_t size,kl_size; size_t offset; size_t oldoffset; /* for overflow check */ int pass; size_t mach_header_sz = sizeof(struct mach_header); boolean_t abi64; boolean_t got_code_signatures = FALSE; int64_t slide = 0; if (header->magic == MH_MAGIC_64 || header->magic == MH_CIGAM_64) { mach_header_sz = sizeof(struct mach_header_64); } /* * Break infinite recursion */ if (depth > 6) { printf("parse_machfile 1: %s\n", load_to_string(LOAD_FAILURE)); return(LOAD_FAILURE); } depth++; /* * Check to see if right machine type. */ // this should be implemented by qemu somehow. /*if (((cpu_type_t)(header->cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK)) || !grade_binary(header->cputype, header->cpusubtype & ~CPU_SUBTYPE_MASK)) return(LOAD_BADARCH);*/ abi64 = ((header->cputype & CPU_ARCH_ABI64) == CPU_ARCH_ABI64); switch (header->filetype) { case MH_OBJECT: case MH_EXECUTE: case MH_PRELOAD: if (depth != 1) { printf("parse_machfile 2: %s\n", load_to_string(LOAD_FAILURE)); return (LOAD_FAILURE); } break; case MH_FVMLIB: case MH_DYLIB: if (depth == 1) { printf("parse_machfile 2: %s\n", load_to_string(LOAD_FAILURE)); return (LOAD_FAILURE); } break; case MH_DYLINKER: if (depth != 2) { printf("parse_machfile 3: %s\n", load_to_string(LOAD_FAILURE)); return (LOAD_FAILURE); } break; default: printf("parse_machfile 4: %s, header->filetype = %d\n", load_to_string(LOAD_FAILURE), header->filetype); return (LOAD_FAILURE); } /* * Map portion that must be accessible directly into * kernel's map. */ if ((off_t)(mach_header_sz + header->sizeofcmds) > macho_size) { printf("parse_machfile 5: %s header->sizeofcmds: %d macho_size %d\n", load_to_string(LOAD_BADMACHO), header->sizeofcmds, macho_size); return(LOAD_BADMACHO); } /* * Round size of Mach-O commands up to page boundry. */ size = round_page(mach_header_sz + header->sizeofcmds); if (size <= 0) { printf("parse_machfile 6: %s\n", load_to_string(LOAD_BADMACHO)); return(LOAD_BADMACHO); } /* * Map the load commands into kernel memory. */ addr = 0; kl_size = size; addr = (caddr_t)(vp); if (addr == NULL) { printf("parse_machfile 7: %s\n", load_to_string(LOAD_NOSPACE)); return(LOAD_NOSPACE); } /* * For PIE and dyld, slide everything by the ASLR offset. */ if ((header->flags & MH_PIE) || (header->filetype == MH_DYLINKER)) { slide = aslr_offset; } /* * Scan through the commands, processing each one as necessary. * We parse in three passes through the headers: * 1: thread state, uuid, code signature * 2: segments * 3: dyld, encryption, check entry point */ for (pass = 1; pass <= 3; pass++) { /* * Check that the entry point is contained in an executable segments */ if ((pass == 3) && (result->validentry == 0)) { ret = LOAD_FAILURE; break; } /* * Loop through each of the load_commands indicated by the * Mach-O header; if an absurd value is provided, we just * run off the end of the reserved section by incrementing * the offset too far, so we are implicitly fail-safe. */ offset = mach_header_sz; ncmds = header->ncmds; while (ncmds--) { /* * Get a pointer to the command. */ lcp = (struct load_command *)(addr + offset); oldoffset = offset; offset += lcp->cmdsize; /* * Perform prevalidation of the struct load_command * before we attempt to use its contents. Invalid * values are ones which result in an overflow, or * which can not possibly be valid commands, or which * straddle or exist past the reserved section at the * start of the image. */ if (oldoffset > offset || lcp->cmdsize < sizeof(struct load_command) || offset > header->sizeofcmds + mach_header_sz) { ret = LOAD_BADMACHO; break; } /* * Act on struct load_command's for which kernel * intervention is required. */ printf("Command: %s\n", command_to_string(lcp->cmd)); switch(lcp->cmd) { case LC_SEGMENT: if (pass != 2) break; if (abi64) { /* * Having an LC_SEGMENT command for the * wrong ABI is invalid <rdar://problem/11021230> */ ret = LOAD_BADMACHO; break; } ret = load_segment(lcp, header->filetype, control, file_offset, macho_size, vp, slide, result); break; case LC_SEGMENT_64: if (pass != 2) break; if (!abi64) { /* * Having an LC_SEGMENT_64 command for the * wrong ABI is invalid <rdar://problem/11021230> */ ret = LOAD_BADMACHO; break; } ret = load_segment(lcp, header->filetype, control, file_offset, macho_size, vp, slide, result); break; case LC_UNIXTHREAD: if (pass != 1) break; ret = load_unixthread( (struct thread_command *) lcp, result); break; case LC_MAIN: if (pass != 1) break; if (depth != 1) break; ret = load_main( (struct entry_point_command *) lcp, result); break; case LC_LOAD_DYLINKER: if (pass != 3) break; if ((depth == 1) && (dlp == 0)) { dlp = (struct dylinker_command *)lcp; dlarchbits = (header->cputype & CPU_ARCH_MASK); } else { ret = LOAD_FAILURE; } break; case LC_UUID: if (pass == 1 && depth == 1) { ret = load_uuid((struct uuid_command *) lcp, (char *)addr + mach_header_sz + header->sizeofcmds, result); } break; case LC_CODE_SIGNATURE: /* CODE SIGNING */ if (pass != 1) break; /* pager -> uip -> load signatures & store in uip set VM object "signed_pages" */ /*ret = load_code_signature( (struct linkedit_data_command *) lcp, vp, file_offset, macho_size, header->cputype, result);*/ if (ret != LOAD_SUCCESS) { printf("proc: load code signature error %d ", ret); ret = LOAD_SUCCESS; /* ignore error */ } else { got_code_signatures = TRUE; } break; #if CONFIG_CODE_DECRYPTION case LC_ENCRYPTION_INFO: case LC_ENCRYPTION_INFO_64: if (pass != 3) break; ret = set_code_unprotect( (struct encryption_info_command *) lcp, addr, map, slide, vp, header->cputype, header->cpusubtype); if (ret != LOAD_SUCCESS) { printf("proc %d: set_code_unprotect() error %d " "for file \"%s\"\n", p->p_pid, ret, vp->v_name); /* * Don't let the app run if it's * encrypted but we failed to set up the * decrypter. If the keys are missing it will * return LOAD_DECRYPTFAIL. */ if (ret == LOAD_DECRYPTFAIL) { /* failed to load due to missing FP keys */ proc_lock(p); p->p_lflag |= P_LTERM_DECRYPTFAIL; proc_unlock(p); } psignal(p, SIGKILL); } break; #endif default: /* Other commands are ignored by the kernel */ ret = LOAD_SUCCESS; break; } printf("parse_machfile 9: ret %s\n", load_to_string(ret)); if (ret != LOAD_SUCCESS) break; } if (ret != LOAD_SUCCESS) break; } if (ret == LOAD_SUCCESS) { if (! got_code_signatures) { //struct cs_blob *blob; /* no embedded signatures: look for detached ones */ //blob = ubc_cs_blob_get(vp, -1, file_offset); //if (blob != NULL) { //unsigned int cs_flag_data = blob->csb_flags; //if(0 != ubc_cs_generation_check(vp)) { // if (0 != ubc_cs_blob_revalidate(vp, blob)) { // /* clear out the flag data if revalidation fails */ // cs_flag_data = 0; // result->csflags &= ~CS_VALID; // } //} /* get flags to be applied to the process */ //result->csflags |= cs_flag_data; //} } /* Make sure if we need dyld, we got it */ if (result->needs_dynlinker && !dlp) { ret = LOAD_FAILURE; } if ((ret == LOAD_SUCCESS) && (dlp != 0)) { /* * load the dylinker, and slide it by the independent DYLD ASLR * offset regardless of the PIE-ness of the main binary. */ ret = load_dylinker(dlp, dlarchbits, depth, dyld_aslr_offset, result); } if((ret == LOAD_SUCCESS) && (depth == 1)) { if (result->thread_count == 0) { ret = LOAD_FAILURE; } } } printf("parse_machfile 8: %s\n", load_to_string(ret)); return(ret); }
static int do_pick_commit(enum todo_command command, struct commit *commit, struct replay_opts *opts) { unsigned char head[20]; struct commit *base, *next, *parent; const char *base_label, *next_label; struct commit_message msg = { NULL, NULL, NULL, NULL }; struct strbuf msgbuf = STRBUF_INIT; int res, unborn = 0, allow; if (opts->no_commit) { /* * We do not intend to commit immediately. We just want to * merge the differences in, so let's compute the tree * that represents the "current" state for merge-recursive * to work on. */ if (write_cache_as_tree(head, 0, NULL)) return error(_("your index file is unmerged.")); } else { unborn = get_sha1("HEAD", head); if (unborn) hashcpy(head, EMPTY_TREE_SHA1_BIN); if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0, 0)) return error_dirty_index(opts); } discard_cache(); if (!commit->parents) { parent = NULL; } else if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; if (!opts->mainline) return error(_("commit %s is a merge but no -m option was given."), oid_to_hex(&commit->object.oid)); for (cnt = 1, p = commit->parents; cnt != opts->mainline && p; cnt++) p = p->next; if (cnt != opts->mainline || !p) return error(_("commit %s does not have parent %d"), oid_to_hex(&commit->object.oid), opts->mainline); parent = p->item; } else if (0 < opts->mainline) return error(_("mainline was specified but commit %s is not a merge."), oid_to_hex(&commit->object.oid)); else parent = commit->parents->item; if (opts->allow_ff && ((parent && !hashcmp(parent->object.oid.hash, head)) || (!parent && unborn))) return fast_forward_to(commit->object.oid.hash, head, unborn, opts); if (parent && parse_commit(parent) < 0) /* TRANSLATORS: The first %s will be a "todo" command like "revert" or "pick", the second %s a SHA1. */ return error(_("%s: cannot parse parent commit %s"), command_to_string(command), oid_to_hex(&parent->object.oid)); if (get_message(commit, &msg) != 0) return error(_("cannot get commit message for %s"), oid_to_hex(&commit->object.oid)); /* * "commit" is an existing commit. We would want to apply * the difference it introduces since its first parent "prev" * on top of the current HEAD if we are cherry-pick. Or the * reverse of it if we are revert. */ if (command == TODO_REVERT) { base = commit; base_label = msg.label; next = parent; next_label = msg.parent_label; strbuf_addstr(&msgbuf, "Revert \""); strbuf_addstr(&msgbuf, msg.subject); strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit "); strbuf_addstr(&msgbuf, oid_to_hex(&commit->object.oid)); if (commit->parents && commit->parents->next) { strbuf_addstr(&msgbuf, ", reversing\nchanges made to "); strbuf_addstr(&msgbuf, oid_to_hex(&parent->object.oid)); } strbuf_addstr(&msgbuf, ".\n"); } else { const char *p; base = parent; base_label = msg.parent_label; next = commit; next_label = msg.label; /* * Append the commit log message to msgbuf; it starts * after the tree, parent, author, committer * information followed by "\n\n". */ p = strstr(msg.message, "\n\n"); if (p) strbuf_addstr(&msgbuf, skip_blank_lines(p + 2)); if (opts->record_origin) { if (!has_conforming_footer(&msgbuf, NULL, 0)) strbuf_addch(&msgbuf, '\n'); strbuf_addstr(&msgbuf, cherry_picked_prefix); strbuf_addstr(&msgbuf, oid_to_hex(&commit->object.oid)); strbuf_addstr(&msgbuf, ")\n"); } } if (!opts->strategy || !strcmp(opts->strategy, "recursive") || command == TODO_REVERT) { res = do_recursive_merge(base, next, base_label, next_label, head, &msgbuf, opts); if (res < 0) return res; res |= write_message(msgbuf.buf, msgbuf.len, git_path_merge_msg(), 0); } else { struct commit_list *common = NULL; struct commit_list *remotes = NULL; res = write_message(msgbuf.buf, msgbuf.len, git_path_merge_msg(), 0); commit_list_insert(base, &common); commit_list_insert(next, &remotes); res |= try_merge_command(opts->strategy, opts->xopts_nr, (const char **)opts->xopts, common, sha1_to_hex(head), remotes); free_commit_list(common); free_commit_list(remotes); } strbuf_release(&msgbuf); /* * If the merge was clean or if it failed due to conflict, we write * CHERRY_PICK_HEAD for the subsequent invocation of commit to use. * However, if the merge did not even start, then we don't want to * write it at all. */ if (command == TODO_PICK && !opts->no_commit && (res == 0 || res == 1) && update_ref(NULL, "CHERRY_PICK_HEAD", commit->object.oid.hash, NULL, REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; if (command == TODO_REVERT && ((opts->no_commit && res == 0) || res == 1) && update_ref(NULL, "REVERT_HEAD", commit->object.oid.hash, NULL, REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; if (res) { error(command == TODO_REVERT ? _("could not revert %s... %s") : _("could not apply %s... %s"), short_commit_name(commit), msg.subject); print_advice(res == 1, opts); rerere(opts->allow_rerere_auto); goto leave; } allow = allow_empty(opts, commit); if (allow < 0) { res = allow; goto leave; } if (!opts->no_commit) res = run_git_commit(opts->edit ? NULL : git_path_merge_msg(), opts, allow, opts->edit, 0, 0); leave: free_message(commit, &msg); update_abort_safety_file(); return res; }
/****************************************************************** * HtmlHelpW (HHCTRL.OCX.15) */ HWND WINAPI HtmlHelpW(HWND caller, LPCWSTR filename, UINT command, DWORD_PTR data) { WCHAR fullname[MAX_PATH]; TRACE("(%p, %s, command=%s, data=%lx)\n", caller, debugstr_w( filename ), command_to_string( command ), data); switch (command) { case HH_DISPLAY_TOPIC: case HH_DISPLAY_TOC: case HH_DISPLAY_SEARCH:{ static const WCHAR delimW[] = {':',':',0}; HHInfo *info; BOOL res; WCHAR chm_file[MAX_PATH]; const WCHAR *index; FIXME("Not all HH cases handled correctly\n"); if (!filename) return NULL; index = strstrW(filename, delimW); if (index) { memcpy(chm_file, filename, (index-filename)*sizeof(WCHAR)); chm_file[index-filename] = 0; filename = chm_file; index += 2; /* advance beyond "::" for calling NavigateToChm() later */ } if (!resolve_filename(filename, fullname, MAX_PATH)) { WARN("can't find %s\n", debugstr_w(filename)); return 0; } info = CreateHelpViewer(fullname); if(!info) return NULL; if(!index) index = info->WinType.pszFile; res = NavigateToChm(info, info->pCHMInfo->szFile, index); if(!res) { ReleaseHelpViewer(info); return NULL; } return info->WinType.hwndHelp; } case HH_HELP_CONTEXT: { HHInfo *info; LPWSTR url; if (!filename) return NULL; if (!resolve_filename(filename, fullname, MAX_PATH)) { WARN("can't find %s\n", debugstr_w(filename)); return 0; } info = CreateHelpViewer(fullname); if(!info) return NULL; url = FindContextAlias(info->pCHMInfo, data); if(!url) { ReleaseHelpViewer(info); return NULL; } NavigateToUrl(info, url); heap_free(url); return info->WinType.hwndHelp; } case HH_PRETRANSLATEMESSAGE: { static BOOL warned = FALSE; if (!warned) { FIXME("HH_PRETRANSLATEMESSAGE unimplemented\n"); warned = TRUE; } return 0; } default: FIXME("HH case %s not handled.\n", command_to_string( command )); } return 0; }
static void engine_handle_cmd(struct android_app* app, int32_t cmd) { LOGI( ">>>>> command: %s\n", command_to_string(cmd) ); switch (cmd) { case APP_CMD_INIT_WINDOW: // The window is being shown, get it ready. // g_ctx.init_display(app); // setupGraphics(); g_gl_transient_state.reset(new gl_transient_state(app)); break; case APP_CMD_TERM_WINDOW: //g_ctx.uninit_display(); g_gl_transient_state.reset(0); break; case APP_CMD_GAINED_FOCUS: // LOGI( "focus gained\n" ); //g_ctx.visible(true); assert( g_gl_transient_state.get() != 0 ); g_gl_transient_state->visible(true); break; case APP_CMD_LOST_FOCUS: // LOGI( "focus lost\n" ); assert( g_gl_transient_state.get() != 0 ); g_gl_transient_state->visible(false); break; case APP_CMD_DESTROY: // LOGI( "destroy: %d\n", g_ctx.initialized() ); // g_destroyed = true; assert( g_gl_transient_state.get() == 0 ); g_engine.reset(0); break; case APP_CMD_SAVE_STATE: { assert( g_engine.get() != 0 ); const size_t es_size = sizeof( engine_state ); app->savedState = malloc( es_size ); *((engine_state *)app->savedState) = g_engine->serialize(); app->savedStateSize = es_size; // app->savedState = malloc( 10 ); // std::string t( "saved\0" ); // std::copy( t.begin(), t.end(), (char*)app->savedState ); // app->savedStateSize = 10; // // LOGI( "save state: %d\n", g_ctx.initialized() ); break; } case APP_CMD_START: LOGI( "engine at start: %p %d\n", (void*)g_engine.get(), app->savedStateSize ); if( g_engine.get() == 0 ) { if( app->savedState != 0 ) { LOGI( "start from saved state: %d\n", app->savedStateSize ); assert( app->savedStateSize == sizeof( engine_state ) ); g_engine.reset( new engine(*((engine_state *)app->savedState)) ); } else { g_engine.reset( new engine() ); } } // g_destroyed = false; // LOGI( "start:\n" ); break; case APP_CMD_RESUME: assert( g_engine.get() != 0 ); // g_destroyed = false; // LOGI( "resume:\n" ); break; // case APP_CMD_SAVE_ST: // LOGI( "save state: %d\n", g_ctx.initialized() ); // break; } }