mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
4.9 KiB
216 lines
4.9 KiB
#include "dtct.h"
|
|
|
|
#include "regnotif.h"
|
|
#include "vol.h"
|
|
|
|
#include "cmmn.h"
|
|
|
|
#include <dbt.h>
|
|
|
|
#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;
|
|
}
|