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.

447 lines
9.2 KiB

  1. // WMDMDeviceEnum.cpp : Implementation of CWMDMDeviceEnum
  2. #include "stdafx.h"
  3. #include "mswmdm.h"
  4. #include "spinfo.h"
  5. #include "WMDMDeviceEnum.h"
  6. #include "Device.h"
  7. #include "loghelp.h"
  8. #include "scserver.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CWMDMDeviceEnum
  11. extern CSPInfo **g_pSPs;
  12. extern WORD g_wSPCount;
  13. extern CSecureChannelServer *g_pAppSCServer;
  14. CWMDMDeviceEnum::CWMDMDeviceEnum()
  15. : m_ppEnums(NULL), m_wCurrentSP(0), m_wSPCount(0)
  16. {
  17. GlobalAddRef();
  18. m_pwSPSkipped=NULL;
  19. hrInitializeEnumArray();
  20. }
  21. CWMDMDeviceEnum::~CWMDMDeviceEnum()
  22. {
  23. if (m_ppEnums)
  24. {
  25. for (WORD x=0;x<m_wSPCount;x++)
  26. m_ppEnums[x]->Release();
  27. delete m_ppEnums;
  28. }
  29. if( m_pwSPSkipped )
  30. {
  31. delete [] m_pwSPSkipped;
  32. m_pwSPSkipped=NULL;
  33. }
  34. GlobalRelease();
  35. }
  36. // IWMDMEnumDevice Methods
  37. HRESULT CWMDMDeviceEnum::Next(ULONG celt,
  38. IWMDMDevice **ppDevice,
  39. ULONG *pceltFetched)
  40. {
  41. HRESULT hr = S_FALSE;
  42. ULONG celtRemaining;
  43. ULONG ulFetched;
  44. ULONG ulX;
  45. IMDSPDevice **ppDevList = NULL;
  46. CComObject<CWMDMDevice> *pDevObj = NULL;
  47. WORD *pwSPIndexList = NULL;
  48. ULONG ulIndexOffset;
  49. if (g_pAppSCServer)
  50. {
  51. if(!g_pAppSCServer->fIsAuthenticated())
  52. {
  53. hr = WMDM_E_NOTCERTIFIED;
  54. goto exit;
  55. }
  56. }
  57. else
  58. {
  59. hr = E_FAIL;
  60. goto exit;
  61. }
  62. if (!ppDevice || !pceltFetched || celt == 0)
  63. {
  64. hr = E_INVALIDARG;
  65. goto exit;
  66. }
  67. m_csCurrentSP.Lock();
  68. // If we have gone through all of the SPs then the user must reset
  69. if (m_wCurrentSP > g_wSPCount - 1)
  70. {
  71. *pceltFetched = 0;
  72. *ppDevice = NULL;
  73. goto exit;
  74. }
  75. if( !m_pwSPSkipped )
  76. {
  77. hr = E_OUTOFMEMORY;
  78. goto exit;
  79. }
  80. ppDevList = new IMDSPDevice *[celt];
  81. if (!ppDevList)
  82. {
  83. hr = E_OUTOFMEMORY;
  84. goto exit;
  85. }
  86. pwSPIndexList = new WORD[celt];
  87. if (!pwSPIndexList)
  88. {
  89. hr = E_OUTOFMEMORY;
  90. goto exit;
  91. }
  92. hr = E_FAIL;
  93. if( m_ppEnums[m_wCurrentSP] )
  94. {
  95. hr = m_ppEnums[m_wCurrentSP]->Next(celt, ppDevList, &ulFetched);
  96. }
  97. if (FAILED(hr))
  98. {
  99. ulFetched = 0;
  100. hr = S_OK; // Ignore the failure, continue to search the next SP.
  101. //goto exit;
  102. }
  103. for (ulIndexOffset=0;ulIndexOffset<ulFetched;ulIndexOffset++)
  104. {
  105. pwSPIndexList[ulIndexOffset] = m_pwSPSkipped[m_wCurrentSP];
  106. }
  107. if(celt != ulFetched)
  108. {
  109. celtRemaining = celt - ulFetched;
  110. m_wCurrentSP++;
  111. while (m_wCurrentSP < m_wSPCount)
  112. {
  113. hr = m_ppEnums[m_wCurrentSP]->Reset();
  114. if (FAILED(hr))
  115. {
  116. goto exit;
  117. }
  118. hr = m_ppEnums[m_wCurrentSP]->Next(celtRemaining,
  119. reinterpret_cast<IMDSPDevice **>(ppDevList + ulIndexOffset),
  120. &ulFetched);
  121. if (FAILED(hr))
  122. {
  123. goto exit;
  124. }
  125. for ( UINT uFetchedIndex = 0;uFetchedIndex<ulFetched; ulIndexOffset++, uFetchedIndex++)
  126. {
  127. pwSPIndexList[ulIndexOffset] = m_pwSPSkipped[m_wCurrentSP];
  128. }
  129. if (celtRemaining == ulFetched)
  130. {
  131. // We have all of the device we need
  132. celtRemaining = 0;
  133. break;
  134. }
  135. celtRemaining = celtRemaining - ulFetched;
  136. m_wCurrentSP++;
  137. }
  138. // Tell the caller how many devices we are returning.
  139. *pceltFetched = celt - celtRemaining;
  140. }
  141. else
  142. {
  143. *pceltFetched = ulFetched;
  144. }
  145. m_csCurrentSP.Unlock();
  146. for (ulX=0;ulX<*pceltFetched;ulX++)
  147. {
  148. hr = CComObject<CWMDMDevice>::CreateInstance(&pDevObj);
  149. if (FAILED(hr))
  150. {
  151. goto exit;
  152. }
  153. hr = pDevObj->QueryInterface(IID_IWMDMDevice, reinterpret_cast<void**>(&ppDevice[ulX]));
  154. if (FAILED(hr))
  155. {
  156. delete pDevObj;
  157. goto exit;
  158. }
  159. pDevObj->SetContainedPointer(ppDevList[ulX], pwSPIndexList[ulX]);
  160. // @@@@ Must release in all failure paths as well
  161. ppDevList[ulX]->Release();
  162. }
  163. exit:
  164. if (SUCCEEDED(hr))
  165. {
  166. if (celt == *pceltFetched)
  167. {
  168. hr = S_OK;
  169. }
  170. else
  171. {
  172. if (*pceltFetched == 0)
  173. {
  174. *ppDevice = NULL;
  175. }
  176. hr = S_FALSE;
  177. }
  178. }
  179. if (ppDevList)
  180. delete [] ppDevList;
  181. if (pwSPIndexList)
  182. delete [] pwSPIndexList;
  183. hrLogDWORD("IWMDMEnumDevice::Next returned 0x%08lx", hr, hr);
  184. return hr;
  185. }
  186. HRESULT CWMDMDeviceEnum::Skip(ULONG celt, ULONG *pceltFetched)
  187. {
  188. HRESULT hr;
  189. ULONG celtRemaining;
  190. ULONG ulFetched;
  191. if (g_pAppSCServer)
  192. {
  193. if(!g_pAppSCServer->fIsAuthenticated())
  194. {
  195. hr = WMDM_E_NOTCERTIFIED;
  196. goto exit;
  197. }
  198. }
  199. else
  200. {
  201. hr = E_FAIL;
  202. goto exit;
  203. }
  204. if (!pceltFetched || celt == 0)
  205. {
  206. hr = E_INVALIDARG;
  207. goto exit;
  208. }
  209. m_csCurrentSP.Lock();
  210. // If we have gone through all of the SPs then the user must reset
  211. // @@@@ unsigned compare: consider g_wSPCount == 0
  212. if (m_wCurrentSP > g_wSPCount - 1)
  213. {
  214. *pceltFetched = 0;
  215. hr = S_OK;
  216. goto exit;
  217. }
  218. hr = m_ppEnums[m_wCurrentSP]->Skip(celt, &ulFetched);
  219. if (FAILED(hr))
  220. {
  221. goto exit;
  222. }
  223. if(celt != ulFetched)
  224. {
  225. celtRemaining = celt - ulFetched;
  226. m_wCurrentSP++;
  227. while (m_wCurrentSP < m_wSPCount)
  228. {
  229. hr = m_ppEnums[m_wCurrentSP]->Reset();
  230. if (FAILED(hr))
  231. {
  232. goto exit;
  233. }
  234. hr = m_ppEnums[m_wCurrentSP]->Skip(celtRemaining, &ulFetched);
  235. if (FAILED(hr))
  236. {
  237. goto exit;
  238. }
  239. if (celtRemaining == ulFetched)
  240. {
  241. // We have all of the device we need
  242. celtRemaining = 0;
  243. break;
  244. }
  245. celtRemaining = celtRemaining - ulFetched;
  246. m_wCurrentSP++;
  247. }
  248. // Tell the caller how many devices we are returning.
  249. *pceltFetched = celt - celtRemaining;
  250. }
  251. else
  252. *pceltFetched = ulFetched;
  253. m_csCurrentSP.Unlock();
  254. exit:
  255. if (SUCCEEDED(hr))
  256. {
  257. if (celt == *pceltFetched)
  258. hr = S_OK;
  259. else
  260. hr = S_FALSE;
  261. }
  262. hrLogDWORD("IWMDMEnumDevice::Skip returned 0x%08lx", hr, hr);
  263. return hr;
  264. }
  265. HRESULT CWMDMDeviceEnum::Reset()
  266. {
  267. HRESULT hr;
  268. if (g_pAppSCServer)
  269. {
  270. if(!g_pAppSCServer->fIsAuthenticated())
  271. {
  272. hr = WMDM_E_NOTCERTIFIED;
  273. goto exit;
  274. }
  275. }
  276. else
  277. {
  278. hr = E_FAIL;
  279. goto exit;
  280. }
  281. m_csCurrentSP.Lock();
  282. m_wCurrentSP = 0;
  283. hr = m_ppEnums[m_wCurrentSP]->Reset();
  284. if (FAILED(hr))
  285. {
  286. goto exit;
  287. }
  288. m_csCurrentSP.Unlock();
  289. exit:
  290. hrLogDWORD("IWMDMEnumDevice::Skip returned 0x%08lx", hr, hr);
  291. return hr;
  292. }
  293. HRESULT CWMDMDeviceEnum::Clone(IWMDMEnumDevice **ppEnumDevice)
  294. {
  295. HRESULT hr;
  296. CComObject<CWMDMDeviceEnum> *pEnumObj;
  297. if (g_pAppSCServer)
  298. {
  299. if(!g_pAppSCServer->fIsAuthenticated())
  300. {
  301. hr = WMDM_E_NOTCERTIFIED;
  302. goto exit;
  303. }
  304. }
  305. else
  306. {
  307. hr = E_FAIL;
  308. goto exit;
  309. }
  310. if (!ppEnumDevice)
  311. {
  312. hr = E_INVALIDARG;
  313. goto exit;
  314. }
  315. m_csCurrentSP.Lock();
  316. hr = CComObject<CWMDMDeviceEnum>::CreateInstance(&pEnumObj);
  317. if (FAILED(hr))
  318. {
  319. goto exit;
  320. }
  321. hr = pEnumObj->QueryInterface(IID_IWMDMEnumDevice, reinterpret_cast<void**>(ppEnumDevice));
  322. if (FAILED(hr))
  323. {
  324. delete pEnumObj;
  325. goto exit;
  326. }
  327. m_csCurrentSP.Unlock();
  328. exit:
  329. hrLogDWORD("IWMDMEnumDevice::Clone returned 0x%08lx", hr, hr);
  330. return hr;
  331. }
  332. HRESULT CWMDMDeviceEnum::hrInitializeEnumArray()
  333. {
  334. HRESULT hr;
  335. WORD x;
  336. IMDServiceProvider *pProv = NULL;
  337. if( m_pwSPSkipped )
  338. {
  339. delete [] m_pwSPSkipped;
  340. }
  341. m_pwSPSkipped = new WORD [g_wSPCount];
  342. if (!m_pwSPSkipped)
  343. {
  344. hr = E_OUTOFMEMORY;
  345. goto exit;
  346. }
  347. m_ppEnums = new IMDSPEnumDevice *[g_wSPCount];
  348. if (!m_ppEnums)
  349. {
  350. hr = E_OUTOFMEMORY;
  351. goto exit;
  352. }
  353. hr = S_OK;
  354. for (x=0,m_wSPCount=0;x<g_wSPCount;x++)
  355. {
  356. hr = g_pSPs[x]->hrGetInterface(&pProv);
  357. if (FAILED(hr))
  358. {
  359. continue; // goto exit;
  360. }
  361. hr = pProv->EnumDevices(&m_ppEnums[m_wSPCount]);
  362. if (FAILED(hr))
  363. {
  364. pProv->Release();
  365. pProv = NULL;
  366. continue; // goto exit;
  367. }
  368. m_pwSPSkipped[m_wSPCount]=x; // Remember the index for SAC
  369. m_wSPCount++;
  370. pProv->Release();
  371. pProv = NULL;
  372. }
  373. exit:
  374. if (pProv)
  375. pProv->Release();
  376. hrLogDWORD("CWMDMDeviceEnum::hrInitializeEnumArray returned 0x%08lx", hr, hr);
  377. return hr;
  378. }