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;
|
|
}
|