Example #1
0
File: hhctrl.c Project: r6144/wine
/******************************************************************
 *		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;
}
Example #2
0
/*
 * 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);
}
Example #3
0
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;
}
Example #4
0
File: hhctrl.c Project: r6144/wine
/******************************************************************
 *		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;
}
Example #5
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;
    }
}