Source code of Windows XP (NT5)
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.

215 lines
4.9 KiB

  1. #include "dtct.h"
  2. #include "regnotif.h"
  3. #include "vol.h"
  4. #include "cmmn.h"
  5. #include <dbt.h>
  6. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  7. HRESULT _ProcessInterfaceDiskGenericArrival(LPCWSTR pszDeviceIntfID,
  8. BOOL )
  9. {
  10. CNamedElemList* pnel;
  11. HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_DISK, &pnel);
  12. if (SUCCEEDED(hr))
  13. {
  14. CNamedElem* pelem;
  15. hr = pnel->GetOrAdd(pszDeviceIntfID, &pelem);
  16. if (SUCCEEDED(hr))
  17. {
  18. pelem->RCRelease();
  19. }
  20. pnel->RCRelease();
  21. }
  22. return hr;
  23. }
  24. HRESULT _ProcessInterfaceVolumeArrival(LPCWSTR pszDeviceIntfID)
  25. {
  26. CNamedElemList* pnel;
  27. HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_VOLUME, &pnel);
  28. if (SUCCEEDED(hr))
  29. {
  30. CNamedElem* pelem;
  31. hr = pnel->GetOrAdd(pszDeviceIntfID, &pelem);
  32. if (SUCCEEDED(hr))
  33. {
  34. // Was it already there, or just added?
  35. if (S_FALSE == hr)
  36. {
  37. // Added
  38. CVolume* pvol = (CVolume*)pelem;
  39. hr = pvol->HandleArrival();
  40. }
  41. pelem->RCRelease();
  42. }
  43. else
  44. {
  45. if (E_FAIL == hr)
  46. {
  47. hr = S_FALSE;
  48. }
  49. }
  50. pnel->RCRelease();
  51. }
  52. return hr;
  53. }
  54. HRESULT _ProcessInterfaceVolumeRemoval(LPCWSTR pszDeviceIntfID)
  55. {
  56. CNamedElemList* pnel;
  57. HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_VOLUME, &pnel);
  58. if (SUCCEEDED(hr))
  59. {
  60. CNamedElem* pelem;
  61. hr = pnel->Get(pszDeviceIntfID, &pelem);
  62. if (SUCCEEDED(hr) && (S_FALSE != hr))
  63. {
  64. CHWDeviceInst* phwdevinst;
  65. CVolume* pvol = (CVolume*)pelem;
  66. pvol->HandleRemoval();
  67. hr = pvol->GetHWDeviceInst(&phwdevinst);
  68. if (SUCCEEDED(hr) && (S_FALSE != hr))
  69. {
  70. hr = _TryAutoplay(pszDeviceIntfID, phwdevinst,
  71. DBT_DEVICEREMOVECOMPLETE);
  72. }
  73. // If we're removing it, let's remove it from the list
  74. HRESULT hr2 = pnel->Remove(pszDeviceIntfID);
  75. hr = FAILED(hr2) ? hr2 : hr;
  76. pelem->RCRelease();
  77. }
  78. pnel->RCRelease();
  79. }
  80. return hr;
  81. }
  82. HRESULT _ProcessInterfaceCDROMArrival(LPCWSTR pszDeviceIntfID)
  83. {
  84. return _ProcessInterfaceDiskGenericArrival(pszDeviceIntfID, TRUE);
  85. }
  86. HRESULT _ProcessInterfaceDiskArrival(LPCWSTR pszDeviceIntfID)
  87. {
  88. return _ProcessInterfaceDiskGenericArrival(pszDeviceIntfID, FALSE);
  89. }
  90. HRESULT _ProcessInterfaceDiskRemoval(LPCWSTR pszDeviceIntfID)
  91. {
  92. CNamedElemList* pnel;
  93. HRESULT hr = CHWEventDetectorHelper::GetList(HWEDLIST_DISK, &pnel);
  94. if (S_OK == hr)
  95. {
  96. hr = pnel->Remove(pszDeviceIntfID);
  97. pnel->RCRelease();
  98. }
  99. return hr;
  100. }
  101. typedef HRESULT (*PROCESSINTERFACESPECIALCASEDFCT)(LPCWSTR pszDeviceIntfID);
  102. struct INTERFACESPECIALCASED
  103. {
  104. const GUID* pguid;
  105. PROCESSINTERFACESPECIALCASEDFCT piscfctArrival;
  106. PROCESSINTERFACESPECIALCASEDFCT piscfctRemoval;
  107. };
  108. const INTERFACESPECIALCASED _rgInterfaceSpecialCased[] =
  109. {
  110. { &guidVolumeClass, _ProcessInterfaceVolumeArrival, _ProcessInterfaceVolumeRemoval, },
  111. { &guidCdRomClass, _ProcessInterfaceCDROMArrival, _ProcessInterfaceDiskRemoval, },
  112. { &guidDiskClass, _ProcessInterfaceDiskArrival, _ProcessInterfaceDiskRemoval, },
  113. };
  114. HRESULT _IsInterfaceSpecialCased(GUID* pguidClass, BOOL* pfSpecialCased)
  115. {
  116. *pfSpecialCased = FALSE;
  117. for (DWORD dw = 0; !(*pfSpecialCased) &&
  118. (dw < ARRAYSIZE(_rgInterfaceSpecialCased)); ++dw)
  119. {
  120. if (*pguidClass == *(_rgInterfaceSpecialCased[dw].pguid))
  121. {
  122. *pfSpecialCased = TRUE;
  123. }
  124. }
  125. return S_OK;
  126. }
  127. HRESULT _ProcessInterfaceSpecialCased(GUID* pguidInterface,
  128. LPCWSTR pszDeviceIntfID, DWORD dwEventType)
  129. {
  130. HRESULT hr;
  131. if ((DBT_DEVICEARRIVAL == dwEventType) ||
  132. (DBT_DEVICEREMOVECOMPLETE == dwEventType))
  133. {
  134. BOOL fExit = FALSE;
  135. hr = E_UNEXPECTED;
  136. for (DWORD dw = 0; !fExit &&
  137. (dw < ARRAYSIZE(_rgInterfaceSpecialCased)); ++dw)
  138. {
  139. if (*pguidInterface == *(_rgInterfaceSpecialCased[dw].pguid))
  140. {
  141. PROCESSINTERFACESPECIALCASEDFCT piscfct;
  142. if (DBT_DEVICEARRIVAL == dwEventType)
  143. {
  144. piscfct = _rgInterfaceSpecialCased[dw].piscfctArrival;
  145. }
  146. else
  147. {
  148. piscfct = _rgInterfaceSpecialCased[dw].piscfctRemoval;
  149. }
  150. fExit = TRUE;
  151. hr = (piscfct)(pszDeviceIntfID);
  152. }
  153. }
  154. if (!fExit)
  155. {
  156. hr = E_UNEXPECTED;
  157. }
  158. }
  159. else
  160. {
  161. // Don't care about others for now
  162. hr = S_FALSE;
  163. }
  164. return hr;
  165. }