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.

552 lines
10 KiB

  1. // SSRMemberShip.cpp : Implementation of CSsrMembership
  2. #include "stdafx.h"
  3. #include "global.h"
  4. #include "SSRTE.h"
  5. #include "SSRMemberShip.h"
  6. #include "SSRLog.h"
  7. #include "MemberAccess.h"
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CSsrMembership
  10. /*
  11. Routine Description:
  12. Name:
  13. CSsrMembership::CSsrMembership
  14. Functionality:
  15. constructor. This constructor also builds the member list.
  16. Virtual:
  17. no.
  18. Arguments:
  19. none.
  20. Return Value:
  21. none.
  22. Notes:
  23. */
  24. CSsrMembership::CSsrMembership()
  25. {
  26. }
  27. /*
  28. Routine Description:
  29. Name:
  30. CSsrMembership::~CSsrMembership
  31. Functionality:
  32. destructor
  33. Virtual:
  34. yes.
  35. Arguments:
  36. none.
  37. Return Value:
  38. none.
  39. Notes:
  40. */
  41. CSsrMembership::~CSsrMembership()
  42. {
  43. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.begin();
  44. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator itEnd = m_ssrMemberAccessMap.end();
  45. while(it != itEnd)
  46. {
  47. CSsrMemberAccess * pMA = (*it).second;
  48. pMA->Release();
  49. it++;
  50. }
  51. m_ssrMemberAccessMap.clear();
  52. }
  53. HRESULT
  54. CSsrMembership::LoadAllMember ()
  55. /*++
  56. Routine Description:
  57. Name:
  58. CSsrMembership::LoadAllMember
  59. Functionality:
  60. Will try to load all information about all the members that
  61. are registered with SSR.
  62. Virtual:
  63. no.
  64. Arguments:
  65. None.
  66. Return Value:
  67. Success: various success code.
  68. Failure: various error codes. However, we may tolerate that and only
  69. load those that we can load successfully. So, don't blindly quit.
  70. Notes:
  71. --*/
  72. {
  73. //
  74. // We should never load more than once.
  75. //
  76. if (m_ssrMemberAccessMap.size() > 0)
  77. {
  78. return S_OK; // we let you call it if you have already call it before
  79. }
  80. //
  81. // Let's enumerate through the Members directory's .xml files. They will
  82. // all be considered as member registration files.
  83. //
  84. WCHAR wcsXmlFiles[MAX_PATH + 2];
  85. _snwprintf(wcsXmlFiles, MAX_PATH + 1, L"%s\\Members\\*.xml", g_wszSsrRoot);
  86. wcsXmlFiles[MAX_PATH + 1] = L'\0';
  87. long lDirLen = wcslen(wcsXmlFiles);
  88. if (lDirLen > MAX_PATH)
  89. {
  90. return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
  91. }
  92. lDirLen -= 5;
  93. WIN32_FIND_DATA wfd;
  94. DWORD dwErr;
  95. HRESULT hr;
  96. HANDLE hFindFiles = FindFirstFile(
  97. wcsXmlFiles, // file name
  98. &wfd // information buffer
  99. );
  100. if (INVALID_HANDLE_VALUE == hFindFiles)
  101. {
  102. hr = S_FALSE;
  103. g_fblog.LogError(hr,
  104. L"There is no member to load",
  105. wcsXmlFiles
  106. );
  107. return hr;
  108. }
  109. HRESULT hrFirstError = S_OK;
  110. long lFileNameLength;
  111. while (INVALID_HANDLE_VALUE != hFindFiles)
  112. {
  113. //
  114. // make sure that we won't load anything other then a perfect .xml extension
  115. // file. I found that this Find will return such files: adc.xml-xxx
  116. //
  117. lFileNameLength = wcslen(wfd.cFileName);
  118. if (_wcsicmp(wfd.cFileName + lFileNameLength - 4, L".xml") == 0)
  119. {
  120. //
  121. // Get the file name and then load that member
  122. //
  123. wcsncpy(wcsXmlFiles + lDirLen, wfd.cFileName, lFileNameLength + 1);
  124. hr = LoadMember(wcsXmlFiles);
  125. if (FAILED(hr))
  126. {
  127. g_fblog.LogError(hr,
  128. L"CSsrMembership loading member failed",
  129. wcsXmlFiles
  130. );
  131. if (SUCCEEDED(hr))
  132. {
  133. hrFirstError = hr;
  134. }
  135. }
  136. }
  137. if (!FindNextFile (hFindFiles, &wfd))
  138. {
  139. dwErr = GetLastError();
  140. if (ERROR_NO_MORE_FILES != dwErr)
  141. {
  142. //
  143. // log it
  144. //
  145. g_fblog.LogError(HRESULT_FROM_WIN32(dwErr),
  146. L"CSsrMembership",
  147. L"FindNextFile"
  148. );
  149. }
  150. break;
  151. }
  152. }
  153. FindClose(hFindFiles);
  154. return hrFirstError;
  155. }
  156. /*
  157. Routine Description:
  158. Name:
  159. CSsrMembership::LoadMember
  160. Functionality:
  161. By given a valid member name, this function will load all the
  162. detailed information from the registry.
  163. Virtual:
  164. no.
  165. Arguments:
  166. wszMemberFilePath - The XML registration file path for a particular member.
  167. Return Value:
  168. Success: S_OK.
  169. Failure: various error codes
  170. Notes:
  171. */
  172. HRESULT
  173. CSsrMembership::LoadMember (
  174. IN LPCWSTR wszMemberFilePath
  175. )
  176. {
  177. HRESULT hr = S_OK;
  178. CComObject<CSsrMemberAccess> * pMA = NULL;
  179. hr = CComObject<CSsrMemberAccess>::CreateInstance(&pMA);
  180. if (SUCCEEDED(hr))
  181. {
  182. //
  183. // holding on to the object. When the member access
  184. // map cleans up, remember to let go the objects
  185. //
  186. pMA->AddRef();
  187. hr = pMA->Load(wszMemberFilePath);
  188. if (S_OK == hr)
  189. {
  190. //
  191. // Everything is fine and we loaded the member.
  192. // Add it to our map. The map owns the object from this point on.
  193. //
  194. m_ssrMemberAccessMap.insert(
  195. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::value_type(pMA->GetName(),
  196. pMA)
  197. );
  198. }
  199. else
  200. {
  201. //
  202. // let go the object
  203. //
  204. pMA->Release();
  205. g_fblog.LogError(hr, wszMemberFilePath, NULL);
  206. }
  207. }
  208. else
  209. {
  210. g_fblog.LogError(hr, wszMemberFilePath, NULL);
  211. }
  212. return hr;
  213. }
  214. /*
  215. Routine Description:
  216. Name:
  217. CSsrMembership::GetAllMembers
  218. Functionality:
  219. Retrieve all members currently registered on the system.
  220. Virtual:
  221. yes.
  222. Arguments:
  223. pvarArrayMembers - Receives names of the members
  224. Return Value:
  225. ?.
  226. Notes:
  227. */
  228. STDMETHODIMP CSsrMembership::GetAllMembers (
  229. OUT VARIANT * pvarArrayMembers // [out, retval]
  230. )
  231. {
  232. if (pvarArrayMembers == NULL)
  233. {
  234. return E_INVALIDARG;
  235. }
  236. //
  237. // have a clean output parameter, no matter what
  238. //
  239. ::VariantInit(pvarArrayMembers);
  240. //
  241. // prepare the safearray
  242. //
  243. SAFEARRAYBOUND rgsabound[1];
  244. rgsabound[0].lLbound = 0;
  245. rgsabound[0].cElements = m_ssrMemberAccessMap.size();
  246. SAFEARRAY * psa = ::SafeArrayCreate(VT_VARIANT , 1, rgsabound);
  247. HRESULT hr = S_OK;
  248. if (psa == NULL)
  249. {
  250. hr = E_OUTOFMEMORY;
  251. }
  252. else
  253. {
  254. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.begin();
  255. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator itEnd = m_ssrMemberAccessMap.end();
  256. //
  257. // we only add one name at a time
  258. //
  259. long indecies[1] = {0};
  260. while(it != itEnd)
  261. {
  262. CSsrMemberAccess * pMA = (*it).second;
  263. VARIANT varName;
  264. varName.vt = VT_BSTR;
  265. //
  266. // don't clean up varName! CSsrMemberAccess::GetName returns
  267. // a const BSTR which simplies points to the cached variable!
  268. //
  269. varName.bstrVal = pMA->GetName();
  270. hr = ::SafeArrayPutElement(psa, indecies, &varName);
  271. if (FAILED(hr))
  272. {
  273. break;
  274. }
  275. indecies[0]++;
  276. ++it;
  277. }
  278. if (SUCCEEDED(hr))
  279. {
  280. pvarArrayMembers->vt = VT_ARRAY | VT_VARIANT;
  281. pvarArrayMembers->parray = psa;
  282. }
  283. else
  284. {
  285. ::SafeArrayDestroy(psa);
  286. }
  287. }
  288. return hr;
  289. }
  290. /*
  291. Routine Description:
  292. Name:
  293. CSsrMembership::GetMember
  294. Functionality:
  295. Retrieve one member of the given name.
  296. Virtual:
  297. yes.
  298. Arguments:
  299. pvarMember - Receives ISsrMemberAccess object of the named member.
  300. Return Value:
  301. Success: S_OK;
  302. Failure: various error codes.
  303. Notes:
  304. */
  305. STDMETHODIMP CSsrMembership::GetMember (
  306. IN BSTR bstrMemberName,
  307. OUT VARIANT * pvarMember //[out, retval]
  308. )
  309. {
  310. if (bstrMemberName == NULL || *bstrMemberName == L'\0' || pvarMember == NULL)
  311. {
  312. return E_INVALIDARG;
  313. }
  314. ::VariantInit(pvarMember);
  315. CSsrMemberAccess * pMA = GetMemberByName(bstrMemberName);
  316. HRESULT hr = S_OK;
  317. if (pMA != NULL)
  318. {
  319. pvarMember->vt = VT_DISPATCH;
  320. hr = pMA->QueryInterface(IID_ISsrMemberAccess,
  321. (LPVOID*)&(pvarMember->pdispVal) );
  322. if (hr != S_OK)
  323. {
  324. pvarMember->vt = VT_EMPTY;
  325. hr = E_SSR_MEMBER_NOT_FOUND;
  326. }
  327. }
  328. else
  329. {
  330. hr = E_SSR_MEMBER_NOT_FOUND;
  331. }
  332. return hr;
  333. }
  334. /*
  335. Routine Description:
  336. Name:
  337. CSsrMembership::GetMemberByName
  338. Functionality:
  339. Will find the CSsrMemberAccess object based the name.
  340. Virtual:
  341. No.
  342. Arguments:
  343. bstrMemberName - The member's name
  344. Return Value:
  345. None NULL if the object is found. Otherwise, it returns NULL.
  346. Notes:
  347. Since this is a helper function, we don't call AddRef to the returned object!
  348. */
  349. CSsrMemberAccess*
  350. CSsrMembership::GetMemberByName (
  351. IN BSTR bstrMemberName
  352. )
  353. {
  354. map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.find(bstrMemberName);
  355. if (it != m_ssrMemberAccessMap.end())
  356. {
  357. CSsrMemberAccess * pMA = (*it).second;
  358. return pMA;
  359. }
  360. return NULL;
  361. }