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.

Copyright © 2007-2012 www.chuibin.com Chuibin Copyright