|
|
#include "dfpnp.h"
#include <stdio.h>
#include <winuser.h>
#include <tchar.h>
#include <initguid.h>
#include <ioevent.h>
#include <winioctl.h>
#include "cfgmgr32.h"
#include "setupapi.h"
#include "dbt.h"
#include "dfstpdi.h"
#include "drvfull.h"
#include "dfhlprs.h"
#define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
static HDEVNOTIFY g_hdevnotify = NULL;
static DWORD g_cchIndent = 0; static DWORD g_dwFlags[MAX_FLAGS] = {0}; static DWORD g_dwEvent = 0;
static GUID g_guidVolume = {0x53f5630d, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
static GUID g_guidUSB = {0x36fc9e60, 0xc465, 0x11cf, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
static GUID g_guidIntfClass = {0x53f5630d, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
static GUID g_guid1 = {0x7373654aL, 0x812a, 0x11d0, {0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f}}; static GUID g_guid2 = {0xd16a55e8L, 0x1059, 0x11d2, {0x8f, 0xfd, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid3 = {0xe3c5b178L, 0x105d, 0x11d2, {0x8f, 0xfd, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid4 = {0xb5804878L, 0x1a96, 0x11d2, {0x8f, 0xfd, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid5 = {0x50708874L, 0xc9af, 0x11d1, {0x8f, 0xef, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid6 = {0xae2eed10L, 0x0ba8, 0x11d2, {0x8f, 0xfb, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid7 = {0x9a8c3d68L, 0xd0cb, 0x11d1, {0x8f, 0xef, 0x00, 0xa0, 0xc9, 0xa0, 0x6d, 0x32}}; static GUID g_guid8 = {0x2de97f83, 0x4c06, 0x11d2, {0xa5, 0x32, 0x0, 0x60, 0x97, 0x13, 0x5, 0x5a}}; static GUID g_guid9 = {0x2de97f84, 0x4c06, 0x11d2, {0xa5, 0x32, 0x0, 0x60, 0x97, 0x13, 0x5, 0x5a}}; static GUID g_guid10 = {0x53f5630d, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}}; static GUID g_guid11 = {0xd07433c0, 0xa98e, 0x11d2, {0x91, 0x7a, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}}; static GUID g_guid12 = {0xd07433c1, 0xa98e, 0x11d2, {0x91, 0x7a, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}}; static GUID g_guid13 = {0xd0744792, 0xa98e, 0x11d2, {0x91, 0x7a, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}};
_sGUID_DESCR _rgintfguidGD2[] = { GUID_DESCR(&g_guid1, TEXT("GUID_IO_VOLUME_CHANGE")), GUID_DESCR(&g_guid2, TEXT("GUID_IO_VOLUME_DISMOUNT")), GUID_DESCR(&g_guid3, TEXT("GUID_IO_VOLUME_DISMOUNT_FAILED")), GUID_DESCR(&g_guid4, TEXT("GUID_IO_VOLUME_MOUNT")), GUID_DESCR(&g_guid5, TEXT("GUID_IO_VOLUME_LOCK")), GUID_DESCR(&g_guid6, TEXT("GUID_IO_VOLUME_LOCK_FAILED")), GUID_DESCR(&g_guid7, TEXT("GUID_IO_VOLUME_UNLOCK")), GUID_DESCR(&g_guid8, TEXT("GUID_IO_VOLUME_NAME_CHANGE")), GUID_DESCR(&g_guid9, TEXT("GUID_IO_VOLUME_PHYSICAL_CONFIGURATION_CHANGE")), GUID_DESCR(&g_guid10, TEXT("GUID_IO_VOLUME_DEVICE_INTERFACE")), GUID_DESCR(&g_guid11, TEXT("GUID_IO_MEDIA_ARRIVAL")), GUID_DESCR(&g_guid12, TEXT("GUID_IO_MEDIA_REMOVAL")), GUID_DESCR(&g_guid13, TEXT("GUID_DEVICE_EVENT_RBC")), };
LRESULT _FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT _Cleanup(DWORD dwFlags[]) { if (g_hdevnotify) { UnregisterDeviceNotification(g_hdevnotify); }
if (_IsFlagSet(PNP_WATCHSETUPDI, dwFlags)) { _CleanupSetupDI(); }
return S_OK; }
HRESULT _InitNotif(DWORD dwFlags[], HWND hwnd, LPTSTR pszArg, DWORD cchIndent) { HRESULT hres = S_OK;
if (_IsFlagSet(PNP_WATCHSETUPDI, dwFlags)) { DEV_BROADCAST_DEVICEINTERFACE dbdNotifFilter = {0};
// Now register to begin receiving notifications for the comings
// and goings of device interfaces which are members of the
// interface class whose GUID was passed in as the lParam to this
// dialog procedure.
dbdNotifFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); dbdNotifFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
CopyMemory(&(dbdNotifFilter.dbcc_classguid), &g_guidIntfClass, sizeof(g_guidIntfClass));
g_hdevnotify = RegisterDeviceNotification(hwnd, &dbdNotifFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (g_hdevnotify) { if (_IsFlagSet(PNP_WATCHSETUPDI, dwFlags)) { hres = _InitNotifSetupDI(dwFlags, cchIndent);
if (FAILED(hres)) { _Cleanup(dwFlags); } } else { hres = E_NOTIMPL; } } else { _PrintIndent(cchIndent); _tprintf(TEXT("RegisterDeviceNotification failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; } } else { if (_IsFlagSet(PNP_HANDLE, dwFlags)) { HANDLE hVol = CreateFile( pszArg, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE != hVol) { DEV_BROADCAST_HANDLE dbhNotifFilter = {0}; dbhNotifFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); dbhNotifFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; dbhNotifFilter.dbch_handle = hVol;
g_hdevnotify = RegisterDeviceNotification(hwnd, &dbhNotifFilter, DEVICE_NOTIFY_WINDOW_HANDLE); if (g_hdevnotify) { _PrintIndent(cchIndent); _tprintf(TEXT("RegisterDeviceNotification SUCCEEDED: %s -> 0x%08X\n"), pszArg, g_hdevnotify); } else { _PrintIndent(cchIndent); _tprintf(TEXT("RegisterDeviceNotification failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; }
CloseHandle(hVol); } else { _PrintIndent(cchIndent); _tprintf(TEXT("Cannot open volume\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; } } else { if (_IsFlagSet(PNP_EJECTBUTTON, dwFlags)) { HANDLE hVol = CreateFile( pszArg, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE != hVol) { DWORD dwDummy; PREVENT_MEDIA_REMOVAL pmr = {0};
pmr.PreventMediaRemoval = TRUE; BOOL f = DeviceIoControl(hVol, IOCTL_STORAGE_MEDIA_REMOVAL, // dwIoControlCode operation to perform
&pmr, // lpInBuffer; must be NULL
sizeof(pmr), // nInBufferSize; must be zero
NULL, // pointer to output buffer
0, // size of output buffer
&dwDummy, // receives number of bytes returned
NULL);
if (f) { // Register for notification
DEV_BROADCAST_HANDLE dbhNotifFilter = {0}; dbhNotifFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); dbhNotifFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; dbhNotifFilter.dbch_handle = hVol;
g_hdevnotify = RegisterDeviceNotification(hwnd, &dbhNotifFilter, DEVICE_NOTIFY_WINDOW_HANDLE); if (g_hdevnotify) { _PrintIndent(cchIndent); _tprintf(TEXT("RegisterDeviceNotification SUCCEEDED: %s -> 0x%08X\n"), pszArg, g_hdevnotify); } else { _PrintIndent(cchIndent); _tprintf(TEXT("RegisterDeviceNotification failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; } } else { _PrintIndent(cchIndent); _tprintf(TEXT("Could not lock the volume, GLE = 0x%08X\n"), GetLastError()); }
CloseHandle(hVol); } else { _PrintIndent(cchIndent); _tprintf(TEXT("Cannot open volume\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; } } } }
///////////////////////////////////////////////////////////////////////////
//
return hres; }
_sFLAG_DESCR _dbtdevtypeFD[] = { FLAG_DESCR(DBT_DEVTYP_OEM), FLAG_DESCR(DBT_DEVTYP_DEVNODE), FLAG_DESCR(DBT_DEVTYP_VOLUME), FLAG_DESCR(DBT_DEVTYP_PORT), FLAG_DESCR(DBT_DEVTYP_NET), FLAG_DESCR(DBT_DEVTYP_DEVICEINTERFACE), FLAG_DESCR(DBT_DEVTYP_HANDLE), };
_sFLAG_DESCR _dbteventFD[] = { FLAG_DESCR(DBT_APPYBEGIN), FLAG_DESCR(DBT_APPYEND), FLAG_DESCR(DBT_DEVNODES_CHANGED), FLAG_DESCR(DBT_QUERYCHANGECONFIG), FLAG_DESCR(DBT_CONFIGCHANGED), FLAG_DESCR(DBT_CONFIGCHANGECANCELED), FLAG_DESCR(DBT_MONITORCHANGE), FLAG_DESCR(DBT_SHELLLOGGEDON), FLAG_DESCR(DBT_CONFIGMGAPI32), FLAG_DESCR(DBT_VXDINITCOMPLETE), FLAG_DESCR(DBT_VOLLOCKQUERYLOCK), FLAG_DESCR(DBT_VOLLOCKLOCKTAKEN), FLAG_DESCR(DBT_VOLLOCKLOCKFAILED), FLAG_DESCR(DBT_VOLLOCKQUERYUNLOCK), FLAG_DESCR(DBT_VOLLOCKLOCKRELEASED), FLAG_DESCR(DBT_VOLLOCKUNLOCKFAILED), FLAG_DESCR(DBT_NO_DISK_SPACE), FLAG_DESCR(DBT_LOW_DISK_SPACE), FLAG_DESCR(DBT_CONFIGMGPRIVATE), FLAG_DESCR(DBT_DEVICEARRIVAL), FLAG_DESCR(DBT_DEVICEQUERYREMOVE), FLAG_DESCR(DBT_DEVICEQUERYREMOVEFAILED), FLAG_DESCR(DBT_DEVICEREMOVEPENDING), FLAG_DESCR(DBT_DEVICEREMOVECOMPLETE), FLAG_DESCR(DBT_DEVICETYPESPECIFIC), FLAG_DESCR(DBT_CUSTOMEVENT), FLAG_DESCR(DBT_DEVTYP_OEM), FLAG_DESCR(DBT_DEVTYP_DEVNODE), FLAG_DESCR(DBT_DEVTYP_VOLUME), FLAG_DESCR(DBT_DEVTYP_PORT), FLAG_DESCR(DBT_DEVTYP_NET), FLAG_DESCR(DBT_DEVTYP_DEVICEINTERFACE), FLAG_DESCR(DBT_DEVTYP_HANDLE), FLAG_DESCR(DBT_VPOWERDAPI), FLAG_DESCR(DBT_USERDEFINED), };
HRESULT _HandleNotif(DWORD dwFlags[], DWORD cchIndent, WPARAM wParam, LPARAM lParam) { HRESULT hres = E_NOTIMPL;
if (_IsFlagSet(PNP_WATCHSETUPDI, dwFlags)) { hres = _HandleNotifSetupDI(dwFlags, cchIndent, wParam, lParam); }
return hres; }
_sGUID_DESCR _rgintfguidGD[] = { GUID_DESCR(&g_guidVolume, TEXT("Volume Device")), };
LRESULT _FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes; BOOL fProcessed = FALSE;
switch (uMsg) { case WM_DEVICECHANGE: fProcessed = TRUE;
_PrintIndent(g_cchIndent + 2); _tprintf(TEXT("Received WM_DEVICECHANGE:\n")); _PrintIndent(g_cchIndent + 4); _tprintf(TEXT("wParam: "));
_PrintFlag((DWORD) wParam, _dbteventFD, ARRAYSIZE(_dbteventFD), 0, TRUE, TRUE, FALSE, FALSE); _PrintCR();
_PrintIndent(g_cchIndent + 4); _tprintf(TEXT("lParam: ")); if (lParam) { _PrintFlag((((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype), _dbtdevtypeFD, ARRAYSIZE(_dbtdevtypeFD), 0, TRUE, TRUE, FALSE, FALSE); _PrintCR();
_PrintIndent(g_cchIndent + 6); _tprintf(TEXT("dbch_size: %u"), (((DEV_BROADCAST_HDR*)lParam)->dbch_size)); _PrintCR();
if (DBT_DEVTYP_DEVICEINTERFACE == ((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype) { _PrintIndent(g_cchIndent + 6); _tprintf(TEXT("Interface: "));
_PrintGUIDEx(&(((DEV_BROADCAST_DEVICEINTERFACE*)lParam)->dbcc_classguid), _rgintfguidGD, ARRAYSIZE(_rgintfguidGD), TRUE, 0); } else { if (DBT_DEVTYP_HANDLE == ((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype) { _PrintIndent(g_cchIndent + 6); _tprintf(TEXT("dbch_hdevnotify: 0x%08X\n"), ((DEV_BROADCAST_HANDLE*)lParam)->dbch_hdevnotify);
_PrintIndent(g_cchIndent + 6); _tprintf(TEXT("Handle notif: "));
_PrintGUIDEx(&(((DEV_BROADCAST_HANDLE*)lParam)->dbch_eventguid), _rgintfguidGD2, ARRAYSIZE(_rgintfguidGD2), TRUE, 0); } }
_HandleNotif(g_dwFlags, g_cchIndent + 4, wParam, lParam); } else { _tprintf(TEXT("NULL\n")); }
lRes = TRUE; ++g_dwEvent; _PrintCR(); _PrintIndent(g_cchIndent); _tprintf(TEXT("== (%d) Waiting for events ======================================\n"), g_dwEvent);
break;
case WM_DESTROY:
_Cleanup(g_dwFlags); fProcessed = FALSE; break;
default:
fProcessed = FALSE; break;
}
if (!fProcessed) { lRes = DefWindowProc(hWnd, uMsg, wParam, lParam); }
return lRes; }
HRESULT _ProcessPNP(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent) { HRESULT hres = E_FAIL; WNDCLASSEX wndclass; HINSTANCE hinst = GetModuleHandle(NULL);
g_cchIndent = cchIndent;
for (DWORD dw = 0; dw < MAX_FLAGS; ++dw) { g_dwFlags[dw] = dwFlags[dw]; }
if (hinst) { wndclass.cbSize = sizeof(wndclass); wndclass.style = NULL; wndclass.lpfnWndProc = _FakeWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hinst; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT("FakeWnd"); wndclass.hIconSm = NULL;
if (RegisterClassEx(&wndclass)) { HWND hwnd = CreateWindow(TEXT("FakeWnd"), TEXT("FakeWnd"), WS_POPUPWINDOW, 0, 0, 100, 200, NULL, NULL, hinst, NULL);
if (hwnd) { hres = _InitNotif(dwFlags, hwnd, pszArg, cchIndent);
if (SUCCEEDED(hres)) { MSG msg;
_PrintCR(); _PrintIndent(cchIndent); _tprintf(TEXT("== (%d) Waiting for events ======================================\n"), g_dwEvent);
while (GetMessage(&msg, NULL, 0, 0)) { DispatchMessage(&msg) ; } } } } }
return hres; }
///////////////////////////////////////////////////////////////////////////////
//
/*Volume {53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
Mounted device {53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
in \NT\public\sdk\inc\mountmgr.h:
//
// Devices that wish to be mounted should report this GUID in
// IoRegisterDeviceInterface.
//
DEFINE_GUID(MOUNTDEV_MOUNTED_DEVICE_GUID, 0x53f5630d, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
*/
|