#include "dtct.h" #include "regnotif.h" #include "vol.h" #include "cmmn.h" #include #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0])) HRESULT _ProcessInterfaceDiskGenericArrival(LPCWSTR pszDeviceIntfID, BOOL ) { CNamedElemList* pnel; HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_DISK, &pnel); if (SUCCEEDED(hr)) { CNamedElem* pelem; hr = pnel->GetOrAdd(pszDeviceIntfID, &pelem); if (SUCCEEDED(hr)) { pelem->RCRelease(); } pnel->RCRelease(); } return hr; } HRESULT _ProcessInterfaceVolumeArrival(LPCWSTR pszDeviceIntfID) { CNamedElemList* pnel; HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_VOLUME, &pnel); if (SUCCEEDED(hr)) { CNamedElem* pelem; hr = pnel->GetOrAdd(pszDeviceIntfID, &pelem); if (SUCCEEDED(hr)) { // Was it already there, or just added? if (S_FALSE == hr) { // Added CVolume* pvol = (CVolume*)pelem; hr = pvol->HandleArrival(); } pelem->RCRelease(); } else { if (E_FAIL == hr) { hr = S_FALSE; } } pnel->RCRelease(); } return hr; } HRESULT _ProcessInterfaceVolumeRemoval(LPCWSTR pszDeviceIntfID) { CNamedElemList* pnel; HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_VOLUME, &pnel); if (SUCCEEDED(hr)) { CNamedElem* pelem; hr = pnel->Get(pszDeviceIntfID, &pelem); if (SUCCEEDED(hr) && (S_FALSE != hr)) { CHWDeviceInst* phwdevinst; CVolume* pvol = (CVolume*)pelem; pvol->HandleRemoval(); hr = pvol->GetHWDeviceInst(&phwdevinst); if (SUCCEEDED(hr) && (S_FALSE != hr)) { hr = _TryAutoplay(pszDeviceIntfID, phwdevinst, DBT_DEVICEREMOVECOMPLETE); } // If we're removing it, let's remove it from the list HRESULT hr2 = pnel->Remove(pszDeviceIntfID); hr = FAILED(hr2) ? hr2 : hr; pelem->RCRelease(); } pnel->RCRelease(); } return hr; } HRESULT _ProcessInterfaceCDROMArrival(LPCWSTR pszDeviceIntfID) { return _ProcessInterfaceDiskGenericArrival(pszDeviceIntfID, TRUE); } HRESULT _ProcessInterfaceDiskArrival(LPCWSTR pszDeviceIntfID) { return _ProcessInterfaceDiskGenericArrival(pszDeviceIntfID, FALSE); } HRESULT _ProcessInterfaceDiskRemoval(LPCWSTR pszDeviceIntfID) { CNamedElemList* pnel; HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_DISK, &pnel); if (S_OK == hr) { hr = pnel->Remove(pszDeviceIntfID); pnel->RCRelease(); } return hr; } typedef HRESULT (*PROCESSINTERFACESPECIALCASEDFCT)(LPCWSTR pszDeviceIntfID); struct INTERFACESPECIALCASED { const GUID* pguid; PROCESSINTERFACESPECIALCASEDFCT piscfctArrival; PROCESSINTERFACESPECIALCASEDFCT piscfctRemoval; }; const INTERFACESPECIALCASED _rgInterfaceSpecialCased[] = { { &guidVolumeClass, _ProcessInterfaceVolumeArrival, _ProcessInterfaceVolumeRemoval, }, { &guidCdRomClass, _ProcessInterfaceCDROMArrival, _ProcessInterfaceDiskRemoval, }, { &guidDiskClass, _ProcessInterfaceDiskArrival, _ProcessInterfaceDiskRemoval, }, }; HRESULT _IsInterfaceSpecialCased(GUID* pguidClass, BOOL* pfSpecialCased) { *pfSpecialCased = FALSE; for (DWORD dw = 0; !(*pfSpecialCased) && (dw < ARRAYSIZE(_rgInterfaceSpecialCased)); ++dw) { if (*pguidClass == *(_rgInterfaceSpecialCased[dw].pguid)) { *pfSpecialCased = TRUE; } } return S_OK; } HRESULT _ProcessInterfaceSpecialCased(GUID* pguidInterface, LPCWSTR pszDeviceIntfID, DWORD dwEventType) { HRESULT hr; if ((DBT_DEVICEARRIVAL == dwEventType) || (DBT_DEVICEREMOVECOMPLETE == dwEventType)) { BOOL fExit = FALSE; hr = E_UNEXPECTED; for (DWORD dw = 0; !fExit && (dw < ARRAYSIZE(_rgInterfaceSpecialCased)); ++dw) { if (*pguidInterface == *(_rgInterfaceSpecialCased[dw].pguid)) { PROCESSINTERFACESPECIALCASEDFCT piscfct; if (DBT_DEVICEARRIVAL == dwEventType) { piscfct = _rgInterfaceSpecialCased[dw].piscfctArrival; } else { piscfct = _rgInterfaceSpecialCased[dw].piscfctRemoval; } fExit = TRUE; hr = (piscfct)(pszDeviceIntfID); } } if (!fExit) { hr = E_UNEXPECTED; } } else { // Don't care about others for now hr = S_FALSE; } return hr; }