summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Montera <[email protected]>2017-08-25 17:35:47 -0700
committerMatthew Montera <[email protected]>2017-08-25 17:35:47 -0700
commit7306c1456b4b6bf82560af70b9e104c874051ee9 (patch)
tree16eb324df6cecd1ecf3b674c610cfe9e711c35f6
parent5f434058994bb32f63ca2578847be9c6388dd9c2 (diff)
Many changes
Went through PR
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp499
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h66
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp61
-rw-r--r--general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h13
4 files changed, 337 insertions, 302 deletions
diff --git a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp
index 6484f834..a02ac24a 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.cpp
@@ -81,32 +81,31 @@ GetDevicePath(
)
{
HRESULT hr = E_FAIL;
- BOOL Return = FALSE;
- CONFIGRET Status = CR_SUCCESS;
+ CONFIGRET cr = CR_SUCCESS;
PWSTR DeviceInterfaceList = NULL;
ULONG DeviceInterfaceListLength = 0;
PWSTR NextInterface;
- //
- // Determine if there are any interfaces that match the OSRFX2 device.
- //
- Status = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListLength,
- InterfaceGuid,
- NULL,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+ //
+ // 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 (Status != CR_SUCCESS)
+ if (cr != CR_SUCCESS)
{
WriteToErrorLog(L"CM_Get_DeviceInterface_List_Size",
- CM_MapCrToWin32Err(Status, ERROR_FILE_NOT_FOUND));
- goto clean0;
+ CM_MapCrToWin32Err(cr, ERROR_FILE_NOT_FOUND));
+ goto cleanup;
}
if (DeviceInterfaceListLength < 1)
{
WriteToErrorLog(L"CM_Get_DeviceInterface_List_Size",
- CM_MapCrToWin32Err(Status, ERROR_EMPTY));
- goto clean0;
+ CM_MapCrToWin32Err(cr, ERROR_EMPTY));
+ goto cleanup;
}
DeviceInterfaceList = (PWSTR)malloc(DeviceInterfaceListLength * sizeof(WCHAR));
@@ -115,22 +114,20 @@ GetDevicePath(
{
WriteToEventLog(L"Failed to allocate memory for the device interface list",
TRACE_LEVEL_ERROR);
- goto clean0;
+ goto cleanup;
}
- ZeroMemory(DeviceInterfaceList, DeviceInterfaceListLength * sizeof(WCHAR));
+ cr = CM_Get_Device_Interface_List(InterfaceGuid,
+ NULL,
+ DeviceInterfaceList,
+ DeviceInterfaceListLength,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
- Status = CM_Get_Device_Interface_List(InterfaceGuid,
- NULL,
- DeviceInterfaceList,
- DeviceInterfaceListLength,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
-
- if (Status != CR_SUCCESS)
+ if (cr != CR_SUCCESS)
{
WriteToErrorLog(L"CM_Get_Device_Interface_List",
- CM_MapCrToWin32Err(Status, ERROR_FILE_NOT_FOUND));
- goto clean0;
+ CM_MapCrToWin32Err(cr, ERROR_FILE_NOT_FOUND));
+ goto cleanup;
}
if (*DeviceInterfaceList == UNICODE_NULL)
@@ -139,11 +136,11 @@ GetDevicePath(
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.
- //
+ //
+ // 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)
@@ -158,22 +155,17 @@ GetDevicePath(
if (FAILED(hr))
{
WriteToErrorLog(L"StringCchCopy", HRESULT_CODE(hr));
- goto clean0;
+ goto cleanup;
}
-clean0:
+cleanup:
if (DeviceInterfaceList != NULL)
{
free(DeviceInterfaceList);
}
- if (Status == CR_SUCCESS)
- {
- Return = TRUE;
- }
-
- return Return;
+ return (cr == CR_SUCCESS);
}
@@ -199,21 +191,21 @@ _Success_(return != INVALID_HANDLE_VALUE)
HANDLE
OpenDevice(
_In_ BOOL Synchronous
-)
+ )
{
- HANDLE DeviceHandle;
+ HANDLE DeviceHandle = INVALID_HANDLE_VALUE;
WCHAR DeviceName[MAX_DEVPATH_LENGTH];
if (!GetDevicePath((LPGUID)&GUID_DEVINTERFACE_OSRUSBFX2,
DeviceName,
sizeof(DeviceName) / sizeof(DeviceName[0])))
{
- return INVALID_HANDLE_VALUE;
+ goto cleanup;
}
- //
- // Open a handle to the interface.
- //
+ //
+ // Open a handle to the interface.
+ //
if (Synchronous)
{
DeviceHandle = CreateFile(DeviceName,
@@ -244,6 +236,8 @@ OpenDevice(
WriteToEventLog(L"Opened Device Successfully", TRACE_LEVEL_INFORMATION);
}
+cleanup:
+
return DeviceHandle;
}
@@ -265,7 +259,7 @@ Return Value:
--*/
DWORD
InterfaceArrivalAction(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
@@ -304,7 +298,7 @@ InterfaceArrivalAction(
cleanup:
- LeaveCriticalSection(&Context->Lock);
+ LeaveCriticalSection(&Context->Lock);
return Err;
}
@@ -320,13 +314,13 @@ Arguments:
hNotify - The notification that fired the callback
- hContext - The callback context
+ hContext - The callback context
- Action - The type of notification
+ Action - The type of notification
- EventData - Additional information about the callback
+ EventData - Additional information about the callback
- EventDataSize - The size of EventData
+ EventDataSize - The size of EventData
Return Value:
@@ -343,15 +337,15 @@ InterfaceCallback(
)
{
DWORD Err = ERROR_SUCCESS;
- PHANDLE_CONTEXT Context = (PHANDLE_CONTEXT)hContext;
+ PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
- //
- // Validate Context.
- //
- if (Context == NULL)
- {
- goto cleanup;
- }
+ //
+ // Validate Context.
+ //
+ if (Context == NULL)
+ {
+ goto cleanup;
+ }
if (Action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL)
{
@@ -369,7 +363,7 @@ cleanup:
Routine Description:
Registers the service for notifications using the notification handle in
- Context.
+ Context.
Arguments:
@@ -382,17 +376,17 @@ Return Value:
--*/
DWORD
RegisterInterfaceNotifications(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
CONFIGRET cr;
CM_NOTIFY_FILTER NotifyFilter = {0};
- if (Context == NULL)
- {
- goto cleanup;
- }
+ if (Context == NULL)
+ {
+ goto cleanup;
+ }
ZeroMemory(&NotifyFilter, sizeof(NotifyFilter));
NotifyFilter.cbSize = sizeof(NotifyFilter);
@@ -422,7 +416,7 @@ cleanup:
Routine Description:
Unregister for interface notifications. Note, this routine deadlocks
- when called from an interface callback.
+ when called from an interface callback.
Arguments:
@@ -435,7 +429,7 @@ Return Value:
--*/
DWORD
UnregisterInterfaceNotifications(
- PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
CONFIGRET cr;
@@ -468,7 +462,7 @@ Return Value:
--*/
DWORD
DeviceQueryRemoveAction(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
@@ -496,16 +490,16 @@ DeviceQueryRemoveAction(
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.
+ 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
+ Instance - The thread's callback instance
hContext - The callback context
- pWork - The thread handle
+ pWork - The thread handle
Return Value:
@@ -520,7 +514,7 @@ UnregisterWorkerThreadCallback(
_Inout_ PTP_WORK pWork
)
{
- PHANDLE_CONTEXT Context = (PHANDLE_CONTEXT)hContext;
+ PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
EnterCriticalSection(&Context->Lock);
@@ -548,7 +542,7 @@ Routine Description:
Arguments:
- hNotify - The notification that spurred this callback
+ hNotify - The notification that spurred this callback
Context - The callback context
@@ -559,8 +553,8 @@ Return Value:
--*/
DWORD
DeviceQueryRemoveFailedAction(
- HCMNOTIFICATION hNotify,
- PHANDLE_CONTEXT Context
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
@@ -576,32 +570,32 @@ DeviceQueryRemoveFailedAction(
//
// Unregister the device callback, and then close the handle
//
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
+ 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);
+ //
+ // Wait for the callback and then re-register the device
+ //
+ WaitForThreadpoolWorkCallbacks(Context->Work, FALSE);
- EnterCriticalSection(&Context->Lock);
+ EnterCriticalSection(&Context->Lock);
- if (Context->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
- {
- Context->DeviceInterfaceHandle = OpenDevice(FALSE);
- }
+ if (Context->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
+ {
+ Context->DeviceInterfaceHandle = OpenDevice(FALSE);
+ }
- if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- RegisterDeviceNotifications(Context);
- }
+ if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
+ {
+ RegisterDeviceNotifications(Context);
+ }
- LeaveCriticalSection(&Context->Lock);
+ LeaveCriticalSection(&Context->Lock);
return Err;
}
@@ -626,11 +620,11 @@ Return Value:
--*/
DWORD
DeviceRemovePendingAction(
- HCMNOTIFICATION hNotify,
- PHANDLE_CONTEXT Context
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PDEVICE_CONTEXT Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
EnterCriticalSection(&Context->Lock);
@@ -643,11 +637,11 @@ DeviceRemovePendingAction(
//
// Unregister the device callback, and then close the handle
//
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
+ if (!Context->Unregister)
+ {
+ Context->Unregister = TRUE;
+ SubmitThreadpoolWork(Context->Work);
+ }
LeaveCriticalSection(&Context->Lock);
@@ -674,11 +668,11 @@ Return Value:
--*/
DWORD
DeviceRemoveCompleteAction(
- HCMNOTIFICATION hNotify,
- PHANDLE_CONTEXT Context
+ _In_ HCMNOTIFICATION hNotify,
+ _In_ PDEVICE_CONTEXT Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
EnterCriticalSection(&Context->Lock);
@@ -691,11 +685,11 @@ DeviceRemoveCompleteAction(
//
// Unregister the device callback, and then close the handle
//
- if (!Context->Unregister)
- {
- Context->Unregister = TRUE;
- SubmitThreadpoolWork(Context->Work);
- }
+ if (!Context->Unregister)
+ {
+ Context->Unregister = TRUE;
+ SubmitThreadpoolWork(Context->Work);
+ }
LeaveCriticalSection(&Context->Lock);
@@ -715,11 +709,11 @@ Arguments:
hContext - The callback context
- Action - The type of callback
+ Action - The type of callback
- EventData - Additional information about this callback
+ EventData - Additional information about this callback
- EventDataSize - The size of EventData
+ EventDataSize - The size of EventData
Return Value:
@@ -733,39 +727,37 @@ DeviceCallback(
_In_ CM_NOTIFY_ACTION Action,
_In_ PCM_NOTIFY_EVENT_DATA EventData,
_In_ DWORD EventDataSize
-)
+ )
{
- DWORD Err = ERROR_SUCCESS;
- PHANDLE_CONTEXT Context = (PHANDLE_CONTEXT)hContext;
-
- //
- // Validate Context.
- //
- if (Context == NULL)
- {
- goto cleanup;
- }
-
- switch (Action)
- {
+ DWORD Err = ERROR_SUCCESS;
+ PDEVICE_CONTEXT Context = (PDEVICE_CONTEXT)hContext;
- case CM_NOTIFY_ACTION_DEVICEQUERYREMOVE:
- DeviceQueryRemoveAction(Context);
- break;
+ //
+ // Validate Context.
+ //
+ if (Context == NULL)
+ {
+ goto cleanup;
+ }
- case CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED:
- DeviceQueryRemoveFailedAction(hNotify, Context);
- break;
+ switch (Action)
+ {
+ case CM_NOTIFY_ACTION_DEVICEQUERYREMOVE:
+ DeviceQueryRemoveAction(Context);
+ break;
- case CM_NOTIFY_ACTION_DEVICEREMOVEPENDING:
- DeviceRemovePendingAction(hNotify, Context);
- break;
+ case CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED:
+ DeviceQueryRemoveFailedAction(hNotify, Context);
+ break;
- case CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE:
- DeviceRemoveCompleteAction(hNotify, Context);
- break;
+ case CM_NOTIFY_ACTION_DEVICEREMOVEPENDING:
+ DeviceRemovePendingAction(hNotify, Context);
+ break;
- }
+ case CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE:
+ DeviceRemoveCompleteAction(hNotify, Context);
+ break;
+ }
cleanup:
@@ -790,10 +782,10 @@ Return Value:
--*/
DWORD
RegisterDeviceNotifications(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
CONFIGRET cr;
CM_NOTIFY_FILTER NotifyFilter = {0};
@@ -813,7 +805,7 @@ RegisterDeviceNotifications(
goto cleanup;
}
- Context->Unregister = FALSE;
+ Context->Unregister = FALSE;
cleanup:
@@ -838,10 +830,10 @@ Return Value:
--*/
DWORD
UnregisterDeviceNotifications(
- PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
CONFIGRET cr;
if (Context->DeviceNotificationHandle != NULL)
@@ -865,7 +857,7 @@ UnregisterDeviceNotifications(
Routine Description:
- Initialize the given PHANDLE_CONTEXT.
+ Initialize the given PDEVICE_CONTEXT.
Arguments:
@@ -878,39 +870,49 @@ Return Value:
--*/
DWORD
InitializeContext(
- _Out_ PHANDLE_CONTEXT* Context
+ _Out_ PDEVICE_CONTEXT *Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
+ BOOL LockInitialized = FALSE;
+ BOOL LockEntered = FALSE;
+ BOOL InterfaceNotificationsInitialized = FALSE;
+ BOOL DeviceNotificationsInitialized = FALSE;
+ PDEVICE_CONTEXT DeviceContext;
- *Context = (PHANDLE_CONTEXT)malloc(sizeof(HANDLE_CONTEXT));
+ DeviceContext = (PDEVICE_CONTEXT)malloc(sizeof(DEVICE_CONTEXT));
- if (*Context == NULL)
+ if (DeviceContext == NULL)
{
Err = ERROR_OUTOFMEMORY;
goto cleanup;
}
- (*Context)->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
+ DeviceContext->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
+ DeviceContext->LockEnabled = FALSE;
+ DeviceContext->InterfaceNotificationsEnabled = FALSE;
+ DeviceContext->DeviceNotificationsEnabled = FALSE;
- InitializeCriticalSection(&(*Context)->Lock);
+ InitializeCriticalSection(&DeviceContext->Lock);
+ DeviceContext->LockEnabled = TRUE;
- (*Context)->Work = CreateThreadpoolWork(UnregisterWorkerThreadCallback, (PVOID)(*Context), NULL);
+ DeviceContext->Work = CreateThreadpoolWork(UnregisterWorkerThreadCallback, (PVOID)DeviceContext, NULL);
- if ((*Context)->Work == NULL)
+ if (DeviceContext->Work == NULL)
{
- WriteToErrorLog(L"Could not create worker thread callback", ERROR_OUTOFMEMORY);
+ Err = GetLastError();
+ WriteToErrorLog(L"Could not create worker thread callback", Err);
goto cleanup;
}
- (*Context)->DeviceNotificationHandle = NULL;
- (*Context)->InterfaceNotificationHandle = NULL;
+ DeviceContext->DeviceNotificationHandle = NULL;
+ DeviceContext->InterfaceNotificationHandle = NULL;
//
// Register for device interface events to open and close the handle to
// the interface.
//
- Err = RegisterInterfaceNotifications(*Context);
+ Err = RegisterInterfaceNotifications(DeviceContext);
if (Err != ERROR_SUCCESS)
{
@@ -918,27 +920,33 @@ InitializeContext(
goto cleanup;
}
- EnterCriticalSection(&(*Context)->Lock);
+ DeviceContext->InterfaceNotificationsEnabled = TRUE;
+
+ EnterCriticalSection(&DeviceContext->Lock);
+ LockEntered = TRUE;
//
// The interface may already have arrived while registering for
- // notifications.
+ // notifications. The lock could be moved earlier, but for sample
+ // purposes this is the proper way to initialize notifications.
//
- if ((*Context)->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
+ if (DeviceContext->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
{
- (*Context)->DeviceInterfaceHandle = OpenDevice(FALSE);
+ DeviceContext->DeviceInterfaceHandle = OpenDevice(FALSE);
}
- if ((*Context)->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
- {
- Err = RegisterDeviceNotifications(*Context);
+ if (DeviceContext->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
+ {
+ Err = RegisterDeviceNotifications(DeviceContext);
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not register device notifications", Err);
- goto cleanup;
- }
- }
+ 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
@@ -947,7 +955,18 @@ InitializeContext(
cleanup:
- LeaveCriticalSection(&(*Context)->Lock);
+ if (LockEntered)
+ {
+ LeaveCriticalSection(&DeviceContext->Lock);
+ }
+
+ *Context = DeviceContext;
+ DeviceContext = NULL;
+
+ if (DeviceContext != NULL)
+ {
+ CloseContext(DeviceContext);
+ }
return Err;
}
@@ -957,7 +976,7 @@ cleanup:
Routine Description:
- Clean up the given PHANDLE_CONTEXT.
+ Clean up the given PDEVICE_CONTEXT.
Arguments:
@@ -970,80 +989,83 @@ Return Value:
--*/
DWORD
CloseContext(
- _In_ PHANDLE_CONTEXT* Context
+ _In_ PDEVICE_CONTEXT Context
)
{
- DWORD Err = ERROR_SUCCESS;
+ DWORD Err = ERROR_SUCCESS;
BOOL Unregister = FALSE;
- if ((Context == NULL) ||
- (*Context == NULL))
- {
- //
- // Nothing to remove.
- //
- goto cleanup;
- }
+ if (Context == NULL)
+ {
+ //
+ // Nothing to remove.
+ //
+ goto cleanup;
+ }
- EnterCriticalSection(&(*Context)->Lock);
+ EnterCriticalSection(&Context->Lock);
- if (!(*Context)->Unregister)
+ if (!Context->Unregister)
{
//
// Unregister from the callback here.
//
Unregister = TRUE;
- (*Context)->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.
- //
- Err = UnregisterInterfaceNotifications(*Context);
+ LeaveCriticalSection(&Context->Lock);
- if (Err != ERROR_SUCCESS)
+ //
+ // Unregister from the interface first, so that re-appearance of the interface
+ // doesn't cause us to register device events again.
+ //
+ if (Context->InterfaceNotificationsEnabled)
{
- WriteToErrorLog(L"Could not unregister interface notifications", Err);
+ Err = UnregisterInterfaceNotifications(Context);
+
+ if (Err != ERROR_SUCCESS)
+ {
+ WriteToErrorLog(L"Could not unregister interface notifications", Err);
+ }
}
if (Unregister)
{
- Err = UnregisterDeviceNotifications(*Context);
+ if (Context->DeviceNotificationsEnabled)
+ {
+ Err = UnregisterDeviceNotifications(Context);
- if (Err != ERROR_SUCCESS)
- {
- WriteToErrorLog(L"Could not unregister device notifications", Err);
- }
+ if (Err != ERROR_SUCCESS)
+ {
+ WriteToErrorLog(L"Could not unregister device notifications", Err);
+ }
+ }
}
else
{
- WaitForThreadpoolWorkCallbacks((*Context)->Work, FALSE);
+ WaitForThreadpoolWorkCallbacks(Context->Work, FALSE);
}
- //
- // No need to lock here, UnregisterDeviceNotifications will wait for all
- // outstanding callbacks before returning.
- //
- if ((*Context)->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
+ //
+ // No need to lock here, UnregisterDeviceNotifications will wait for all
+ // outstanding callbacks before returning.
+ //
+ if (Context->DeviceInterfaceHandle != INVALID_HANDLE_VALUE)
{
- CloseHandle((*Context)->DeviceInterfaceHandle);
+ CloseHandle(Context->DeviceInterfaceHandle);
- (*Context)->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
+ Context->DeviceInterfaceHandle = INVALID_HANDLE_VALUE;
}
- if ((*Context)->Work != NULL)
+ if (Context->Work != NULL)
{
- CloseThreadpoolWork((*Context)->Work);
+ CloseThreadpoolWork(Context->Work);
}
- DeleteCriticalSection(&(*Context)->Lock);
-
- free(*Context);
+ DeleteCriticalSection(&Context->Lock);
- *Context = NULL;
+ free(Context);
cleanup:
@@ -1067,7 +1089,7 @@ Return Value:
--*/
DWORD
ClearAllBars(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
@@ -1112,7 +1134,7 @@ Return Value:
--*/
DWORD
LightNextBar(
- _In_ PHANDLE_CONTEXT Context
+ _In_ PDEVICE_CONTEXT Context
)
{
DWORD Err = ERROR_SUCCESS;
@@ -1147,4 +1169,49 @@ LightNextBar(
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
index ecdfa4ad..3b8be711 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/Main.h
@@ -50,14 +50,17 @@ DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2,
#pragma warning(disable:4201) // nameless struct/union
#pragma warning(disable:4214) // bit field types other than int
-typedef struct _HANDLE_CONTEXT {
+typedef struct _DEVICE_CONTEXT {
HANDLE DeviceInterfaceHandle;
CRITICAL_SECTION Lock;
+ BOOL LockEnabled;
PTP_WORK Work;
BOOL Unregister;
- HCMNOTIFICATION InterfaceNotificationHandle;
- HCMNOTIFICATION DeviceNotificationHandle;
-} HANDLE_CONTEXT, *PHANDLE_CONTEXT;
+ HCMNOTIFICATION InterfaceNotificationHandle;
+ BOOL InterfaceNotificationsEnabled;
+ HCMNOTIFICATION DeviceNotificationHandle;
+ BOOL DeviceNotificationsEnabled;
+} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
//
// Define the structures that will be used by the IOCTL
@@ -201,73 +204,56 @@ typedef struct _SWITCH_STATE {
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.
+Lights the next bar on the OSRFX2 device.
Arguments:
- Synchronous - Whether or not this device should be
- opened for synchronous access
+Context - The device context
Return Value:
- The handle to the OSR USB FX2 device.
+A Win32 error code.
--*/
-HANDLE OpenDevice(_In_ BOOL Synchronous);
+DWORD
+ControlDevice(PDEVICE_CONTEXT Context);
/*++
Routine Description:
- Turns off all of the bar graph lights on the OSR USB FX2 device.
+ Sets the variables in this service to their default values.
Arguments:
- DeviceHandle - The handle to the OSR USB FX2 device.
+ VOID
Return Value:
VOID
--*/
-DWORD ClearAllBars(PHANDLE_CONTEXT Context);
+VOID SetVariables(VOID);
/*++
Routine Description:
- Lights the next bar on the OSR USB FX2 device.
+ Opens up the OSR USB FX2 device handle.
Arguments:
- DeviceHandle - The handle to the OSR USB FX2 device.
+ Synchronous - Whether or not this device should be
+ opened for synchronous access
Return Value:
-VOID
+ The handle to the OSR USB FX2 device.
--*/
-DWORD LightNextBar(PHANDLE_CONTEXT Context);
+HANDLE OpenDevice(_In_ BOOL Synchronous);
/*++
@@ -285,7 +271,7 @@ Return Value:
A Win32 error code.
--*/
-DWORD RegisterDeviceNotifications(PHANDLE_CONTEXT Context);
+DWORD RegisterDeviceNotifications(PDEVICE_CONTEXT Context);
/*++
@@ -303,14 +289,14 @@ Return Value:
A Win32 error code.
--*/
-DWORD UnregisterDeviceNotifications(PHANDLE_CONTEXT Context);
+DWORD UnregisterDeviceNotifications(PDEVICE_CONTEXT Context);
/*++
Routine Description:
-Initialize the given PHANDLE_CONTEXT.
+Initialize the given PDEVICE_CONTEXT.
Arguments:
@@ -321,14 +307,14 @@ Return Value:
A Win32 error code.
--*/
-DWORD InitializeContext(PHANDLE_CONTEXT* Context);
+DWORD InitializeContext(PDEVICE_CONTEXT* Context);
/*++
Routine Description:
-Clean up the given PHANDLE_CONTEXT.
+Clean up the given PDEVICE_CONTEXT.
Arguments:
@@ -339,4 +325,4 @@ Return Value:
A Win32 error code.
--*/
-DWORD CloseContext(PHANDLE_CONTEXT* Context); \ No newline at end of file
+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
index 5a59319b..fd3d497f 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.cpp
@@ -29,16 +29,6 @@ Environment:
#include "ThreadPool.h"
#pragma endregion
-//
-// 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 as well. So,
-// this variable is global so that the services OnStart and OnStart method can
-// handle its creation and destruction.
-//
-PHANDLE_CONTEXT Context;
-
/*++
Routine Description:
@@ -151,21 +141,23 @@ CSampleService::OnStart(
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 any variables the service needs.
+ //
+ SetVariables();
- //
- // Set up the context, and register for notifications.
- //
- InitializeContext(&Context);
+ //
+ // Set up the context, and register for notifications.
+ //
+ InitializeContext(&m_Context);
//
// Queue the main service function for execution in a worker thread.
@@ -193,8 +185,6 @@ Return Value:
VOID
CSampleService::ServiceWorkerThread()
{
- DWORD Err = ERROR_SUCCESS;
-
//
// Periodically check if the service is stopping.
//
@@ -204,28 +194,7 @@ CSampleService::ServiceWorkerThread()
// Perform main service function here...
//
- //
- // Wait for the device to arrive.
- //
- if (Context->DeviceInterfaceHandle == INVALID_HANDLE_VALUE)
- {
- ::Sleep(2000);
- continue;
- }
-
- Err = ClearAllBars(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- continue;
- }
-
- Err = LightNextBar(Context);
-
- if (Err != ERROR_SUCCESS)
- {
- continue;
- }
+ ControlDevice(m_Context);
::Sleep(2000); // Simulate some lengthy operations.
}
@@ -278,8 +247,8 @@ CSampleService::OnStop()
throw GetLastError();
}
- //
- // Clean up the context after the worker thread has finished.
- //
- CloseContext(&Context);
+ //
+ // 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
index eee8a609..73be42e9 100644
--- a/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h
+++ b/general/DCHU/osrfx2_DCHU_base/osrfx2_DCHU_usersvc/SampleService.h
@@ -171,4 +171,17 @@ private:
// 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