diff options
| author | andylsn <[email protected]> | 2020-03-24 16:38:30 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-03-24 16:38:30 -0700 |
| commit | 9b58d9a908a45a55452b87d001789d27fbf0e8ee (patch) | |
| tree | 4455a2868af111fc979ad8f3964dae8e15923e89 /general | |
| parent | 8fb512ac674df5ba129a69906d450f2a1361136d (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]>
Diffstat (limited to 'general')
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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index 61e1e958..00000000 --- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/osrfx2_DCHU_usersvc.inx +++ /dev/null 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" |
