79 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <cstdlib>
 | 
						|
#include <cstring>
 | 
						|
#include <iostream>
 | 
						|
#include <string>
 | 
						|
#include <filesystem>
 | 
						|
 | 
						|
#include <unistd.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#include <sys/wait.h>
 | 
						|
#include <sys/mount.h>
 | 
						|
 | 
						|
/**
 | 
						|
 * execute a program from an absolute path
 | 
						|
 *
 | 
						|
 * \param path absolute path to program (duh)
 | 
						|
 * \return program return value, 1 if it does not exist or -1 on error
 | 
						|
 */
 | 
						|
int Pii_ExecuteProgram(const std::string& path) {
 | 
						|
	if (pid_t child = fork()) {
 | 
						|
		int exitcode = -1;
 | 
						|
		waitpid(child, &exitcode, 0);
 | 
						|
 | 
						|
		return exitcode;
 | 
						|
	} else {
 | 
						|
		char* args[] = { strdup(path.c_str()), nullptr };
 | 
						|
		execv(args[0], args); 
 | 
						|
 | 
						|
		// this should only be reached if we cant load the program
 | 
						|
		std::exit(1);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Abort the boot process and drop the user into a recovery shell
 | 
						|
 */
 | 
						|
[[noreturn]]
 | 
						|
void Pii_AbortBoot() {
 | 
						|
	std::cout << "Unable to complete preinitialization. You have been dropped into a minimal recovery environment. Good luck." << std::endl;
 | 
						|
	Pii_ExecuteProgram("/Windows/System32/bash.exe");
 | 
						|
	std::exit(1);
 | 
						|
}
 | 
						|
 | 
						|
int main() {
 | 
						|
	// create temporary files
 | 
						|
	std::cout << "Mounting temporary filesystems\n";
 | 
						|
	if (mount("tmpfs", "/Windows/Temporary Files/", "tmpfs", 0, "") < 0) {
 | 
						|
		perror("mount");
 | 
						|
		Pii_AbortBoot();
 | 
						|
	}
 | 
						|
 | 
						|
	// we need this because we mount as readonly in preinit so that we can prep the system
 | 
						|
	// and load the user mode ntfs driver
 | 
						|
	// std::cout << "Creating system32 overlay for preinit\n";
 | 
						|
	// std::filesystem::create_directory("/Windows/Temporary Files/System32OverlayUD");
 | 
						|
	// std::filesystem::create_directory("/Windows/Temporary Files/System32OverlayWD");
 | 
						|
	// if (mount("overlay", "/Windows/System32/", "overlay", 0, "lowerdir=/Windows/System32,upperdir=/Windows/Temporary Files/System32OverlayUD,workdir=/Windoes/Temporary Files/System32OverlayWD") < 0) {
 | 
						|
	//	perror("mount");
 | 
						|
	//	Pii_AbortBoot();
 | 
						|
	// }
 | 
						|
 | 
						|
	// oh wow !
 | 
						|
	// std::cout << "Symlimking well known library names\n";
 | 
						|
 | 
						|
	// dynamic linking fun
 | 
						|
	std::cout << "Regenerating dynamic linker cache\n";
 | 
						|
	// Pii_ExecuteProgram("/Windows/System32/ldconfig.exe");
 | 
						|
 | 
						|
	// boot still failed
 | 
						|
	for (const auto& ent : std::filesystem::directory_iterator("/Windows/System32")) {
 | 
						|
		std::cout << ent << " s:" << ent.is_symlink() << " d:" << ent.is_directory() << "\n";
 | 
						|
	}
 | 
						|
 | 
						|
	// we are never ok
 | 
						|
	Pii_AbortBoot();
 | 
						|
	
 | 
						|
	return 0;
 | 
						|
}
 |