Leaked source code of windows server 2003
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.

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