summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandylsn <[email protected]>2020-03-24 16:38:30 -0700
committerGitHub <[email protected]>2020-03-24 16:38:30 -0700
commit9b58d9a908a45a55452b87d001789d27fbf0e8ee (patch)
tree4455a2868af111fc979ad8f3964dae8e15923e89
parent8fb512ac674df5ba129a69906d450f2a1361136d (diff)
Rewrite the service for the best practice of Win32 Services Interacti… (#472)131800
* Rewrite the service for the best practice of Win32 Services Interacting with Devices * Rewrite the service using pure WIN32 APIs * Support multiple device interfaces * Add WINAPI decoration to notification callbacks to avoid AV issue * A small fix * Implement OSRFX2 samples for AddTrigger syntax and service lifetime control * Add comment on AddTrigger syntax Co-authored-by: Shunni Li <[email protected]> * Update inx file (#2) Co-authored-by: Shunni Li <[email protected]> * Add PnpLockdown in INX * Update osrfx2_DCHU_base.inx Co-authored-by: Shunni Li <[email protected]>
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.inxbin10266 -> 4248 bytes
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.vcxproj2
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_filter/osrfx2_DCHU_filter.vcxproj2
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_testapp/osrusbfx2.vcxproj2
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/CppWindowsService.cpp74
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.cpp856
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.h155
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.cpp192
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.h144
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp1217
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h328
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp254
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h187
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.cpp794
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.h423
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.cpp375
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.h56
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ThreadPool.h80
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.cpp156
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.h111
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.inxbin3190 -> 0 bytes
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.vcxproj30
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/stdafx.h26
23 files changed, 1820 insertions, 3644 deletions
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.inx b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.inx
index 8271e39d..73b6d10e 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.inx
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.inx
Binary files differ
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.vcxproj b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.vcxproj
index 57439bd9..f78f16b4 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.vcxproj
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_base/osrfx2_DCHU_base.vcxproj
@@ -26,7 +26,7 @@
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<SampleGuid>{F915ED95-7BE9-4CDB-B09A-0D3F4C9657FE}</SampleGuid>
<ProjectName>osrfx2_DCHU_base</ProjectName>
- <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_filter/osrfx2_DCHU_filter.vcxproj b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_filter/osrfx2_DCHU_filter.vcxproj
index 36d85583..09724ba5 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_filter/osrfx2_DCHU_filter.vcxproj
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_filter/osrfx2_DCHU_filter.vcxproj
@@ -27,7 +27,7 @@
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<SampleGuid>{1A4A32BA-1596-4F52-BC48-B85A6D8D5D12}</SampleGuid>
- <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<ProjectName>osrfx2_DCHU_filter</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_testapp/osrusbfx2.vcxproj b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_testapp/osrusbfx2.vcxproj
index 225dcde2..bc56feac 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_testapp/osrusbfx2.vcxproj
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_testapp/osrusbfx2.vcxproj
@@ -25,7 +25,7 @@
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<SampleGuid>{F19E45AF-8B05-4204-A66B-9BDBFE333233}</SampleGuid>
<ProjectName>osrfx2_DCHU_testapp</ProjectName>
- <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/CppWindowsService.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/CppWindowsService.cpp
deleted file mode 100644
index 98a3975c..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/CppWindowsService.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- CppWindowsService.cpp
-
-Abstract:
-
- The file defines the entry point of the application. According to the
- arguments in the command line, the function installs or uninstalls or
- starts the service by calling into different routines.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma region Includes
-#include <stdio.h>
-#include <windows.h>
-#include "ServiceBase.h"
-#include "SampleService.h"
-#pragma endregion
-
-//
-// Settings of the service
-//
-
-//
-// Internal name of the service
-//
-#define SERVICE_NAME L"OsrUsbFx2UmUserSvc"
-
-
-/*++
-
-Routine Description:
-
- Entry point for the service.
-
-Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
-Return Value:
-
- VOID
-
---*/
-INT
-wmain(
- INT Argc,
- WCHAR *Argv[]
- )
-{
- CSampleService service(SERVICE_NAME);
-
- if (!CServiceBase::Run(service))
- {
- wprintf(L"Service failed to run w/err 0x%08lx\n", GetLastError());
- }
-
- return 0;
-} \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.cpp
new file mode 100644
index 00000000..318e0dd5
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.cpp
@@ -0,0 +1,856 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ DeviceContext.cpp
+
+Abstract:
+
+ Implements the functions to create/destroy device context by
+ registering/unregistering for device notifications.
+
+Environment:
+
+ User mode
+
+--*/
+
+#include "stdafx.h"
+
+extern HANDLE SvcStopRequestEvent;
+extern HCMNOTIFICATION InterfaceNotificationHandle;
+extern DEVICE_LIST_ENTRY DeviceList;
+extern SRWLOCK DeviceListLock;
+
+//
+// Keep track of running theads for unregistering device notifications
+//
+DWORD RunningUnregistrations = 0;
+SRWLOCK RunningUnregistrationsLock = SRWLOCK_INIT;
+CONDITION_VARIABLE UnregistrationComplete = CONDITION_VARIABLE_INIT;
+
+/*++
+
+Routine Description:
+
+ Setup device interface context by registering for device interface
+ notifications
+
+Arguments:
+
+ NULL
+
+Return Value:
+
+ A Win32 error code.
+
+--*/
+DWORD
+SetupDeviceInterfaceContext(
+ VOID
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+ CONFIGRET Cr = CR_SUCCESS;
+ PCWSTR DeviceInterface = NULL;
+ PWSTR DeviceInterfaceList = NULL;
+ DWORD DeviceInterfaceListSize = 0;
+
+ //
+ // Register for device interface events to open and close the handle to
+ // the interface.
+ //
+ Err = RegisterInterfaceNotifications(&InterfaceNotificationHandle);
+
+ if (Err != ERROR_SUCCESS)
+ {
+ goto cleanup;
+ }
+
+ //
+ // The interface may already be present on the system. Retrieve a list of
+ // existing interfaces
+ //
+ do
+ {
+ Cr = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListSize,
+ (LPGUID)&GUID_DEVINTERFACE_OSRUSBFX2,
+ NULL,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+
+ if (Cr != CR_SUCCESS)
+ {
+ break;
+ }
+
+ if (DeviceInterfaceList != NULL)
+ {
+ free(DeviceInterfaceList);
+ }
+
+ DeviceInterfaceList = (PWSTR)malloc(DeviceInterfaceListSize * sizeof(WCHAR));
+
+ if (DeviceInterfaceList == NULL)
+ {
+ Cr = CR_OUT_OF_MEMORY;
+ break;
+ }
+
+ Cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_OSRUSBFX2,
+ NULL,
+ DeviceInterfaceList,
+ DeviceInterfaceListSize,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+ } while (Cr == CR_BUFFER_SMALL);
+
+ if (Cr != CR_SUCCESS)
+ {
+ Err = CM_MapCrToWin32Err(Cr, ERROR_INVALID_DATA);
+ goto cleanup;
+ }
+
+ //
+ // Register for notifications on existing device interfaces
+ //
+ for (DeviceInterface = DeviceInterfaceList;
+ *DeviceInterface != L'\0';
+ DeviceInterface += wcslen(DeviceInterface) + 1)
+ {
+ RegisterDeviceNotifications(DeviceInterface);
+ }
+
+cleanup:
+
+ if (DeviceInterfaceList != NULL)
+ {
+ free(DeviceInterfaceList);
+ }
+
+ return Err;
+}
+
+
+/*++
+
+Routine Description:
+
+ Clean up device interface context
+
+Arguments:
+
+ NULL
+
+Return Value:
+
+ NULL
+
+--*/
+VOID
+CleanupDeviceInterfaceContext(
+ VOID
+ )
+{
+ PDEVICE_CONTEXT Context = NULL;
+ BOOL NeedsUnregister = FALSE;
+
+ //
+ // Unregister from the interface first, so that re-appearance of the
+ // interface does not cause us to register device events again.
+ //
+ if (InterfaceNotificationHandle != NULL)
+ {
+ CM_Unregister_Notification(InterfaceNotificationHandle);
+ InterfaceNotificationHandle = NULL;
+ }
+
+ //
+ // Unregister notifications for device handles.
+ //
+ while (TRUE)
+ {
+ NeedsUnregister = FALSE;
+
+ AcquireSRWLockShared(&DeviceListLock);
+
+ if (IsDeviceListEmpty(&DeviceList))
+ {
+ ReleaseSRWLockShared(&DeviceListLock);
+ break;
+ }
+
+ //
+ // Get next device context
+ //
+ Context = CONTAINING_DEVICE_RECORD(DeviceList.Flink);
+
+ //
+ // The device context can be unregistered either within notification
+ // callbacks or cleanup routines. Synchronize these operations to only
+ // unregister once.
+ //
+ EnterCriticalSection(&Context->ContextLock);
+
+ if (!Context->Unregistered)
+ {
+ Context->Unregistered = TRUE;
+ NeedsUnregister = TRUE;
+ }
+
+ LeaveCriticalSection(&Context->ContextLock);
+
+ ReleaseSRWLockShared(&DeviceListLock);
+
+ if (NeedsUnregister)
+ {
+ //
+ // Remove next device from device list
+ //
+ AcquireSRWLockExclusive(&DeviceListLock);
+ RemoveDeviceListEntry(DeviceList.Flink);
+ ReleaseSRWLockExclusive(&DeviceListLock);
+
+ UnregisterDeviceNotifications(Context);
+ }
+ }
+
+ //
+ // Wait for all other unregistrations for device handle that is not in
+ // device list.
+ //
+ AcquireSRWLockShared(&RunningUnregistrationsLock);
+
+ while (RunningUnregistrations != 0)
+ {
+ SleepConditionVariableSRW(&UnregistrationComplete,
+ &RunningUnregistrationsLock,
+ INFINITE,
+ CONDITION_VARIABLE_LOCKMODE_SHARED);
+ }
+
+ ReleaseSRWLockShared(&RunningUnregistrationsLock);
+}
+
+
+/*++
+
+Routine Description:
+
+ Handles a device query remove notification.
+
+Arguments:
+
+ Context - The callback context
+
+Return Value:
+
+ NULL
+
+--*/
+VOID
+DeviceQueryRemoveAction(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ if (Context->DeviceHandle != INVALID_HANDLE_VALUE)
+ {
+ //
+ // Close open handles to allow the device to be query removed
+ //
+ CloseHandle(Context->DeviceHandle);
+
+ Context->DeviceHandle = INVALID_HANDLE_VALUE;
+ }
+}
+
+
+/*++
+
+Routine Description:
+
+ Handles a device query remove failed notification.
+
+Arguments:
+
+ Context - The callback context
+
+Return Value:
+
+ NULL
+
+--*/
+VOID
+DeviceQueryRemoveFailedAction(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ PWSTR DeviceInterfacePath = NULL;
+ BOOL NeedsUnregister = FALSE;
+
+ //
+ // Keep a record of device symbolic link since the callback context will
+ // be freed up during unregistration
+ //
+ DeviceInterfacePath = Context->SymbolicLink;
+ Context->SymbolicLink = NULL;
+
+ //
+ // The device context can be unregistered either within notification
+ // callbacks or cleanup routines. Synchronize these operations to only
+ // unregister once.
+ //
+ EnterCriticalSection(&Context->ContextLock);
+
+ if (!Context->Unregistered)
+ {
+ Context->Unregistered = TRUE;
+ NeedsUnregister = TRUE;
+ }
+
+ LeaveCriticalSection(&Context->ContextLock);
+
+ //
+ // Remove device from device list if needed
+ //
+ if (NeedsUnregister)
+ {
+ AcquireSRWLockExclusive(&DeviceListLock);
+ RemoveDeviceListEntry(&Context->ListEntry);
+ ReleaseSRWLockExclusive(&DeviceListLock);
+
+ //
+ // Unregister notifications for the old device handle from a deferred
+ // routine since CM_Unregister_Notification can not be called from a
+ // notification callback
+ //
+ AcquireSRWLockExclusive(&RunningUnregistrationsLock);
+ RunningUnregistrations++;
+ ReleaseSRWLockExclusive(&RunningUnregistrationsLock);
+
+ QueueUserWorkItem(UnregisterDeviceNotificationsWorkerThread,
+ Context,
+ WT_EXECUTEDEFAULT);
+ }
+
+ //
+ // Re-register for device notifications on a new device handle
+ //
+ RegisterDeviceNotifications(DeviceInterfacePath);
+
+ //
+ // Free memory that the callback context used to point at but was not freed
+ // during unregistration
+ //
+ free(DeviceInterfacePath);
+}
+
+/*++
+
+Routine Description:
+
+ Handles a device remove complete notification.
+
+Arguments:
+
+ Context - The callback context
+
+Return Value:
+
+ NULL
+
+--*/
+VOID
+DeviceRemoveCompleteAction(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ BOOL NeedsUnregister = FALSE;
+
+ //
+ // The device context can be unregistered either within notification
+ // callbacks or cleanup routines. Synchronize these operations to only
+ // unregister once.
+ //
+ EnterCriticalSection(&Context->ContextLock);
+
+ if (!Context->Unregistered)
+ {
+ Context->Unregistered = TRUE;
+ NeedsUnregister = TRUE;
+ }
+
+ LeaveCriticalSection(&Context->ContextLock);
+
+ //
+ // Remove device from device list if needed
+ //
+ if (NeedsUnregister)
+ {
+ AcquireSRWLockExclusive(&DeviceListLock);
+ RemoveDeviceListEntry(&Context->ListEntry);
+ ReleaseSRWLockExclusive(&DeviceListLock);
+
+ //
+ // Unregister notifications for the old device handle from a deferred
+ // routine since CM_Unregister_Notification can not be called from a
+ // notification callback
+ //
+ AcquireSRWLockExclusive(&RunningUnregistrationsLock);
+ RunningUnregistrations++;
+ ReleaseSRWLockExclusive(&RunningUnregistrationsLock);
+
+ QueueUserWorkItem(UnregisterDeviceNotificationsWorkerThread,
+ Context,
+ WT_EXECUTEDEFAULT);
+ }
+}
+
+/*++
+
+Routine Description:
+
+ Handles device notifications.
+
+Arguments:
+
+ hNotify - The notification that spurred this callback
+
+ hContext - The callback context
+
+ Action - The type of callback
+
+ EventData - Additional information about this callback
+
+ EventDataSize - The size of EventData
+
+Return Value:
+
+ A Win32 error code.
+
+--*/
+DWORD
+WINAPI
+DeviceCallback(
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PVOID hContext,
+ _In_ CM_NOTIFY_ACTION Action,
+ _In_ PCM_NOTIFY_EVENT_DATA EventData,
+ _In_ DWORD EventDataSize
+ )
+{
+ PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
+
+ UNREFERENCED_PARAMETER(EventData);
+ UNREFERENCED_PARAMETER(EventDataSize);
+
+ //
+ // In case this callback fires before the registration call returns, make
+ // sure the notification handle is properly set
+ //
+ Context->DeviceNotificationHandle = hNotify;
+
+ switch (Action)
+ {
+ case CM_NOTIFY_ACTION_DEVICEQUERYREMOVE:
+ DeviceQueryRemoveAction(Context);
+ break;
+
+ case CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED:
+ DeviceQueryRemoveFailedAction(Context);
+ break;
+
+ case CM_NOTIFY_ACTION_DEVICEREMOVEPENDING:
+ case CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE:
+ DeviceRemoveCompleteAction(Context);
+ break;
+
+ default:
+ break;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+
+ Register for device notifications.
+
+Arguments:
+
+ DeviceInterfacePath - The symbolic link path of the device interface
+
+Return Value:
+
+ A Win32 error code.
+
+--*/
+DWORD
+RegisterDeviceNotifications(
+ _In_ PCWSTR DeviceInterfacePath
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+ CONFIGRET Cr = CR_SUCCESS;
+ PDEVICE_CONTEXT Context = NULL;
+ PDEVICE_LIST_ENTRY Link = NULL;
+ DWORD BufferSize = 0;
+ CM_NOTIFY_FILTER NotifyFilter = {0};
+
+ //
+ // Check whether the device interface has already been registered for device
+ // handle notifications since it can be done either in interface arrival
+ // callback routine or initial device interface setup routine
+ //
+ AcquireSRWLockExclusive(&DeviceListLock);
+
+ for (Link = DeviceList.Flink; Link != &DeviceList; Link = Link->Flink)
+ {
+ Context = CONTAINING_DEVICE_RECORD(Link);
+
+ if (_wcsicmp(DeviceInterfacePath, Context->SymbolicLink) == 0)
+ {
+ break;
+ }
+ }
+
+ if (Link != &DeviceList)
+ {
+ Err = ERROR_SUCCESS;
+ goto cleanup;
+ }
+
+ //
+ // Create a new device context
+ //
+ Context = (PDEVICE_CONTEXT)malloc(sizeof(DEVICE_CONTEXT));
+
+ if (Context == NULL)
+ {
+ Err = ERROR_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ //
+ // Initialize device context
+ //
+ ZeroMemory(Context, sizeof(DEVICE_CONTEXT));
+ Context->DeviceHandle = INVALID_HANDLE_VALUE;
+ InitializeCriticalSection(&Context->ContextLock);
+
+ //
+ // Fill out the context and register device handle notifications
+ //
+ BufferSize = (DWORD)wcslen(DeviceInterfacePath) + 1;
+ Context->SymbolicLink = (PWSTR)malloc(BufferSize * sizeof(WCHAR));
+
+ if ((Context->SymbolicLink == NULL) ||
+ (FAILED(StringCchCopy(Context->SymbolicLink,
+ BufferSize,
+ DeviceInterfacePath))))
+ {
+ Err = ERROR_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ Context->DeviceHandle = CreateFile(Context->SymbolicLink,
+ GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL, // default security
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (Context->DeviceHandle == INVALID_HANDLE_VALUE)
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+ NotifyFilter.cbSize = sizeof(NotifyFilter);
+ NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE;
+ NotifyFilter.u.DeviceHandle.hTarget = Context->DeviceHandle;
+
+ Cr = CM_Register_Notification(&NotifyFilter,
+ (PVOID)Context,
+ (PCM_NOTIFY_CALLBACK)DeviceCallback,
+ &Context->DeviceNotificationHandle);
+
+ if (Cr != CR_SUCCESS)
+ {
+ Err = CM_MapCrToWin32Err(Cr, ERROR_INVALID_DATA);
+ goto cleanup;
+ }
+
+ //
+ // Add the device entry to device list
+ //
+ InsertTailDeviceListEntry(&DeviceList, &Context->ListEntry);
+ Context = NULL;
+
+cleanup:
+
+ ReleaseSRWLockExclusive(&DeviceListLock);
+
+ //
+ // Clean up device context if an error occurred.
+ //
+ if (Context != NULL)
+ {
+ if (Context->SymbolicLink != NULL)
+ {
+ free(Context->SymbolicLink);
+ }
+
+ if (Context->DeviceHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(Context->DeviceHandle);
+ }
+
+ free(Context);
+ }
+
+ return Err;
+}
+
+
+VOID
+UnregisterDeviceNotifications(
+ _Inout_ PDEVICE_CONTEXT Context
+ )
+{
+ if (Context->DeviceNotificationHandle != NULL)
+ {
+ CM_Unregister_Notification(Context->DeviceNotificationHandle);
+ }
+
+ if (Context->DeviceHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(Context->DeviceHandle);
+ }
+
+ if (Context->SymbolicLink != NULL)
+ {
+ free(Context->SymbolicLink);
+ }
+
+ DeleteCriticalSection(&Context->ContextLock);
+
+ free(Context);
+}
+
+
+/*++
+
+Routine Description:
+
+ This worker thread avoids a deadlock when unregistering device notifications.
+ Rather than calling CM_Unregister_Notification from the callback, the
+ callback gives that work to a separate thread to avoid deadlock.
+
+Arguments:
+
+ lpThreadParameter - The thread data passed to the function
+
+Return Value:
+
+ Zero
+
+--*/
+DWORD
+WINAPI
+UnregisterDeviceNotificationsWorkerThread(
+ _In_ PVOID lpThreadParameter
+ )
+{
+ PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)lpThreadParameter;
+
+ UnregisterDeviceNotifications(Context);
+
+ //
+ // Decrease running unregistrations
+ //
+ AcquireSRWLockExclusive(&RunningUnregistrationsLock);
+ RunningUnregistrations--;
+ ReleaseSRWLockExclusive(&RunningUnregistrationsLock);
+
+ WakeAllConditionVariable(&UnregistrationComplete);
+
+ return 0;
+}
+
+
+/*++
+
+Routine Description:
+
+ Handles an interface arrival notification.
+
+Arguments:
+
+ hNotify - The notification that fired the callback
+
+ hContext - The callback context
+
+ Action - The type of notification
+
+ EventData - Additional information about the callback
+
+ EventDataSize - The size of EventData
+
+Return Value:
+
+ Notification callback should return ERROR_SUCCESS.
+
+--*/
+DWORD
+WINAPI
+InterfaceCallback(
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PVOID hContext,
+ _In_ CM_NOTIFY_ACTION Action,
+ _In_ PCM_NOTIFY_EVENT_DATA EventData,
+ _In_ DWORD EventDataSize
+ )
+{
+ PDEVICE_CONTEXT Context = NULL;
+ PDEVICE_LIST_ENTRY Link = NULL;
+ BOOL NeedsUnregister = FALSE;
+
+ UNREFERENCED_PARAMETER(hNotify);
+ UNREFERENCED_PARAMETER(hContext);
+ UNREFERENCED_PARAMETER(EventDataSize);
+
+ switch (Action)
+ {
+ case CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL:
+ //
+ // Register for device notifications
+ //
+ RegisterDeviceNotifications(EventData->u.DeviceInterface.SymbolicLink);
+ break;
+
+ case CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL:
+ //
+ // The device may still be running in the case where the driver disables
+ // its interfaces. Find whether it is still on the device list and clean
+ // it up.
+ //
+ AcquireSRWLockShared(&DeviceListLock);
+
+ for (Link = DeviceList.Flink; Link != &DeviceList; Link = Link->Flink)
+ {
+ Context = CONTAINING_DEVICE_RECORD(Link);
+
+ if (_wcsicmp(EventData->u.DeviceInterface.SymbolicLink,
+ Context->SymbolicLink) == 0)
+ {
+ //
+ // The device context can be unregistered either within
+ // notification callbacks or cleanup routines. Synchronize these
+ // operations to only unregister once.
+ //
+ EnterCriticalSection(&Context->ContextLock);
+
+ if (!Context->Unregistered)
+ {
+ Context->Unregistered = TRUE;
+ NeedsUnregister = TRUE;
+ }
+
+ LeaveCriticalSection(&Context->ContextLock);
+
+ break;
+ }
+ }
+
+ ReleaseSRWLockShared(&DeviceListLock);
+
+ if (NeedsUnregister)
+ {
+ //
+ // Remove the device from device list
+ //
+ AcquireSRWLockExclusive(&DeviceListLock);
+ RemoveDeviceListEntry(&Context->ListEntry);
+ ReleaseSRWLockExclusive(&DeviceListLock);
+
+ UnregisterDeviceNotifications(Context);
+ }
+
+ //
+ // Notify service to stop if this is the last device interface
+ //
+ AcquireSRWLockShared(&DeviceListLock);
+
+ if (IsDeviceListEmpty(&DeviceList))
+ {
+ SetEvent(SvcStopRequestEvent);
+ }
+
+ ReleaseSRWLockShared(&DeviceListLock);
+ break;
+
+ default:
+ break;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+
+ Registers the service for interface notifications
+
+Arguments:
+
+ pInterfaceNotificationHandle - Pointer to receive the HCMNOTIFICATION handle
+
+Return Value:
+
+ A Win32 error code.
+
+--*/
+DWORD
+RegisterInterfaceNotifications(
+ _Out_ PHCMNOTIFICATION pInterfaceNotificationHandle
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+ CONFIGRET Cr = CR_SUCCESS;
+ CM_NOTIFY_FILTER NotifyFilter = {0};
+
+ NotifyFilter.cbSize = sizeof(NotifyFilter);
+ NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
+ NotifyFilter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_OSRUSBFX2;
+
+ //
+ // Register for device interface events to open and close the handle to
+ // the interface.
+ //
+ Cr = CM_Register_Notification(&NotifyFilter,
+ NULL,
+ (PCM_NOTIFY_CALLBACK)InterfaceCallback,
+ pInterfaceNotificationHandle);
+
+ if (Cr != CR_SUCCESS)
+ {
+ Err = CM_MapCrToWin32Err(Cr, ERROR_INVALID_DATA);
+ goto cleanup;
+ }
+
+cleanup:
+
+ return Err;
+}
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.h
new file mode 100644
index 00000000..4d744989
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceContext.h
@@ -0,0 +1,155 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+--*/
+
+#pragma once
+
+//
+// Device list
+//
+typedef struct _DEVICE_LIST_ENTRY {
+ struct _DEVICE_LIST_ENTRY *Flink;
+ struct _DEVICE_LIST_ENTRY *Blink;
+} DEVICE_LIST_ENTRY, *PDEVICE_LIST_ENTRY;
+
+FORCEINLINE
+VOID
+InitializeDeviceListHead(
+ _Out_ PDEVICE_LIST_ENTRY Head
+ )
+{
+ Head->Blink = Head->Flink = Head;
+}
+
+FORCEINLINE
+BOOL
+IsDeviceListEmpty(
+ _In_ const PDEVICE_LIST_ENTRY ListHead
+ )
+
+{
+ return (ListHead->Flink == ListHead);
+}
+
+FORCEINLINE
+VOID
+RemoveDeviceListEntry(
+ _In_ PDEVICE_LIST_ENTRY Entry
+ )
+{
+ PDEVICE_LIST_ENTRY Prev = Entry->Blink;
+ PDEVICE_LIST_ENTRY Next = Entry->Flink;
+
+ Prev->Flink = Next;
+ Next->Blink = Prev;
+}
+
+FORCEINLINE
+VOID
+InsertTailDeviceListEntry(
+ _Inout_ PDEVICE_LIST_ENTRY Head,
+ _Inout_ PDEVICE_LIST_ENTRY Entry
+ )
+{
+ PDEVICE_LIST_ENTRY Tail = Head->Blink;
+
+ Tail->Flink = Entry;
+ Entry->Blink = Tail;
+ Entry->Flink = Head;
+ Head->Blink = Entry;
+}
+
+//
+// Context for device handle
+//
+typedef struct _DEVICE_CONTEXT {
+ PWSTR SymbolicLink;
+ HANDLE DeviceHandle;
+ HCMNOTIFICATION DeviceNotificationHandle;
+ BOOL Unregistered;
+ CRITICAL_SECTION ContextLock;
+ DEVICE_LIST_ENTRY ListEntry;
+} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
+
+#define CONTAINING_DEVICE_RECORD(address) ((PDEVICE_CONTEXT)( \
+ (PCHAR)(address) - \
+ (ULONG_PTR)(&((PDEVICE_CONTEXT)0)->ListEntry)))
+
+//
+// Device interface context
+//
+DWORD
+SetupDeviceInterfaceContext(
+ VOID
+ );
+
+VOID
+CleanupDeviceInterfaceContext(
+ VOID
+ );
+
+//
+// Device notifications related
+//
+VOID
+DeviceQueryRemoveAction(
+ _In_ PDEVICE_CONTEXT Context
+ );
+
+VOID
+DeviceQueryRemoveFailedAction(
+ _In_ PDEVICE_CONTEXT Context
+ );
+
+VOID
+DeviceRemoveCompleteAction(
+ _In_ PDEVICE_CONTEXT Context
+ );
+
+DWORD
+WINAPI
+DeviceCallback(
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PVOID hContext,
+ _In_ CM_NOTIFY_ACTION Action,
+ _In_ PCM_NOTIFY_EVENT_DATA EventData,
+ _In_ DWORD EventDataSize
+ );
+
+DWORD
+RegisterDeviceNotifications(
+ _In_ PCWSTR DeviceInterfacePath
+ );
+
+VOID
+UnregisterDeviceNotifications(
+ _Inout_ PDEVICE_CONTEXT Context
+ );
+
+DWORD
+WINAPI
+InterfaceCallback(
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PVOID hContext,
+ _In_ CM_NOTIFY_ACTION Action,
+ _In_ PCM_NOTIFY_EVENT_DATA EventData,
+ _In_ DWORD EventDataSize
+ );
+
+DWORD
+RegisterInterfaceNotifications(
+ _Out_ PHCMNOTIFICATION pInterfaceNotificationHandle
+ );
+
+DWORD
+WINAPI
+UnregisterDeviceNotificationsWorkerThread(
+ _In_ PVOID lpThreadParameter
+ );
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.cpp
new file mode 100644
index 00000000..ced895cc
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.cpp
@@ -0,0 +1,192 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ DeviceControl.cpp
+
+Abstract:
+
+ Implements the functions to control the OSR USB FX2 device.
+
+Environment:
+
+ User mode
+
+--*/
+
+#include "stdafx.h"
+
+//
+// Keep track of where the OSRFX2 device's bar graph currently is.
+//
+INT CurrentBar;
+BAR_GRAPH_STATE BarGraphState;
+
+/*++
+
+Routine Description:
+
+ Initialize global variables for OSRFX2 device.
+
+Arguments:
+
+ VOID
+
+Return Value:
+
+ VOID
+
+--*/
+VOID
+OsrFx2InitializeDevice(
+ VOID
+ )
+{
+ CurrentBar = 0;
+}
+
+
+/*++
+
+Routine Description:
+
+ Turns off all of the bar graph lights on the OSR USB FX2 device.
+
+Arguments:
+
+ Context - The callback context
+
+Return Value:
+
+ VOID
+
+--*/
+DWORD
+OsrFx2ClearAllBars(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+ ULONG BytesReturned;
+
+ BarGraphState.BarsAsUChar = 0;
+
+ if (!DeviceIoControl(Context->DeviceHandle,
+ IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY,
+ &BarGraphState, // Pointer to InBuffer
+ sizeof(BAR_GRAPH_STATE), // Length of InBuffer
+ NULL, // Pointer to OutBuffer
+ 0, // Length of OutBuffer
+ &BytesReturned, // BytesReturned
+ 0)) // Pointer to Overlapped structure
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+cleanup:
+
+ return Err;
+}
+
+
+/*++
+
+Routine Description:
+
+ Lights the next bar on the OSR USB FX2 device.
+
+Arguments:
+
+ Context - The callback context
+
+Return Value:
+
+ VOID
+
+--*/
+DWORD
+OsrFx2LightNextBar(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+ ULONG BytesReturned;
+
+ //
+ // Normalize to 0-7
+ //
+ CurrentBar += 1;
+
+ if (CurrentBar > 7)
+ {
+ CurrentBar = 0;
+ }
+
+ BarGraphState.BarsAsUChar = 1 << (UCHAR)CurrentBar;
+
+ if (!DeviceIoControl(Context->DeviceHandle,
+ IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY,
+ &BarGraphState, // Pointer to InBuffer
+ sizeof(BAR_GRAPH_STATE), // Length of InBuffer
+ NULL, // Pointer to OutBuffer
+ 0, // Length of OutBuffer
+ &BytesReturned, // BytesReturned
+ 0)) // Pointer to Overlapped structure
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+cleanup:
+
+ return Err;
+}
+
+/*++
+
+Routine Description:
+
+ Lights the next bar on the OSRFX2 device.
+
+Arguments:
+
+ Context - The device context
+
+Return Value:
+
+ A Win32 error code.
+
+--*/
+DWORD
+OsrFx2ControlDevice(
+ _In_ PDEVICE_CONTEXT Context
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+
+ Err = OsrFx2ClearAllBars(Context);
+
+ if (Err != ERROR_SUCCESS)
+ {
+ goto cleanup;
+ }
+
+ Err = OsrFx2LightNextBar(Context);
+
+ if (Err != ERROR_SUCCESS)
+ {
+ goto cleanup;
+ }
+
+cleanup:
+
+ return Err;
+}
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.h
new file mode 100644
index 00000000..235e64ba
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/DeviceControl.h
@@ -0,0 +1,144 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+--*/
+
+#pragma once
+#pragma warning(disable : 4201) // disable nameless struct/union warning
+
+//
+// {573E8C73-0CB4-4471-A1BF-FAB26C31D384}
+//
+DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2,
+ 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);
+
+//
+// Define the structures that will be used by the IOCTL interface to the driver
+//
+
+// BAR_GRAPH_STATE is a bit field structure with each bit corresponding to one
+// of the bar graph on the OSRFX2 Development Board
+//
+typedef struct _BAR_GRAPH_STATE {
+
+ union {
+
+ struct {
+ //
+ // Individual bars starting from the top of the stack of bars
+ //
+ // NOTE: There are actually 10 bars, but the very top two do not
+ // light and are not counted here
+ //
+ UCHAR Bar1 : 1;
+ UCHAR Bar2 : 1;
+ UCHAR Bar3 : 1;
+ UCHAR Bar4 : 1;
+ UCHAR Bar5 : 1;
+ UCHAR Bar6 : 1;
+ UCHAR Bar7 : 1;
+ UCHAR Bar8 : 1;
+ };
+
+ //
+ // The state of all the bar graph as a single
+ // UCHAR
+ //
+ UCHAR BarsAsUChar;
+ };
+
+} BAR_GRAPH_STATE, *PBAR_GRAPH_STATE;
+
+//
+// SWITCH_STATE is a bit field structure with each bit corresponding to one of
+// the switches on the OSRFX2 Development Board
+//
+typedef struct _SWITCH_STATE {
+
+ union {
+ struct {
+ //
+ // Individual switches starting from the left of the set of switches
+ //
+ UCHAR Switch1 : 1;
+ UCHAR Switch2 : 1;
+ UCHAR Switch3 : 1;
+ UCHAR Switch4 : 1;
+ UCHAR Switch5 : 1;
+ UCHAR Switch6 : 1;
+ UCHAR Switch7 : 1;
+ UCHAR Switch8 : 1;
+ };
+
+ //
+ // The state of all the switches as a single
+ // UCHAR
+ //
+ UCHAR SwitchesAsUChar;
+ };
+
+} SWITCH_STATE, *PSWITCH_STATE;
+
+DWORD
+OsrFx2ControlDevice(
+ _In_ PDEVICE_CONTEXT Context
+ );
+
+VOID
+OsrFx2InitializeDevice(
+ VOID
+ );
+
+#define IOCTL_INDEX 0x800
+#define FILE_DEVICE_OSRUSBFX2 65500U
+
+#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX, \
+ METHOD_BUFFERED, \
+ FILE_READ_ACCESS)
+
+#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 1, \
+ METHOD_BUFFERED, \
+ FILE_WRITE_ACCESS)
+
+#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 3, \
+ METHOD_BUFFERED, \
+ FILE_WRITE_ACCESS)
+
+#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 4, \
+ METHOD_BUFFERED, \
+ FILE_READ_ACCESS)
+
+#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 5, \
+ METHOD_BUFFERED, \
+ FILE_WRITE_ACCESS)
+
+#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 6, \
+ METHOD_BUFFERED, \
+ FILE_READ_ACCESS)
+
+#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 7, \
+ METHOD_BUFFERED, \
+ FILE_READ_ACCESS)
+
+#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
+ IOCTL_INDEX + 8, \
+ METHOD_BUFFERED, \
+ FILE_WRITE_ACCESS)
+
+#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\
+ IOCTL_INDEX + 9, \
+ METHOD_OUT_DIRECT, \
+ FILE_READ_ACCESS)
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp
deleted file mode 100644
index a02ac24a..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- Main.cpp
-
-Abstract:
-
- Implements the functions to control the OSR USB FX2 device.
-
-Environment:
-
- User mode
-
---*/
-
-#include "Main.h"
-#include "Utils.h"
-
-//
-// Keep track of where the OSRFX2 device's bar graph currently is.
-//
-INT CurrentBar;
-BAR_GRAPH_STATE BarGraphState;
-
-/*++
-
-Routine Description:
-
- Sets the variables in this service to their default values.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-SetVariables()
-{
- CurrentBar = 0;
-}
-
-
-/*++
-
-Routine Description:
-
- Retrieves the device path of a given interface.
-
-Arguments:
-
- InterfaceGuid - The GUID of the interface to search for
-
- DevicePath - The resulting device path
-
- DevicePathLength - The length of DevicePath
-
-Return Value:
-
- TRUE if the function succeeded and FALSE otherwise. Errors
- are logged in the Application event log.
-
---*/
-_Success_(return)
-BOOL
-GetDevicePath(
- _In_ LPGUID InterfaceGuid,
- _Out_writes_z_(DevicePathLength) PWCHAR DevicePath,
- _In_ size_t DevicePathLength
- )
-{
- HRESULT hr = E_FAIL;
- CONFIGRET cr = CR_SUCCESS;
- PWSTR DeviceInterfaceList = NULL;
- ULONG DeviceInterfaceListLength = 0;
- PWSTR NextInterface;
-
- //
- // Determine if there are any interfaces that match the OSRFX2 device.
- //
- cr = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListLength,
- InterfaceGuid,
- NULL,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
-
- if (cr != CR_SUCCESS)
- {
- WriteToErrorLog(L"CM_Get_DeviceInterface_List_Size",
- CM_MapCrToWin32Err(cr, ERROR_FILE_NOT_FOUND));
- goto cleanup;
- }
-
- if (DeviceInterfaceListLength < 1)
- {
- WriteToErrorLog(L"CM_Get_DeviceInterface_List_Size",
- CM_MapCrToWin32Err(cr, ERROR_EMPTY));
- goto cleanup;
- }
-
- DeviceInterfaceList = (PWSTR)malloc(DeviceInterfaceListLength * sizeof(WCHAR));
-
- if (DeviceInterfaceList == NULL)
- {
- WriteToEventLog(L"Failed to allocate memory for the device interface list",
- TRACE_LEVEL_ERROR);
- goto cleanup;
- }
-
- cr = CM_Get_Device_Interface_List(InterfaceGuid,
- NULL,
- DeviceInterfaceList,
- DeviceInterfaceListLength,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
-
- if (cr != CR_SUCCESS)
- {
- WriteToErrorLog(L"CM_Get_Device_Interface_List",
- CM_MapCrToWin32Err(cr, ERROR_FILE_NOT_FOUND));
- goto cleanup;
- }
-
- if (*DeviceInterfaceList == UNICODE_NULL)
- {
- WriteToEventLog(L"CM_Get_Device_Interface_List returned an empty list",
- TRACE_LEVEL_ERROR);
- }
-
- //
- // This sample only expects one interface for the OSRFX2 device. For other
- // devices, though, it maybe necessary to sift through the interfaces
- // from CM_Get_Device_Interface_List in order to find the correct device.
- //
- NextInterface = DeviceInterfaceList + wcslen(DeviceInterfaceList) + 1;
-
- if (*NextInterface != UNICODE_NULL)
- {
- WriteToEventLog(L"More than one device interface instance found. "
- "Selecting first matching device.",
- TRACE_LEVEL_WARNING);
- }
-
- hr = StringCchCopy(DevicePath, DevicePathLength, DeviceInterfaceList);
-
- if (FAILED(hr))
- {
- WriteToErrorLog(L"StringCchCopy", HRESULT_CODE(hr));
- goto cleanup;
- }
-
-cleanup:
-
- if (DeviceInterfaceList != NULL)
- {
- free(DeviceInterfaceList);
- }
-
- return (cr == CR_SUCCESS);
-}
-
-
-/*++
-
-Routine Description:
-
- Opens up the OSR USB FX2 device handle.
-
-Arguments:
-
- Synchronous - Whether or not this device should be opened for syncrhonous
- access
-
-Return Value:
-
- The handle to the OSR USB FX2 device.
-
---*/
-_Check_return_
-_Ret_notnull_
-_Success_(return != INVALID_HANDLE_VALUE)
-HANDLE
-OpenDevice(
- _In_ BOOL Synchronous
- )
-{
- HANDLE DeviceHandle = INVALID_HANDLE_VALUE;
- WCHAR DeviceName[MAX_DEVPATH_LENGTH];
-
- if (!GetDevicePath((LPGUID)&GUID_DEVINTERFACE_OSRUSBFX2,
- DeviceName,
- sizeof(DeviceName) / sizeof(DeviceName[0])))
- {
- goto cleanup;
- }
-
- //
- // Open a handle to the interface.
- //
- if (Synchronous)
- {
- DeviceHandle = CreateFile(DeviceName,
- GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_WRITE | FILE_SHARE_READ,
- NULL, // default security
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- }
- else
- {
- DeviceHandle = CreateFile(DeviceName,
- GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_WRITE | FILE_SHARE_READ,
- NULL, // default security
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
- NULL);
- }
-
- if (DeviceHandle == INVALID_HANDLE_VALUE)
- {
- WriteToErrorLog(L"CreateFile", GetLastError());
- }
- else
- {
- WriteToEventLog(L"Opened Device Successfully", TRACE_LEVEL_INFORMATION);
- }
-
-cleanup:
-
- return DeviceHandle;
-}
-
-
-/*++
-
-Routine Description:
-
- Handles an interface arrival notification.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-InterfaceArrivalAction(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- //
- // Now that the interface has arrived, open a handle to it, and then
- // register that handle for device events.
- //
- EnterCriticalSection(&Context->Lock);
-
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- //
- // The handle was already retrieved.
- //
- Err = ERROR_SUCCESS;
- goto cleanup;
- }
-
- Context->DeviceInterfaceHandle = OpenDevice(FALSE);
-
- if (Context->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
- {
- Err = GetLastError();
- WriteToErrorLog(L"Could not open device interface", Err);
- goto cleanup;
- }
-
- Err = RegisterDeviceNotifications(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not register device notifications", Err);
- goto cleanup;
- }
-
-cleanup:
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Handles an interface arrival notification.
-
-Arguments:
-
- hNotify - The notification that fired the callback
-
- hContext - The callback context
-
- Action - The type of notification
-
- EventData - Additional information about the callback
-
- EventDataSize - The size of EventData
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-InterfaceCallback(
- _In_ HCMNOTIFICATION hNotify,
- _In_ PVOID hContext,
- _In_ CM_NOTIFY_ACTION Action,
- _In_ PCM_NOTIFY_EVENT_DATA EventData,
- _In_ DWORD EventDataSize
- )
-{
- DWORD Err = ERROR_SUCCESS;
- PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
-
- //
- // Validate Context.
- //
- if (Context == NULL)
- {
- goto cleanup;
- }
-
- if (Action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL)
- {
- Err = InterfaceArrivalAction(Context);
- }
-
-cleanup:
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Registers the service for notifications using the notification handle in
- Context.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-RegisterInterfaceNotifications(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- CONFIGRET cr;
- CM_NOTIFY_FILTER NotifyFilter = {0};
-
- if (Context == NULL)
- {
- goto cleanup;
- }
-
- ZeroMemory(&NotifyFilter, sizeof(NotifyFilter));
- NotifyFilter.cbSize = sizeof(NotifyFilter);
- NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
- NotifyFilter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_OSRUSBFX2;
-
- cr = CM_Register_Notification(&NotifyFilter,
- (PVOID)Context,
- (PCM_NOTIFY_CALLBACK)InterfaceCallback,
- &Context->InterfaceNotificationHandle);
-
- if (cr != CR_SUCCESS)
- {
- Err = CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA);
- WriteToErrorLog(L"CM_Register_Notification", Err);
- goto cleanup;
- }
-
-cleanup:
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Unregister for interface notifications. Note, this routine deadlocks
- when called from an interface callback.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-UnregisterInterfaceNotifications(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- CONFIGRET cr;
-
- if (Context->InterfaceNotificationHandle != NULL)
- {
- cr = CM_Unregister_Notification(Context->InterfaceNotificationHandle);
-
- Context->InterfaceNotificationHandle = NULL;
- }
-
- return CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA);
-}
-
-
-/*++
-
-Routine Description:
-
- Callback for when a device is being query removed.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-DeviceQueryRemoveAction(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- EnterCriticalSection(&Context->Lock);
-
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- //
- // Close open handles to allow the device to exit
- //
- CloseHandle(Context->DeviceInterfaceHandle);
-
- Context->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- This callback avoids a deadlock when unregistering device notifications.
- Rather than calling CM_Unregister_Notification from the callback, the
- callback gives that work to a separate thread to avoid deadlock.
-
-Arguments:
-
- Instance - The thread's callback instance
-
- hContext - The callback context
-
- pWork - The thread handle
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CALLBACK
-UnregisterWorkerThreadCallback(
- _Inout_ PTP_CALLBACK_INSTANCE Instance,
- _Inout_opt_ PVOID hContext,
- _Inout_ PTP_WORK pWork
- )
-{
- PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
-
- EnterCriticalSection(&Context->Lock);
-
- UnregisterDeviceNotifications(Context);
-
- //
- // Close the device handle.
- //
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- CloseHandle(Context->DeviceInterfaceHandle);
-
- Context->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
- }
-
- LeaveCriticalSection(&Context->Lock);
-}
-
-
-/*++
-
-Routine Description:
-
- Handles a device query remove failed notification.
-
-Arguments:
-
- hNotify - The notification that spurred this callback
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-DeviceQueryRemoveFailedAction(
- _In_ HCMNOTIFICATION hNotify,
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- EnterCriticalSection(&Context->Lock);
-
- //
- // In case this callback fires before the registration call returns, make
- // sure the notification handle is properly set.
- //
- Context->InterfaceNotificationHandle = hNotify;
-
- //
- // Unregister the device callback, and then close the handle
- //
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- //
- // Wait for the callback and then re-register the device
- //
- WaitForThreadpoolWorkCallbacks(Context->Work, FALSE);
-
- EnterCriticalSection(&Context->Lock);
-
- if (Context->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
- {
- Context->DeviceInterfaceHandle = OpenDevice(FALSE);
- }
-
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- RegisterDeviceNotifications(Context);
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Handles a device remove pending notification.
-
-Arguments:
-
- hNotify - The notification that spurred this callback
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-DeviceRemovePendingAction(
- _In_ HCMNOTIFICATION hNotify,
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- EnterCriticalSection(&Context->Lock);
-
- //
- // In case this callback fires before the registration call returns, make
- // sure the notification handle is properly set.
- //
- Context->InterfaceNotificationHandle = hNotify;
-
- //
- // Unregister the device callback, and then close the handle
- //
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Handles a device remove complete notification.
-
-Arguments:
-
- hNotify - The notification that spurred this callback
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-DeviceRemoveCompleteAction(
- _In_ HCMNOTIFICATION hNotify,
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- EnterCriticalSection(&Context->Lock);
-
- //
- // In case this callback fires before the registration call returns, make
- // sure the notification handle is properly set.
- //
- Context->InterfaceNotificationHandle = hNotify;
-
- //
- // Unregister the device callback, and then close the handle
- //
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Handles device notifications.
-
-Arguments:
-
- hNotify - The notification that spurred this callback
-
- hContext - The callback context
-
- Action - The type of callback
-
- EventData - Additional information about this callback
-
- EventDataSize - The size of EventData
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-DeviceCallback(
- _In_ HCMNOTIFICATION hNotify,
- _In_ PVOID hContext,
- _In_ CM_NOTIFY_ACTION Action,
- _In_ PCM_NOTIFY_EVENT_DATA EventData,
- _In_ DWORD EventDataSize
- )
-{
- DWORD Err = ERROR_SUCCESS;
- PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
-
- //
- // Validate Context.
- //
- if (Context == NULL)
- {
- goto cleanup;
- }
-
- switch (Action)
- {
- case CM_NOTIFY_ACTION_DEVICEQUERYREMOVE:
- DeviceQueryRemoveAction(Context);
- break;
-
- case CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED:
- DeviceQueryRemoveFailedAction(hNotify, Context);
- break;
-
- case CM_NOTIFY_ACTION_DEVICEREMOVEPENDING:
- DeviceRemovePendingAction(hNotify, Context);
- break;
-
- case CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE:
- DeviceRemoveCompleteAction(hNotify, Context);
- break;
- }
-
-cleanup:
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Register for device notifications.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-RegisterDeviceNotifications(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- CONFIGRET cr;
- CM_NOTIFY_FILTER NotifyFilter = {0};
-
- NotifyFilter.cbSize = sizeof(NotifyFilter);
- NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE;
- NotifyFilter.u.DeviceHandle.hTarget = Context->DeviceInterfaceHandle;
-
- cr = CM_Register_Notification(&NotifyFilter,
- (PVOID)Context,
- (PCM_NOTIFY_CALLBACK)DeviceCallback,
- &Context->DeviceNotificationHandle);
-
- if (cr != CR_SUCCESS)
- {
- Err = CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA);
- WriteToEventLog(L"Could not register for notifications", TRACE_LEVEL_WARNING);
- goto cleanup;
- }
-
- Context->Unregister = FALSE;
-
-cleanup:
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Unregister for device notifications.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-UnregisterDeviceNotifications(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- CONFIGRET cr;
-
- if (Context->DeviceNotificationHandle != NULL)
- {
- cr = CM_Unregister_Notification(Context->DeviceNotificationHandle);
-
- if (cr != CR_SUCCESS)
- {
- Err = CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA);
- WriteToEventLog(L"Could not unregister notifications", TRACE_LEVEL_WARNING);
- }
-
- Context->DeviceNotificationHandle = NULL;
- }
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Initialize the given PDEVICE_CONTEXT.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-InitializeContext(
- _Out_ PDEVICE_CONTEXT *Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- BOOL LockInitialized = FALSE;
- BOOL LockEntered = FALSE;
- BOOL InterfaceNotificationsInitialized = FALSE;
- BOOL DeviceNotificationsInitialized = FALSE;
- PDEVICE_CONTEXT DeviceContext;
-
- DeviceContext = (PDEVICE_CONTEXT)malloc(sizeof(DEVICE_CONTEXT));
-
- if (DeviceContext == NULL)
- {
- Err = ERROR_OUTOFMEMORY;
- goto cleanup;
- }
-
- DeviceContext->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
- DeviceContext->LockEnabled = FALSE;
- DeviceContext->InterfaceNotificationsEnabled = FALSE;
- DeviceContext->DeviceNotificationsEnabled = FALSE;
-
- InitializeCriticalSection(&DeviceContext->Lock);
- DeviceContext->LockEnabled = TRUE;
-
- DeviceContext->Work = CreateThreadpoolWork(UnregisterWorkerThreadCallback, (PVOID)DeviceContext, NULL);
-
- if (DeviceContext->Work == NULL)
- {
- Err = GetLastError();
- WriteToErrorLog(L"Could not create worker thread callback", Err);
- goto cleanup;
- }
-
- DeviceContext->DeviceNotificationHandle = NULL;
- DeviceContext->InterfaceNotificationHandle = NULL;
-
- //
- // Register for device interface events to open and close the handle to
- // the interface.
- //
- Err = RegisterInterfaceNotifications(DeviceContext);
-
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not register notifications", Err);
- goto cleanup;
- }
-
- DeviceContext->InterfaceNotificationsEnabled = TRUE;
-
- EnterCriticalSection(&DeviceContext->Lock);
- LockEntered = TRUE;
-
- //
- // The interface may already have arrived while registering for
- // notifications. The lock could be moved earlier, but for sample
- // purposes this is the proper way to initialize notifications.
- //
- if (DeviceContext->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
- {
- DeviceContext->DeviceInterfaceHandle = OpenDevice(FALSE);
- }
-
- if (DeviceContext->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- Err = RegisterDeviceNotifications(DeviceContext);
-
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not register device notifications", Err);
- goto cleanup;
- }
-
- DeviceContext->DeviceNotificationsEnabled = TRUE;
- }
-
- //
- // If OpenDevice ends up returning INVALID_HANDLE_VALUE, that's fine
- // since a notification for the interface will arrive later.
- //
-
-cleanup:
-
- if (LockEntered)
- {
- LeaveCriticalSection(&DeviceContext->Lock);
- }
-
- *Context = DeviceContext;
- DeviceContext = NULL;
-
- if (DeviceContext != NULL)
- {
- CloseContext(DeviceContext);
- }
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Clean up the given PDEVICE_CONTEXT.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-CloseContext(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- BOOL Unregister = FALSE;
-
- if (Context == NULL)
- {
- //
- // Nothing to remove.
- //
- goto cleanup;
- }
-
- EnterCriticalSection(&Context->Lock);
-
- if (!Context->Unregister)
- {
- //
- // Unregister from the callback here.
- //
- Unregister = TRUE;
- Context->Unregister = TRUE;
- }
-
- LeaveCriticalSection(&Context->Lock);
-
- //
- // Unregister from the interface first, so that re-appearance of the interface
- // doesn't cause us to register device events again.
- //
- if (Context->InterfaceNotificationsEnabled)
- {
- Err = UnregisterInterfaceNotifications(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not unregister interface notifications", Err);
- }
- }
-
- if (Unregister)
- {
- if (Context->DeviceNotificationsEnabled)
- {
- Err = UnregisterDeviceNotifications(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not unregister device notifications", Err);
- }
- }
- }
- else
- {
- WaitForThreadpoolWorkCallbacks(Context->Work, FALSE);
- }
-
- //
- // No need to lock here, UnregisterDeviceNotifications will wait for all
- // outstanding callbacks before returning.
- //
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- CloseHandle(Context->DeviceInterfaceHandle);
-
- Context->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
- }
-
- if (Context->Work != NULL)
- {
- CloseThreadpoolWork(Context->Work);
- }
-
- DeleteCriticalSection(&Context->Lock);
-
- free(Context);
-
-cleanup:
-
- return Err;
-}
-
-/*++
-
-Routine Description:
-
- Turns off all of the bar graph lights on the OSR USB FX2 device.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- VOID
-
---*/
-DWORD
-ClearAllBars(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- ULONG BytesReturned;
-
- BarGraphState.BarsAsUChar = 0;
-
- if (!DeviceIoControl(Context->DeviceInterfaceHandle,
- IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY,
- &BarGraphState, // Pointer to InBuffer
- sizeof(BAR_GRAPH_STATE), // Length of InBuffer
- NULL, // Pointer to OutBuffer
- 0, // Length of OutBuffer
- &BytesReturned, // BytesReturned
- 0)) // Pointer to Overlapped structure
- {
- Err = GetLastError();
- WriteToErrorLog(L"DeviceIOControl", Err);
- goto cleanup;
- }
-
-cleanup:
-
- return Err;
-}
-
-
-/*++
-
-Routine Description:
-
- Lights the next bar on the OSR USB FX2 device.
-
-Arguments:
-
- Context - The callback context
-
-Return Value:
-
- VOID
-
---*/
-DWORD
-LightNextBar(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
- ULONG BytesReturned;
-
- //
- // Normalize to 0-7
- //
- CurrentBar += 1;
-
- if (CurrentBar > 7)
- {
- CurrentBar = 0;
- }
-
- BarGraphState.BarsAsUChar = 1 << (UCHAR)CurrentBar;
-
- if (!DeviceIoControl(Context->DeviceInterfaceHandle,
- IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY,
- &BarGraphState, // Pointer to InBuffer
- sizeof(BAR_GRAPH_STATE), // Length of InBuffer
- NULL, // Pointer to OutBuffer
- 0, // Length of OutBuffer
- &BytesReturned, // BytesReturned
- 0)) // Pointer to Overlapped structure
- {
- Err = GetLastError();
- WriteToErrorLog(L"DeviceIOControl", Err);
- goto cleanup;
- }
-
-cleanup:
-
- return Err;
-}
-
-/*++
-
-Routine Description:
-
- Lights the next bar on the OSRFX2 device.
-
-Arguments:
-
- Context - The device context
-
-Return Value:
-
- A Win32 error code.
-
---*/
-DWORD
-ControlDevice(
- _In_ PDEVICE_CONTEXT Context
- )
-{
- DWORD Err = ERROR_SUCCESS;
-
- EnterCriticalSection(&Context->Lock);
-
- Err = ClearAllBars(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- goto cleanup;
- }
-
- Err = LightNextBar(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- goto cleanup;
- }
-
-cleanup:
-
- LeaveCriticalSection(&Context->Lock);
-
- return Err;
-} \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h
deleted file mode 100644
index 3b8be711..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- Main.h
-
-Abstract:
-
- Implements the functions to control the OSR USB FX2 device.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma once
-
-#include <Windows.h>
-#include <devioctl.h>
-#include <cfgmgr32.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <strsafe.h>
-#include <driverspecs.h>
-#include <basetyps.h>
-
-#include <initguid.h>
-
-// {573E8C73-0CB4-4471-A1BF-FAB26C31D384}
-DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2,
- 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);
-
-//
-// Most device interface paths will fit into a buffer of this size.
-// However, some could be longer, and a larger buffer or dynamically
-// allocated buffer may be needed for robust code.
-//
-#define MAX_DEVPATH_LENGTH 1024
-
-#pragma warning(push)
-#pragma warning(disable:4201) // nameless struct/union
-#pragma warning(disable:4214) // bit field types other than int
-
-typedef struct _DEVICE_CONTEXT {
- HANDLE DeviceInterfaceHandle;
- CRITICAL_SECTION Lock;
- BOOL LockEnabled;
- PTP_WORK Work;
- BOOL Unregister;
- HCMNOTIFICATION InterfaceNotificationHandle;
- BOOL InterfaceNotificationsEnabled;
- HCMNOTIFICATION DeviceNotificationHandle;
- BOOL DeviceNotificationsEnabled;
-} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
-
-//
-// Define the structures that will be used by the IOCTL
-// interface to the driver
-//
-
-//
-// BAR_GRAPH_STATE
-//
-// BAR_GRAPH_STATE is a bit field structure with each
-// bit corresponding to one of the bar graph on the
-// OSRFX2 Development Board
-//
-#include <pshpack1.h>
-typedef struct _BAR_GRAPH_STATE {
-
- union {
-
- struct {
- //
- // Individual bars starting from the
- // top of the stack of bars
- //
- // NOTE: There are actually 10 bars,
- // but the very top two do not light
- // and are not counted here
- //
- UCHAR Bar1 : 1;
- UCHAR Bar2 : 1;
- UCHAR Bar3 : 1;
- UCHAR Bar4 : 1;
- UCHAR Bar5 : 1;
- UCHAR Bar6 : 1;
- UCHAR Bar7 : 1;
- UCHAR Bar8 : 1;
- };
-
- //
- // The state of all the bar graph as a single
- // UCHAR
- //
- UCHAR BarsAsUChar;
-
- };
-
-}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE;
-
-//
-// SWITCH_STATE
-//
-// SWITCH_STATE is a bit field structure with each
-// bit corresponding to one of the switches on the
-// OSRFX2 Development Board
-//
-typedef struct _SWITCH_STATE {
-
- union {
- struct {
- //
- // Individual switches starting from the
- // left of the set of switches
- //
- UCHAR Switch1 : 1;
- UCHAR Switch2 : 1;
- UCHAR Switch3 : 1;
- UCHAR Switch4 : 1;
- UCHAR Switch5 : 1;
- UCHAR Switch6 : 1;
- UCHAR Switch7 : 1;
- UCHAR Switch8 : 1;
- };
-
- //
- // The state of all the switches as a single
- // UCHAR
- //
- UCHAR SwitchesAsUChar;
-
- };
-
-
-}SWITCH_STATE, *PSWITCH_STATE;
-
-#include <poppack.h>
-
-#pragma warning(pop)
-
-#define IOCTL_INDEX 0x800
-#define FILE_DEVICE_OSRUSBFX2 65500U
-
-#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX, \
- METHOD_BUFFERED, \
- FILE_READ_ACCESS)
-
-#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 1, \
- METHOD_BUFFERED, \
- FILE_WRITE_ACCESS)
-
-#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 3, \
- METHOD_BUFFERED, \
- FILE_WRITE_ACCESS)
-
-#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 4, \
- METHOD_BUFFERED, \
- FILE_READ_ACCESS)
-
-
-#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 5, \
- METHOD_BUFFERED, \
- FILE_WRITE_ACCESS)
-
-
-#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 6, \
- METHOD_BUFFERED, \
- FILE_READ_ACCESS)
-
-
-#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 7, \
- METHOD_BUFFERED, \
- FILE_READ_ACCESS)
-
-
-#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
- IOCTL_INDEX + 8, \
- METHOD_BUFFERED, \
- FILE_WRITE_ACCESS)
-
-#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\
- IOCTL_INDEX + 9, \
- METHOD_OUT_DIRECT, \
- FILE_READ_ACCESS)
-
-/*++
-
-Routine Description:
-
-Lights the next bar on the OSRFX2 device.
-
-Arguments:
-
-Context - The device context
-
-Return Value:
-
-A Win32 error code.
-
---*/
-DWORD
-ControlDevice(PDEVICE_CONTEXT Context);
-
-
-/*++
-
-Routine Description:
-
- Sets the variables in this service to their default values.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID SetVariables(VOID);
-
-
-/*++
-
-Routine Description:
-
- Opens up the OSR USB FX2 device handle.
-
-Arguments:
-
- Synchronous - Whether or not this device should be
- opened for synchronous access
-
-Return Value:
-
- The handle to the OSR USB FX2 device.
-
---*/
-HANDLE OpenDevice(_In_ BOOL Synchronous);
-
-
-/*++
-
-Routine Description:
-
-Register for device notifications.
-
-Arguments:
-
-Context - The callback context
-
-Return Value:
-
-A Win32 error code.
-
---*/
-DWORD RegisterDeviceNotifications(PDEVICE_CONTEXT Context);
-
-
-/*++
-
-Routine Description:
-
-Unregister for device notifications.
-
-Arguments:
-
-Context - The callback context
-
-Return Value:
-
-A Win32 error code.
-
---*/
-DWORD UnregisterDeviceNotifications(PDEVICE_CONTEXT Context);
-
-
-/*++
-
-Routine Description:
-
-Initialize the given PDEVICE_CONTEXT.
-
-Arguments:
-
-Context - The callback context
-
-Return Value:
-
-A Win32 error code.
-
---*/
-DWORD InitializeContext(PDEVICE_CONTEXT* Context);
-
-
-/*++
-
-Routine Description:
-
-Clean up the given PDEVICE_CONTEXT.
-
-Arguments:
-
-Context - The callback context
-
-Return Value:
-
-A Win32 error code.
-
---*/
-DWORD CloseContext(PDEVICE_CONTEXT Context); \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp
deleted file mode 100644
index fd3d497f..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- SampleService.cpp
-
-Abstract:
-
- 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.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma region Includes
-#include "SampleService.h"
-#include "ThreadPool.h"
-#pragma endregion
-
-/*++
-
-Routine Description:
-
- The constructor of CSampleService. It initializes a new instance
- of the CSampleService class. The optional parameters (CanStop,
- CanShutdown and CanPauseContinue) allow you to specify whether the
- service can be stopped, paused and continued, or be notified when system
- shutdown occurs. Inherits properties from the class CServiceBase.
-
-Arguments:
-
- ServiceName - The name of the service
-
- CanStop - The service can be stopped
-
- CanShutdown - The service is notified when system shutdown occurs
-
- CanPauseContinue - The service can be paused and continued
-
-Return Value:
-
- VOID
-
---*/
-CSampleService::CSampleService(
- PWSTR ServiceName,
- BOOL CanStop,
- BOOL CanShutdown,
- BOOL CanPauseContinue
- )
-: CServiceBase(ServiceName, CanStop, CanShutdown, CanPauseContinue)
-{
- m_fStopping = FALSE;
-
- //
- // Create a manual-reset event that is not signaled at first to indicate
- // the stopped signal of the service.
- //
- m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
- if (m_hStoppedEvent == NULL)
- {
- throw GetLastError();
- }
-}
-
-
-/*++
-
-Routine Description:
-
- The virtual destructor of CSampleService.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-CSampleService::~CSampleService()
-{
- if (m_hStoppedEvent)
- {
- CloseHandle(m_hStoppedEvent);
- m_hStoppedEvent = NULL;
- }
-}
-
-
-/*++
-
-Routine Description:
-
- This 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.
-
- 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.
-
-Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CSampleService::OnStart(
- DWORD Argc,
- PWSTR *Argv
- )
-{
- __debugbreak();
-
- //
- // Log a service start message to the Application log.
- //
- WriteToEventLog(L"SampleService in OnStart",
- EVENTLOG_INFORMATION_TYPE);
-
- //
- // Set up any variables the service needs.
- //
- SetVariables();
-
- //
- // Set up the context, and register for notifications.
- //
- InitializeContext(&m_Context);
-
- //
- // Queue the main service function for execution in a worker thread.
- //
- CThreadPool::QueueUserWorkItem(&CSampleService::ServiceWorkerThread, this);
-}
-
-
-/*++
-
-Routine Description:
-
- This method performs the main function of the service. It runs
- on a thread pool worker thread.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CSampleService::ServiceWorkerThread()
-{
- //
- // Periodically check if the service is stopping.
- //
- while (!m_fStopping)
- {
- //
- // Perform main service function here...
- //
-
- ControlDevice(m_Context);
-
- ::Sleep(2000); // Simulate some lengthy operations.
- }
-
- //
- // Signal the stopped event.
- //
- SetEvent(m_hStoppedEvent);
-}
-
-
-/*++
-
-Routine Description:
-
- This 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.
-
- Be sure to periodically call ReportServiceStatus() with
- SERVICE_STOP_PENDING if the procedure is going to take a long time.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CSampleService::OnStop()
-{
- //
- // Log a service stop message to the Application log.
- //
- WriteToEventLog(L"SampleService in OnStop",
- EVENTLOG_INFORMATION_TYPE);
-
- //
- // Indicate that the service is stopping and wait for the finish of the
- // main service function (ServiceWorkerThread).
- //
- m_fStopping = TRUE;
-
- if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
- {
- throw GetLastError();
- }
-
- //
- // Clean up the context after the worker thread has finished.
- //
- CloseContext(m_Context);
-} \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h
deleted file mode 100644
index 73be42e9..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- SampleService.h
-
-Abstract:
-
- 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.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma once
-
-#include "ServiceBase.h"
-#include "Main.h"
-
-class CSampleService : public CServiceBase
-{
-public:
-
- /*++
-
- Routine Description:
-
- The constructor of CSampleService. It initializes a new instance
- of the CSampleService class. The optional parameters (CanStop,
- CanShutdown and CanPauseContinue) allow you to specify whether the
- service can be stopped, paused and continued, or be notified when system
- shutdown occurs. Inherits properties from the class CServiceBase.
-
- Arguments:
-
- ServiceName - The name of the service
-
- CanStop - The service can be stopped
-
- CanShutdown - The service is notified when system shutdown occurs
-
- CanPauseContinue - The service can be paused and continued
-
- Return Value:
-
- VOID
-
- --*/
- CSampleService(PWSTR ServiceName,
- BOOL CanStop = TRUE,
- BOOL CanShutdown = TRUE,
- BOOL CanPauseContinue = FALSE);
-
- /*++
-
- Routine Description:
-
- The virtual destructor of CSampleService.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual ~CSampleService();
-
-protected:
-
- /*++
-
- Routine Description:
-
- This 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.
-
- 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.
-
- Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnStart(DWORD Argc, PWSTR *Argv);
-
-
- /*++
-
- Routine Description:
-
- This 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.
-
- Be sure to periodically call ReportServiceStatus() with
- SERVICE_STOP_PENDING if the procedure is going to take a long time.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnStop();
-
-
- /*++
-
- Routine Description:
-
- This method performs the main function of the service. It runs
- on a thread pool worker thread.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- VOID ServiceWorkerThread();
-
-private:
-
- //
- // Determines if the service is currently stopping.
- //
- BOOL m_fStopping;
-
- //
- // The handle to wait for a stop event.
- //
- HANDLE m_hStoppedEvent;
-
- //
- // The device context to manage notifications with.
- //
- // NOTE:
- // Variables used for device notifications should normally be local. However,
- // we must use a global variable here since there is a potential race condition
- // when the service needs to restart during device installation that could
- // cause the service to prevent the device from being restarted. So, this
- // variable is global so that the service's OnStart and OnStart method can
- // handle its creation and destruction.
- //
- PDEVICE_CONTEXT m_Context;
-}; \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.cpp
deleted file mode 100644
index 4c20af2e..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- ServiceBase.cpp
-
-Abstract:
-
- 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.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma region Includes
-#include "ServiceBase.h"
-#include "Main.h"
-#include "Utils.h"
-#include <assert.h>
-#include <strsafe.h>
-#pragma endregion
-
-
-#pragma region Static Members
-
-//
-// Initialize the singleton service instance.
-//
-CServiceBase *CServiceBase::s_service = NULL;
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- 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 },
- { NULL, NULL }
- };
-
- //
- // 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);
-}
-
-
-/*++
-
-Routine Description:
-
- The entry point for the service. It registers the handler function
- for the service and starts the service.
-
-Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
-Return Value:
-
- VOID
-
---*/
-VOID
-WINAPI
-CServiceBase::ServiceMain(
- DWORD Argc,
- PWSTR *Argv
- )
-{
- 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(Argc, Argv);
-}
-
-
-/*++
-
-Routine Description:
-
- Called by the SCM whenever a control code is sent to the service.
-
-Arguments:
-
- CtrlCode - 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 ranging from 128 to 255.
-
-Return Value:
-
- VOID
-
---*/
-VOID
-WINAPI
-CServiceBase::ServiceCtrlHandler(
- DWORD Ctrl
- )
-{
- switch (Ctrl)
- {
- 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
-
-/*++
-
-Routine Description:
-
- The constructor of CServiceBase. It initializes a new instance
- of the CServiceBase class. The optional parameters (CanStop,
- CanShutdown and CanPauseContinue) allow you to specify whether the
- service can be stopped, paused and continued, or be notified when system
- shutdown occurs.
-
-Arguments:
-
- ServiceName - The name of the service
-
- CanStop - The service can be stopped
-
- CanShutdown - The service is notified when system shutdown occurs
-
- CanPauseContinue - The service can be paused and continued
-
-Return Value:
-
- VOID
-
---*/
-CServiceBase::CServiceBase(
- PWSTR ServiceName,
- BOOL CanStop,
- BOOL CanShutdown,
- BOOL CanPauseContinue
- )
-{
- //
- // Service name must be a valid string and cannot be NULL.
- //
- m_name = (ServiceName == NULL) ? L"" : ServiceName;
-
- m_statusHandle = NULL;
-
- //
- // 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 (CanStop)
- {
- dwControlsAccepted |= SERVICE_ACCEPT_STOP;
- }
-
- if (CanShutdown)
- {
- dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
- }
-
- if (CanPauseContinue)
- {
- 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;
-
- SetupEvents();
-}
-
-
-/*++
-
-Routine Description:
-
- The virtual destructor of CServiceBase.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-CServiceBase::~CServiceBase()
-{
- DestroyEvents();
-}
-
-#pragma endregion
-
-
-#pragma region Service Start, Stop, Pause, Continue, and Shutdown
-
-/*++
-
-Routine Description:
-
- This 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.
-
-Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::Start(
- DWORD Argc,
- PWSTR *Argv
-)
-{
- try
- {
- //
- // Tell SCM that the service is starting.
- //
- SetServiceStatus(SERVICE_START_PENDING);
-
- //
- // Perform service-specific initialization.
- //
- OnStart(Argc, Argv);
-
- //
- // Tell SCM that the service is started.
- //
- SetServiceStatus(SERVICE_RUNNING);
- }
- catch (DWORD Error)
- {
- //
- // Log the error.
- //
- WriteToErrorLog(L"Service Start", Error);
-
- //
- // Set the service status to be stopped.
- //
- SetServiceStatus(SERVICE_STOPPED, Error);
- }
- catch (...)
- {
- //
- // Log the error.
- //
- WriteToEventLog(L"Service failed to start.", EVENTLOG_ERROR_TYPE);
-
- //
- // Set the service status to be stopped.
- //
- SetServiceStatus(SERVICE_STOPPED);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::OnStart(
- DWORD Argc,
- PWSTR *Argv
-)
-{
- SetVariables();
-}
-
-
-/*++
-
-Routine Description:
-
- This 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::Stop()
-{
- DWORD OriginalState = 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 Error)
- {
- //
- // Log the error.
- //
- WriteToErrorLog(L"Service Stop", Error);
-
- //
- // Set the orginal service status.
- //
- SetServiceStatus(OriginalState);
- }
- catch (...)
- {
- //
- // Log the error.
- //
- WriteToEventLog(L"Service failed to stop.", EVENTLOG_ERROR_TYPE);
-
- //
- // Set the orginal service status.
- //
- SetServiceStatus(OriginalState);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::OnStop()
-{
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-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 Error)
- {
- //
- // Log the error.
- //
- WriteToErrorLog(L"Service Pause", Error);
-
- //
- // Tell SCM that the service is still running.
- //
- SetServiceStatus(SERVICE_RUNNING);
- }
- catch (...)
- {
- //
- // Log the error.
- //
- WriteToEventLog(L"Service failed to pause.", EVENTLOG_ERROR_TYPE);
-
- //
- // Tell SCM that the service is still running.
- //
- SetServiceStatus(SERVICE_RUNNING);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::OnPause()
-{
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-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 Error)
- {
- //
- // Log the error.
- //
- WriteToErrorLog(L"Service Continue", Error);
-
- //
- // Tell SCM that the service is still paused.
- //
- SetServiceStatus(SERVICE_PAUSED);
- }
- catch (...)
- {
- //
- // Log the error.
- //
- WriteToEventLog(L"Service failed to resume.", EVENTLOG_ERROR_TYPE);
-
- //
- // Tell SCM that the service is still paused.
- //
- SetServiceStatus(SERVICE_PAUSED);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::OnContinue()
-{
-}
-
-
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::Shutdown()
-{
- try
- {
- //
- // Perform service-specific shutdown operations.
- //
- OnShutdown();
-
- //
- // Tell SCM that the service is stopped.
- //
- SetServiceStatus(SERVICE_STOPPED);
- }
- catch (DWORD Error)
- {
- //
- // Log the error.
- //
- WriteToErrorLog(L"Service Shutdown", Error);
- }
- catch (...)
- {
- //
- // Log the error.
- //
- WriteToEventLog(L"Service failed to shut down.", EVENTLOG_ERROR_TYPE);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- When implemented in a derived class, executes when the system
- is shutting down. Specifies what should occur immediately prior to the
- system shutting down.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::OnShutdown()
-{
-}
-
-#pragma endregion
-
-
-#pragma region Helper Functions
-
-/*++
-
-Routine Description:
-
- The function sets the service status and reports the status to the SCM.
-
-Arguments:
-
- CurrentState - The current state of the service
-
- Win32ExitCode - The error code to report
-
- WaitHint - The estimated time for pending operation, in milliseconds
-
-Return Value:
-
- VOID
-
---*/
-VOID
-CServiceBase::SetServiceStatus(
- DWORD CurrentState,
- DWORD Win32ExitCode,
- DWORD WaitHint
- )
-{
- static DWORD CheckPoint = 1;
-
- //
- // Fill in the SERVICE_STATUS structure of the service.
- //
-
- m_status.dwCurrentState = CurrentState;
- m_status.dwWin32ExitCode = Win32ExitCode;
- m_status.dwWaitHint = WaitHint;
-
- m_status.dwCheckPoint = ((CurrentState == SERVICE_RUNNING) ||
- (CurrentState == SERVICE_STOPPED)) ? 0 :
- CheckPoint++;
-
- //
- // Report the status of the service to the SCM.
- //
- ::SetServiceStatus(m_statusHandle, &m_status);
-}
-
-#pragma endregion \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.h
deleted file mode 100644
index 106597e1..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceBase.h
+++ /dev/null
@@ -1,423 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- ServiceBase.cpp
-
-Abstract:
-
- 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.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma once
-
-#include <windows.h>
-#include "Utils.h"
-
-class CServiceBase
-{
-public:
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- 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.
-
- --*/
- static BOOL Run(CServiceBase &service);
-
-
- /*++
-
- Routine Description:
-
- The constructor of CServiceBase. It initializes a new instance
- of the CServiceBase class. The optional parameters (CanStop,
- CanShutdown and CanPauseContinue) allow you to specify whether the
- service can be stopped, paused and continued, or be notified when system
- shutdown occurs.
-
- Arguments:
-
- ServiceName - The name of the service
-
- CanStop - The service can be stopped
-
- CanShutdown - The service is notified when system shutdown occurs
-
- CanPauseContinue - The service can be paused and continued
-
- Return Value:
-
- VOID
-
- --*/
- CServiceBase(PWSTR ServiceName,
- BOOL CanStop = TRUE,
- BOOL CanShutdown = TRUE,
- BOOL CanPauseContinue = FALSE);
-
-
- /*++
-
- Routine Description:
-
- The virtual destructor of CServiceBase.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual ~CServiceBase();
-
-
- /*++
-
- Routine Description:
-
- This 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- VOID Stop();
-
-protected:
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnStart(DWORD Argc, PWSTR *Argv);
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnStop();
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnPause();
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnContinue();
-
-
- /*++
-
- Routine Description:
-
- When implemented in a derived class, executes when the system
- is shutting down. Specifies what should occur immediately prior to the
- system shutting down.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- virtual VOID OnShutdown();
-
-
- /*++
-
- Routine Description:
-
- The function sets the service status and reports the status to the SCM.
-
- Arguments:
-
- CurrentState - The current state of the service
-
- Win32ExitCode - The error code to report
-
- WaitHint - The estimated time for pending operation, in milliseconds
-
- Return Value:
-
- VOID
-
- --*/
- VOID SetServiceStatus(DWORD CurrentState,
- DWORD Win32ExitCode = NO_ERROR,
- DWORD WaitHint = 0);
-
-private:
-
- /*++
-
- Routine Description:
-
- The entry point for the service. It registers the handler function
- for the service and starts the service.
-
- Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
- Return Value:
-
- VOID
-
- --*/
- static VOID WINAPI ServiceMain(DWORD Argc, PWSTR *Argv);
-
-
- /*++
-
- Routine Description:
-
- Called by the SCM whenever a control code is sent to the service.
-
- Arguments:
-
- CtrlCode - 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 ranging from 128 to 255.
-
- Return Value:
-
- VOID
-
- --*/
- static VOID WINAPI ServiceCtrlHandler(DWORD Ctrl);
-
-
- /*++
-
- Routine Description:
-
- This 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.
-
- Arguments:
-
- Argc - The number of command line arguments
-
- Argv - The array of command line arguments
-
- Return Value:
-
- VOID
-
- --*/
- VOID Start(DWORD Argc, PWSTR *Argv);
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- VOID Pause();
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- VOID Continue();
-
-
- /*++
-
- Routine Description:
-
- 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.
-
- Arguments:
-
- VOID
-
- Return Value:
-
- VOID
-
- --*/
- 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;
-}; \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.cpp
new file mode 100644
index 00000000..f6616850
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.cpp
@@ -0,0 +1,375 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ServiceWin32API.cpp
+
+Abstract:
+
+ Implements functions to start/run/stop the service.
+
+Environment:
+
+ User mode
+
+--*/
+
+#include "stdafx.h"
+
+//
+// Settings of the service
+//
+#define SERVICE_NAME L"OsrUsbFx2UmUserSvc"
+#define SERVICE_FLAGS_RUNNING 0x1
+
+//
+// Service context
+//
+SERVICE_STATUS_HANDLE SvcStatusHandle = NULL;
+volatile LONG SvcControlFlags = 0;
+HANDLE SvcStoppedEvent = NULL;
+HANDLE SvcStopRequestEvent = NULL;
+HANDLE SvcStopWaitObject = NULL;
+
+//
+// Device interface context
+//
+HCMNOTIFICATION InterfaceNotificationHandle = NULL;
+SRWLOCK DeviceListLock = SRWLOCK_INIT;
+DEVICE_LIST_ENTRY DeviceList;
+
+//
+// Debugging support during development time
+//
+//#define DEBUG_SUPPORT
+
+/*++
+
+Routine Description:
+
+ Entry point for the service.
+
+Arguments:
+
+ Argc - The number of command line arguments
+
+ Argv - The array of command line arguments
+
+Return Value:
+
+ VOID
+
+--*/
+INT
+wmain(
+ INT Argc,
+ WCHAR *Argv[]
+ )
+{
+ UNREFERENCED_PARAMETER(Argc);
+ UNREFERENCED_PARAMETER(Argv);
+
+ SERVICE_TABLE_ENTRY serviceTable[] =
+ {
+ { SERVICE_NAME, ServiceMain },
+ { NULL, NULL }
+ };
+
+ return StartServiceCtrlDispatcher(serviceTable);
+}
+
+VOID WINAPI ServiceMain(
+ DWORD Argc,
+ PWSTR *Argv
+ )
+{
+ DWORD Err = ERROR_SUCCESS;
+
+ UNREFERENCED_PARAMETER(Argc);
+ UNREFERENCED_PARAMETER(Argv);
+
+ //
+ // Initialize global variables
+ //
+ InitializeDeviceListHead(&DeviceList);
+
+#ifdef DEBUG_SUPPORT
+
+ while (!IsDebuggerPresent()) {
+ Sleep(1000);
+ }
+
+ __debugbreak();
+
+#endif
+
+ SvcStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME,
+ ServiceCtrlHandler);
+
+ if (SvcStatusHandle == NULL)
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+ UpdateServiceStatus(SvcStatusHandle,
+ SERVICE_START_PENDING,
+ ERROR_SUCCESS);
+
+ //
+ // Setup device interface context
+ //
+ Err = SetupDeviceInterfaceContext();
+
+ UpdateServiceStatus(SvcStatusHandle,
+ SERVICE_START_PENDING,
+ ERROR_SUCCESS);
+
+ //
+ // Initialize device control
+ //
+ OsrFx2InitializeDevice();
+
+ //
+ // Register callback function for stop event
+ //
+ SvcStopRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (SvcStopRequestEvent == NULL)
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+ if (!RegisterWaitForSingleObject(&SvcStopWaitObject,
+ SvcStopRequestEvent,
+ ServiceStopCallback,
+ NULL,
+ INFINITE,
+ WT_EXECUTEONLYONCE | WT_EXECUTEINPERSISTENTTHREAD))
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+ //
+ // Create stopped event for the running worker thread
+ //
+ SvcStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (SvcStoppedEvent == NULL)
+ {
+ Err = GetLastError();
+ goto cleanup;
+ }
+
+ UpdateServiceStatus(SvcStatusHandle,
+ SERVICE_START_PENDING,
+ ERROR_SUCCESS);
+
+ //
+ // Queue the main service function for execution in a worker thread.
+ //
+ QueueUserWorkItem(&ServiceRunningWorkerThread,
+ NULL,
+ WT_EXECUTELONGFUNCTION);
+
+ UpdateServiceStatus(SvcStatusHandle,
+ SERVICE_RUNNING,
+ ERROR_SUCCESS);
+
+cleanup:
+
+ if (Err != ERROR_SUCCESS)
+ {
+ ServiceStop(Err);
+ }
+}
+
+VOID
+WINAPI
+ServiceCtrlHandler(
+ DWORD Ctrl
+ )
+{
+ switch (Ctrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ //
+ // Set service stop event
+ //
+ UpdateServiceStatus(SvcStatusHandle, SERVICE_STOP_PENDING, ERROR_SUCCESS);
+ SetEvent(SvcStopRequestEvent);
+ break;
+
+ default:
+ break;
+ }
+}
+
+#define SERVICE_WAIT_HINT_TIME 30000 // 30 seconds
+
+BOOL
+UpdateServiceStatus(
+ __in_opt SERVICE_STATUS_HANDLE hSvcHandle,
+ __in DWORD dwCurrentState,
+ __in DWORD dwWin32ExitCode
+ )
+{
+ SERVICE_STATUS SvcStatus;
+
+ static DWORD dwCheckPoint = 1;
+
+ SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ SvcStatus.dwCurrentState = dwCurrentState;
+ SvcStatus.dwWin32ExitCode = dwWin32ExitCode;
+ SvcStatus.dwServiceSpecificExitCode = ERROR_SUCCESS;
+
+ if (dwCurrentState == SERVICE_START_PENDING)
+ {
+ SvcStatus.dwControlsAccepted = 0;
+ }
+ else
+ {
+ SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ }
+
+ if ((dwCurrentState == SERVICE_RUNNING) ||
+ (dwCurrentState == SERVICE_STOPPED))
+ {
+ SvcStatus.dwCheckPoint = 0;
+ SvcStatus.dwWaitHint = 0;
+ }
+ else
+ {
+ SvcStatus.dwCheckPoint = dwCheckPoint++;
+ SvcStatus.dwWaitHint = SERVICE_WAIT_HINT_TIME;
+ }
+
+ return SetServiceStatus(hSvcHandle, &SvcStatus);
+}
+
+DWORD
+WINAPI
+ServiceRunningWorkerThread(
+ _In_ PVOID lpThreadParameter
+ )
+{
+ PDEVICE_CONTEXT DeviceContext = NULL;
+ PDEVICE_LIST_ENTRY Link = NULL;
+
+ UNREFERENCED_PARAMETER(lpThreadParameter);
+
+ InterlockedOr(&SvcControlFlags, SERVICE_FLAGS_RUNNING);
+
+ //
+ // Periodically check if the service is stopping.
+ //
+ while ((InterlockedOr(&SvcControlFlags, 0) & SERVICE_FLAGS_RUNNING) != 0)
+ {
+ AcquireSRWLockShared(&DeviceListLock);
+
+ for (Link = DeviceList.Flink; Link != &DeviceList; Link = Link->Flink)
+ {
+ DeviceContext = CONTAINING_DEVICE_RECORD(Link);
+
+ OsrFx2ControlDevice(DeviceContext);
+ }
+
+ ReleaseSRWLockShared(&DeviceListLock);
+
+ Sleep(2000); // Simulate some lengthy operations.
+ }
+
+ //
+ // Signal the stopped event.
+ //
+ SetEvent(SvcStoppedEvent);
+
+ return 0;
+}
+
+VOID
+CALLBACK
+ServiceStopCallback(
+ _In_ PVOID lpParameter,
+ _In_ BOOLEAN TimerOrWaitFired
+ )
+{
+ UNREFERENCED_PARAMETER(TimerOrWaitFired);
+
+ //
+ // Since wait object can not be unregistered in callback function, queue
+ // another thread
+ //
+ QueueUserWorkItem(ServiceStopWorkerThread,
+ lpParameter,
+ WT_EXECUTEDEFAULT);
+}
+
+DWORD
+WINAPI
+ServiceStopWorkerThread(
+ _In_ PVOID lpThreadParameter
+ )
+{
+ UNREFERENCED_PARAMETER(lpThreadParameter);
+
+ ServiceStop(ERROR_SUCCESS);
+
+ return 0;
+}
+
+VOID
+ServiceStop(
+ _In_ DWORD ExitCode
+ )
+{
+ if (SvcStatusHandle == NULL)
+ {
+ return;
+ }
+
+ UpdateServiceStatus(SvcStatusHandle, SERVICE_STOP_PENDING, ExitCode);
+
+ //
+ // Notify the working thread to stop
+ //
+ if ((InterlockedOr(&SvcControlFlags, 0) & SERVICE_FLAGS_RUNNING) != 0)
+ {
+ InterlockedAnd(&SvcControlFlags, ~SERVICE_FLAGS_RUNNING);
+ WaitForSingleObject(SvcStoppedEvent, INFINITE);
+ }
+
+ //
+ // Clean up device context after the worker thread has finished.
+ //
+ CleanupDeviceInterfaceContext();
+
+ //
+ // cleanup work
+ //
+ if (SvcStopWaitObject != NULL)
+ {
+ UnregisterWait(SvcStopWaitObject);
+ }
+
+ if (SvcStopRequestEvent != NULL)
+ {
+ CloseHandle(SvcStopRequestEvent);
+ }
+
+ if (SvcStoppedEvent != NULL)
+ {
+ CloseHandle(SvcStoppedEvent);
+ }
+
+ UpdateServiceStatus(SvcStatusHandle, SERVICE_STOPPED, ExitCode);
+}
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.h
new file mode 100644
index 00000000..e469ca9d
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ServiceWin32API.h
@@ -0,0 +1,56 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+--*/
+
+#pragma once
+
+VOID
+WINAPI
+ServiceMain(
+ DWORD Argc,
+ PWSTR *Argv
+ );
+
+VOID
+WINAPI
+ServiceCtrlHandler(
+ DWORD Ctrl
+ );
+
+BOOL
+UpdateServiceStatus(
+ __in_opt SERVICE_STATUS_HANDLE hSvcHandle,
+ __in DWORD dwCurrentState,
+ __in DWORD dwWin32ExitCode
+ );
+
+VOID
+CALLBACK
+ServiceStopCallback(
+ _In_ PVOID lpParameter,
+ _In_ BOOLEAN TimerOrWaitFired
+ );
+
+VOID
+ServiceStop(
+ _In_ DWORD ExitCode
+ );
+
+DWORD
+WINAPI
+ServiceRunningWorkerThread(
+ _In_ PVOID lpThreadParameter
+ );
+
+DWORD
+WINAPI
+ServiceStopWorkerThread(
+ _In_ PVOID lpThreadParameter
+ );
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ThreadPool.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ThreadPool.h
deleted file mode 100644
index 3d851537..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/ThreadPool.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************** Module Header ******************************\
-* Module Name: ThreadPool.h
-* Project: CppWindowsService
-* Copyright (c) Microsoft Corporation.
-*
-* The class was designed by Kenny Kerr. It provides the ability to queue
-* simple member functions of a class to the Windows thread pool.
-*
-* Using the thread pool is simple and feels natural in C++.
-*
-* class CSampleService
-* {
-* public:
-*
-* void AsyncRun()
-* {
-* CThreadPool::QueueUserWorkItem(&Service::Run, this);
-* }
-*
-* void Run()
-* {
-* // Some lengthy operation
-* }
-* };
-*
-* Kenny Kerr spends most of his time designing and building distributed
-* applications for the Microsoft Windows platform. He also has a particular
-* passion for C++ and security programming. Reach Kenny at
-* http://weblogs.asp.net/kennykerr/ or visit his Web site:
-* http://www.kennyandkarin.com/Kenny/.
-*
-* This source is subject to the Microsoft Public License.
-* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL.
-* All other rights reserved.
-*
-* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
-* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-\***************************************************************************/
-
-#pragma once
-
-#include <memory>
-
-
-class CThreadPool
-{
-public:
-
- template <typename T>
- static void QueueUserWorkItem(void (T::*function)(void),
- T *object, ULONG flags = WT_EXECUTELONGFUNCTION)
- {
- typedef std::pair<void (T::*)(), T *> CallbackType;
- std::auto_ptr<CallbackType> p(new CallbackType(function, object));
-
- if (::QueueUserWorkItem(ThreadProc<T>, p.get(), flags))
- {
- // The ThreadProc now has the responsibility of deleting the pair.
- p.release();
- }
- else
- {
- throw GetLastError();
- }
- }
-
-private:
-
- template <typename T>
- static DWORD WINAPI ThreadProc(PVOID context)
- {
- typedef std::pair<void (T::*)(), T *> CallbackType;
-
- std::auto_ptr<CallbackType> p(static_cast<CallbackType *>(context));
-
- (p->second->*p->first)();
- return 0;
- }
-}; \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.cpp
deleted file mode 100644
index e8fc87ee..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- Utils.cpp
-
-Abstract:
-
- Provides utility function to SampleApp.cpp.
-
-Environment:
-
- User mode
-
---*/
-
-#include "Utils.h"
-
-//
-// Service trace event provider
-// {54a25c42-cd91-4210-98cc-c3447b56e447}
-//
-EXTERN_C __declspec(selectany) const GUID SERVICE_PROVIDER_GUID = { 0x54a25c42, 0xcd91, 0x4210,{ 0x98, 0xcc, 0xc3, 0x44, 0x7b, 0x56, 0xe4, 0x47 } };
-
-REGHANDLE m_etwRegHandle;
-
-
-/*++
-
-Routine Description:
-
- Sets up logging.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-SetupEvents()
-{
- NTSTATUS status = EventRegister(&SERVICE_PROVIDER_GUID,
- nullptr,
- nullptr,
- &m_etwRegHandle);
-
- if (status != ERROR_SUCCESS)
- {
- wprintf(L"Provider not registered. EventRegister failed with error: 0x%08X\n", status);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- Destroys logging.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID
-DestroyEvents()
-{
- if (m_etwRegHandle != NULL)
- {
- EventUnregister(m_etwRegHandle);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- Log a message.
-
-Arguments:
-
- Message - The string message to be logged
-
- Level - The type of event to be logged. This parameter can
- be one of the following values:
-
- TRACE_LEVEL_CRITICAL
- TRACE_LEVEL_ERROR
- TRACE_LEVEL_WARNING
- TRACE_LEVEL_INFORMATION
- TRACE_LEVEL_VERBOSE
-
-Return Value:
-
- VOID
-
---*/
-VOID
-WriteToEventLog(
- PWSTR Message,
- BYTE Level
- )
-{
- if (m_etwRegHandle != NULL)
- {
- EventWriteString(m_etwRegHandle, Level, 0, Message);
- }
-}
-
-
-/*++
-
-Routine Description:
-
- Log an error message.
-
-Arguments:
-
- Function - The function that gives the error
-
- Error - The error code
-
-Return Value:
-
- VOID
-
---*/
-VOID
-WriteToErrorLog(
- PWSTR Function,
- DWORD Error
- )
-{
- WCHAR Message[260];
-
- StringCchPrintf(Message, ARRAYSIZE(Message),
- L"%ws failed with error: 0x%08x", Function, Error);
-
- WriteToEventLog(Message, TRACE_LEVEL_ERROR);
-} \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.h
deleted file mode 100644
index b619f461..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Utils.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- PURPOSE.
-
-Module Name:
-
- Utils.cpp
-
-Abstract:
-
- Provides utility function to SampleApp.cpp.
-
-Environment:
-
- User mode
-
---*/
-
-#pragma once
-
-#include <Windows.h>
-#include <strsafe.h>
-#include <evntprov.h>
-#include <evntrace.h>
-
-/*++
-
-Routine Description:
-
- Sets up logging.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID SetupEvents();
-
-
-/*++
-
-Routine Description:
-
- Destroys logging.
-
-Arguments:
-
- VOID
-
-Return Value:
-
- VOID
-
---*/
-VOID DestroyEvents();
-
-
-/*++
-
-Routine Description:
-
- Log a message.
-
-Arguments:
-
- Message - The string message to be logged
-
- Level - The type of event to be logged. This parameter can
- be one of the following values:
-
- TRACE_LEVEL_CRITICAL
- TRACE_LEVEL_ERROR
- TRACE_LEVEL_WARNING
- TRACE_LEVEL_INFORMATION
- TRACE_LEVEL_VERBOSE
-
-Return Value:
-
- VOID
-
---*/
-VOID WriteToEventLog(PWSTR Message, BYTE Level);
-
-
-/*++
-
-Routine Description:
-
- Log an error message.
-
-Arguments:
-
- Function - The function that gives the error
-
- Error - The error code
-
-Return Value:
-
- VOID
-
---*/
-VOID WriteToErrorLog(PWSTR Function, DWORD Error); \ No newline at end of file
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.inx b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.inx
deleted file mode 100644
index 61e1e958..00000000
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.inx
+++ /dev/null
Binary files differ
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.vcxproj b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.vcxproj
index 6965d745..60174c56 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.vcxproj
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.vcxproj
@@ -23,7 +23,7 @@
<RootNamespace>osrfx2_DCHU_usersvc</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>osrfx2_DCHU_usersvc</ProjectName>
- <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -93,14 +93,13 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
- <Optimization>Full</Optimization>
+ <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
+ <WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
@@ -108,11 +107,11 @@
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies);</AdditionalDependencies>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
- <Optimization>Full</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -121,6 +120,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Full</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -138,8 +138,7 @@
<ClCompile>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
@@ -182,18 +181,15 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="CppWindowsService.cpp" />
- <ClCompile Include="SampleService.cpp" />
- <ClCompile Include="ServiceBase.cpp" />
- <ClCompile Include="Main.cpp" />
- <ClCompile Include="Utils.cpp" />
+ <ClCompile Include="DeviceControl.cpp" />
+ <ClCompile Include="DeviceContext.cpp" />
+ <ClCompile Include="ServiceWin32API.cpp" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="SampleService.h" />
- <ClInclude Include="ServiceBase.h" />
- <ClInclude Include="Main.h" />
- <ClInclude Include="ThreadPool.h" />
- <ClInclude Include="Utils.h" />
+ <ClInclude Include="DeviceControl.h" />
+ <ClInclude Include="DeviceContext.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="ServiceWin32API.h" />
</ItemGroup>
<ItemGroup>
<None Include="Documentation\ReadMe.htm">
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/stdafx.h b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/stdafx.h
new file mode 100644
index 00000000..7bd67951
--- /dev/null
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/stdafx.h
@@ -0,0 +1,26 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+--*/
+
+#pragma once
+
+#include <Windows.h>
+#include <strsafe.h>
+
+//
+// Device context
+//
+#include <cfgmgr32.h>
+
+#include <initguid.h>
+
+#include "ServiceWin32API.h"
+#include "DeviceContext.h"
+#include "DeviceControl.h"