extern "C" int TWinstall_zip(const char* path, int* wipe_cache) {
	int ret_val, zip_verify, md5_return, key_count;
	twrpDigest md5sum;
	string strpath = path;
	ZipArchive Zip;

	gui_print("Installing '%s'...\nChecking for MD5 file...\n", path);
	md5sum.setfn(strpath);
	md5_return = md5sum.verify_md5digest();
	if (md5_return == -2) {
		// MD5 did not match.
		LOGERR("Zip MD5 does not match.\nUnable to install zip.\n");
		return INSTALL_CORRUPT;
	} else if (md5_return == -1) {
		gui_print("Skipping MD5 check: no MD5 file found.\n");
	} else if (md5_return == 0)
		gui_print("Zip MD5 matched.\n"); // MD5 found and matched.

	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
	DataManager::SetProgress(0);
	if (zip_verify) {
		gui_print("Verifying zip signature...\n");
		ret_val = verify_file(path);
		if (ret_val != VERIFY_SUCCESS) {
			LOGERR("Zip signature verification failed: %i\n", ret_val);
			return -1;
		}
	}
	ret_val = mzOpenZipArchive(path, &Zip);
	if (ret_val != 0) {
		LOGERR("Zip file is corrupt!\n", path);
		return INSTALL_CORRUPT;
	}
	return Run_Update_Binary(path, &Zip, wipe_cache);
}
extern "C" int TWinstall_zip(const char* path, int* wipe_cache) {
	int ret_val, zip_verify = 1, md5_return, key_count;
	twrpDigest md5sum;
	string strpath = path;
	ZipArchive Zip;

	if (strcmp(path, "error") == 0) {
		LOGERR("Failed to get adb sideload file: '%s'\n", path);
		return INSTALL_CORRUPT;
	}

	gui_print("Installing '%s'...\n", path);
	if (strlen(path) < 9 || strncmp(path, "/sideload", 9) != 0) {
		gui_print("Checking for MD5 file...\n");
		md5sum.setfn(strpath);
		md5_return = md5sum.verify_md5digest();
		if (md5_return == -2) { // md5 did not match
			LOGERR("Aborting zip install\n");
			return INSTALL_CORRUPT;
		}
	}

#ifndef TW_OEM_BUILD
	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
#endif
	DataManager::SetProgress(0);

	MemMapping map;
	if (sysMapFile(path, &map) != 0) {
		LOGERR("Failed to sysMapFile '%s'\n", path);
        return -1;
    }

	if (zip_verify) {
		gui_print("Verifying zip signature...\n");
		ret_val = verify_file(map.addr, map.length);
		if (ret_val != VERIFY_SUCCESS) {
			LOGERR("Zip signature verification failed: %i\n", ret_val);
			sysReleaseMap(&map);
			return -1;
		} else {
			gui_print("Zip signature verified successfully.\n");
		}
	}
	ret_val = mzOpenZipArchive(map.addr, map.length, &Zip);
	if (ret_val != 0) {
		LOGERR("Zip file is corrupt!\n", path);
		sysReleaseMap(&map);
		return INSTALL_CORRUPT;
	}
	ret_val = Run_Update_Binary(path, &Zip, wipe_cache);
	sysReleaseMap(&map);
	return ret_val;
}