// InstallDrv.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. // #define _CRT_SECURE_NO_WARNINGS #include #include #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-файл.