summaryrefslogtreecommitdiff
path: root/general/WinHEC 2017 Lab/Toaster Driver/Service
diff options
context:
space:
mode:
authorLuke <[email protected]>2017-11-28 00:22:11 -0800
committerGitHub <[email protected]>2017-11-28 00:22:11 -0800
commit79bbbca2f6e37d94fbbbd60d12c5c1e7dde650da (patch)
tree793ff943b8b641f95d05401156badd42da4a0f12 /general/WinHEC 2017 Lab/Toaster Driver/Service
parented1df9a8b80b154b71b79635e40af75f4f19001c (diff)
parent2817004092cee784d4aaf36c045fdb5b0bc09f7e (diff)
Merge pull request #1 from Microsoft/master
Updating Local
Diffstat (limited to 'general/WinHEC 2017 Lab/Toaster Driver/Service')
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/HsaService.cpp116
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.cpp148
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.h29
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.Idl51
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.acf17
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_c.c476
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_h.h103
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_s.c430
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.cpp320
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.h16
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj284
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj.filters76
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.cpp155
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.h46
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.cpp566
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.h121
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.cpp191
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.h57
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.cpp8
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.h15
-rw-r--r--general/WinHEC 2017 Lab/Toaster Driver/Service/targetver.h8
21 files changed, 3233 insertions, 0 deletions
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/HsaService.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/HsaService.cpp
new file mode 100644
index 00000000..d3f70fdf
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/HsaService.cpp
@@ -0,0 +1,116 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+
+#pragma region Includes
+#include <stdio.h>
+#include <windows.h>
+#include "ServiceInstaller.h"
+#include "ServiceBase.h"
+#include "SampleService.h"
+#pragma endregion
+
+//
+// Settings of the service
+//
+
+// Internal name of the service
+#define SERVICE_NAME L"HsaService"
+
+// Displayed name of the service
+#define SERVICE_DISPLAY_NAME L"Hsa Sample Service"
+
+// Service start options.
+#define SERVICE_START_TYPE SERVICE_DEMAND_START
+
+// List of service dependencies - "dep1\0dep2\0\0"
+#define SERVICE_DEPENDENCIES L""
+
+// The name of the account under which the service should run - NULL uses LocalSystem account.
+#define SERVICE_ACCOUNT NULL
+
+// The password to the service account name
+#define SERVICE_PASSWORD NULL
+
+
+//
+// FUNCTION: wmain(int, wchar_t *[])
+//
+// PURPOSE: entrypoint for the application.
+//
+// PARAMETERS:
+// argc - number of command line arguments
+// argv - array of command line arguments
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+// wmain() either performs the command line task, or run the service.
+//
+int wmain(_In_ int argc, _In_ wchar_t *argv[])
+{
+ bool invalidArgs = false;
+
+ if ((argc > 1) && ((*argv[1] == L'-' || (*argv[1] == L'/'))))
+ {
+ if (_wcsicmp(L"install", argv[1] + 1) == 0)
+ {
+ // Install the service when the command is
+ // "-install" or "/install".
+ InstallService(
+ SERVICE_NAME, // Name of service
+ SERVICE_DISPLAY_NAME, // Name to display
+ SERVICE_START_TYPE, // Service start type
+ SERVICE_DEPENDENCIES, // Dependencies
+ SERVICE_ACCOUNT, // Service running account
+ SERVICE_PASSWORD // Password of the account
+ );
+ }
+ else if (_wcsicmp(L"remove", argv[1] + 1) == 0)
+ {
+ // Uninstall the service when the command is
+ // "-remove" or "/remove".
+ UninstallService(SERVICE_NAME);
+ }
+ else if (_wcsicmp(L"console", argv[1] + 1) == 0)
+ {
+ // Uninstall the service when the command is
+ // "-remove" or "/remove".
+ CSampleService service(SERVICE_NAME);
+ service.ConsoleRun();
+ }
+ else
+ {
+ invalidArgs = true;
+ }
+ }
+ else
+ {
+ invalidArgs = true;
+ CSampleService service(SERVICE_NAME);
+ if (!CServiceBase::Run(service))
+ {
+ wprintf(L"Service failed to run w/err 0x%08lx\n", GetLastError());
+ }
+ }
+
+ if (invalidArgs)
+ {
+ wprintf(L"Parameters:\n");
+ wprintf(L" -install to install the service.\n");
+ wprintf(L" -remove to remove the service.\n");
+ wprintf(L" -console to run in console mode.\n");
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.cpp
new file mode 100644
index 00000000..1766b37c
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.cpp
@@ -0,0 +1,148 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+#include "Metering.h"
+#include <assert.h>
+#include "RpcInterface_h.h"
+
+using namespace RpcServer;
+
+//
+// Thread pool callback method for metering worker
+//
+void CALLBACK MeteringWorkerTpCallback(
+ _In_ PTP_CALLBACK_INSTANCE /*iTimerInstance*/,
+ _In_ PVOID pContext,
+ _In_ PTP_TIMER /*pTimer*/)
+{
+ Metering *metering = static_cast<Metering *>(pContext);
+
+ if (metering != nullptr)
+ {
+ // Run the metering worker for this instance of metering
+ metering->MeteringWorker();
+ }
+}
+
+//
+// ctor for Metering
+//
+Metering::Metering(
+ _In_ __int64 period)
+{
+ tpTimer = CreateThreadpoolTimer(::MeteringWorkerTpCallback, this, nullptr);
+ // TODO: Handle if CreateThreadpoolTimer fails i.e tpTimer == nullptr
+
+ samplePeriod = period;
+ event = CreateEvent(
+ nullptr, // default security attributes
+ FALSE, // auto-reset event object
+ FALSE, // initial state is nonsignaled
+ nullptr); // unnamed object
+}
+
+//
+// dtor for Metering
+//
+Metering::~Metering()
+{
+ if (tpTimer != nullptr)
+ {
+ // How to close threadpool timer when there are outstanding callbacks:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682040(v=vs.85).aspx
+ SetThreadpoolTimer(tpTimer, nullptr, 0, 0);
+ WaitForThreadpoolTimerCallbacks(tpTimer, true);
+ CloseThreadpoolTimer(tpTimer);
+ tpTimer = nullptr;
+ }
+ CloseHandle(event);
+}
+
+//
+// Set the lowest sample period
+//
+void Metering::SetSamplePeriod(_In_ __int64 period)
+{
+ if (period < 1)
+ {
+ // Don't allow 0 (too fast) or negative numbers.
+ period = 1;
+ }
+ if (period > 1000)
+ {
+ // Don't let the period be too long, or we will be
+ // slow to shut down.
+ period = 1000;
+ }
+ samplePeriod = period;
+}
+
+//
+// Get last known metering data
+//
+__int64 Metering::GetMeteringData() const
+{
+ return _data;
+}
+
+//
+// Metering worker that updates metering data
+//
+void Metering::MeteringWorker()
+{
+ // Get the value from the imaginary driver and update the data
+ _data = GetTickCount();
+ SetEvent(event);
+}
+
+//
+// Set the thread poot timer and wait for metering data.
+//
+void Metering::WaitForMeteringData() const
+{
+ ULARGE_INTEGER ulDueTime;
+ FILETIME FileDueTime;
+ ulDueTime.QuadPart = static_cast<ULONGLONG>(-(1 * 10 * 1000 * samplePeriod));
+ FileDueTime.dwHighDateTime = ulDueTime.HighPart;
+ FileDueTime.dwLowDateTime = ulDueTime.LowPart;
+
+ SetThreadpoolTimer(tpTimer,
+ &FileDueTime,
+ 0,
+ 0);
+
+ WaitForSingleObject(event, INFINITE);
+}
+
+void Metering::StartMetering(
+ _In_ __int64 samplePeriod,
+ _In_ __int64 context)
+{
+ stopMeteringRequested = false;
+ SetSamplePeriod(samplePeriod);
+
+ while (true)
+ {
+ WaitForMeteringData();
+ if (stopMeteringRequested || ShutdownRequested)
+ {
+ break;
+ }
+ MeteringDataEvent(GetMeteringData(), context);
+ }
+}
+
+void Metering::StopMetering()
+{
+ stopMeteringRequested = true;
+}
+
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.h
new file mode 100644
index 00000000..bfb48216
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/Metering.h
@@ -0,0 +1,29 @@
+#include "stdafx.h"
+#include <windows.h>
+
+#include <iostream> // std::cout
+#include <thread> // std::thread
+#include <mutex>
+
+namespace RpcServer
+{
+ class Metering
+ {
+ public:
+ Metering(__int64 period);
+ void SetSamplePeriod(__int64 period);
+ __int64 GetMeteringData() const;
+ void MeteringWorker();
+ void WaitForMeteringData() const;
+ void StartMetering(__int64 samplePeriod, __int64 context);
+ void StopMetering();
+ ~Metering();
+
+ private:
+ volatile __int64 _data;
+ volatile __int64 samplePeriod;
+ PTP_TIMER tpTimer = nullptr;
+ HANDLE event;
+ volatile bool stopMeteringRequested = false;
+ };
+}
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.Idl b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.Idl
new file mode 100644
index 00000000..1b4b74cc
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.Idl
@@ -0,0 +1,51 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+import "oaidl.idl";
+import "unknwn.idl";
+
+[uuid (906B0CE0-C70B-1067-B317-00DD010662DA),
+version(1.0),
+pointer_default(unique),
+]
+interface RpcInterface
+{
+
+ // context_handle_noserialize in acf for RPC to call rundown when the client goes away
+ typedef [context_handle] void* PCONTEXT_HANDLE_TYPE;
+ typedef [ref] PCONTEXT_HANDLE_TYPE * PPCONTEXT_HANDLE_TYPE;
+
+ //
+ // RPC methods to retrieve/clean client context
+ //
+ void RemoteOpen([in] handle_t hBinding,
+ [out] PPCONTEXT_HANDLE_TYPE pphContext);
+
+ void RemoteClose([in, out] PPCONTEXT_HANDLE_TYPE pphContext);
+
+ //
+ // Metering Interface
+ //
+ void StartMetering(
+ [in] PCONTEXT_HANDLE_TYPE phContext,
+ [in] __int64 samplePeriod,
+ [in, optional] __int64 context);
+
+ void SetSamplePeriod(
+ [in] PCONTEXT_HANDLE_TYPE phContext,
+ [in] __int64 samplePeriod);
+
+ void StopMetering([in] PCONTEXT_HANDLE_TYPE phContext);
+
+ [callback] void MeteringDataEvent(
+ [in] __int64 data,
+ [in, optional] __int64 context);
+}
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.acf b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.acf
new file mode 100644
index 00000000..d00ed5af
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface.acf
@@ -0,0 +1,17 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the Microsoft Public License.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+
+interface RpcInterface
+{
+ // We need the RPC to call rundown when the client goes away
+ typedef [context_handle_noserialize] PCONTEXT_HANDLE_TYPE;
+}
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_c.c b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_c.c
new file mode 100644
index 00000000..fbe0a799
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_c.c
@@ -0,0 +1,476 @@
+
+
+/* this ALWAYS GENERATED file contains the RPC client stubs */
+
+
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for RpcInterface.Idl:
+ Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0622
+ protocol : dce , ms_ext, c_ext, robust
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+/* @@MIDL_FILE_HEADING( ) */
+
+#if defined(_M_AMD64)
+
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+
+#pragma warning( disable: 4211 ) /* redefine extern to static */
+#pragma warning( disable: 4232 ) /* dllimport identity*/
+#pragma warning( disable: 4024 ) /* array to pointer mapping*/
+
+#include <string.h>
+
+#include "RpcInterface_h.h"
+
+#define TYPE_FORMAT_STRING_SIZE 23
+#define PROC_FORMAT_STRING_SIZE 245
+#define EXPR_FORMAT_STRING_SIZE 1
+#define TRANSMIT_AS_TABLE_SIZE 0
+#define WIRE_MARSHAL_TABLE_SIZE 0
+
+typedef struct _RpcInterface_MIDL_TYPE_FORMAT_STRING
+ {
+ short Pad;
+ unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_TYPE_FORMAT_STRING;
+
+typedef struct _RpcInterface_MIDL_PROC_FORMAT_STRING
+ {
+ short Pad;
+ unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_PROC_FORMAT_STRING;
+
+typedef struct _RpcInterface_MIDL_EXPR_FORMAT_STRING
+ {
+ long Pad;
+ unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_EXPR_FORMAT_STRING;
+
+
+static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
+{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
+
+
+extern const RpcInterface_MIDL_TYPE_FORMAT_STRING RpcInterface__MIDL_TypeFormatString;
+extern const RpcInterface_MIDL_PROC_FORMAT_STRING RpcInterface__MIDL_ProcFormatString;
+extern const RpcInterface_MIDL_EXPR_FORMAT_STRING RpcInterface__MIDL_ExprFormatString;
+
+#define GENERIC_BINDING_TABLE_SIZE 0
+
+
+/* Standard interface: RpcInterface, ver. 1.0,
+ GUID={0x906B0CE0,0xC70B,0x1067,{0xB3,0x17,0x00,0xDD,0x01,0x06,0x62,0xDA}} */
+
+
+extern const MIDL_SERVER_INFO RpcInterface_ServerInfo;
+
+
+extern const RPC_DISPATCH_TABLE RpcInterface_v1_0_DispatchTable;
+
+static const RPC_CLIENT_INTERFACE RpcInterface___RpcClientInterface =
+ {
+ sizeof(RPC_CLIENT_INTERFACE),
+ {{0x906B0CE0,0xC70B,0x1067,{0xB3,0x17,0x00,0xDD,0x01,0x06,0x62,0xDA}},{1,0}},
+ {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
+ (RPC_DISPATCH_TABLE*)&RpcInterface_v1_0_DispatchTable,
+ 0,
+ 0,
+ 0,
+ &RpcInterface_ServerInfo,
+ 0x04000000
+ };
+RPC_IF_HANDLE RpcInterface_v1_0_c_ifspec = (RPC_IF_HANDLE)& RpcInterface___RpcClientInterface;
+
+extern const MIDL_STUB_DESC RpcInterface_StubDesc;
+
+static RPC_BINDING_HANDLE RpcInterface__MIDL_AutoBindHandle;
+
+
+void RemoteOpen(
+ /* [in] */ handle_t hBinding,
+ /* [out] */ PPCONTEXT_HANDLE_TYPE pphContext)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[0],
+ hBinding,
+ pphContext);
+
+}
+
+
+void RemoteClose(
+ /* [out][in] */ PPCONTEXT_HANDLE_TYPE pphContext)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[36],
+ pphContext);
+
+}
+
+
+void StartMetering(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext,
+ /* [in] */ __int64 samplePeriod,
+ /* [optional][in] */ __int64 context)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[74],
+ phContext,
+ samplePeriod,
+ context);
+
+}
+
+
+void SetSamplePeriod(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext,
+ /* [in] */ __int64 samplePeriod)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[124],
+ phContext,
+ samplePeriod);
+
+}
+
+
+void StopMetering(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[168],
+ phContext);
+
+}
+
+
+#if !defined(__RPC_WIN64__)
+#error Invalid build platform for this stub.
+#endif
+
+static const RpcInterface_MIDL_PROC_FORMAT_STRING RpcInterface__MIDL_ProcFormatString =
+ {
+ 0,
+ {
+
+ /* Procedure RemoteOpen */
+
+ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 2 */ NdrFcLong( 0x0 ), /* 0 */
+/* 6 */ NdrFcShort( 0x0 ), /* 0 */
+/* 8 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
+ 0x0, /* 0 */
+/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 14 */ NdrFcShort( 0x0 ), /* 0 */
+/* 16 */ NdrFcShort( 0x38 ), /* 56 */
+/* 18 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 20 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 22 */ NdrFcShort( 0x0 ), /* 0 */
+/* 24 */ NdrFcShort( 0x0 ), /* 0 */
+/* 26 */ NdrFcShort( 0x0 ), /* 0 */
+/* 28 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter pphContext */
+
+/* 30 */ NdrFcShort( 0x110 ), /* Flags: out, simple ref, */
+/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 34 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
+
+ /* Procedure RemoteClose */
+
+/* 36 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 38 */ NdrFcLong( 0x0 ), /* 0 */
+/* 42 */ NdrFcShort( 0x1 ), /* 1 */
+/* 44 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 46 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xe4, /* Ctxt flags: via ptr, in, out, no serialize, */
+/* 48 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 50 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 52 */ NdrFcShort( 0x38 ), /* 56 */
+/* 54 */ NdrFcShort( 0x38 ), /* 56 */
+/* 56 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 58 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 60 */ NdrFcShort( 0x0 ), /* 0 */
+/* 62 */ NdrFcShort( 0x0 ), /* 0 */
+/* 64 */ NdrFcShort( 0x0 ), /* 0 */
+/* 66 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter pphContext */
+
+/* 68 */ NdrFcShort( 0x118 ), /* Flags: in, out, simple ref, */
+/* 70 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 72 */ NdrFcShort( 0xe ), /* Type Offset=14 */
+
+ /* Procedure StartMetering */
+
+/* 74 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 76 */ NdrFcLong( 0x0 ), /* 0 */
+/* 80 */ NdrFcShort( 0x2 ), /* 2 */
+/* 82 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
+/* 84 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 86 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 88 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 90 */ NdrFcShort( 0x44 ), /* 68 */
+/* 92 */ NdrFcShort( 0x0 ), /* 0 */
+/* 94 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x3, /* 3 */
+/* 96 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 98 */ NdrFcShort( 0x0 ), /* 0 */
+/* 100 */ NdrFcShort( 0x0 ), /* 0 */
+/* 102 */ NdrFcShort( 0x0 ), /* 0 */
+/* 104 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 106 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 108 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 110 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Parameter samplePeriod */
+
+/* 112 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 114 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 116 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Parameter context */
+
+/* 118 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 120 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 122 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Procedure SetSamplePeriod */
+
+/* 124 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 126 */ NdrFcLong( 0x0 ), /* 0 */
+/* 130 */ NdrFcShort( 0x3 ), /* 3 */
+/* 132 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 134 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 136 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 138 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 140 */ NdrFcShort( 0x34 ), /* 52 */
+/* 142 */ NdrFcShort( 0x0 ), /* 0 */
+/* 144 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x2, /* 2 */
+/* 146 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 148 */ NdrFcShort( 0x0 ), /* 0 */
+/* 150 */ NdrFcShort( 0x0 ), /* 0 */
+/* 152 */ NdrFcShort( 0x0 ), /* 0 */
+/* 154 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 156 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 158 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 160 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Parameter samplePeriod */
+
+/* 162 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 164 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 166 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Procedure StopMetering */
+
+/* 168 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 170 */ NdrFcLong( 0x0 ), /* 0 */
+/* 174 */ NdrFcShort( 0x4 ), /* 4 */
+/* 176 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 178 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 180 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 182 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 184 */ NdrFcShort( 0x24 ), /* 36 */
+/* 186 */ NdrFcShort( 0x0 ), /* 0 */
+/* 188 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 190 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 192 */ NdrFcShort( 0x0 ), /* 0 */
+/* 194 */ NdrFcShort( 0x0 ), /* 0 */
+/* 196 */ NdrFcShort( 0x0 ), /* 0 */
+/* 198 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 200 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 202 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 204 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Procedure MeteringDataEvent */
+
+/* 206 */ 0x34, /* FC_CALLBACK_HANDLE */
+ 0x48, /* Old Flags: */
+/* 208 */ NdrFcLong( 0x0 ), /* 0 */
+/* 212 */ NdrFcShort( 0x0 ), /* 0 */
+/* 214 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 216 */ NdrFcShort( 0x20 ), /* 32 */
+/* 218 */ NdrFcShort( 0x0 ), /* 0 */
+/* 220 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x2, /* 2 */
+/* 222 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 224 */ NdrFcShort( 0x0 ), /* 0 */
+/* 226 */ NdrFcShort( 0x0 ), /* 0 */
+/* 228 */ NdrFcShort( 0x0 ), /* 0 */
+/* 230 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter data */
+
+/* 232 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 234 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 236 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Parameter context */
+
+/* 238 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 240 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 242 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ 0x0
+ }
+ };
+
+static const RpcInterface_MIDL_TYPE_FORMAT_STRING RpcInterface__MIDL_TypeFormatString =
+ {
+ 0,
+ {
+ NdrFcShort( 0x0 ), /* 0 */
+/* 2 */
+ 0x11, 0x4, /* FC_RP [alloced_on_stack] */
+/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
+/* 6 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xa4, /* Ctxt flags: via ptr, out, no serialize, */
+/* 8 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 10 */
+ 0x11, 0x4, /* FC_RP [alloced_on_stack] */
+/* 12 */ NdrFcShort( 0x2 ), /* Offset= 2 (14) */
+/* 14 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xe5, /* Ctxt flags: via ptr, in, out, no serialize, can't be null */
+/* 16 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 18 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x45, /* Ctxt flags: in, no serialize, can't be null */
+/* 20 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+
+ 0x0
+ }
+ };
+
+static const unsigned short RpcInterface_FormatStringOffsetTable[] =
+ {
+ 0,
+ 36,
+ 74,
+ 124,
+ 168,
+ };
+
+
+static const unsigned short _callbackRpcInterface_FormatStringOffsetTable[] =
+ {
+ 206
+ };
+
+
+static const MIDL_STUB_DESC RpcInterface_StubDesc =
+ {
+ (void *)& RpcInterface___RpcClientInterface,
+ MIDL_user_allocate,
+ MIDL_user_free,
+ &RpcInterface__MIDL_AutoBindHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RpcInterface__MIDL_TypeFormatString.Format,
+ 1, /* -error bounds_check flag */
+ 0x50002, /* Ndr library version */
+ 0,
+ 0x801026e, /* MIDL Version 8.1.622 */
+ 0,
+ 0,
+ 0, /* notify & notify_flag routine table */
+ 0x1, /* MIDL flag */
+ 0, /* cs routines */
+ 0, /* proxy/server info */
+ 0
+ };
+
+static const RPC_DISPATCH_FUNCTION RpcInterface_table[] =
+ {
+ NdrServerCall2,
+ 0
+ };
+static const RPC_DISPATCH_TABLE RpcInterface_v1_0_DispatchTable =
+ {
+ 1,
+ (RPC_DISPATCH_FUNCTION*)RpcInterface_table
+ };
+
+static const SERVER_ROUTINE RpcInterface_ServerRoutineTable[] =
+ {
+ (SERVER_ROUTINE)MeteringDataEvent
+ };
+
+static const MIDL_SERVER_INFO RpcInterface_ServerInfo =
+ {
+ &RpcInterface_StubDesc,
+ RpcInterface_ServerRoutineTable,
+ RpcInterface__MIDL_ProcFormatString.Format,
+ _callbackRpcInterface_FormatStringOffsetTable,
+ 0,
+ 0,
+ 0,
+ 0};
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#endif
+
+
+#endif /* defined(_M_AMD64)*/
+
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_h.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_h.h
new file mode 100644
index 00000000..98544da7
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_h.h
@@ -0,0 +1,103 @@
+
+
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */
+
+
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for RpcInterface.Idl:
+ Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0622
+ protocol : dce , ms_ext, c_ext, robust
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+/* @@MIDL_FILE_HEADING( ) */
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+
+
+/* verify that the <rpcndr.h> version is high enough to compile this file*/
+#ifndef __REQUIRED_RPCNDR_H_VERSION__
+#define __REQUIRED_RPCNDR_H_VERSION__ 475
+#endif
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#ifndef __RPCNDR_H_VERSION__
+#error this stub requires an updated version of <rpcndr.h>
+#endif /* __RPCNDR_H_VERSION__ */
+
+
+#ifndef __RpcInterface_h_h__
+#define __RpcInterface_h_h__
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+/* Forward Declarations */
+
+/* header files for imported files */
+#include "oaidl.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#ifndef __RpcInterface_INTERFACE_DEFINED__
+#define __RpcInterface_INTERFACE_DEFINED__
+
+/* interface RpcInterface */
+/* [unique][version][uuid] */
+
+typedef /* [context_handle_noserialize][context_handle] */ void *PCONTEXT_HANDLE_TYPE;
+
+typedef /* [ref] */ PCONTEXT_HANDLE_TYPE *PPCONTEXT_HANDLE_TYPE;
+
+void RemoteOpen(
+ /* [in] */ handle_t hBinding,
+ /* [out] */ PPCONTEXT_HANDLE_TYPE pphContext);
+
+void RemoteClose(
+ /* [out][in] */ PPCONTEXT_HANDLE_TYPE pphContext);
+
+void StartMetering(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext,
+ /* [in] */ __int64 samplePeriod,
+ /* [optional][in] */ __int64 context);
+
+void SetSamplePeriod(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext,
+ /* [in] */ __int64 samplePeriod);
+
+void StopMetering(
+ /* [in] */ PCONTEXT_HANDLE_TYPE phContext);
+
+/* [callback] */ void MeteringDataEvent(
+ /* [in] */ __int64 data,
+ /* [optional][in] */ __int64 context);
+
+
+
+extern RPC_IF_HANDLE RpcInterface_v1_0_c_ifspec;
+extern RPC_IF_HANDLE RpcInterface_v1_0_s_ifspec;
+#endif /* __RpcInterface_INTERFACE_DEFINED__ */
+
+/* Additional Prototypes for ALL interfaces */
+
+void __RPC_USER PCONTEXT_HANDLE_TYPE_rundown( PCONTEXT_HANDLE_TYPE );
+
+/* end of Additional Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_s.c b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_s.c
new file mode 100644
index 00000000..89aa59bf
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcInterface_s.c
@@ -0,0 +1,430 @@
+
+
+/* this ALWAYS GENERATED file contains the RPC server stubs */
+
+
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for RpcInterface.Idl:
+ Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0622
+ protocol : dce , ms_ext, c_ext, robust
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+/* @@MIDL_FILE_HEADING( ) */
+
+#if defined(_M_AMD64)
+
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+
+#pragma warning( disable: 4211 ) /* redefine extern to static */
+#pragma warning( disable: 4232 ) /* dllimport identity*/
+#pragma warning( disable: 4024 ) /* array to pointer mapping*/
+
+#include <string.h>
+#include "RpcInterface_h.h"
+
+#define TYPE_FORMAT_STRING_SIZE 23
+#define PROC_FORMAT_STRING_SIZE 245
+#define EXPR_FORMAT_STRING_SIZE 1
+#define TRANSMIT_AS_TABLE_SIZE 0
+#define WIRE_MARSHAL_TABLE_SIZE 0
+
+typedef struct _RpcInterface_MIDL_TYPE_FORMAT_STRING
+ {
+ short Pad;
+ unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_TYPE_FORMAT_STRING;
+
+typedef struct _RpcInterface_MIDL_PROC_FORMAT_STRING
+ {
+ short Pad;
+ unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_PROC_FORMAT_STRING;
+
+typedef struct _RpcInterface_MIDL_EXPR_FORMAT_STRING
+ {
+ long Pad;
+ unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
+ } RpcInterface_MIDL_EXPR_FORMAT_STRING;
+
+
+static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
+{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
+
+extern const RpcInterface_MIDL_TYPE_FORMAT_STRING RpcInterface__MIDL_TypeFormatString;
+extern const RpcInterface_MIDL_PROC_FORMAT_STRING RpcInterface__MIDL_ProcFormatString;
+extern const RpcInterface_MIDL_EXPR_FORMAT_STRING RpcInterface__MIDL_ExprFormatString;
+
+/* Standard interface: RpcInterface, ver. 1.0,
+ GUID={0x906B0CE0,0xC70B,0x1067,{0xB3,0x17,0x00,0xDD,0x01,0x06,0x62,0xDA}} */
+
+
+extern const MIDL_SERVER_INFO RpcInterface_ServerInfo;
+
+extern const RPC_DISPATCH_TABLE RpcInterface_v1_0_DispatchTable;
+
+static const RPC_SERVER_INTERFACE RpcInterface___RpcServerInterface =
+ {
+ sizeof(RPC_SERVER_INTERFACE),
+ {{0x906B0CE0,0xC70B,0x1067,{0xB3,0x17,0x00,0xDD,0x01,0x06,0x62,0xDA}},{1,0}},
+ {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
+ (RPC_DISPATCH_TABLE*)&RpcInterface_v1_0_DispatchTable,
+ 0,
+ 0,
+ 0,
+ &RpcInterface_ServerInfo,
+ 0x04000000
+ };
+RPC_IF_HANDLE RpcInterface_v1_0_s_ifspec = (RPC_IF_HANDLE)& RpcInterface___RpcServerInterface;
+
+extern const MIDL_STUB_DESC RpcInterface_StubDesc;
+
+ extern const MIDL_STUBLESS_PROXY_INFO RpcInterface_ProxyInfo;
+
+/* [callback] */ void MeteringDataEvent(
+ /* [in] */ __int64 data,
+ /* [optional][in] */ __int64 context)
+{
+
+ NdrClientCall2(
+ ( PMIDL_STUB_DESC )&RpcInterface_StubDesc,
+ (PFORMAT_STRING) &RpcInterface__MIDL_ProcFormatString.Format[206],
+ data,
+ context);
+
+}
+
+extern const NDR_RUNDOWN RundownRoutines[];
+
+#if !defined(__RPC_WIN64__)
+#error Invalid build platform for this stub.
+#endif
+
+static const RpcInterface_MIDL_PROC_FORMAT_STRING RpcInterface__MIDL_ProcFormatString =
+ {
+ 0,
+ {
+
+ /* Procedure RemoteOpen */
+
+ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 2 */ NdrFcLong( 0x0 ), /* 0 */
+/* 6 */ NdrFcShort( 0x0 ), /* 0 */
+/* 8 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
+ 0x0, /* 0 */
+/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 14 */ NdrFcShort( 0x0 ), /* 0 */
+/* 16 */ NdrFcShort( 0x38 ), /* 56 */
+/* 18 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 20 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 22 */ NdrFcShort( 0x0 ), /* 0 */
+/* 24 */ NdrFcShort( 0x0 ), /* 0 */
+/* 26 */ NdrFcShort( 0x0 ), /* 0 */
+/* 28 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter pphContext */
+
+/* 30 */ NdrFcShort( 0x110 ), /* Flags: out, simple ref, */
+/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 34 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
+
+ /* Procedure RemoteClose */
+
+/* 36 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 38 */ NdrFcLong( 0x0 ), /* 0 */
+/* 42 */ NdrFcShort( 0x1 ), /* 1 */
+/* 44 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 46 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xe4, /* Ctxt flags: via ptr, in, out, no serialize, */
+/* 48 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 50 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 52 */ NdrFcShort( 0x38 ), /* 56 */
+/* 54 */ NdrFcShort( 0x38 ), /* 56 */
+/* 56 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 58 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 60 */ NdrFcShort( 0x0 ), /* 0 */
+/* 62 */ NdrFcShort( 0x0 ), /* 0 */
+/* 64 */ NdrFcShort( 0x0 ), /* 0 */
+/* 66 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter pphContext */
+
+/* 68 */ NdrFcShort( 0x118 ), /* Flags: in, out, simple ref, */
+/* 70 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 72 */ NdrFcShort( 0xe ), /* Type Offset=14 */
+
+ /* Procedure StartMetering */
+
+/* 74 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 76 */ NdrFcLong( 0x0 ), /* 0 */
+/* 80 */ NdrFcShort( 0x2 ), /* 2 */
+/* 82 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
+/* 84 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 86 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 88 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 90 */ NdrFcShort( 0x44 ), /* 68 */
+/* 92 */ NdrFcShort( 0x0 ), /* 0 */
+/* 94 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x3, /* 3 */
+/* 96 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 98 */ NdrFcShort( 0x0 ), /* 0 */
+/* 100 */ NdrFcShort( 0x0 ), /* 0 */
+/* 102 */ NdrFcShort( 0x0 ), /* 0 */
+/* 104 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 106 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 108 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 110 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Parameter samplePeriod */
+
+/* 112 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 114 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 116 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Parameter context */
+
+/* 118 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 120 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 122 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Procedure SetSamplePeriod */
+
+/* 124 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 126 */ NdrFcLong( 0x0 ), /* 0 */
+/* 130 */ NdrFcShort( 0x3 ), /* 3 */
+/* 132 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 134 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 136 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 138 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 140 */ NdrFcShort( 0x34 ), /* 52 */
+/* 142 */ NdrFcShort( 0x0 ), /* 0 */
+/* 144 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x2, /* 2 */
+/* 146 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 148 */ NdrFcShort( 0x0 ), /* 0 */
+/* 150 */ NdrFcShort( 0x0 ), /* 0 */
+/* 152 */ NdrFcShort( 0x0 ), /* 0 */
+/* 154 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 156 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 158 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 160 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Parameter samplePeriod */
+
+/* 162 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 164 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 166 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Procedure StopMetering */
+
+/* 168 */ 0x0, /* 0 */
+ 0x48, /* Old Flags: */
+/* 170 */ NdrFcLong( 0x0 ), /* 0 */
+/* 174 */ NdrFcShort( 0x4 ), /* 4 */
+/* 176 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 178 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x44, /* Ctxt flags: in, no serialize, */
+/* 180 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 182 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 184 */ NdrFcShort( 0x24 ), /* 36 */
+/* 186 */ NdrFcShort( 0x0 ), /* 0 */
+/* 188 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x1, /* 1 */
+/* 190 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 192 */ NdrFcShort( 0x0 ), /* 0 */
+/* 194 */ NdrFcShort( 0x0 ), /* 0 */
+/* 196 */ NdrFcShort( 0x0 ), /* 0 */
+/* 198 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter phContext */
+
+/* 200 */ NdrFcShort( 0x8 ), /* Flags: in, */
+/* 202 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 204 */ NdrFcShort( 0x12 ), /* Type Offset=18 */
+
+ /* Procedure MeteringDataEvent */
+
+/* 206 */ 0x34, /* FC_CALLBACK_HANDLE */
+ 0x48, /* Old Flags: */
+/* 208 */ NdrFcLong( 0x0 ), /* 0 */
+/* 212 */ NdrFcShort( 0x0 ), /* 0 */
+/* 214 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
+/* 216 */ NdrFcShort( 0x20 ), /* 32 */
+/* 218 */ NdrFcShort( 0x0 ), /* 0 */
+/* 220 */ 0x40, /* Oi2 Flags: has ext, */
+ 0x2, /* 2 */
+/* 222 */ 0xa, /* 10 */
+ 0x1, /* Ext Flags: new corr desc, */
+/* 224 */ NdrFcShort( 0x0 ), /* 0 */
+/* 226 */ NdrFcShort( 0x0 ), /* 0 */
+/* 228 */ NdrFcShort( 0x0 ), /* 0 */
+/* 230 */ NdrFcShort( 0x0 ), /* 0 */
+
+ /* Parameter data */
+
+/* 232 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 234 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
+/* 236 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ /* Parameter context */
+
+/* 238 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
+/* 240 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
+/* 242 */ 0xb, /* FC_HYPER */
+ 0x0, /* 0 */
+
+ 0x0
+ }
+ };
+
+static const RpcInterface_MIDL_TYPE_FORMAT_STRING RpcInterface__MIDL_TypeFormatString =
+ {
+ 0,
+ {
+ NdrFcShort( 0x0 ), /* 0 */
+/* 2 */
+ 0x11, 0x4, /* FC_RP [alloced_on_stack] */
+/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
+/* 6 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xa4, /* Ctxt flags: via ptr, out, no serialize, */
+/* 8 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 10 */
+ 0x11, 0x4, /* FC_RP [alloced_on_stack] */
+/* 12 */ NdrFcShort( 0x2 ), /* Offset= 2 (14) */
+/* 14 */ 0x30, /* FC_BIND_CONTEXT */
+ 0xe5, /* Ctxt flags: via ptr, in, out, no serialize, can't be null */
+/* 16 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+/* 18 */ 0x30, /* FC_BIND_CONTEXT */
+ 0x45, /* Ctxt flags: in, no serialize, can't be null */
+/* 20 */ 0x0, /* 0 */
+ 0x0, /* 0 */
+
+ 0x0
+ }
+ };
+
+static const NDR_RUNDOWN RundownRoutines[] =
+ {
+ PCONTEXT_HANDLE_TYPE_rundown
+ };
+
+
+static const unsigned short RpcInterface_FormatStringOffsetTable[] =
+ {
+ 0,
+ 36,
+ 74,
+ 124,
+ 168,
+ };
+
+
+static const unsigned short _callbackRpcInterface_FormatStringOffsetTable[] =
+ {
+ 206
+ };
+
+
+static const MIDL_STUB_DESC RpcInterface_StubDesc =
+ {
+ (void *)& RpcInterface___RpcServerInterface,
+ MIDL_user_allocate,
+ MIDL_user_free,
+ 0,
+ RundownRoutines,
+ 0,
+ 0,
+ 0,
+ RpcInterface__MIDL_TypeFormatString.Format,
+ 1, /* -error bounds_check flag */
+ 0x50002, /* Ndr library version */
+ 0,
+ 0x801026e, /* MIDL Version 8.1.622 */
+ 0,
+ 0,
+ 0, /* notify & notify_flag routine table */
+ 0x1, /* MIDL flag */
+ 0, /* cs routines */
+ 0, /* proxy/server info */
+ 0
+ };
+
+static const RPC_DISPATCH_FUNCTION RpcInterface_table[] =
+ {
+ NdrServerCall2,
+ NdrServerCall2,
+ NdrServerCall2,
+ NdrServerCall2,
+ NdrServerCall2,
+ 0
+ };
+static const RPC_DISPATCH_TABLE RpcInterface_v1_0_DispatchTable =
+ {
+ 5,
+ (RPC_DISPATCH_FUNCTION*)RpcInterface_table
+ };
+
+static const SERVER_ROUTINE RpcInterface_ServerRoutineTable[] =
+ {
+ (SERVER_ROUTINE)RemoteOpen,
+ (SERVER_ROUTINE)RemoteClose,
+ (SERVER_ROUTINE)StartMetering,
+ (SERVER_ROUTINE)SetSamplePeriod,
+ (SERVER_ROUTINE)StopMetering,
+ };
+
+static const MIDL_SERVER_INFO RpcInterface_ServerInfo =
+ {
+ &RpcInterface_StubDesc,
+ RpcInterface_ServerRoutineTable,
+ RpcInterface__MIDL_ProcFormatString.Format,
+ RpcInterface_FormatStringOffsetTable,
+ 0,
+ 0,
+ 0,
+ 0};
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#endif
+
+
+#endif /* defined(_M_AMD64)*/
+
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.cpp
new file mode 100644
index 00000000..0cad3578
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.cpp
@@ -0,0 +1,320 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include "RpcInterface_h.h"
+#include <windows.h>
+
+#include <sddl.h>
+#include <securitybaseapi.h>
+#include <AclAPI.h>
+#include "RpcServer.h"
+
+using namespace RpcServer;
+
+#define DEFAULT_METERING_PERIOD 100
+
+bool ShutdownRequested;
+static RPC_BINDING_VECTOR* BindingVector = nullptr;
+
+void FreeSidArray(__inout_ecount(cSIDs) PSID* pSIDs, ULONG cSIDs)
+{
+ if (pSIDs != nullptr)
+ {
+ for (ULONG i = 0; i < cSIDs; i++)
+ {
+ LocalFree(pSIDs[i]);
+
+ pSIDs[i] = nullptr;
+ }
+
+ LocalFree(pSIDs);
+
+ pSIDs = nullptr;
+ cSIDs = 0;
+ }
+}
+
+//
+// Routine to create RPC server and listen to incoming RPC calls
+//
+DWORD RpcServerStart()
+{
+ DWORD hResult = S_OK;
+ WCHAR* protocolSequence = L"ncalrpc";
+ unsigned int minCalls = 1;
+ unsigned int dontWait = false;
+ ShutdownRequested = false;
+
+ SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+ PSID everyoneSid = nullptr;
+ PSID* capabilitySids = nullptr;
+ DWORD capabilitySidCount = 0;
+ PSID* capabilityGroupSids = nullptr;
+ DWORD capabilityGroupSidCount = 0;
+ EXPLICIT_ACCESS ea[2] = {};
+ PACL acl = nullptr;
+ SECURITY_DESCRIPTOR rpcSecurityDescriptor = {};
+
+ // When creating the RPC endpoint we want it to allow connections from any UWA that contains
+ // the custom capability SID in its process token. When a UWA declares the custom capability
+ // in its app manifest, it will later contain the SID form of that custom capability in its
+ // process token at runtime. By default, RPC endpoints don't allow UWAs (AppContainer processes)
+ // to connect to them, so we need to set the security on the endpoint to allow access to UWAs with the
+ // custom capability.
+ //
+ // To do this we'll perform the following steps:
+ // 1) Convert the custom capability name to a SID
+ // 2) Create a security descriptor using that SID, as well as other needed SIDs. This sample shows how to allow
+ // all 'non UWAs' access as well as UWAs containing the custom capability SID.
+ // 3) Create the RPC endpoint using that security descriptor
+ //
+ // To create the security descriptor we're roughly following this MSDN sample:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa446595(v=vs.85).aspx
+
+ // Get the SID form of the custom capability. In this case we only expect one SID and
+ // we don't care about the capability group.
+ //INSERT DERIVE CAPABILTY SIDS FROM NAME HERE
+
+ // Get the SID that represents 'everyone' (this doesn't include AppContainers)
+ if (!AllocateAndInitializeSid(
+ &SIDAuthWorld, 1,
+ SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &everyoneSid))
+ {
+ hResult = GetLastError();
+ goto end;
+ }
+
+ // Now create the Access Control List (ACL) for the Security descriptor
+
+ // Everyone GENERIC_ALL access
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfAccessPermissions = GENERIC_ALL;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ea[0].Trustee.ptstrName = static_cast<LPWSTR>(everyoneSid);
+
+ // Custom capability GENERIC_ALL access
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfAccessPermissions = GENERIC_ALL;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[1].Trustee.ptstrName = static_cast<LPWSTR>(everyoneSid);
+
+ hResult = SetEntriesInAcl(ARRAYSIZE(ea), ea, nullptr, &acl);
+
+ if (hResult != ERROR_SUCCESS)
+ {
+ goto end;
+ }
+
+ // Initialize an empty security descriptor
+ if (!InitializeSecurityDescriptor(&rpcSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
+ {
+ hResult = GetLastError();
+ goto end;
+ }
+
+ // Assign the ACL to the security descriptor
+ if (!SetSecurityDescriptorDacl(&rpcSecurityDescriptor, TRUE, acl, FALSE))
+ {
+ hResult = GetLastError();
+ goto end;
+ }
+
+ //
+ // Bind to LRPC using dynamic endpoints
+ //
+ hResult = RpcServerUseProtseqEp(
+ reinterpret_cast<RPC_WSTR>(protocolSequence),
+ RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
+ reinterpret_cast<RPC_WSTR>(RPC_STATIC_ENDPOINT),
+ &rpcSecurityDescriptor);
+
+ if (hResult != S_OK)
+ {
+ goto end;
+ }
+
+ hResult = RpcServerRegisterIf3(
+ RpcInterface_v1_0_s_ifspec,
+ nullptr,
+ nullptr,
+ RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_LOCAL_ONLY,
+ RPC_C_LISTEN_MAX_CALLS_DEFAULT,
+ 0,
+ nullptr,
+ &rpcSecurityDescriptor);
+
+ if (hResult != S_OK)
+ {
+ goto end;
+ }
+
+ hResult = RpcServerInqBindings(&BindingVector);
+
+ if (hResult != S_OK)
+ {
+ goto end;
+ }
+
+ hResult = RpcEpRegister(
+ RpcInterface_v1_0_s_ifspec,
+ BindingVector,
+ nullptr,
+ nullptr);
+
+ if (hResult != S_OK)
+ {
+ goto end;
+ }
+
+ hResult = RpcServerListen(
+ minCalls,
+ RPC_C_LISTEN_MAX_CALLS_DEFAULT,
+ dontWait);
+
+ if (hResult == RPC_S_ALREADY_LISTENING)
+ {
+ hResult = RPC_S_OK;
+ }
+
+end:
+
+ // Cleanup sids
+ FreeSidArray(capabilityGroupSids, capabilityGroupSidCount);
+ FreeSidArray(capabilitySids, capabilitySidCount);
+
+ if (everyoneSid != nullptr)
+ {
+ FreeSid(everyoneSid);
+ }
+
+ // cleanup acl
+ if (acl != nullptr)
+ {
+ LocalFree(acl);
+ }
+
+ return hResult;
+}
+
+//
+// Notify rpc server to stop listening to incoming rpc calls
+//
+void RpcServerDisconnect()
+{
+ DWORD hResult = S_OK;
+ ShutdownRequested = true;
+ hResult = RpcServerUnregisterIf(RpcInterface_v1_0_s_ifspec, nullptr, 0);
+
+ RpcEpUnregister(RpcInterface_v1_0_s_ifspec, BindingVector, nullptr);
+
+ if (BindingVector != nullptr)
+ {
+ RpcBindingVectorFree(&BindingVector);
+ BindingVector = nullptr;
+ }
+}
+
+//
+// Rpc method to retrieve client context handle
+//
+void RemoteOpen(
+ _In_ handle_t hBinding,
+ _Out_ PPCONTEXT_HANDLE_TYPE pphContext)
+{
+ *pphContext = static_cast<PCONTEXT_HANDLE_TYPE *>(midl_user_allocate(sizeof(METERING_CONTEXT)));
+ METERING_CONTEXT* meteringContext = static_cast<METERING_CONTEXT *>(*pphContext);
+ meteringContext->metering = new Metering(DEFAULT_METERING_PERIOD);
+}
+
+//
+// Rpc method to close the client context handle
+//
+void RemoteClose(_Inout_ PPCONTEXT_HANDLE_TYPE pphContext)
+{
+ if (*pphContext == nullptr)
+ {
+ //Log error, client tried to close a NULL handle.
+ return;
+ }
+
+ METERING_CONTEXT* meteringContext = static_cast<METERING_CONTEXT *>(*pphContext);
+ delete meteringContext->metering;
+ MIDL_user_free(meteringContext);
+
+ // This tells the run-time, when it is marshalling the out
+ // parameters, that the context handle has been closed normally.
+ *pphContext = nullptr;
+}
+
+//
+// Routine to cleanup client context when client has died with active
+// connection with server
+//
+void __RPC_USER PCONTEXT_HANDLE_TYPE_rundown(
+ _In_ PCONTEXT_HANDLE_TYPE phContext)
+{
+ StopMetering(phContext);
+ RemoteClose(&phContext);
+}
+
+#pragma region METERING_RPCROUTINES
+
+void StartMetering(
+ _In_ PCONTEXT_HANDLE_TYPE phContext,
+ _In_ __int64 period,
+ _In_ __int64 context)
+{
+ std::cout << "start metering" << std::endl;
+ METERING_CONTEXT* meteringContext = static_cast<METERING_CONTEXT *>(phContext);
+ meteringContext->metering->StartMetering(period, context);
+ std::cout << "done metering" << std::endl;
+}
+
+void SetSamplePeriod(
+ _In_ PCONTEXT_HANDLE_TYPE phContext,
+ _In_ __int64 period)
+{
+ METERING_CONTEXT* meteringContext = static_cast<METERING_CONTEXT *>(phContext);
+ meteringContext->metering->SetSamplePeriod(period);
+}
+
+
+void StopMetering(_In_ PCONTEXT_HANDLE_TYPE phContext)
+{
+ METERING_CONTEXT* meteringContext = static_cast<METERING_CONTEXT *>(phContext);
+ meteringContext->metering->StopMetering();
+}
+
+#pragma endregion METERING_RPCROUTINES
+
+/******************************************************/
+/* MIDL allocate and free */
+/******************************************************/
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(_In_ size_t len)
+{
+ return(malloc(len));
+}
+
+void __RPC_USER midl_user_free(_In_ void __RPC_FAR* ptr)
+{
+ free(ptr);
+}
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.h
new file mode 100644
index 00000000..bc7294db
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.h
@@ -0,0 +1,16 @@
+#include "metering.h"
+
+#define RPC_STATIC_ENDPOINT L"HsaSampleRpcEndpoint"
+
+// Client context used for making rpc calls using context handle
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa378674(v=vs.85).aspx
+typedef struct
+{
+ RpcServer::Metering* metering;
+} METERING_CONTEXT;
+
+// Create a rpc server endpoint and listen to incoming rpc calls
+DWORD RpcServerStart();
+
+// Signal the rpc server to stop listening to incoming rpc calls
+void RpcServerDisconnect();
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj
new file mode 100644
index 00000000..b5c043dc
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{ADFC4322-5F0E-5BFD-83DA-19B35EFD513B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>RpcServer</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);ucrt.lib;rpcrt4.lib;libcmt.lib;libvcruntime.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ <AdditionalOptions>/VERBOSE %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);ucrt.lib;rpcrt4.lib;libcmt.lib;libvcruntime.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ <AdditionalOptions>/VERBOSE %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(OutDir)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);ucrt.lib;rpcrt4.lib;libcmt.lib;libvcruntime.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);kernel32.lib;user32.lib;shell32.lib;gdi32.lib</IgnoreSpecificDefaultLibraries>
+ <AdditionalOptions>/VERBOSE %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="Metering.h" />
+ <ClInclude Include="RpcServer.h" />
+ <ClInclude Include="SampleService.h" />
+ <ClInclude Include="ServiceBase.h" />
+ <ClInclude Include="ServiceInstaller.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="RpcInterface_s.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="HsaService.cpp" />
+ <ClCompile Include="Metering.cpp" />
+ <ClCompile Include="RpcServer.cpp" />
+ <ClCompile Include="SampleService.cpp" />
+ <ClCompile Include="ServiceBase.cpp" />
+ <ClCompile Include="ServiceInstaller.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="RpcInterface.acf" />
+ </ItemGroup>
+ <ItemGroup>
+ <Midl Include="RpcInterface.Idl" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj.filters b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj.filters
new file mode 100644
index 00000000..9644ad4e
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/RpcServer.vcxproj.filters
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="targetver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Metering.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="RpcServer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SampleService.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ServiceBase.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ServiceInstaller.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="HsaService.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Metering.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="RpcServer.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SampleService.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ServiceBase.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ServiceInstaller.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="RpcInterface_s.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="RpcInterface.acf">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Midl Include="RpcInterface.Idl">
+ <Filter>Source Files</Filter>
+ </Midl>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.cpp
new file mode 100644
index 00000000..793a7009
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.cpp
@@ -0,0 +1,155 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+
+#pragma region Includes
+#include "SampleService.h"
+#include "RpcServer.h"
+#include <Evntrace.h>
+#pragma endregion
+
+CSampleService::CSampleService(
+ PWSTR pszServiceName,
+ BOOL fCanStop,
+ BOOL fCanShutdown,
+ BOOL fCanPauseContinue)
+ : CServiceBase(pszServiceName, fCanStop, fCanShutdown, fCanPauseContinue)
+{
+}
+
+void CSampleService::WriteEventLogEntry(PWSTR pszMessage, BYTE bLevel)
+{
+ if (IsConsoleRun())
+ {
+ wprintf(L"%d: %ls\n", bLevel, pszMessage);
+ }
+ __super::WriteEventLogEntry(pszMessage, bLevel);
+}
+
+CSampleService::~CSampleService(void)
+{
+}
+
+//
+// This is the thread pool work callback function.
+//
+VOID CALLBACK ServiceWorkerThread(
+ _In_ PTP_CALLBACK_INSTANCE /*Instance*/,
+ _In_ PVOID Parameter,
+ _In_ PTP_WORK /*Work*/)
+{
+ //
+ // Do something when the work callback is invoked.
+ //
+ {
+ _int64 status = RpcServerStart();
+ if (status)
+ {
+ CSampleService* sampleService = static_cast<CSampleService *>(Parameter);
+ sampleService->Stop();
+ }
+ }
+
+ return;
+}
+
+//
+// FUNCTION: CSampleService::OnStart(DWORD, LPWSTR *)
+//
+// PURPOSE: The function is executed when a Start command is sent to the
+// service by the SCM or when the operating system starts (for a service
+// that starts automatically). It specifies actions to take when the
+// service starts. In this code sample, OnStart logs a service-start
+// message to the Application log, and queues the main service function for
+// execution in a thread pool worker thread.
+//
+// PARAMETERS:
+// * dwArgc - number of command line arguments
+// * lpszArgv - array of command line arguments
+//
+// NOTE: A service application is designed to be long running. Therefore,
+// it usually polls or monitors something in the system. The monitoring is
+// set up in the OnStart method. However, OnStart does not actually do the
+// monitoring. The OnStart method must return to the operating system after
+// the service's operation has begun. It must not loop forever or block. To
+// set up a simple monitoring mechanism, one general solution is to create
+// a timer in OnStart. The timer would then raise events in your code
+// periodically, at which time your service could do its monitoring. The
+// other solution is to spawn a new thread to perform the main service
+// functions, which is demonstrated in this code sample.
+//
+void CSampleService::OnStart(
+ _In_ DWORD dwArgc,
+ _In_ LPWSTR *lpszArgv)
+{
+ // Log a service start message to the Application log.
+ WriteEventLogEntry(L"CppWindowsService in OnStart", TRACE_LEVEL_INFORMATION);
+
+ // Queue the main service function for execution in a worker thread.
+ PTP_WORK_CALLBACK workcallback = ServiceWorkerThread;
+ m_work = CreateThreadpoolWork(workcallback, this, nullptr);
+
+ if (NULL == m_work)
+ {
+ // TODO: Capture get last error
+ WriteEventLogEntry(L"CreateThreadpoolWork failed", TRACE_LEVEL_ERROR);
+ }
+
+ //
+ // Submit the work to the pool. Because this was a pre-allocated
+ // work item (using CreateThreadpoolWork), it is guaranteed to execute.
+ //
+ SubmitThreadpoolWork(m_work);
+}
+
+//
+// FUNCTION: CSampleService::ConsoleRun()
+//
+// PURPOSE: The function is executed to simulate OnStart in
+// console mode.
+//
+void CSampleService::ConsoleRun()
+{
+ m_runningInConsole = true;
+
+ WriteEventLogEntry(L"Starting Rpc Server..", TRACE_LEVEL_INFORMATION);
+ long status = RpcServerStart();
+
+ if (status)
+ {
+ printf_s("RpcServerConnect returned: 0x%x\n", status);
+ WriteEventLogEntry(L"Starting Rpc Server..", TRACE_LEVEL_INFORMATION);
+ exit(static_cast<int>(status));
+ }
+}
+
+//
+// FUNCTION: CSampleService::OnStop()
+//
+// PURPOSE: The function is executed when a Stop command is sent to the
+// service by SCM. It specifies actions to take when a service stops
+// running. In this code sample, OnStop logs a service-stop message to the
+// Application log, and waits for the finish of the main service function.
+//
+// COMMENTS:
+// Be sure to periodically call ReportServiceStatus() with
+// SERVICE_STOP_PENDING if the procedure is going to take long time.
+//
+void CSampleService::OnStop()
+{
+ // Log a service stop message to the Application log.
+ WriteEventLogEntry(L"CppWindowsService in OnStop", TRACE_LEVEL_INFORMATION);
+
+ // Instruct server to stop listening to remote procedure calls and
+ // unregister rpc interface
+ RpcServerDisconnect();
+} \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.h
new file mode 100644
index 00000000..04621b3e
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/SampleService.h
@@ -0,0 +1,46 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+// Provides a sample service class that derives from the service base class -
+// CServiceBase. The sample service logs the service start and stop
+// information to the Application event log, and shows how to run the main
+// function of the service in a thread pool worker thread.
+
+#pragma once
+
+#include "ServiceBase.h"
+
+class CSampleService : public CServiceBase
+{
+public:
+
+ CSampleService(PWSTR pszServiceName,
+ BOOL fCanStop = TRUE,
+ BOOL fCanShutdown = TRUE,
+ BOOL fCanPauseContinue = FALSE);
+ void ConsoleRun();
+ bool IsConsoleRun()
+ {
+ return m_runningInConsole;
+ }
+ void WriteEventLogEntry(PWSTR pszMessage, BYTE bLevel) override;
+ virtual ~CSampleService(void);
+
+protected:
+
+ virtual void OnStart(DWORD dwArgc, PWSTR *pszArgv) override;
+ virtual void OnStop() override;
+
+
+private:
+ PTP_WORK m_work = nullptr;
+ bool m_runningInConsole = false;
+}; \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.cpp
new file mode 100644
index 00000000..117d740c
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.cpp
@@ -0,0 +1,566 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+#pragma region Includes
+
+#include "ServiceBase.h"
+#include <assert.h>
+#include <strsafe.h>
+#include <evntprov.h>
+#include <Evntrace.h>
+#pragma endregion
+
+//
+// HSA Service trace event provider
+// {BE2E880E-F79F-4C30-9C95-09F003A0A7EA}
+//
+EXTERN_C __declspec(selectany) const GUID HSA_SERVICE_PROVIDER_GUID = { 0xbe2e880e, 0xf79f, 0x4c30,{ 0x9c, 0x95, 0x9, 0xf0, 0x3, 0xa0, 0xa7, 0xea } };
+
+#pragma region Static Members
+
+// Initialize the singleton service instance.
+CServiceBase *CServiceBase::s_service = nullptr;
+
+
+//
+// FUNCTION: CServiceBase::Run(CServiceBase &)
+//
+// PURPOSE: Register the executable for a service with the Service Control
+// Manager (SCM). After you call Run(ServiceBase), the SCM issues a Start
+// command, which results in a call to the OnStart method in the service.
+// This method blocks until the service has stopped.
+//
+// PARAMETERS:
+// * service - the reference to a CServiceBase object. It will become the
+// singleton service instance of this service application.
+//
+// RETURN VALUE: If the function succeeds, the return value is TRUE. If the
+// function fails, the return value is FALSE. To get extended error
+// information, call GetLastError.
+//
+BOOL CServiceBase::Run(CServiceBase &service)
+{
+ s_service = &service;
+
+ SERVICE_TABLE_ENTRY serviceTable[] =
+ {
+ { service.m_name, ServiceMain },
+ { nullptr, nullptr }
+ };
+
+ // Connects the main thread of a service process to the service control
+ // manager, which causes the thread to be the service control dispatcher
+ // thread for the calling process. This call returns when the service has
+ // stopped. The process should simply terminate when the call returns.
+ return StartServiceCtrlDispatcher(serviceTable);
+}
+
+
+//
+// FUNCTION: CServiceBase::ServiceMain(DWORD, PWSTR *)
+//
+// PURPOSE: Entry point for the service. It registers the handler function
+// for the service and starts the service.
+//
+// PARAMETERS:
+// * dwArgc - number of command line arguments
+// * lpszArgv - array of command line arguments
+//
+void WINAPI CServiceBase::ServiceMain(DWORD dwArgc, PWSTR *pszArgv)
+{
+ assert(s_service != NULL);
+
+ // Register the handler function for the service
+ s_service->m_statusHandle = RegisterServiceCtrlHandler(
+ s_service->m_name, ServiceCtrlHandler);
+
+ if (s_service->m_statusHandle == NULL)
+ {
+ throw GetLastError();
+ }
+
+ // Start the service.
+ s_service->Start(dwArgc, pszArgv);
+}
+
+
+//
+// FUNCTION: CServiceBase::ServiceCtrlHandler(DWORD)
+//
+// PURPOSE: The function is called by the SCM whenever a control code is
+// sent to the service.
+//
+// PARAMETERS:
+// * dwCtrlCode - the control code. This parameter can be one of the
+// following values:
+//
+// SERVICE_CONTROL_CONTINUE
+// SERVICE_CONTROL_INTERROGATE
+// SERVICE_CONTROL_NETBINDADD
+// SERVICE_CONTROL_NETBINDDISABLE
+// SERVICE_CONTROL_NETBINDREMOVE
+// SERVICE_CONTROL_PARAMCHANGE
+// SERVICE_CONTROL_PAUSE
+// SERVICE_CONTROL_SHUTDOWN
+// SERVICE_CONTROL_STOP
+//
+// This parameter can also be a user-defined control code ranges from 128
+// to 255.
+//
+void WINAPI CServiceBase::ServiceCtrlHandler(DWORD dwCtrl)
+{
+ switch (dwCtrl)
+ {
+ case SERVICE_CONTROL_STOP: s_service->Stop(); break;
+ case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
+ case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
+ case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
+ case SERVICE_CONTROL_INTERROGATE: break;
+ default: break;
+ }
+}
+
+#pragma endregion
+
+
+#pragma region Service Constructor and Destructor
+
+//
+// FUNCTION: CServiceBase::CServiceBase(PWSTR, BOOL, BOOL, BOOL)
+//
+// PURPOSE: The constructor of CServiceBase. It initializes a new instance
+// of the CServiceBase class. The optional parameters (fCanStop,
+/// fCanShutdown and fCanPauseContinue) allow you to specify whether the
+// service can be stopped, paused and continued, or be notified when system
+// shutdown occurs.
+//
+// PARAMETERS:
+// * pszServiceName - the name of the service
+// * fCanStop - the service can be stopped
+// * fCanShutdown - the service is notified when system shutdown occurs
+// * fCanPauseContinue - the service can be paused and continued
+//
+CServiceBase::CServiceBase(
+ PWSTR pszServiceName,
+ BOOL fCanStop,
+ BOOL fCanShutdown,
+ BOOL fCanPauseContinue)
+{
+ // Service name must be a valid string and cannot be NULL.
+ m_name = (pszServiceName == nullptr) ? L"" : pszServiceName;
+
+ m_statusHandle = nullptr;
+
+ // The service runs in its own process.
+ m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+
+ // The service is starting.
+ m_status.dwCurrentState = SERVICE_START_PENDING;
+
+ // The accepted commands of the service.
+ DWORD dwControlsAccepted = 0;
+ if (fCanStop)
+ dwControlsAccepted |= SERVICE_ACCEPT_STOP;
+ if (fCanShutdown)
+ dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
+ if (fCanPauseContinue)
+ dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
+ m_status.dwControlsAccepted = dwControlsAccepted;
+
+ m_status.dwWin32ExitCode = NO_ERROR;
+ m_status.dwServiceSpecificExitCode = 0;
+ m_status.dwCheckPoint = 0;
+ m_status.dwWaitHint = 0;
+
+ NTSTATUS status = EventRegister(&HSA_SERVICE_PROVIDER_GUID,
+ nullptr,
+ nullptr,
+ &m_etwRegHandle);
+ if (ERROR_SUCCESS != status)
+ {
+ wprintf(L"Provider not registered. EventRegister failed with %d\n", status);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::~CServiceBase()
+//
+// PURPOSE: The virtual destructor of CServiceBase.
+//
+CServiceBase::~CServiceBase(void)
+{
+ if (m_etwRegHandle != NULL)
+ {
+ EventUnregister(m_etwRegHandle);
+ }
+}
+
+#pragma endregion
+
+
+#pragma region Service Start, Stop, Pause, Continue, and Shutdown
+
+//
+// FUNCTION: CServiceBase::Start(DWORD, PWSTR *)
+//
+// PURPOSE: The function starts the service. It calls the OnStart virtual
+// function in which you can specify the actions to take when the service
+// starts. If an error occurs during the startup, the error will be logged
+// in the Application event log, and the service will be stopped.
+//
+// PARAMETERS:
+// * dwArgc - number of command line arguments
+// * lpszArgv - array of command line arguments
+//
+void CServiceBase::Start(DWORD dwArgc, PWSTR *pszArgv)
+{
+ WriteEventLogEntry(L"Service trying to start.", TRACE_LEVEL_ERROR);
+ try
+ {
+ // Tell SCM that the service is starting.
+ SetServiceStatus(SERVICE_START_PENDING);
+
+ // Perform service-specific initialization.
+ OnStart(dwArgc, pszArgv);
+
+ // Tell SCM that the service is started.
+ SetServiceStatus(SERVICE_RUNNING);
+ }
+ catch (DWORD dwError)
+ {
+ // Log the error.
+ WriteErrorLogEntry(L"Service Start", dwError);
+
+ // Set the service status to be stopped.
+ SetServiceStatus(SERVICE_STOPPED, dwError);
+ }
+ catch (...)
+ {
+ // Log the error.
+ WriteEventLogEntry(L"Service failed to start.", TRACE_LEVEL_ERROR);
+
+ // Set the service status to be stopped.
+ SetServiceStatus(SERVICE_STOPPED);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::OnStart(DWORD, PWSTR *)
+//
+// PURPOSE: When implemented in a derived class, executes when a Start
+// command is sent to the service by the SCM or when the operating system
+// starts (for a service that starts automatically). Specifies actions to
+// take when the service starts. Be sure to periodically call
+// CServiceBase::SetServiceStatus() with SERVICE_START_PENDING if the
+// procedure is going to take long time. You may also consider spawning a
+// new thread in OnStart to perform time-consuming initialization tasks.
+//
+// PARAMETERS:
+// * dwArgc - number of command line arguments
+// * lpszArgv - array of command line arguments
+//
+void CServiceBase::OnStart(DWORD dwArgc, PWSTR *pszArgv)
+{
+}
+
+
+//
+// FUNCTION: CServiceBase::Stop()
+//
+// PURPOSE: The function stops the service. It calls the OnStop virtual
+// function in which you can specify the actions to take when the service
+// stops. If an error occurs, the error will be logged in the Application
+// event log, and the service will be restored to the original state.
+//
+void CServiceBase::Stop()
+{
+ DWORD dwOriginalState = m_status.dwCurrentState;
+ try
+ {
+ // Tell SCM that the service is stopping.
+ SetServiceStatus(SERVICE_STOP_PENDING);
+
+ // Perform service-specific stop operations.
+ OnStop();
+
+ // Tell SCM that the service is stopped.
+ SetServiceStatus(SERVICE_STOPPED);
+ }
+ catch (DWORD dwError)
+ {
+ // Log the error.
+ WriteErrorLogEntry(L"Service Stop", dwError);
+
+ // Set the orginal service status.
+ SetServiceStatus(dwOriginalState);
+ }
+ catch (...)
+ {
+ // Log the error.
+ WriteEventLogEntry(L"Service failed to stop.", TRACE_LEVEL_ERROR);
+
+ // Set the orginal service status.
+ SetServiceStatus(dwOriginalState);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::OnStop()
+//
+// PURPOSE: When implemented in a derived class, executes when a Stop
+// command is sent to the service by the SCM. Specifies actions to take
+// when a service stops running. Be sure to periodically call
+// CServiceBase::SetServiceStatus() with SERVICE_STOP_PENDING if the
+// procedure is going to take long time.
+//
+void CServiceBase::OnStop()
+{
+}
+
+
+//
+// FUNCTION: CServiceBase::Pause()
+//
+// PURPOSE: The function pauses the service if the service supports pause
+// and continue. It calls the OnPause virtual function in which you can
+// specify the actions to take when the service pauses. If an error occurs,
+// the error will be logged in the Application event log, and the service
+// will become running.
+//
+void CServiceBase::Pause()
+{
+ try
+ {
+ // Tell SCM that the service is pausing.
+ SetServiceStatus(SERVICE_PAUSE_PENDING);
+
+ // Perform service-specific pause operations.
+ OnPause();
+
+ // Tell SCM that the service is paused.
+ SetServiceStatus(SERVICE_PAUSED);
+ }
+ catch (DWORD dwError)
+ {
+ // Log the error.
+ WriteErrorLogEntry(L"Service Pause", dwError);
+
+ // Tell SCM that the service is still running.
+ SetServiceStatus(SERVICE_RUNNING);
+ }
+ catch (...)
+ {
+ // Log the error.
+ WriteEventLogEntry(L"Service failed to pause.", TRACE_LEVEL_ERROR);
+
+ // Tell SCM that the service is still running.
+ SetServiceStatus(SERVICE_RUNNING);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::OnPause()
+//
+// PURPOSE: When implemented in a derived class, executes when a Pause
+// command is sent to the service by the SCM. Specifies actions to take
+// when a service pauses.
+//
+void CServiceBase::OnPause()
+{
+}
+
+
+//
+// FUNCTION: CServiceBase::Continue()
+//
+// PURPOSE: The function resumes normal functioning after being paused if
+// the service supports pause and continue. It calls the OnContinue virtual
+// function in which you can specify the actions to take when the service
+// continues. If an error occurs, the error will be logged in the
+// Application event log, and the service will still be paused.
+//
+void CServiceBase::Continue()
+{
+ try
+ {
+ // Tell SCM that the service is resuming.
+ SetServiceStatus(SERVICE_CONTINUE_PENDING);
+
+ // Perform service-specific continue operations.
+ OnContinue();
+
+ // Tell SCM that the service is running.
+ SetServiceStatus(SERVICE_RUNNING);
+ }
+ catch (DWORD dwError)
+ {
+ // Log the error.
+ WriteErrorLogEntry(L"Service Continue", dwError);
+
+ // Tell SCM that the service is still paused.
+ SetServiceStatus(SERVICE_PAUSED);
+ }
+ catch (...)
+ {
+ // Log the error.
+ WriteEventLogEntry(L"Service failed to resume.", TRACE_LEVEL_ERROR);
+
+ // Tell SCM that the service is still paused.
+ SetServiceStatus(SERVICE_PAUSED);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::OnContinue()
+//
+// PURPOSE: When implemented in a derived class, OnContinue runs when a
+// Continue command is sent to the service by the SCM. Specifies actions to
+// take when a service resumes normal functioning after being paused.
+//
+void CServiceBase::OnContinue()
+{
+}
+
+
+//
+// FUNCTION: CServiceBase::Shutdown()
+//
+// PURPOSE: The function executes when the system is shutting down. It
+// calls the OnShutdown virtual function in which you can specify what
+// should occur immediately prior to the system shutting down. If an error
+// occurs, the error will be logged in the Application event log.
+//
+void CServiceBase::Shutdown()
+{
+ try
+ {
+ // Perform service-specific shutdown operations.
+ OnShutdown();
+
+ // Tell SCM that the service is stopped.
+ SetServiceStatus(SERVICE_STOPPED);
+ }
+ catch (DWORD dwError)
+ {
+ // Log the error.
+ WriteErrorLogEntry(L"Service Shutdown", dwError);
+ }
+ catch (...)
+ {
+ // Log the error.
+ WriteEventLogEntry(L"Service failed to shut down.", TRACE_LEVEL_ERROR);
+ }
+}
+
+
+//
+// FUNCTION: CServiceBase::OnShutdown()
+//
+// PURPOSE: When implemented in a derived class, executes when the system
+// is shutting down. Specifies what should occur immediately prior to the
+// system shutting down.
+//
+void CServiceBase::OnShutdown()
+{
+}
+
+#pragma endregion
+
+
+#pragma region Helper Functions
+
+//
+// FUNCTION: CServiceBase::SetServiceStatus(DWORD, DWORD, DWORD)
+//
+// PURPOSE: The function sets the service status and reports the status to
+// the SCM.
+//
+// PARAMETERS:
+// * dwCurrentState - the state of the service
+// * dwWin32ExitCode - error code to report
+// * dwWaitHint - estimated time for pending operation, in milliseconds
+//
+void CServiceBase::SetServiceStatus(
+ _In_ DWORD dwCurrentState,
+ _In_ DWORD dwWin32ExitCode,
+ _In_ DWORD dwWaitHint)
+{
+ static DWORD dwCheckPoint = 1;
+
+ // Fill in the SERVICE_STATUS structure of the service.
+
+ m_status.dwCurrentState = dwCurrentState;
+ m_status.dwWin32ExitCode = dwWin32ExitCode;
+ m_status.dwWaitHint = dwWaitHint;
+
+ m_status.dwCheckPoint =
+ ((dwCurrentState == SERVICE_RUNNING) ||
+ (dwCurrentState == SERVICE_STOPPED)) ?
+ 0 : dwCheckPoint++;
+
+ // Report the status of the service to the SCM.
+ ::SetServiceStatus(m_statusHandle, &m_status);
+}
+
+
+//
+// FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD)
+//
+// PURPOSE: Log an event.
+//
+// PARAMETERS:
+// * pszMessage - string message to be logged.
+// * wType - the type of event to be logged. The parameter can be one of
+// the following values.
+//
+// EVENTLOG_SUCCESS
+// EVENTLOG_AUDIT_FAILURE
+// EVENTLOG_AUDIT_SUCCESS
+// EVENTLOG_ERROR_TYPE
+// EVENTLOG_INFORMATION_TYPE
+// EVENTLOG_WARNING_TYPE
+//
+void CServiceBase::WriteEventLogEntry(
+ _In_ PWSTR pszMessage,
+ _In_ BYTE bLevel)
+{
+ if (m_etwRegHandle != NULL)
+ {
+ EventWriteString(m_etwRegHandle, bLevel, 0, pszMessage);
+ }
+}
+
+//
+// FUNCTION: CServiceBase::WriteErrorLogEntry(PWSTR, DWORD)
+//
+// PURPOSE: Log an event.
+//
+// PARAMETERS:
+// * pszFunction - the function that gives the error
+// * dwError - the error code
+//
+void CServiceBase::WriteErrorLogEntry(
+ _In_ PWSTR pszFunction,
+ _In_ DWORD dwError)
+{
+ wchar_t szMessage[260];
+ StringCchPrintf(szMessage, ARRAYSIZE(szMessage),
+ L"%s failed w/err 0x%08lx", pszFunction, dwError);
+ WriteEventLogEntry(szMessage, TRACE_LEVEL_ERROR);
+}
+
+#pragma endregion \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.h
new file mode 100644
index 00000000..ebae808e
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceBase.h
@@ -0,0 +1,121 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+// Provides a base class for a service that will exist as part of a service
+// application. CServiceBase must be derived from when creating a new service
+// class.
+
+#pragma once
+
+#include <windows.h>
+#include <evntprov.h>
+
+class CServiceBase
+{
+public:
+
+ // Register the executable for a service with the Service Control Manager
+ // (SCM). After you call Run(ServiceBase), the SCM issues a Start command,
+ // which results in a call to the OnStart method in the service. This
+ // method blocks until the service has stopped.
+ static BOOL Run(CServiceBase& service);
+
+ // Service object constructor. The optional parameters (fCanStop,
+ // fCanShutdown and fCanPauseContinue) allow you to specify whether the
+ // service can be stopped, paused and continued, or be notified when
+ // system shutdown occurs.
+ CServiceBase(PWSTR pszServiceName,
+ BOOL fCanStop = TRUE,
+ BOOL fCanShutdown = TRUE,
+ BOOL fCanPauseContinue = FALSE);
+
+ // Service object destructor.
+ virtual ~CServiceBase(void);
+
+ // Stop the service.
+ void Stop();
+
+protected:
+
+ // When implemented in a derived class, executes when a Start command is
+ // sent to the service by the SCM or when the operating system starts
+ // (for a service that starts automatically). Specifies actions to take
+ // when the service starts.
+ virtual void OnStart(DWORD dwArgc, PWSTR *pszArgv);
+
+ // When implemented in a derived class, executes when a Stop command is
+ // sent to the service by the SCM. Specifies actions to take when a
+ // service stops running.
+ virtual void OnStop();
+
+ // When implemented in a derived class, executes when a Pause command is
+ // sent to the service by the SCM. Specifies actions to take when a
+ // service pauses.
+ virtual void OnPause();
+
+ // When implemented in a derived class, OnContinue runs when a Continue
+ // command is sent to the service by the SCM. Specifies actions to take
+ // when a service resumes normal functioning after being paused.
+ virtual void OnContinue();
+
+ // When implemented in a derived class, executes when the system is
+ // shutting down. Specifies what should occur immediately prior to the
+ // system shutting down.
+ virtual void OnShutdown();
+
+ // Set the service status and report the status to the SCM.
+ void SetServiceStatus(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode = NO_ERROR,
+ DWORD dwWaitHint = 0);
+
+ // Log an event.
+ virtual void WriteEventLogEntry(PWSTR pszMessage, BYTE bLevel);
+
+ // Log an event.
+ void WriteErrorLogEntry(PWSTR pszFunction,
+ DWORD dwError = GetLastError());
+
+private:
+
+ // Entry point for the service. It registers the handler function for the
+ // service and starts the service.
+ static void WINAPI ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv);
+
+ // The function is called by the SCM whenever a control code is sent to
+ // the service.
+ static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
+
+ // Start the service.
+ void Start(DWORD dwArgc, PWSTR *pszArgv);
+
+ // Pause the service.
+ void Pause();
+
+ // Resume the service after being paused.
+ void Continue();
+
+ // Execute when the system is shutting down.
+ void Shutdown();
+
+ // The singleton service instance.
+ static CServiceBase *s_service;
+
+ // The name of the service
+ PWSTR m_name;
+
+ // The status of the service
+ SERVICE_STATUS m_status;
+
+ // The service status handle
+ SERVICE_STATUS_HANDLE m_statusHandle;
+
+ REGHANDLE m_etwRegHandle;
+}; \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.cpp
new file mode 100644
index 00000000..27b107a9
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.cpp
@@ -0,0 +1,191 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "stdafx.h"
+#pragma region "Includes"
+
+#include <stdio.h>
+#include <windows.h>
+#include "ServiceInstaller.h"
+#pragma endregion
+
+
+//
+// FUNCTION: InstallService
+//
+// PURPOSE: Install the current application as a service to the local
+// service control manager database.
+//
+// PARAMETERS:
+// * pszServiceName - the name of the service to be installed
+// * pszDisplayName - the display name of the service
+// * dwStartType - the service start option. This parameter can be one of
+// the following values: SERVICE_AUTO_START, SERVICE_BOOT_START,
+// SERVICE_DEMAND_START, SERVICE_DISABLED, SERVICE_SYSTEM_START.
+// * pszDependencies - a pointer to a double null-terminated array of null-
+// separated names of services or load ordering groups that the system
+// must start before this service.
+// * pszAccount - the name of the account under which the service runs.
+// * pszPassword - the password to the account name.
+//
+// NOTE: If the function fails to install the service, it prints the error
+// in the standard output stream for users to diagnose the problem.
+//
+void InstallService(
+ _In_ PWSTR pszServiceName,
+ _In_ PWSTR pszDisplayName,
+ _In_ DWORD dwStartType,
+ _In_ PWSTR pszDependencies,
+ _In_ PWSTR pszAccount,
+ _In_ PWSTR pszPassword)
+{
+ wchar_t szPath[MAX_PATH];
+ SC_HANDLE schSCManager = nullptr;
+ SC_HANDLE schService = nullptr;
+
+ if (GetModuleFileName(nullptr, szPath, ARRAYSIZE(szPath)) == 0)
+ {
+ wprintf(L"GetModuleFileName failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Open the local default service control manager database
+ schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT |
+ SC_MANAGER_CREATE_SERVICE);
+ if (schSCManager == nullptr)
+ {
+ wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Install the service into SCM by calling CreateService
+ schService = CreateService(
+ schSCManager, // SCManager database
+ pszServiceName, // Name of service
+ pszDisplayName, // Name to display
+ SERVICE_QUERY_STATUS, // Desired access
+ SERVICE_WIN32_OWN_PROCESS, // Service type
+ dwStartType, // Service start type
+ SERVICE_ERROR_NORMAL, // Error control type
+ szPath, // Service's binary
+ nullptr, // No load ordering group
+ nullptr, // No tag identifier
+ pszDependencies, // Dependencies
+ pszAccount, // Service running account
+ pszPassword // Password of the account
+ );
+
+ if (schService == nullptr)
+ {
+ wprintf(L"CreateService failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ wprintf(L"%s is installed.\n", pszServiceName);
+
+Cleanup:
+ // Centralized cleanup for all allocated resources.
+ if (schSCManager)
+ {
+ CloseServiceHandle(schSCManager);
+ schSCManager = nullptr;
+ }
+ if (schService)
+ {
+ CloseServiceHandle(schService);
+ schService = nullptr;
+ }
+}
+
+
+//
+// FUNCTION: UninstallService
+//
+// PURPOSE: Stop and remove the service from the local service control
+// manager database.
+//
+// PARAMETERS:
+// * pszServiceName - the name of the service to be removed.
+//
+// NOTE: If the function fails to uninstall the service, it prints the
+// error in the standard output stream for users to diagnose the problem.
+//
+void UninstallService(_In_ PWSTR pszServiceName)
+{
+ SC_HANDLE schSCManager = nullptr;
+ SC_HANDLE schService = nullptr;
+ SERVICE_STATUS ssSvcStatus = {};
+
+ // Open the local default service control manager database
+ schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
+ if (schSCManager == nullptr)
+ {
+ wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Open the service with delete, stop, and query status permissions
+ schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP |
+ SERVICE_QUERY_STATUS | DELETE);
+ if (schService == nullptr)
+ {
+ wprintf(L"OpenService failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Try to stop the service
+ if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
+ {
+ wprintf(L"Stopping %s.", pszServiceName);
+ Sleep(1000);
+
+ while (QueryServiceStatus(schService, &ssSvcStatus))
+ {
+ if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
+ {
+ wprintf(L".");
+ Sleep(1000);
+ }
+ else break;
+ }
+
+ if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED)
+ {
+ wprintf(L"\n%s is stopped.\n", pszServiceName);
+ }
+ else
+ {
+ wprintf(L"\n%s failed to stop.\n", pszServiceName);
+ }
+ }
+
+ // Now remove the service by calling DeleteService.
+ if (!DeleteService(schService))
+ {
+ wprintf(L"DeleteService failed w/err 0x%08lx\n", GetLastError());
+ goto Cleanup;
+ }
+
+ wprintf(L"%s is removed.\n", pszServiceName);
+
+Cleanup:
+ // Centralized cleanup for all allocated resources.
+ if (schSCManager)
+ {
+ CloseServiceHandle(schSCManager);
+ schSCManager = nullptr;
+ }
+ if (schService)
+ {
+ CloseServiceHandle(schService);
+ schService = nullptr;
+ }
+} \ No newline at end of file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.h
new file mode 100644
index 00000000..af6507e6
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/ServiceInstaller.h
@@ -0,0 +1,57 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+// The file declares functions that install and uninstall the service.
+
+#pragma once
+
+//
+// FUNCTION: InstallService
+//
+// PURPOSE: Install the current application as a service to the local
+// service control manager database.
+//
+// PARAMETERS:
+// * pszServiceName - the name of the service to be installed
+// * pszDisplayName - the display name of the service
+// * dwStartType - the service start option. This parameter can be one of
+// the following values: SERVICE_AUTO_START, SERVICE_BOOT_START,
+// SERVICE_DEMAND_START, SERVICE_DISABLED, SERVICE_SYSTEM_START.
+// * pszDependencies - a pointer to a double null-terminated array of null-
+// separated names of services or load ordering groups that the system
+// must start before this service.
+// * pszAccount - the name of the account under which the service runs.
+// * pszPassword - the password to the account name.
+//
+// NOTE: If the function fails to install the service, it prints the error
+// in the standard output stream for users to diagnose the problem.
+//
+void InstallService(PWSTR pszServiceName,
+ PWSTR pszDisplayName,
+ DWORD dwStartType,
+ PWSTR pszDependencies,
+ PWSTR pszAccount,
+ PWSTR pszPassword);
+
+
+//
+// FUNCTION: UninstallService
+//
+// PURPOSE: Stop and remove the service from the local service control
+// manager database.
+//
+// PARAMETERS:
+// * pszServiceName - the name of the service to be removed.
+//
+// NOTE: If the function fails to uninstall the service, it prints the
+// error in the standard output stream for users to diagnose the problem.
+//
+void UninstallService(PWSTR pszServiceName);
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.cpp b/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.cpp
new file mode 100644
index 00000000..ce19a949
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// RpcServer.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.h
new file mode 100644
index 00000000..306c4330
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/stdafx.h
@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+#define NOMINMAX // disable min and max macros in windows.h
+
+extern bool ShutdownRequested;
diff --git a/general/WinHEC 2017 Lab/Toaster Driver/Service/targetver.h b/general/WinHEC 2017 Lab/Toaster Driver/Service/targetver.h
new file mode 100644
index 00000000..87c0086d
--- /dev/null
+++ b/general/WinHEC 2017 Lab/Toaster Driver/Service/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>