the notification handle is NULL and GetLastError returns 0x42A (ERROR_SERVICE_SPECIFIC_ERROR).
the notification handle is NULL and GetLastError returns 0x42A (ERROR_SERVICE_SPECIFIC_ERROR).
So I'm trying to create an empty Window in a DLL and use it to receive device notifications, however, when I try to register for device notifications, the notification handle is NULL and GetLastError returns 0x42A (ERROR_SERVICE_SPECIFIC_ERROR).
#include <dbt.h>
#include <winuser.h>
#include <iostream>
#include <devguid.h>
const TCHAR XMsgCName[] = TEXT("XCallbackC");
const TCHAR XMsgWName[] = TEXT("XCallbackW");
DWORD WINAPI XNotifyListener(LPVOID);
// Almost empty msg handler
LRESULT CALLBACK XMsgDummy(
HWND hnd,
UINT msg,
WPARAM wPar,
LPARAM lPar)
{
if (msg != WM_DEVICECHANGE)
{
return DefWindowProcA(hnd,msg,wPar,lPar);
}
// Todo:
return TRUE;
}
struct XMSGDATA
{
HWND XMsgHnd;
WNDCLASSEX XMsgClass;
HDEVNOTIFY XNotifyHnd;
HANDLE XThrHnd;
DWORD DevTmp;
DEV_BROADCAST_HANDLE DevData;
STORAGE_DEVICE_NUMBER DevInfo;
bool Init()
{
memset(this, 0, sizeof(XMSGDATA));
// Prep and register class
XMsgClass.cbSize = sizeof(WNDCLASSEX);
XMsgClass.lpszClassName = XMsgCName;
XMsgClass.lpfnWndProc = XMsgDummy;
XMsgClass.hInstance = XAPI;
if (RegisterClassEx(&XMsgClass))
{
if (XMsgHnd = CreateWindowEx(
0,
XMsgCName,
XMsgWName,
0,
0,0,0,0,
NULL,
NULL,
XAPI, // Obtained from DllMain
NULL))
{
if (XThrHnd = CreateThread(
NULL,
0,
XNotifyListener,
NULL,
0,
NULL))
{
// Prep notification and register
DevData.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
DevData.dbch_devicetype = DBT_DEVTYP_HANDLE;
DevData.dbch_eventguid = GUID_DEVCLASS_USB;
SetLastError(0);
if (XNotifyHnd = RegisterDeviceNotification(
XMsgHnd,
&DevData,
DEVICE_NOTIFY_WINDOW_HANDLE))
{
return true;
}
// Cleanup
cout << GetLastError() << endl;
if (!TerminateThread(XThrHnd, 0) || !CloseHandle(XThrHnd))
{
return false;
}
XThrHnd = NULL;
}
if (!DestroyWindow(XMsgHnd))
{
return false;
}
XMsgHnd = NULL;
}
if (UnregisterClass(XMsgCName, NULL))
{
XMsgClass.cbSize = 0;
}
}
return false;
}
} *XMsg = NULL;
INLINE BOOL getDevInfo(HANDLE dev)
{
return DeviceIoControl(
dev,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL,
0,
&XMsg->DevInfo,
sizeof(STORAGE_DEVICE_NUMBER),
&XMsg->DevTmp,
NULL);
}
DWORD WINAPI XNotifyListener(LPVOID param)
{
MSG msg;
BOOL res;
while ((res = GetMessage(&msg, XMsg->XMsgHnd, 0, 0)))
{
if (res == -1)
{
// Todo:
}
TranslateMessage(&msg);
if (msg.message == WM_DEVICECHANGE)
{
if (getDevInfo(XMsg->DevData.dbch_handle))
{
// Todo:
}
}
}
return 0;
}
Figured it out, was trying to run the message pump on a separate thread and using wrong method; I placed window creation, device notification (using DEVICENOTIFICATION instead), and message pump on the same thread.