예제 #1
0
파일: reboot.c 프로젝트: Borkata/linux
// reboot: Reboot the system. Return -1 on error, no return on success
int tw_reboot(RebootCommand command)
{
    if (DataManager_GetIntValue(TW_BACKUP_SYSTEM_SIZE) < DataManager_GetIntValue(TW_MIN_SYSTEM_VAR)) {
		update_system_details();
		if (DataManager_GetIntValue(TW_BACKUP_SYSTEM_SIZE) < DataManager_GetIntValue(TW_MIN_SYSTEM_VAR)) {
			LOGE("System is not installed - preventing reboot!\n");
			return -1;
		}
	}

	// Always force a sync before we reboot
    sync();

    ensure_path_unmounted("/sdcard");

    switch (command)
    {
    case rb_current:
    case rb_system:
        finish_recovery("s");
		sync();
		check_and_run_script("/sbin/rebootsystem.sh", "reboot system");
        return reboot(RB_AUTOBOOT);
    case rb_recovery:
		check_and_run_script("/sbin/rebootrecovery.sh", "reboot recovery");
        return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "recovery");
    case rb_bootloader:
		check_and_run_script("/sbin/rebootbootloader.sh", "reboot bootloader");
        return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "bootloader");
    case rb_poweroff:
		check_and_run_script("/sbin/poweroff.sh", "power off");
        return reboot(RB_POWER_OFF);
    case rb_download:
		check_and_run_script("/sbin/rebootdownload.sh", "reboot download");
		return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, (void*) "download");
	return 1;
    default:
        return -1;
    }
    return -1;
}
예제 #2
0
int decrypt_device(void)
{
#ifdef TW_INCLUDE_CRYPTO
	int ret_val, password_len;
	char crypto_blkdev[255], password[255];
	size_t result;

	strcpy(password, DataManager_GetStrValue(TW_CRYPTO_PASSWORD));
	property_set("ro.crypto.state", "encrypted");
	property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
	property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
	property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
	property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
	property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
	property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
	if (cryptfs_check_passwd(password) != 0) {
		LOGE("Failed to decrypt data\n");
		return -1;
	}
	property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
	if (strcmp(crypto_blkdev, "error") == 0) {
		LOGE("Error retrieving decrypted data block device.\n");
	} else {
		DataManager_SetStrValue(TW_DATA_BLK_DEVICE, dat.blk);
		DataManager_SetIntValue(TW_IS_DECRYPTED, 1);
		strcpy(dat.blk, crypto_blkdev);
		LOGI("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
		// Sleep for a bit so that the device will be ready
		sleep(1);
		update_system_details();
	}
	return 0;
#else
	LOGE("No crypto support was compiled into this build.\n");
	return -1;
#endif
}
예제 #3
0
파일: action.cpp 프로젝트: Borkata/linux
int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
	static string zip_queue[10];
	static int zip_queue_index;
	int simulate;

	std::string arg = gui_parse_text(action.mArg);

	std::string function = gui_parse_text(action.mFunction);

	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

    if (function == "reboot")
    {
        //curtainClose(); this sometimes causes a crash

        sync();

        if (arg == "recovery")
            tw_reboot(rb_recovery);
        else if (arg == "poweroff")
            tw_reboot(rb_poweroff);
        else if (arg == "bootloader")
            tw_reboot(rb_bootloader);
        else if (arg == "download")
	    tw_reboot(rb_download);
        else
            tw_reboot(rb_system);

        // This should never occur
        return -1;
    }
    if (function == "home")
    {
        PageManager::SelectPackage("TWRP");
        gui_changePage("main");
        return 0;
    }

    if (function == "key")
    {
        PageManager::NotifyKey(getKeyByName(arg));
        return 0;
    }

    if (function == "page") {
		std::string page_name = gui_parse_text(arg);
        return gui_changePage(page_name);
	}

    if (function == "reload") {
		int check = 0, ret_val = 0;
		std::string theme_path;

		operation_start("Reload Theme");
		theme_path = DataManager::GetSettingsStoragePath();
		if (ensure_path_mounted(theme_path.c_str()) < 0) {
			LOGE("Unable to mount %s during reload function startup.\n", theme_path.c_str());
			check = 1;
		}

		theme_path += "/TWRP/theme/ui.zip";
		if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0)
		{
			// Loading the custom theme failed - try loading the stock theme
			LOGI("Attempting to reload stock theme...\n");
			if (PageManager::ReloadPackage("TWRP", "/res/ui.xml"))
			{
				LOGE("Failed to load base packages.\n");
				ret_val = 1;
			}
		}
        operation_end(ret_val, simulate);
	}

    if (function == "readBackup")
    {
		set_restore_files();
        return 0;
    }

    if (function == "set")
    {
        if (arg.find('=') != string::npos)
        {
            string varName = arg.substr(0, arg.find('='));
            string value = arg.substr(arg.find('=') + 1, string::npos);

            DataManager::GetValue(value, value);
            DataManager::SetValue(varName, value);
        }
        else
            DataManager::SetValue(arg, "1");
        return 0;
    }
    if (function == "clear")
    {
        DataManager::SetValue(arg, "0");
        return 0;
    }

    if (function == "mount")
    {
        if (arg == "usb")
        {
            DataManager::SetValue(TW_ACTION_BUSY, 1);
			if (!simulate)
				usb_storage_enable();
			else
				ui_print("Simulating actions...\n");
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else
				cmd = "mount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("mount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }

    if (function == "umount" || function == "unmount")
    {
        if (arg == "usb")
        {
            if (!simulate)
				usb_storage_disable();
			else
				ui_print("Simulating actions...\n");
			DataManager::SetValue(TW_ACTION_BUSY, 0);
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else if (DataManager::GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && (arg == "system" || arg == "/system"))
				return 0;
			else
				cmd = "umount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("umount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }
	
	if (function == "restoredefaultsettings")
	{
		operation_start("Restore Defaults");
		if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
			ui_print("Simulating actions...\n");
		else {
			DataManager::ResetDefaults();
			mount_current_storage();
		}
		operation_end(0, simulate);
	}
	
	if (function == "copylog")
	{
		operation_start("Copy Log");
		if (!simulate)
		{
			char command[255];

			mount_current_storage();
			sprintf(command, "cp /tmp/recovery.log %s", DataManager::GetCurrentStoragePath().c_str());
			__system(command);
			sync();
			ui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
		} else
			simulate_progress_bar();
		operation_end(0, simulate);
		return 0;
	}
	
	if (function == "compute" || function == "addsubtract")
	{
		if (arg.find("+") != string::npos)
        {
            string varName = arg.substr(0, arg.find('+'));
            string string_to_add = arg.substr(arg.find('+') + 1, string::npos);
			int amount_to_add = atoi(string_to_add.c_str());
			int value;

			DataManager::GetValue(varName, value);
            DataManager::SetValue(varName, value + amount_to_add);
			return 0;
        }
		if (arg.find("-") != string::npos)
        {
            string varName = arg.substr(0, arg.find('-'));
            string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos);
			int amount_to_subtract = atoi(string_to_subtract.c_str());
			int value;

			DataManager::GetValue(varName, value);
			value -= amount_to_subtract;
			if (value <= 0)
				value = 0;
            DataManager::SetValue(varName, value);
			return 0;
        }
	}
	
	if (function == "setguitimezone")
	{
		string SelectedZone;
		DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone
		string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone
		string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component
		
		int dst;
		DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST
		
		string offset;
		DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset
		
		string NewTimeZone = Zone;
		if (offset != "0")
			NewTimeZone += ":" + offset;
		
		if (dst != 0)
			NewTimeZone += DSTZone;
		
		DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone);
		update_tz_environment_variables();
		return 0;
	}

	if (function == "togglestorage") {
		if (arg == "internal") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
		} else if (arg == "external") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
		}
		if (mount_current_storage() == 0) {
			if (arg == "internal") {
				// Save the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_INTERNAL_VAR));
			} else if (arg == "external") {
				// Save the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_INTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_EXTERNAL_VAR));
			}
		} else {
			// We weren't able to toggle for some reason, restore original setting
			if (arg == "internal") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
			} else if (arg == "external") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
			}
		}
		return 0;
	}
	
	if (function == "overlay")
        return gui_changeOverlay(arg);

	if (function == "queuezip")
    {
        if (zip_queue_index >= 10) {
			ui_print("Maximum zip queue reached!\n");
			return 0;
		}
		DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]);
		if (strlen(zip_queue[zip_queue_index].c_str()) > 0) {
			zip_queue_index++;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "cancelzip")
    {
        if (zip_queue_index <= 0) {
			ui_print("Minimum zip queue reached!\n");
			return 0;
		} else {
			zip_queue_index--;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "queueclear")
	{
		zip_queue_index = 0;
		DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		return 0;
	}

	if (function == "sleep")
	{
		usleep(atoi(arg.c_str()));
		return 0;
	}

    if (isThreaded)
    {
        if (function == "flash")
        {
			int i, ret_val = 0;

			for (i=0; i<zip_queue_index; i++) {
				operation_start("Flashing");
		        DataManager::SetValue("tw_filename", zip_queue[i]);
		        DataManager::SetValue(TW_ZIP_INDEX, (i + 1));

				ret_val = flash_zip(zip_queue[i], arg, simulate);
				if (ret_val != 0) {
					ui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
					i = 10; // Error flashing zip - exit queue
					ret_val = 1;
				}
			}
			zip_queue_index = 0;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);

			if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
				operation_start("ReinjectTWRP");
				ui_print("Injecting TWRP into boot image...\n");
				if (simulate) {
					simulate_progress_bar();
				} else {
					__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
					ui_print("TWRP injection complete.\n");
				}
			}
			operation_end(ret_val, simulate);
            return 0;
        }
        if (function == "wipe")
        {
            operation_start("Format");
            DataManager::SetValue("tw_partition", arg);

			if (simulate) {
				simulate_progress_bar();
			} else {
				if (arg == "data")
					wipe_data(0);
				else if (arg == "battery")
					wipe_battery_stats();
				else if (arg == "rotate")
					wipe_rotate_data();
				else if (arg == "dalvik")
					wipe_dalvik_cache();
				else
					erase_volume(arg.c_str());
				
				if (arg == "/sdcard") {
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
				}
			}
			update_system_details();
            operation_end(0, simulate);
            return 0;
        }
		if (function == "refreshsizes")
		{
			operation_start("Refreshing Sizes");
			if (simulate) {
				simulate_progress_bar();
			} else
				update_system_details();
			operation_end(0, simulate);
		}
        if (function == "nandroid")
        {
            operation_start("Nandroid");

			if (simulate) {
				DataManager::SetValue("tw_partition", "Simulation");
				simulate_progress_bar();
			} else {
				if (arg == "backup")
					nandroid_back_exe();
				else if (arg == "restore")
					nandroid_rest_exe();
				else {
					operation_end(1, simulate);
					return -1;
				}
			}
            operation_end(0, simulate);
			return 0;
        }
		if (function == "fixpermissions")
		{
			operation_start("Fix Permissions");
            LOGI("fix permissions started!\n");
			if (simulate) {
				simulate_progress_bar();
			} else
				fix_perms();

			LOGI("fix permissions DONE!\n");
			operation_end(0, simulate);
			return 0;
		}
        if (function == "dd")
        {
            operation_start("imaging");

			if (simulate) {
				simulate_progress_bar();
			} else {
				char cmd[512];
				sprintf(cmd, "dd %s", arg.c_str());
				__system(cmd);
			}
            operation_end(0, simulate);
            return 0;
        }
		if (function == "partitionsd")
		{
			operation_start("Partition SD Card");

			if (simulate) {
				simulate_progress_bar();
			} else {
				int allow_partition;
				DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition);
				if (allow_partition == 0) {
					ui_print("This device does not have a real SD Card!\nAborting!\n");
				} else {
					// Below seen in Koush's recovery
					char sddevice[256];
					Volume *vol = volume_for_path("/sdcard");
					strcpy(sddevice, vol->device);
					// Just need block not whole partition
					sddevice[strlen("/dev/block/mmcblkX")] = NULL;

					char es[64];
					std::string ext_format;
					int ext, swap;
					DataManager::GetValue("tw_sdext_size", ext);
					DataManager::GetValue("tw_swap_size", swap);
					DataManager::GetValue("tw_sdpart_file_system", ext_format);
					sprintf(es, "/sbin/sdparted -es %dM -ss %dM -efs %s -s > /cache/part.log",ext,swap,ext_format.c_str());
					LOGI("\nrunning script: %s\n", es);
					run_script("\nContinue partitioning?",
						   "\nPartitioning sdcard : ",
						   es,
						   "\nunable to execute parted!\n(%s)\n",
						   "\nOops... something went wrong!\nPlease check the recovery log!\n",
						   "\nPartitioning complete!\n\n",
						   "\nPartitioning aborted!\n\n", 0);
					
					// recreate TWRP folder and rewrite settings - these will be gone after sdcard is partitioned
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
					DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, "/sdcard");
					if (DataManager::GetIntValue(TW_USE_EXTERNAL_STORAGE) == 1)
						DataManager::SetValue(TW_ZIP_LOCATION_VAR, "/sdcard");

					update_system_details();
				}
			}
			operation_end(0, simulate);
			return 0;
		}
		if (function == "installhtcdumlock")
		{
			operation_start("Install HTC Dumlock");
			if (simulate) {
				simulate_progress_bar();
			} else
				install_htc_dumlock();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockrestoreboot")
		{
			operation_start("HTC Dumlock Restore Boot");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_restore_original_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockreflashrecovery")
		{
			operation_start("HTC Dumlock Reflash Recovery");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_reflash_recovery_to_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "cmd")
		{
			int op_status = 0;

			operation_start("Command");
			ui_print("Running command: '%s'\n", arg.c_str());
			if (simulate) {
				simulate_progress_bar();
			} else {
				op_status = __system(arg.c_str());
				if (op_status != 0)
					op_status = 1;
			}

			operation_end(op_status, simulate);
			return 0;
		}
		if (function == "reinjecttwrp")
		{
			int op_status = 0;

			operation_start("ReinjectTWRP");
			ui_print("Injecting TWRP into boot image...\n");
			if (simulate) {
				simulate_progress_bar();
			} else {
				__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
				ui_print("TWRP injection complete.\n");
			}

			operation_end(op_status, simulate);
			return 0;
		}
    }
    else
    {
        pthread_t t;
        pthread_create(&t, NULL, thread_start, this);
        return 0;
    }
    return -1;
}
예제 #4
0
int getLocations()
{
    // This decides if a partition can be mounted and appears in the fstab
    sys.mountable = 1;
    dat.mountable = 1;
	datdat.mountable = 1;
    cac.mountable = 1;
    sde.mountable = 1;
//    boo.mountable = 1;        // Boot is detected earlier
    rec.mountable = 0;
    sdcext.mountable = 1;
    sdcint.mountable = 1;
    ase.mountable = 0;
    sp1.mountable = SP1_MOUNTABLE;
    sp2.mountable = SP2_MOUNTABLE;
    sp3.mountable = SP3_MOUNTABLE;

	sys.is_sub_partition = 0;
    dat.is_sub_partition = 0;
	datdat.is_sub_partition = 1;
    cac.is_sub_partition = 0;
    sde.is_sub_partition = 0;
    boo.is_sub_partition = 0;
    rec.is_sub_partition = 0;
    sdcext.is_sub_partition = 0;
    sdcint.is_sub_partition = 0;
    ase.is_sub_partition = 0;
    sp1.is_sub_partition = 0;
    sp2.is_sub_partition = 0;
    sp3.is_sub_partition = 0;

    // This decides how we backup/restore a block
    sys.backup = files;
    dat.backup = files;
	datdat.backup = files;
    cac.backup = files;
    sde.backup = files;
    boo.backup = image;
    rec.backup = image;
    sdcext.backup = none;
    sdcint.backup = none;
    ase.backup = files;
    sp1.backup = SP1_BACKUP_METHOD;
    sp2.backup = SP2_BACKUP_METHOD;
    sp3.backup = SP3_BACKUP_METHOD;

	sys.is_encrypted = 0;
    dat.is_encrypted = 0;
	datdat.is_encrypted = 0;
    cac.is_encrypted = 0;
    sde.is_encrypted = 0;
    boo.is_encrypted = 0;
    rec.is_encrypted = 0;
    sdcext.is_encrypted = 0;
    sdcint.is_encrypted = 0;
    ase.is_encrypted = 0;
    sp1.is_encrypted = 0;
    sp2.is_encrypted = 0;
    sp3.is_encrypted = 0;

    if (getLocationsViaProc("emmc") != 0 && getLocationsViaProc("mtd") != 0 && getLocationsViafstab() != 0)
    {
        LOGE("E: Unable to get device locations.\n");
        return -1;
    }

    // Handle .android_secure
	char path[255];
	if (DataManager_GetIntValue(TW_HAS_INTERNAL)) {
		sprintf(ase.dev, "%s/.android_secure", DataManager_GetSettingsStoragePath());
		strcpy(ase.blk, DataManager_GetSettingsStoragePath());
	} else {
		sprintf(ase.dev, "%s/.android_secure", DataManager_GetStrValue(TW_EXTERNAL_PATH));
		strcpy(ase.blk, DataManager_GetStrValue(TW_EXTERNAL_PATH));
	}
    strcpy(ase.mnt, ".android_secure");
    strcpy(ase.fst, "vfat");

    if (strlen(sdcext.blk) > 0)
    {
        int tmpInt;
        char tmpBase[50];
        char tmpWildCard[50];
    
        // We make the base via sdcard block
        strcpy(sde.mnt, "sd-ext");
        strcpy(tmpBase, sdcext.blk);
        tmpBase[strlen(tmpBase)-1] = '\0';
        sprintf(tmpWildCard,"%s%%d",tmpBase);
        sscanf(sdcext.blk, tmpWildCard, &tmpInt); // sdcard block used as sd-ext base
        sprintf(sde.blk, "%s%d",tmpBase, tmpInt+1);
    }

    get_device_id();

	update_system_details();

    // Now, let's update the data manager...
    DataManager_SetIntValue("tw_boot_is_mountable", boo.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_system_is_mountable", sys.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_data_is_mountable", dat.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_cache_is_mountable", cac.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sdcext_is_mountable", sdcext.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sdcint_is_mountable", sdcint.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sd-ext_is_mountable", sde.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sp1_is_mountable", sp1.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sp2_is_mountable", sp2.mountable ? 1 : 0);
    DataManager_SetIntValue("tw_sp3_is_mountable", sp3.mountable ? 1 : 0);

    listMntInfo(&boo, "boot");
    listMntInfo(&sys, "system");
    listMntInfo(&dat, "data");
	if (DataManager_GetIntValue(TW_HAS_DATADATA) == 1)
		listMntInfo(&datdat, "datadata");
    listMntInfo(&cac, "cache");
    listMntInfo(&rec, "recovery");
    listMntInfo(&sdcext, "sdcext");
    listMntInfo(&sdcint, "sdcint");
    listMntInfo(&sde, "sd-ext");
	listMntInfo(&ase, "android_secure");
    listMntInfo(&sp1, "special 1");
    listMntInfo(&sp2, "special 2");
    listMntInfo(&sp3, "special 3");
    return 0;
}