Skip to content
Permalink
Browse files

Improve HaxmLoader.

- Naming test service display name as "Intel HAXM Test Service" while
  installed release service is "Intel HAXM Service".
- Stop release service "IntelHaxm" before loading the test service.
  User doesn't have to stop "IntelHaxm" manually before using HaxmLoader.
  Before the change, HaxmLoader can't load the test service.
- Allow test service overwriting.
  Before the change user must -u before -i the driver from different location.
- Prompt required administrative privileges if not run as administrators.
  If no administrative privileges, user only see "access denied" error but
  isn't clear what should do.
- Update version to 1.1.0.

Signed-off-by: Colin Xu <colin.xu@intel.com>
  • Loading branch information
coxuintel committed Jun 24, 2019
1 parent 4fdb0ad commit 6656a1c5a326789ac37557284463fde57e9c6dfa
Showing with 128 additions and 43 deletions.
  1. +128 −43 HaxmLoader/haxm_loader.c
@@ -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 6656a1c

Please sign in to comment.
You can’t perform that action at this time.