|
@@ -32,7 +32,13 @@ |
|
|
#include <strsafe.h> |
|
|
#include <windows.h> |
|
|
|
|
|
#define SERVICE_NAME L"haxm service for test" |
|
|
#define WIDE2(x) L##x |
|
|
#define WIDE1(x) WIDE2(x) |
|
|
#define WFUNCTION WIDE1(__FUNCTION__) |
|
|
|
|
|
#define SERVICE_NAME_RELEASE L"IntelHaxm" |
|
|
#define SERVICE_NAME L"IntelHaxmTest" |
|
|
#define SERVICE_DISPLAY_NAME L"Intel HAXM Test Service" |
|
|
|
|
|
static void PrintErrorMessage(void) |
|
|
{ |
|
@@ -54,38 +60,106 @@ static void PrintErrorMessage(void) |
|
|
LocalFree(lpMsgBuf); |
|
|
} |
|
|
|
|
|
BOOL IsTokenElevated() { |
|
|
BOOL bElevated = FALSE; |
|
|
HANDLE hToken = NULL; |
|
|
TOKEN_ELEVATION procTokenElevation; |
|
|
DWORD cbSize = sizeof(TOKEN_ELEVATION); |
|
|
|
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) || |
|
|
(hToken == NULL)) { |
|
|
wprintf(L"%s(): OpenProcessToken failed.\r\n", WFUNCTION); |
|
|
PrintErrorMessage(); |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
if (GetTokenInformation(hToken, TokenElevation, &procTokenElevation, |
|
|
sizeof(procTokenElevation), &cbSize)) { |
|
|
bElevated = procTokenElevation.TokenIsElevated; |
|
|
} else { |
|
|
wprintf(L"%s(): GetTokenInformation failed.\r\n", WFUNCTION); |
|
|
PrintErrorMessage(); |
|
|
} |
|
|
|
|
|
CloseHandle(hToken); |
|
|
|
|
|
return bElevated; |
|
|
} |
|
|
|
|
|
static int StopService(SC_HANDLE hService, const wchar_t * serviceName) |
|
|
{ |
|
|
int retval = 1; |
|
|
|
|
|
if (hService) { |
|
|
SERVICE_STATUS ss = {0}; |
|
|
SERVICE_STATUS_PROCESS ssp = { 0 }; |
|
|
DWORD ssp_size = 0; |
|
|
|
|
|
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, |
|
|
(LPBYTE)(&ssp), sizeof(ssp), &ssp_size)) { |
|
|
if (ssp.dwCurrentState == SERVICE_RUNNING) { |
|
|
if (ControlService(hService, SERVICE_CONTROL_STOP, &ss)) { |
|
|
wprintf(L"%s(): Service %s is stopped.\r\n", WFUNCTION, |
|
|
serviceName); |
|
|
retval = 0; |
|
|
} else if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE) { |
|
|
wprintf(L"%s(): Service %s is already stopped.\r\n", |
|
|
WFUNCTION, serviceName); |
|
|
retval = 0; |
|
|
} else { |
|
|
wprintf(L"%s() Error: couldn't stop service \"%s\".\r\n", |
|
|
WFUNCTION, serviceName); |
|
|
PrintErrorMessage(); |
|
|
} |
|
|
} else { |
|
|
wprintf(L"%s(): Service %s is not running.\r\n", WFUNCTION, |
|
|
serviceName); |
|
|
retval = 0; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
static int DriverUninstall(void) |
|
|
{ |
|
|
SC_HANDLE hSCManager = NULL; |
|
|
SC_HANDLE hService = NULL; |
|
|
SERVICE_STATUS ss; |
|
|
int retval = 1; |
|
|
|
|
|
hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
|
|
if (!hSCManager) { |
|
|
printf("%s(): OpenSCManager failed.\r\n", __FUNCTION__); |
|
|
wprintf(L"%s(): OpenSCManager failed.\r\n", WFUNCTION); |
|
|
goto cleanup; |
|
|
} |
|
|
hService = OpenServiceW(hSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS); |
|
|
if (!hService) { // service already deleted |
|
|
retval = 0; |
|
|
goto cleanup; |
|
|
// Stop release service |
|
|
hService = OpenServiceW(hSCManager, |
|
|
SERVICE_NAME_RELEASE, SERVICE_ALL_ACCESS); |
|
|
if (hService) { |
|
|
StopService(hService, SERVICE_NAME_RELEASE); |
|
|
CloseServiceHandle(hService); |
|
|
} |
|
|
// service exist, try to stop it |
|
|
if (!ControlService(hService, SERVICE_CONTROL_STOP, &ss)) { |
|
|
if (GetLastError() != ERROR_SERVICE_NOT_ACTIVE) { |
|
|
printf("%s() Error: couldn't stop service. \r\n", |
|
|
__FUNCTION__); |
|
|
PrintErrorMessage(); |
|
|
// Stop and delete test service |
|
|
hService = OpenServiceW(hSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS); |
|
|
if (hService) { |
|
|
StopService(hService, SERVICE_NAME); |
|
|
if (DeleteService(hService)) { |
|
|
retval = 0; |
|
|
} |
|
|
else { |
|
|
wprintf(L"%s() Error: couldn't delete service \"%s\".\r\n", |
|
|
WFUNCTION, SERVICE_NAME); |
|
|
goto cleanup; |
|
|
} |
|
|
} else { |
|
|
if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { |
|
|
wprintf(L"%s(): Service %s already deleted.\r\n", WFUNCTION, |
|
|
SERVICE_NAME); |
|
|
retval = 0; |
|
|
} |
|
|
retval = 0; |
|
|
} |
|
|
// try to delete service, even stop service failed |
|
|
if (!DeleteService(hService)) { |
|
|
printf("%s() Error: couldn't delete service. \r\n", |
|
|
__FUNCTION__); |
|
|
goto cleanup; |
|
|
} |
|
|
retval = 0; |
|
|
cleanup: |
|
|
if (retval) |
|
|
PrintErrorMessage(); |
|
@@ -94,8 +168,8 @@ static int DriverUninstall(void) |
|
|
if (hSCManager) |
|
|
CloseServiceHandle(hSCManager); |
|
|
if (retval == 0) |
|
|
printf("%s(): Driver is unloaded successfully\r\n", |
|
|
__FUNCTION__); |
|
|
wprintf(L"%s(): Driver is unloaded successfully.\r\n", WFUNCTION); |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
@@ -110,9 +184,8 @@ static int DriverInstall(const wchar_t *sysFilePath) |
|
|
|
|
|
pathLen = GetFullPathNameW(sysFilePath, MAX_PATH, driverLocation, NULL); |
|
|
if (!pathLen || pathLen >= MAX_PATH) { |
|
|
printf("%s(): Failed to get absolute path:\r\n", |
|
|
__FUNCTION__); |
|
|
wprintf(L" sysFilePath='%s'\r\n", sysFilePath); |
|
|
wprintf(L"%s(): Failed to get absolute path:\r\n", WFUNCTION); |
|
|
wprintf(L" sysFilePath=\"%s\"\r\n", sysFilePath); |
|
|
goto cleanup; |
|
|
} |
|
|
|
|
@@ -125,37 +198,43 @@ static int DriverInstall(const wchar_t *sysFilePath) |
|
|
FILE_ATTRIBUTE_NORMAL, |
|
|
NULL); |
|
|
if (fileHandle == INVALID_HANDLE_VALUE) { |
|
|
printf("%s() Error: Cannot locate driver file:\r\n", |
|
|
__FUNCTION__); |
|
|
wprintf(L"%s() Error: Cannot locate driver file:\r\n", WFUNCTION); |
|
|
wprintf(L" driverLocation='%s'\r\n", driverLocation); |
|
|
goto cleanup; |
|
|
} else { |
|
|
CloseHandle(fileHandle); |
|
|
} |
|
|
|
|
|
// Clean existing |
|
|
DriverUninstall(); |
|
|
|
|
|
hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
|
|
if (!hSCManager) { |
|
|
printf("%s() Error: OpenSCManager Fail. \r\n", __FUNCTION__); |
|
|
wprintf(L"%s() Error: OpenSCManager Fail.\r\n", WFUNCTION); |
|
|
goto cleanup; |
|
|
} |
|
|
|
|
|
hService = CreateServiceW(hSCManager, SERVICE_NAME, |
|
|
SERVICE_NAME, |
|
|
SERVICE_DISPLAY_NAME, |
|
|
SERVICE_ALL_ACCESS, |
|
|
SERVICE_KERNEL_DRIVER, |
|
|
SERVICE_DEMAND_START, |
|
|
SERVICE_ERROR_IGNORE, |
|
|
driverLocation, |
|
|
NULL, NULL, NULL, NULL, NULL); |
|
|
if (!hService) { |
|
|
printf("%s() Error: OpenDriverService failed \r\n", |
|
|
__FUNCTION__); |
|
|
if (hService) { |
|
|
wprintf(L"%s(): Service %s created.\r\n", WFUNCTION, SERVICE_NAME); |
|
|
} else { |
|
|
wprintf(L"%s() Error: OpenDriverService \"%s\"failed.\r\n", WFUNCTION, |
|
|
SERVICE_NAME); |
|
|
goto cleanup; |
|
|
} |
|
|
|
|
|
if (!StartServiceW(hService, 0, NULL)) { |
|
|
printf("%s() Error: StartService, Couldn't start service. \r\n", |
|
|
__FUNCTION__); |
|
|
if (StartServiceW(hService, 0, NULL)) { |
|
|
wprintf(L"%s(): Service %s started.\r\n", WFUNCTION, SERVICE_NAME); |
|
|
} else { |
|
|
wprintf(L"%s() Error: StartService, Couldn't start service \"%s\".\r\n", |
|
|
WFUNCTION, SERVICE_NAME); |
|
|
goto cleanup; |
|
|
} |
|
|
retval = 0; |
|
@@ -167,25 +246,31 @@ static int DriverInstall(const wchar_t *sysFilePath) |
|
|
if (hSCManager) |
|
|
CloseServiceHandle(hSCManager); |
|
|
if (retval == 0) |
|
|
printf("%s(): Driver is loaded successfully\r\n", __FUNCTION__); |
|
|
wprintf(L"%s(): Driver %s is loaded successfully.\r\n", WFUNCTION, |
|
|
sysFilePath); |
|
|
return retval; |
|
|
} |
|
|
|
|
|
static void PrintUsage(void) |
|
|
{ |
|
|
printf("HaxmLoader version 1.0.0\r\n"); |
|
|
printf("Usage: HaxmLoader [mode]\r\n"); |
|
|
printf(" Modes:\r\n"); |
|
|
printf(" -i <sys_file_path>: install driver" |
|
|
" (*.sys, must be signed)\r\n"); |
|
|
printf(" -u: uninstall driver\r\n"); |
|
|
wprintf(L"HaxmLoader version 1.1.0\r\n"); |
|
|
wprintf(L"Usage: HaxmLoader [mode]\r\n"); |
|
|
wprintf(L" Modes:\r\n"); |
|
|
wprintf(L" -i <sys_file_path>: install driver" |
|
|
L" (*.sys, must be signed)\r\n"); |
|
|
wprintf(L" -u: uninstall driver\r\n"); |
|
|
} |
|
|
|
|
|
int __cdecl wmain(int argc, wchar_t *argv[]) |
|
|
{ |
|
|
wchar_t *modeStr; |
|
|
size_t modeStrLen = 0; |
|
|
|
|
|
if (!IsTokenElevated()) { |
|
|
wprintf(L"Please run HaxmLoader as Administrators.\r\n"); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
if (argc == 1) { |
|
|
PrintUsage(); |
|
|
return 0; |
|
@@ -208,7 +293,7 @@ int __cdecl wmain(int argc, wchar_t *argv[]) |
|
|
break; |
|
|
} |
|
|
} |
|
|
printf("invalid parameter\r\n"); |
|
|
wprintf(L"Invalid parameter\r\n"); |
|
|
PrintUsage(); |
|
|
return 1; |
|
|
} |
0 comments on commit
42c26eb