Exemple #1
0
void WaterQuadTree::draw(const Camera &camera, double delta_time) {
	if (!setup_done()) { return; }
	if (!camera.intersects_box(_patch->get_center(), _patch->get_extents())) {
		remove_children();
		return;
	}

	// Get LOD metric to see if we should draw child quads or just draw this one
	double rho = compute_level_metric(camera, distance_to_patch(camera, _patch->get_center()));
	if (rho >= 0.0 || _level > _deepest_level) {
		_patch->draw(camera, delta_time);
		remove_children();
	}
	else {
		// If we already have created the children then just draw them
		if (_has_children) {
			if (_northwest->setup_done() && _northeast->setup_done() &&
				_southwest->setup_done() && _southeast->setup_done()) {
				_northwest->draw(camera, delta_time);
				_northeast->draw(camera, delta_time);
				_southwest->draw(camera, delta_time);
				_southeast->draw(camera, delta_time);

			}
			else {
				// Draw this tile until all children is setup
				_patch->draw(camera, delta_time);
			}
		}
		else { // Else create children and draw this tile
			subdivide();
			_patch->draw(camera, delta_time);
		}
	}
}
Exemple #2
0
InterfaceStore::size_type InterfaceStore::remove(Interface::Type_t type, const unsigned char *identifier, InterfaceRefList *ifl)
{
        Mutex::AutoLocker l(mutex);
        size_type removed = 0;

	if (!identifier) {
		// This must be a request to remove children discovered by 
		// a local connectivity, i.e., local interfaces.
		return remove_children(NULL, ifl);
	}
	InterfaceStore::iterator it = begin();

	while (it != end()) {
		InterfaceRecord *ir = *it;
		
		if (ir->iface->equal(type, identifier)) {
			it = erase(it);	

			removed += remove_children(ir->iface, ifl) + 1;

                        if (ifl)
                                ifl->add(ir->iface);

			ir->iface->resetFlag(IFFLAG_STORED);
			delete ir;
			return removed;
		}
		it++;
	}

	return removed;
}
Exemple #3
0
InterfaceStore::size_type InterfaceStore::remove(const string name, InterfaceRefList *ifl)
{
        Mutex::AutoLocker l(mutex);
        size_type removed = 0;

	InterfaceStore::iterator it = begin();

	while (it != end()) {
		InterfaceRecord *ir = *it;
		
		if (ir->iface->getName() == name) {	
			it = erase(it);	
                      
                        if (ifl)
                                ifl->add(ir->iface);

			removed += remove_children(ir->iface, ifl) + 1;

			ir->iface->resetFlag(IFFLAG_STORED);
			delete ir;
			return removed;
		}
		it++;
	}
	
	return removed;
}
Exemple #4
0
InterfaceStore::size_type InterfaceStore::remove_children(const InterfaceRef &parent, InterfaceRefList *ifl)
{
	InterfaceStore::iterator it = begin();
	InterfaceRefList children;
        int removed = 0;

	while (it != end()) {
		InterfaceRecord *ir = *it;

		if (ir->parent && ir->parent == parent) {
                        if (ifl)
                                ifl->add(ir->iface);

			ir->iface->resetFlag(IFFLAG_STORED);
			children.push_front(ir->iface);
			it = erase(it);
			delete ir;
                        removed++;
			continue;
		}
		it++;
	}
	
	while (!children.empty()) {
		removed += remove_children(children.pop(), ifl);
	}
	
	return removed;
}
Exemple #5
0
InterfaceStore::size_type InterfaceStore::age(const InterfaceRef &parent, InterfaceRefList *ifl, Timeval *lifetime)
{
        Mutex::AutoLocker l(mutex);
	InterfaceRefList children;
        size_type removed = 0;
	
	// Initialize the lifetime to an "invalid" number
	if (lifetime)
		*lifetime = Timeval(-1);
	
	InterfaceStore::iterator it = begin();

	while (it != end()) {
		InterfaceRecord *ir = *it;

		if ((ir->iface->isLocal() && !parent) || 
		    (parent && ir->parent && ir->parent == parent && !ir->iface->isSnooped())) {
			
			if (ir->cip->isDead()) {
				if (ifl)
                                        ifl->add(ir->iface);

                                removed++;
				ir->iface->resetFlag(IFFLAG_STORED);
				it = erase(it);
				children.push_front(ir->iface);
				
				delete ir;
				continue;
			}
			ir->cip->age();
			
			if (lifetime && ir->cip->lifetime().isValid()) {
				if (!lifetime->isValid() || ir->cip->lifetime() < *lifetime) {
					*lifetime = ir->cip->lifetime();
				}
			}
		}
		it++;
	}
	
	while (!children.empty()) {
		removed += remove_children(children.pop(), ifl);
	}

	return removed;
}
Exemple #6
0
int order_tree(struct rooted_tree *tree,
		int (*comparator)(const void*,const void*),
		int (*sort_field_setter)(struct rnode *))
{
	struct list_elem *elem;

	/* the rnode->data member is used to store the sort field. This is set
	 * by the set_sort_field_num_desc callback.*/

	for (elem=tree->nodes_in_order->head; NULL!=elem; elem=elem->next) {
		struct rnode *current = elem->data;
		if (is_leaf(current)) {
			sort_field_setter(current);
		} else {
			/* Since all children have been visited (because we're
			 * traversing the tree in postorder), we can
			 * just order the children on their sort field. */
			struct rnode ** kids_array;
			int count = current->child_count;
			kids_array = (struct rnode **)
				children_array(current);
			if (NULL == kids_array) return FAILURE;

			qsort(kids_array, count, sizeof(struct rnode *),
					comparator);

			remove_children(current);
			int i;
			for (i = 0; i < count; i++)
				add_child(current, kids_array[i]);
			current->last_child->next_sibling = NULL;

			sort_field_setter(current);
			free(kids_array);
		}
	}

	return SUCCESS;
}
Exemple #7
0
int 
main(int argc, char **argv)
{
    int res=0,
        run=0,
        dump=0,
        reset=0,
        detachall=0,
        detachpid=0,
        all=0,                  /* applies to all running processes */
        pid=-1,                 /* applies to pid, -1 means -all */
        hotp_nudge_pid=0,
        hotp_modes_nudge_pid=0,
        hotp_nudge_all=0,
        hotp_modes_nudge_all=0,
        nudge=0,                /* generic nudge with argument */
        nudge_action_mask=0,    /* generic nudge action mask */
        delay_ms_all=           /* delay between acting on processes */
                NUDGE_NO_DELAY,         
        timeout_ms=             /* timeout for finishing a nudge on a single process */
                DETACH_RECOMMENDED_TIMEOUT,
        runval=0,
        canary_default=0,
        canary_run = CANARY_RUN_FLAGS_DEFAULT,
        canary_fault_run = 0,
        exists = 0,
        destroy = 0,
        free_eventlog = 0;

    uint64 nudge_client_arg=0;     /* client nudge argument */

    int verbose = 0;

    char *create=NULL,
        *addapp=NULL, 
        *appdump=NULL, 
        *removeapp=NULL, 
        *opstring=NULL,
        *drdll=NULL,
        *preinject=NULL,
        *logdir=NULL,
        *sharedcache=NULL,
        *appname=NULL,
        *drhome=NULL,
        *modes=NULL,
        *defs=NULL,
        *detach_exename=NULL,
        *load=NULL,
        *save=NULL,
        *eventlog=NULL,
        *canary_process=NULL,
        *scratch_folder=NULL,
        *canary_fault_ops=NULL;

    dr_platform_t dr_platform = DR_PLATFORM_DEFAULT;
    
    int argidx=1;

    WCHAR wbuf[MAX_PATH];
    ConfigGroup *policy = NULL, *working_group;

    if (argc < 2) 
        usage();

    while (argidx < argc) {

        if (!strcmp(argv[argidx], "-help")) {
  	    help();
	}
        /* ******************** actions on active processes ******************** */
	else if (!strcmp(argv[argidx], "-detachall")) {
	    detachall=1;
	}
	else if (!strcmp(argv[argidx], "-detach")) {
            if (++argidx >= argc)
                usage();
	    detachpid=atoi(argv[argidx]);
	}
	else if (!strcmp(argv[argidx], "-detachexe")) {
            if (++argidx >= argc)
                usage();
	    detach_exename=argv[argidx];
	}
        else if (!strcmp(argv[argidx], "-pid") || !strcmp(argv[argidx], "-p")) {
            if (++argidx >= argc)
                usage();
            pid=atoi(argv[argidx]);
        }
	else if (!strcmp(argv[argidx], "-all")) {
	    all=1;
	}
        else if (!strcmp(argv[argidx], "-delay")) {
            /* in milliseconds */
            if (++argidx >= argc)
                usage();
            delay_ms_all=atoi(argv[argidx]);
        }
        else if (!strcmp(argv[argidx], "-timeout")) {
            /* in milliseconds */
            if (++argidx >= argc)
                usage();
            timeout_ms=atoi(argv[argidx]);
        }
	else if (!strcmp(argv[argidx], "-hot_patch_nudge")) {
            if (++argidx >= argc)
                usage();
	    hotp_nudge_pid=atoi(argv[argidx]);
	}
	else if (!strcmp(argv[argidx], "-hot_patch_modes_nudge")) {
            if (++argidx >= argc)
                usage();
	    hotp_modes_nudge_pid=atoi(argv[argidx]);
	}
	else if (!strcmp(argv[argidx], "-hot_patch_nudge_all")) {
	    hotp_nudge_all = 1;
	}
	else if (!strcmp(argv[argidx], "-verbose")) {
	    verbose = 1;
	}
	else if (!strcmp(argv[argidx], "-hot_patch_modes_nudge_all")) {
	    hotp_modes_nudge_all = 1;
	}
	else if (!strcmp(argv[argidx], "-drpop")) {
	    nudge = 1;
            /* allow composition */
	    nudge_action_mask |= NUDGE_GENERIC(opt) | NUDGE_GENERIC(reset);
	}
	else if (!strcmp(argv[argidx], "-nudge")) {
            int nudge_numeric;
            if (++argidx >= argc)
                usage();
            nudge_numeric = atoi(argv[argidx]); /* 0 if fails */
            nudge_action_mask |= nudge_numeric;

            /* compare against numeric new code, or against symbolic names */
            /* -nudge opt -nudge reset -nudge stats -nudge 30000 */
            {
                int found = 0;
#define NUDGE_DEF(name, comment) if (strcmp(#name, argv[argidx]) == 0) { found = 1; nudge_action_mask |= NUDGE_GENERIC(name);}
                NUDGE_DEFINITIONS();
#undef NUDGE_DEF
                if (!found && nudge_numeric == 0) {
                    printf("unknown -nudge %s\n", argv[argidx]);
                    usage();
                }
            }   

	    nudge=1;
	}
        else if (!strcmp(argv[argidx], "-client_nudge")) {
            if (++argidx >= argc)
                usage();
            nudge_client_arg = _strtoui64(argv[argidx], NULL, 16);
            nudge_action_mask |= NUDGE_GENERIC(client);
            nudge = 1;
        }
        /* ******************** configuration actions ******************** */
	else if (!strcmp(argv[argidx], "-reset")) {
	    reset=1;
	}
	else if (!strcmp(argv[argidx], "-create")) {
            if (++argidx >= argc)
                usage();
	    create = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-destroy")) {
            destroy = 1;
	}
	else if (!strcmp(argv[argidx], "-exists")) {
            exists = 1;
	}
	else if (!strcmp(argv[argidx], "-run")) {
            run = 1;
            if (++argidx >= argc)
                usage();
            runval = atoi(argv[argidx]);
	}
	else if (!strcmp(argv[argidx], "-app")) {
            if (++argidx >= argc)
                usage();
            appname = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-add")) {
            if (++argidx >= argc)
                usage();
	    addapp = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-remove")) {
            if (++argidx >= argc)
                usage();
	    removeapp = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-options")) {
            if (++argidx >= argc)
                usage();
	    opstring = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-drlib")) {
            if (++argidx >= argc)
                usage();
	    drdll = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-preinject")) {
            if (++argidx >= argc)
                usage();
            preinject = argv[argidx];
	}
        else if (!strcmp(argv[argidx], "-create_eventlog")) {
            if (++argidx >= argc)
                usage();
            eventlog = argv[argidx];
        }
	else if (!strcmp(argv[argidx], "-destroy_eventlog")) {
            free_eventlog = 1;
	}
	else if (!strcmp(argv[argidx], "-drhome")) {
            if (++argidx >= argc)
                usage();
            drhome = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-modes")) {
            if (++argidx >= argc)
                usage();
            modes = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-defs")) {
            if (++argidx >= argc)
                usage();
            defs = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-logdir")) {
            if (++argidx >= argc)
                usage();
	    logdir = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-sharedcache")) {
            if (++argidx >= argc)
                usage();
	    sharedcache = argv[argidx];
	}
	else if (!strcmp(argv[argidx], "-load")) {
            if (++argidx >= argc)
                usage();
	    load = argv[argidx];
	}
        else if (!strcmp(argv[argidx], "-save")) {
            if (++argidx >= argc)
                usage();
            save = argv[argidx];
        }
	else if (!strcmp(argv[argidx], "-dump")) {
	    dump = 1;
	}
	else if (!strcmp(argv[argidx], "-appdump")) {
            if (++argidx >= argc)
                usage();
            appdump = argv[argidx];	    
	}
	else if (!strcmp(argv[argidx], "-fulldump")) {
	    dump = 1;
	}
	else if (!strcmp(argv[argidx], "-v")) {
#ifdef BUILD_NUMBER
	  printf("DRcontrol.exe build %d -- %s", BUILD_NUMBER, __DATE__);
#else
	  printf("DRcontrol.exe custom build -- %s, %s", __DATE__, __TIME__);
#endif
	} else if (!strcmp(argv[argidx], "-canary_default")) {
            canary_default = 1;
	} else if (!strcmp(argv[argidx], "-canary")) {
            if (++argidx >= argc)
                usage();
	    canary_process=argv[argidx];
            if (++argidx >= argc)
                usage();
	    scratch_folder=argv[argidx];
	} else if (!strcmp(argv[argidx], "-canary_run")) {
            if (++argidx >= argc)
                usage();
	    canary_run = strtol(argv[argidx], NULL, 0);
	} else if (!strcmp(argv[argidx], "-canary_fault")) {
            char *dummy;
            if (++argidx >= argc)
                usage();
            canary_fault_run = strtol(argv[argidx], &dummy, 0);
            if (++argidx >= argc)
                usage();
            canary_fault_ops = argv[argidx];
	} else if (!strcmp(argv[argidx], "-32")) {
	    dr_platform = DR_PLATFORM_32BIT;
	} else if (!strcmp(argv[argidx], "-64")) {
	    dr_platform = DR_PLATFORM_64BIT;
	} else {
	    fprintf(stderr, "Unknown option: %s\n", argv[argidx]);
	    usage();
	}
	argidx++;
    }
  
    /* PR 244206: set the registry view before any registry access */
    set_dr_platform(dr_platform);

    if (canary_process != NULL || canary_default != 0) {
        BOOL result = TRUE;
        WCHAR canary_fault_args[MAX_PATH];
        CANARY_INFO info = {0};

        info.run_flags = canary_run;
        info.info_flags = CANARY_INFO_FLAGS_DEFAULT;
        info.fault_run = canary_fault_run;
        _snwprintf(canary_fault_args, BUFFER_SIZE_ELEMENTS(canary_fault_args),
                   L"%S", canary_fault_ops);
        NULL_TERMINATE_BUFFER(canary_fault_args);
        info.canary_fault_args = canary_fault_args;

        if (canary_process != NULL && *canary_process != '\0' &&
            scratch_folder != NULL && *scratch_folder != '\0') {
            wchar_t canary[MAX_PATH], scratch[MAX_PATH], out[MAX_PATH];
            FILE *out_file;
            _snwprintf(canary, BUFFER_SIZE_ELEMENTS(canary), L"%S", canary_process);
            NULL_TERMINATE_BUFFER(canary);
            _snwprintf(scratch, BUFFER_SIZE_ELEMENTS(scratch), L"%S\\canary_test",
                       scratch_folder);
            NULL_TERMINATE_BUFFER(scratch);
            CreateDirectory(scratch, NULL);
            _snwprintf(out, BUFFER_SIZE_ELEMENTS(out), L"%S\\canary_report.crep",
                       scratch_folder);
            out_file = _wfopen(out, L"wb");
            /* FIXME - check directory, out_file, and canary proc exist */
            result = run_canary_test_ex(out_file, &info, scratch, canary);
        } else if (canary_default != 0) {
            result = run_canary_test(&info, L_EXPAND_LEVEL(STRINGIFY(BUILD_NUMBER)));
            printf("See report file \"%S\"\n", info.report);
        }
        printf("Canary test - %s enable protection - code 0x%08x\n"
               "  msg=\"%S\"\n  url=\"%S\"\n", result ? "do" : "don\'t",
               info.canary_code, info.msg, info.url);
        return info.canary_code;
    }

    if (exists) {
        if (get_dynamorio_home() != NULL) {
            printf("Registry setup exists\n");
            return 0;
        }
        printf("Registry setup doesn't exist\n");
        return 1;
    }    

    if (save) {
        _snwprintf(wbuf, MAX_PATH, L"%S", save);
        NULL_TERMINATE_BUFFER(wbuf);
        checked_operation("save policy", save_policy(wbuf));
    }

    if (destroy) {
        checked_operation("delete product key", destroy_root_key());
        if (!load && create == NULL)
            return 0;
    }

    if (load) {
        _snwprintf(wbuf, MAX_PATH, L"%S", load);
        NULL_TERMINATE_BUFFER(wbuf);
        checked_operation("load policy", load_policy(wbuf, FALSE, NULL));
    }

    if (create != NULL) {
        _snwprintf(wbuf, MAX_PATH, L"%S", create);
        NULL_TERMINATE_BUFFER(wbuf);
        /* FALSE: do not overwrite (preserves old behavior) */
        checked_operation("create registry", setup_installation(wbuf, FALSE));
    }

    /* ensure we init dynamorio_home, case 4009 */
    get_dynamorio_home(); /* ignore return value */

    if (nudge) {
        if (verbose)
            printf("-nudge %d -pid %d %s\n", nudge_action_mask, pid, all ? "all" : "");
        if (pid == -1)           /* explicitly set */
            all = 1;

        if (all)
            checked_operation("nudge all", 
                              generic_nudge_all(nudge_action_mask, nudge_client_arg,
                                                timeout_ms, delay_ms_all));
        else
            checked_operation("nudge", 
                              generic_nudge(pid, TRUE,
                                            nudge_action_mask,
                                            0, /* client ID (ignored here) */
                                            nudge_client_arg,
                                            timeout_ms));
        goto finished;
    }

    if (detachall) {
        checked_operation("detach all", 
                          detach_all(timeout_ms));
        goto finished;
    }
    if (detachpid) {
        checked_operation("detach", 
                          detach(detachpid, TRUE, timeout_ms));
        goto finished;
    }

    if (detach_exename) {
        _snwprintf(wbuf, MAX_PATH, L"%S", detach_exename);
        NULL_TERMINATE_BUFFER(wbuf);
        checked_operation("detach-exe", 
                          detach_exe(wbuf, timeout_ms));
        goto finished;
    }

    
    if (hotp_nudge_pid) {
        checked_operation("hot patch update", 
                          hotp_notify_defs_update(hotp_nudge_pid, TRUE,
                                                  timeout_ms));
        goto finished;
    }

    if (hotp_modes_nudge_pid) {
        checked_operation("hot patch modes update", 
                          hotp_notify_modes_update(hotp_modes_nudge_pid, TRUE,
                                                   timeout_ms));
        goto finished;
    }

    if (hotp_nudge_all) {
        checked_operation("hot patch nudge all", 
                          hotp_notify_all_defs_update(timeout_ms));
        goto finished;
    }

    if (hotp_modes_nudge_all) {
        checked_operation("hot patch modes nudge all", 
                          hotp_notify_all_modes_update(timeout_ms));
        goto finished;
    }

    checked_operation("read config",
                      read_config_group(&policy, L_PRODUCT_NAME, TRUE));
    
    if (reset) {
        remove_children(policy);
        policy->should_clear = TRUE;
        checked_operation("write registry", write_config_group(policy));
    }

    working_group = policy;

    if (dump || appdump)
        goto dumponly;

    if (preinject) {
        if (0 == strcmp(preinject, "OFF")) {
            checked_operation("unset autoinject", unset_autoinjection());
        }
        else if (0 == strcmp(preinject, "ON")) {
            checked_operation("set autoinject", set_autoinjection());
        }
        else if (0 == strcmp(preinject, "CLEAR")) {
            checked_operation("clear autoinject", 
                              set_autoinjection_ex(FALSE, 
                                                   APPINIT_USE_WHITELIST,
                                                   NULL,
                                                   L"",
                                                   NULL,
                                                   NULL,
                                                   NULL,
                                                   0));
        }
        else if (0 == strcmp(preinject, "LIST")) {
            WCHAR list[MAX_PARAM_LEN];
            checked_operation("read appinit",
                              get_config_parameter(INJECT_ALL_KEY_L, 
                                                   TRUE, 
                                                   INJECT_ALL_SUBKEY_L, 
                                                   list, 
                                                   MAX_PARAM_LEN));
            printf("%S\n", list);
            if (is_vista()) {
                printf("LoadAppInit is %s\n",
                       is_loadappinit_set() ? "on" : "off");
            }
        }
        else if (0 == strcmp(preinject, "REPORT")) {
            WCHAR list[MAX_PARAM_LEN], *entry, *sep;
            checked_operation("read appinit",
                              get_config_parameter(INJECT_ALL_KEY_L, 
                                                   TRUE, 
                                                   INJECT_ALL_SUBKEY_L, 
                                                   list, 
                                                   MAX_PARAM_LEN));
            entry = get_entry_location(list, L_EXPAND_LEVEL(INJECT_DLL_8_3_NAME),
                                       APPINIT_SEPARATOR_CHAR);
            if (NULL != entry) {
                sep = wcschr(entry, APPINIT_SEPARATOR_CHAR);
                if (NULL != sep)
                    *sep = L'\0';
                printf("%S\n", entry);
                if (is_vista()) {
                    printf("LoadAppInit is %s\n",
                           is_loadappinit_set() ? "on" : "off");
                }
            }
        }
        else if (0 == strcmp(preinject, "LOAD_OFF")) {
            checked_operation("unset load autoinject", unset_loadappinit());
        }
        else if (0 == strcmp(preinject, "LOAD_ON")) {
            checked_operation("set load autoinject", set_loadappinit());
        }
        else {
            _snwprintf(wbuf, MAX_PATH, L"%S", preinject);
            NULL_TERMINATE_BUFFER(wbuf);
            checked_operation("set custom autoinject", 
                              set_autoinjection_ex(TRUE, APPINIT_OVERWRITE,
                                                   NULL, NULL, NULL, wbuf,
                                                   NULL, 0));
        }

        if (0 != strcmp(preinject, "LIST") &&
            0 != strcmp(preinject, "REPORT") &&
            using_system32_for_preinject(NULL)) {
            DWORD platform;
            if (get_platform(&platform) == ERROR_SUCCESS &&
                platform == PLATFORM_WIN_NT_4) {
                fprintf(stderr, "Warning! On NT4, new AppInit_DLLs setting will not take effect until reboot!\n");
            }
        }

    }

    if (free_eventlog) {
        checked_operation("free eventlog", destroy_eventlog());
    }

    if (eventlog) {
        _snwprintf(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%S", eventlog);
        NULL_TERMINATE_BUFFER(wbuf);
        checked_operation("create eventlog", create_eventlog(wbuf));
    }

    /* configuration */


    if (addapp) {
        _snwprintf(wbuf, MAX_PATH, L"%S", addapp);
        NULL_TERMINATE_BUFFER(wbuf);
        if (NULL == get_child(wbuf, policy)) {
            add_config_group(policy, new_config_group(wbuf));
        }
    }

    if (removeapp) {
        _snwprintf(wbuf, MAX_PATH, L"%S", removeapp);
        NULL_TERMINATE_BUFFER(wbuf);
        remove_child(wbuf, policy);
        policy->should_clear = TRUE;
    }

    if (appname) {
        _snwprintf(wbuf, MAX_PATH, L"%S", appname);
        NULL_TERMINATE_BUFFER(wbuf);
        working_group = get_child(wbuf, policy);

        if (NULL == working_group) {
            working_group = new_config_group(wbuf);
            add_config_group(policy, working_group);
        }
    }
    
    if (run) {
        _snwprintf(wbuf, MAX_PATH, L"%d", runval);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_RUNUNDER, wbuf);
    }

    if (opstring) {
        _snwprintf(wbuf, MAX_PATH, L"%S", opstring);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group,
                                   L_DYNAMORIO_VAR_OPTIONS, wbuf);
    }
    
    if (drdll) {
        _snwprintf(wbuf, MAX_PATH, L"%S", drdll);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_AUTOINJECT, wbuf);
    }

    if (drhome) {
        _snwprintf(wbuf, MAX_PATH, L"%S", drhome);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_HOME, wbuf);
    }

    if (modes) {
        _snwprintf(wbuf, MAX_PATH, L"%S", modes);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_HOT_PATCH_MODES, wbuf);
    }

    if (defs) {
        _snwprintf(wbuf, MAX_PATH, L"%S", defs);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_HOT_PATCH_POLICIES, wbuf);
    }

    if (logdir) {
        _snwprintf(wbuf, MAX_PATH, L"%S", logdir);
        NULL_TERMINATE_BUFFER(wbuf);
        set_config_group_parameter(working_group, 
                                   L_DYNAMORIO_VAR_LOGDIR, wbuf);
    }

    if (sharedcache) {
        /* note if the sharedcache root directory doesn't exist it should be
         * created before calling this function */
        _snwprintf(wbuf, MAX_PATH, L"%S", sharedcache);
        NULL_TERMINATE_BUFFER(wbuf);

        res = setup_cache_shared_directories(wbuf);
        if (res != ERROR_SUCCESS) {
            fprintf(stderr, "error %d creating directories!\n", res);
        }
        setup_cache_shared_registry(wbuf, working_group);
    }

    checked_operation("write policy", write_config_group(policy));

 dumponly:

    if (appdump) {
        _snwprintf(wbuf, MAX_PATH, L"%S", appdump);
        NULL_TERMINATE_BUFFER(wbuf);
        working_group = get_child(wbuf, policy);
    }
    else {
        working_group = policy;
    }

    if (dump || appdump) {
        if (NULL == working_group)
            fprintf(stderr, "No Configuration Exists!\n");
        else
            dump_config_group("","  ",working_group,FALSE);
    }

 finished:
    if (policy != NULL)
        free_config_group(policy);

    return 0;

}