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.

304 lines
8.5 KiB

  1. #include "setenum.h"
  2. #include "dtctreg.h"
  3. #include "cmmn.h"
  4. #include "misc.h"
  5. #include "reg.h"
  6. #include "sfstr.h"
  7. #include "tfids.h"
  8. #include "dbg.h"
  9. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  10. STDMETHODIMP CEnumAutoplayHandlerImpl::Next(LPWSTR* ppszHandler,
  11. LPWSTR* ppszAction, LPWSTR* ppszProvider, LPWSTR* ppszIconLocation)
  12. {
  13. HRESULT hr;
  14. *ppszHandler = NULL;
  15. *ppszAction = NULL;
  16. *ppszProvider = NULL;
  17. *ppszIconLocation = NULL;
  18. if (!_fTakeNoActionDone)
  19. {
  20. LPCWSTR pszHandler = TEXT("MSTakeNoAction");
  21. WCHAR szAction[MAX_ACTION];
  22. WCHAR szProvider[MAX_PROVIDER];
  23. WCHAR szIconLocation[MAX_ICONLOCATION];
  24. if (_rghkiHandlers)
  25. {
  26. if (_dwIndex < _cHandlers)
  27. {
  28. pszHandler = _rghkiHandlers[_dwIndex].szHandler;
  29. }
  30. else
  31. {
  32. _fTakeNoActionDone = TRUE;
  33. }
  34. }
  35. else
  36. {
  37. _fTakeNoActionDone = TRUE;
  38. }
  39. hr = _GetActionFromHandler(pszHandler, szAction, ARRAYSIZE(szAction));
  40. if (SUCCEEDED(hr))
  41. {
  42. hr = _GetIconLocationFromHandler(pszHandler, szIconLocation,
  43. ARRAYSIZE(szIconLocation));
  44. if (SUCCEEDED(hr))
  45. {
  46. hr = _GetProviderFromHandler(pszHandler, szProvider,
  47. ARRAYSIZE(szProvider));
  48. if (SUCCEEDED(hr))
  49. {
  50. hr = _CoTaskMemCopy(pszHandler, ppszHandler);
  51. if (SUCCEEDED(hr))
  52. {
  53. hr = _CoTaskMemCopy(szAction,
  54. ppszAction);
  55. if (SUCCEEDED(hr))
  56. {
  57. hr = _CoTaskMemCopy(szIconLocation,
  58. ppszIconLocation);
  59. if (SUCCEEDED(hr))
  60. {
  61. hr = _CoTaskMemCopy(szProvider,
  62. ppszProvider);
  63. }
  64. }
  65. }
  66. }
  67. }
  68. }
  69. if (FAILED(hr))
  70. {
  71. if (*ppszHandler)
  72. {
  73. CoTaskMemFree((PVOID)*ppszHandler);
  74. *ppszHandler = NULL;
  75. }
  76. if (*ppszAction)
  77. {
  78. CoTaskMemFree((PVOID)*ppszAction);
  79. *ppszAction = NULL;
  80. }
  81. if (*ppszProvider)
  82. {
  83. CoTaskMemFree((PVOID)*ppszProvider);
  84. *ppszProvider = NULL;
  85. }
  86. if (*ppszIconLocation)
  87. {
  88. CoTaskMemFree((PVOID)*ppszIconLocation);
  89. *ppszIconLocation = NULL;
  90. }
  91. }
  92. }
  93. else
  94. {
  95. hr = S_FALSE;
  96. }
  97. ++_dwIndex;
  98. return hr;
  99. }
  100. HRESULT _GetKeyLastWriteTime(LPCWSTR pszHandler, FILETIME* pft)
  101. {
  102. WCHAR szKeyName[MAX_KEY] = SHDEVICEEVENTROOT(TEXT("Handlers\\"));
  103. HRESULT hr = SafeStrCatN(szKeyName, pszHandler, ARRAYSIZE(szKeyName));
  104. if (SUCCEEDED(hr))
  105. {
  106. HKEY hkey;
  107. hr = _RegOpenKey(HKEY_LOCAL_MACHINE, szKeyName, &hkey);
  108. if (SUCCEEDED(hr) && (S_FALSE != hr))
  109. {
  110. if (ERROR_SUCCESS != RegQueryInfoKey(hkey,
  111. NULL, // class buffer
  112. 0, // size of class buffer
  113. NULL, // reserved
  114. NULL, // number of subkeys
  115. NULL, // longest subkey name
  116. NULL, // longest class string
  117. NULL, // number of value entries
  118. NULL, // longest value name
  119. NULL, // longest value data
  120. NULL, // descriptor length
  121. pft // last write time
  122. ))
  123. {
  124. // Bad. Set it to right now
  125. GetSystemTimeAsFileTime(pft);
  126. }
  127. hr = S_OK;
  128. _RegCloseKey(hkey);
  129. }
  130. }
  131. return hr;
  132. }
  133. HRESULT CEnumAutoplayHandlerImpl::_Init(LPWSTR pszEventHandler)
  134. {
  135. WCHAR szKeyName[MAX_KEY] = SHDEVICEEVENTROOT(TEXT("EventHandlers\\"));
  136. HRESULT hr = SafeStrCatN(szKeyName, pszEventHandler,
  137. ARRAYSIZE(szKeyName));
  138. if (SUCCEEDED(hr))
  139. {
  140. HKEY hkey;
  141. hr = _RegOpenKey(HKEY_LOCAL_MACHINE, szKeyName, &hkey);
  142. if (SUCCEEDED(hr) && (S_FALSE != hr))
  143. {
  144. if (ERROR_SUCCESS == RegQueryInfoKey(hkey,
  145. NULL, // class buffer
  146. 0, // size of class buffer
  147. NULL, // reserved
  148. NULL, // number of subkeys
  149. NULL, // longest subkey name
  150. NULL, // longest class string
  151. &_cHandlers, // number of value entries
  152. NULL, // longest value name
  153. NULL, // longest value data
  154. NULL, // descriptor length
  155. NULL // last write time
  156. ))
  157. {
  158. hr = _AllocMemoryChunk<_HANDLERKEYINFO*>(_cHandlers *
  159. sizeof(_HANDLERKEYINFO), &_rghkiHandlers);
  160. if (SUCCEEDED(hr))
  161. {
  162. for (DWORD dw = 0; SUCCEEDED(hr) && (dw < _cHandlers); ++dw)
  163. {
  164. hr = _RegEnumStringValue(hkey, dw, _rghkiHandlers[dw].szHandler,
  165. ARRAYSIZE(_rghkiHandlers[dw].szHandler));
  166. if (SUCCEEDED(hr))
  167. {
  168. if (S_FALSE != hr)
  169. {
  170. hr = _GetKeyLastWriteTime(
  171. _rghkiHandlers[dw].szHandler,
  172. &(_rghkiHandlers[dw].ftLastWriteTime));
  173. }
  174. else
  175. {
  176. // There's less then there was when we queried for it...
  177. _cHandlers = dw;
  178. break;
  179. }
  180. }
  181. }
  182. if (SUCCEEDED(hr))
  183. {
  184. // We don't care if this fails
  185. _SortHandlers();
  186. }
  187. else
  188. {
  189. _FreeMemoryChunk<_HANDLERKEYINFO*>(_rghkiHandlers);
  190. _rghkiHandlers = NULL;
  191. _cHandlers = 0;
  192. }
  193. }
  194. else
  195. {
  196. _cHandlers = 0;
  197. }
  198. }
  199. else
  200. {
  201. hr = S_FALSE;
  202. }
  203. _RegCloseKey(hkey);
  204. }
  205. }
  206. return hr;
  207. }
  208. HRESULT CEnumAutoplayHandlerImpl::_SwapHandlerKeyInfo(DWORD dwLeft,
  209. DWORD dwRight)
  210. {
  211. _HANDLERKEYINFO hkiTmp = _rghkiHandlers[dwLeft];
  212. _rghkiHandlers[dwLeft] = _rghkiHandlers[dwRight];
  213. _rghkiHandlers[dwRight] = hkiTmp;
  214. return S_OK;
  215. }
  216. HRESULT CEnumAutoplayHandlerImpl::_SortHandlers()
  217. {
  218. HRESULT hr;
  219. if (_rghkiHandlers)
  220. {
  221. hr = S_OK;
  222. for (DWORD dwOuter = 0; dwOuter < _cHandlers; ++dwOuter)
  223. {
  224. _HANDLERKEYINFO* phkiOuter = &(_rghkiHandlers[dwOuter]);
  225. ULARGE_INTEGER ulOuter;
  226. ulOuter.LowPart = phkiOuter->ftLastWriteTime.dwLowDateTime;
  227. ulOuter.HighPart = phkiOuter->ftLastWriteTime.dwHighDateTime;
  228. for (DWORD dwInner = dwOuter + 1; dwInner < _cHandlers; ++dwInner)
  229. {
  230. _HANDLERKEYINFO* phkiInner = &(_rghkiHandlers[dwInner]);
  231. ULARGE_INTEGER ulInner;
  232. ulInner.LowPart = phkiInner->ftLastWriteTime.dwLowDateTime;
  233. ulInner.HighPart = phkiInner->ftLastWriteTime.dwHighDateTime;
  234. if (ulOuter.QuadPart > ulInner.QuadPart)
  235. {
  236. hr = _SwapHandlerKeyInfo(dwOuter, dwInner);
  237. }
  238. }
  239. }
  240. }
  241. else
  242. {
  243. hr = S_FALSE;
  244. }
  245. return hr;
  246. }
  247. CEnumAutoplayHandlerImpl::CEnumAutoplayHandlerImpl() : _dwIndex(0), _rghkiHandlers(NULL),
  248. _cHandlers(0), _fTakeNoActionDone(FALSE)
  249. {}
  250. CEnumAutoplayHandlerImpl::~CEnumAutoplayHandlerImpl()
  251. {
  252. if (_rghkiHandlers)
  253. {
  254. _FreeMemoryChunk<_HANDLERKEYINFO*>(_rghkiHandlers);
  255. }
  256. }