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.

223 lines
4.2 KiB

  1. #include "drvbase.h"
  2. #include "cmmn.h"
  3. #include <dbt.h>
  4. HRESULT CDisk::Init(LPCWSTR pszElemName)
  5. {
  6. HRESULT hr = _SetName(pszElemName);
  7. return hr;
  8. }
  9. HRESULT CDisk::GetDeviceNumber(ULONG* puldeviceNumber)
  10. {
  11. HRESULT hr = _Init();
  12. if (SUCCEEDED(hr))
  13. {
  14. if (((DEVICE_TYPE)-1) != _devtype)
  15. {
  16. *puldeviceNumber = _ulDeviceNumber;
  17. hr = S_OK;
  18. }
  19. else
  20. {
  21. hr = S_FALSE;
  22. }
  23. }
  24. else
  25. {
  26. hr = S_FALSE;
  27. }
  28. return hr;
  29. }
  30. HRESULT CDisk::GetDeviceType(DEVICE_TYPE* pdevtype)
  31. {
  32. HRESULT hr = _Init();
  33. if (SUCCEEDED(hr))
  34. {
  35. if (((DEVICE_TYPE)-1) != _devtype)
  36. {
  37. *pdevtype = _devtype;
  38. hr = S_OK;
  39. }
  40. else
  41. {
  42. hr = S_FALSE;
  43. }
  44. }
  45. else
  46. {
  47. hr = S_FALSE;
  48. }
  49. return hr;
  50. }
  51. HRESULT _GetDeviceNumberInfo(LPCWSTR pszDeviceID, DEVICE_TYPE* pdevtype,
  52. ULONG* pulDeviceNumber, ULONG* pulPartitionNumber)
  53. {
  54. HRESULT hr;
  55. HANDLE hDevice = _GetDeviceHandle(pszDeviceID, FILE_READ_ATTRIBUTES);
  56. if (INVALID_HANDLE_VALUE != hDevice)
  57. {
  58. HDEVNOTIFY hdevnotify;
  59. DEV_BROADCAST_HANDLE dbhNotifFilter = {0};
  60. BOOL fRegistered = FALSE;
  61. dbhNotifFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
  62. dbhNotifFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  63. dbhNotifFilter.dbch_handle = hDevice;
  64. hr = CHWEventDetectorHelper::RegisterDeviceNotification(
  65. &dbhNotifFilter, &hdevnotify, FALSE);
  66. if (SUCCEEDED(hr))
  67. {
  68. fRegistered = TRUE;
  69. hr = _GetDeviceNumberInfoFromHandle(hDevice, pdevtype,
  70. pulDeviceNumber, pulPartitionNumber);
  71. }
  72. _CloseDeviceHandle(hDevice);
  73. if (fRegistered)
  74. {
  75. UnregisterDeviceNotification(hdevnotify);
  76. }
  77. }
  78. else
  79. {
  80. hr = S_FALSE;
  81. }
  82. return hr;
  83. }
  84. HRESULT CDisk::_Init()
  85. {
  86. HRESULT hr = S_OK;
  87. if (!_fDeviceNumberInited)
  88. {
  89. hr = _GetDeviceNumberInfo(_pszElemName, &_devtype, &_ulDeviceNumber,
  90. &_ulPartitionNumber);
  91. _fDeviceNumberInited = TRUE;
  92. }
  93. return hr;
  94. }
  95. CDisk::CDisk() : _devtype((DEVICE_TYPE)-1),
  96. _ulDeviceNumber((ULONG)-1), _ulPartitionNumber((ULONG)-1),
  97. _fDeviceNumberInited(FALSE)
  98. {}
  99. ///////////////////////////////////////////////////////////////////////////////
  100. ///////////////////////////////////////////////////////////////////////////////
  101. // static
  102. HRESULT CDisk::Create(CNamedElem** ppelem)
  103. {
  104. HRESULT hr = S_OK;
  105. *ppelem = new CDisk();
  106. if (!(*ppelem))
  107. {
  108. hr = E_OUTOFMEMORY;
  109. }
  110. return hr;
  111. }
  112. class CDiskFillEnum : public CFillEnum
  113. {
  114. public:
  115. HRESULT _Init();
  116. HRESULT Next(LPTSTR pszElemName, DWORD cchElemName, DWORD* pcchRequired);
  117. private:
  118. CIntfFillEnum _intffillenumDisk;
  119. CIntfFillEnum _intffillenumCDROM;
  120. BOOL _fDiskDone;
  121. };
  122. //static
  123. HRESULT CDisk::GetFillEnum(CFillEnum** ppfillenum)
  124. {
  125. HRESULT hres;
  126. CDiskFillEnum* pfillenum = new CDiskFillEnum();
  127. if (pfillenum)
  128. {
  129. hres = pfillenum->_Init();
  130. if (FAILED(hres))
  131. {
  132. delete pfillenum;
  133. pfillenum = NULL;
  134. }
  135. }
  136. else
  137. {
  138. hres = E_OUTOFMEMORY;
  139. }
  140. *ppfillenum = pfillenum;
  141. return hres;
  142. }
  143. HRESULT CDiskFillEnum::_Init()
  144. {
  145. _fDiskDone = FALSE;
  146. return _intffillenumDisk._Init(&guidDiskClass, NULL);
  147. }
  148. HRESULT CDiskFillEnum::Next(LPTSTR pszElemName, DWORD cchElemName,
  149. DWORD* pcchRequired)
  150. {
  151. HRESULT hr;
  152. BOOL fDoCDROM = FALSE;
  153. if (!_fDiskDone)
  154. {
  155. hr = _intffillenumDisk.Next(pszElemName, cchElemName,
  156. pcchRequired);
  157. if (S_FALSE == hr)
  158. {
  159. hr = _intffillenumCDROM._Init(&guidCdRomClass, NULL);
  160. _fDiskDone = TRUE;
  161. if (SUCCEEDED(hr))
  162. {
  163. fDoCDROM = TRUE;
  164. }
  165. }
  166. }
  167. else
  168. {
  169. fDoCDROM = TRUE;
  170. hr = S_OK;
  171. }
  172. if (fDoCDROM)
  173. {
  174. hr = _intffillenumCDROM.Next(pszElemName, cchElemName,
  175. pcchRequired);
  176. }
  177. return hr;
  178. }