Skip to content

Instantly share code, notes, and snippets.

@0xbadfca11
Last active April 22, 2019 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xbadfca11/5891309f9cff61eee3b1438029e0fcf0 to your computer and use it in GitHub Desktop.
Save 0xbadfca11/5891309f9cff61eee3b1438029e0fcf0 to your computer and use it in GitHub Desktop.
EXPORTS
WslLaunch
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wslapi.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <numeric>
#include <string>
#include <vector>
#pragma comment(lib, "wslapi.lib")// Make yourself
int wmain(int, PWSTR argv[])
{
LoadLibraryW(LR"(C:\Windows\System32\lxss\LxssManagerProxyStub.dll)");
SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (!scm)
{
fprintf(stderr, "!scm %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
SC_HANDLE lxss = OpenServiceW(scm, L"LxssManager", SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
if (!lxss)
{
fprintf(stderr, "!lxss %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
SECURITY_ATTRIBUTES sa = { sizeof sa, nullptr, TRUE };
HANDLE nul = CreateFileW(L"NUL", GENERIC_READ | GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, nullptr);
if (nul == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "!nul %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
HANDLE process;
if (HRESULT result = WslLaunch(L"Ubuntu", argv[1], TRUE, nul, nul, nul, &process); FAILED(result))
{
fprintf(stderr, "!WslLaunch %08lx\n", result);
ExitProcess(EXIT_FAILURE);
}
if (WaitForSingleObject(process, INFINITE) == WAIT_FAILED)
{
fprintf(stderr, "!WaitForSingleObject %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
std::vector<UINT64> results;
results.resize(std::stoi(argv[2]));
for (auto& e : results)
{
SERVICE_STATUS status;
if (!ControlService(lxss, SERVICE_CONTROL_STOP, &status))
{
fprintf(stderr, "!ControlService %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
Sleep(1);
do
{
if (!QueryServiceStatus(lxss, &status))
{
fprintf(stderr, "!QueryServiceStatus %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
if (status.dwCurrentState == SERVICE_STOPPED)
{
break;
}
else if (status.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(1);
}
else
{
fprintf(stderr, "unexpected service state %u\n", status.dwCurrentState);
ExitProcess(EXIT_FAILURE);
}
} while (status.dwCurrentState != SERVICE_STOPPED);
if (HRESULT result = WslLaunch(L"Ubuntu", argv[1], TRUE, nul, nul, nul, &process); FAILED(result))
{
fprintf(stderr, "!WslLaunch %08lx\n", result);
ExitProcess(EXIT_FAILURE);
}
if (WaitForSingleObject(process, INFINITE) == WAIT_FAILED)
{
fprintf(stderr, "!WaitForSingleObject %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
if (!QueryProcessCycleTime(process, &e))
{
fprintf(stderr, "!QueryProcessCycleTime %08lx\n", GetLastError());
ExitProcess(EXIT_FAILURE);
}
CloseHandle(process);
}
auto[fastest, worst] = std::minmax_element(std::cbegin(results), std::cend(results));
printf(
"Fastest %llu\n"
"Worst %llu\n"
"Average %llu\n",
*fastest,
*worst,
std::accumulate(std::cbegin(results), std::cend(results), 0ULL) / results.size()
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment