RunImageVC/Run.c

377 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// InstallDrv.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#define bzero(b) (memset((b), '\0', sizeof(b)), (void) 0)
char volumeName[_MAX_PATH];
BOOL SetPrivilege(
HANDLE hToken,
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
// printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege) {
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else {
tp.Privileges[0].Attributes = 0;
}
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL)) {
// printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
// printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
int setSeDebug(HANDLE handleThreadId)
{
HANDLE hToken;
if (!OpenThreadToken(handleThreadId,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
FALSE,
&hToken)
) {
if (GetLastError() == ERROR_NO_TOKEN) {
if (!ImpersonateSelf(SecurityImpersonation)) {
//Log2File("Error setting impersonation! [UnsetSeDebug()]", L_DEBUG);
return 0;
}
if (!OpenThreadToken(handleThreadId,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
FALSE,
&hToken)
) {
//Log2File("Error Opening Thread Token! [UnsetSeDebug()]", L_DEBUG);
return 0;
}
}
}
//now disable SeDebug
if (!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)) {
//Log2File("Error unsetting SeDebug Privilege [SetPrivilege()]", L_WARN);
return 0;
}
CloseHandle(hToken);
return 1;
}
int runProcess(char* strDevcon, BOOL isVolume) {
// char strDevcon[_MAX_PATH];
// strcpy_s(strDevcon, _MAX_PATH, "1.bat ");
// for (int i = 1; i < argc; ++i) {
// strcat_s(strDevcon, _MAX_PATH, argv[i]);
// strcat_s(strDevcon, _MAX_PATH, " ");
// }
char buf[1024 * 10]; //буфер ввода/вывода
PROCESS_INFORMATION piProcInfo;
STARTUPINFOA siStartInfo;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd; //структура security для пайпов
HANDLE newstdin, newstdout, read_stdout, write_stdin; //дескрипторы пайпов
// if (IsWinNT()) //инициализация security для Windows NT
// {
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.lpSecurityDescriptor = &sd;
// }
// else sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; //разрешаем наследование дескрипторов
if (!CreatePipe(&newstdin, &write_stdin, &sa, 0)) //создаем пайп
{
printf("Error creating input channel");
return 1;
}
if (!CreatePipe(&read_stdout, &newstdout, &sa, 0)) //создаем пайп
// для stdout
{
printf("Error creating output channel");
CloseHandle(newstdin);
CloseHandle(write_stdin);
return 1;
}
ZeroMemory(&siStartInfo, sizeof(siStartInfo));
ZeroMemory(&piProcInfo, sizeof(piProcInfo));
GetStartupInfoA(&siStartInfo); //создаем startupinfo для дочернего процесса
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.wShowWindow = SW_HIDE; //прячем окно
siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
// siStartInfo.lpDesktop = NULL;
siStartInfo.hStdOutput = newstdout;
siStartInfo.hStdError = newstdout; //подменяем дескрипторы для
siStartInfo.hStdInput = newstdin; // дочернего процесса
//char app_spawn[] = "devcon.exe";
int result = CreateProcessA(NULL, strDevcon, &sa, &sa, TRUE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
NULL, NULL, &siStartInfo, &piProcInfo);
if (!result)
{
printf("Error starting thread");
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
return 1;
}
unsigned long exit = 0; //код завершения процесса
unsigned long bread; //кол-во прочитанных байт
unsigned long avail; //кол-во доступных байт
bzero(buf);
for (;;) //основной цикл программы
{
Sleep(1);
GetExitCodeProcess(piProcInfo.hProcess, &exit); //пока дочерний процесс
// не закрыт
if (exit != STILL_ACTIVE) {
break;
}
}
PeekNamedPipe(read_stdout, buf, sizeof(buf) - 1, &bread, &avail, NULL);
//Проверяем, есть ли данные для чтения в stdout
if (bread != 0)
{
bzero(buf);
ReadFile(read_stdout, buf, avail, &bread, NULL); //читаем из пайпа stdout
//printf("%s", buf);
}
int volume = 0;
if (isVolume) {
char bufStr[1024];
bzero(bufStr);
int j = 0;
for (unsigned long i = 0; i < bread; ++i) {
if (buf[i] == 0x0A) {
printf("%s", bufStr);
char* res_ptr = strstr(bufStr, volumeName);
if (res_ptr) {
char str[_MAX_PATH];
sscanf(bufStr, "%s %d", str, &volume);
//volume = atoi(&bufStr[10]);
}
bzero(bufStr);
j = 0;
}
bufStr[j] = buf[i];
++j;
}
}
// KillProcByPid(piProcInfo.dwProcessId);
CloseHandle(piProcInfo.hThread);
CloseHandle(piProcInfo.hProcess); // в stdin
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
return volume;
}
void CreateScriptFile(char* text) {
FILE* file = fopen("script.txt", "w");
fprintf(file, text);
fclose(file);
}
void CreateBatFile(char* text) {
FILE* file = fopen("script.bat", "w");
fprintf(file, text);
fclose(file);
}
DWORD CurrentProcessId;
// Функция обратного вызова для EnumWindows
BOOL CALLBACK EnumWindowProc(HWND hWnd, LPARAM lParam) {
DWORD processId;
GetWindowThreadProcessId(hWnd, &processId);
if (processId == CurrentProcessId) {
// HWND найден, передаем его через lParam
*(HWND*)lParam = hWnd;
return FALSE; // Завершаем перебор окон
}
return TRUE; // Продолжаем перебор окон
}
HWND GetWindowHwndByProcessId() {
HWND hWnd = NULL;
// Перебираем все окна
EnumWindows(EnumWindowProc, (LPARAM)&hWnd);
return hWnd;
}
int main(int argc, char* argv[]) {
// if (!setSeDebug(GetCurrentThread())) {
// printf("Error", "Could not set Debug Privilege");
// return 1;
// }
CurrentProcessId = GetCurrentProcessId();
HWND WindowHandle = GetWindowHwndByProcessId();
if (WindowHandle) {
ShowWindow(WindowHandle, SW_HIDE);
}
bzero(volumeName);
FILE* file = fopen("volume", "r");
fscanf(file, "%s", volumeName);
fclose(file);
char current_work_dir_mount[FILENAME_MAX];
_getcwd(current_work_dir_mount, sizeof(current_work_dir_mount));
strcat(current_work_dir_mount, "\\mount");
char current_work_dir_vhd[FILENAME_MAX];
_getcwd(current_work_dir_vhd, sizeof(current_work_dir_vhd));
strcat(current_work_dir_vhd, "\\image.vhd");
char scriptCom[FILENAME_MAX];
// readonly
if (access("readonly", 0) == 0) {
sprintf(scriptCom, "select vdisk file=\"%s\"\r\nattach vdisk readonly", current_work_dir_vhd);
}
else {
sprintf(scriptCom, "select vdisk file=\"%s\"\r\nattach vdisk", current_work_dir_vhd);
}
CreateScriptFile(scriptCom);
runProcess("diskpart.exe /s script.txt", FALSE);
CreateScriptFile("list volume");
int volume = runProcess("diskpart.exe /s script.txt", TRUE);
if (volume > 0) {
sprintf(scriptCom, "select volume %d\r\nassign mount=\"%s\"", volume, current_work_dir_mount);
CreateScriptFile(scriptCom);
runProcess("diskpart.exe /s script.txt", FALSE);
CreateScriptFile("");
CreateBatFile("cd mount\r\nrun.bat");
runProcess("script.bat", FALSE);
CreateBatFile("");
sprintf(scriptCom, "select volume %d\r\nremove mount=\"%s\"", volume, current_work_dir_mount);
CreateScriptFile(scriptCom);
runProcess("diskpart.exe /s script.txt", FALSE);
sprintf(scriptCom, "select vdisk file=\"%s\"\r\ndetach vdisk", current_work_dir_vhd);
CreateScriptFile(scriptCom);
runProcess("diskpart.exe /s script.txt", FALSE);
CreateScriptFile("");
}
else {
printf("Virtual Disk not Found");
exit(1);
}
}
// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
// Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
// Советы по началу работы
// 1. В окне обозревателя решений можно добавлять файлы и управлять ими.
// 2. В окне Team Explorer можно подключиться к системе управления версиями.
// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
// 4. В окне "Список ошибок" можно просматривать ошибки.
// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.