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.

528 lines
12 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998
  5. //
  6. // File: guidlist.cpp
  7. //
  8. // Contents: Classes for marshalling, unmarshalling Guids
  9. //
  10. // History: 24-Oct-98 SitaramR Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "main.h"
  14. //*************************************************************
  15. //
  16. // CGuidList::CGuidList, ~CGuidList
  17. //
  18. // Purpose: Constructor, destructor
  19. //
  20. //*************************************************************
  21. CGuidList::CGuidList()
  22. : m_pExtGuidList(0),
  23. m_bGuidsChanged(FALSE)
  24. {
  25. }
  26. CGuidList::~CGuidList()
  27. {
  28. FreeGuidList( m_pExtGuidList );
  29. }
  30. void FreeGuidList( GUIDELEM *pGuidList )
  31. {
  32. while ( pGuidList )
  33. {
  34. //
  35. // Free snapin guids
  36. //
  37. GUIDELEM *pTemp;
  38. GUIDELEM *pGuidSnp = pGuidList->pSnapinGuids;
  39. while ( pGuidSnp )
  40. {
  41. pTemp = pGuidSnp->pNext;
  42. delete pGuidSnp;
  43. pGuidSnp = pTemp;
  44. }
  45. pTemp = pGuidList->pNext;
  46. delete pGuidList;
  47. pGuidList = pTemp;
  48. }
  49. }
  50. //*************************************************************
  51. //
  52. // CGuidList::UnMarshallGuids
  53. //
  54. // Purpose: Converts string representation of guids to list
  55. // of guids.
  56. //
  57. // Parameters: pszGuids - String to convert
  58. //
  59. // Returns: S_OK if successful
  60. //
  61. //*************************************************************
  62. HRESULT CGuidList::UnMarshallGuids( TCHAR *pszGuids )
  63. {
  64. //
  65. // Format is [{ext guid1}{snapin guid1}..{snapin guidn}][{ext guid2}...]...\0
  66. // Both extension and snapin guids are in ascending order.
  67. //
  68. TCHAR *pchCur = pszGuids;
  69. XGuidElem xGuidElem;
  70. GUIDELEM *pGuidExtTail = 0;
  71. if ( pszGuids == 0 || lstrcmpi( pszGuids, TEXT(" ") ) == 0 )
  72. {
  73. //
  74. // Empty property case, so nothing to unmarshall
  75. //
  76. m_pExtGuidList = 0;
  77. return S_OK;
  78. }
  79. //
  80. // Outer loop over extensions
  81. //
  82. while ( *pchCur )
  83. {
  84. if ( *pchCur == TEXT('[') )
  85. pchCur++;
  86. else
  87. return E_FAIL;
  88. GUID guidExt;
  89. if ( ValidateGuid( pchCur ) )
  90. StringToGuid( pchCur, &guidExt );
  91. else
  92. return E_FAIL;
  93. GUIDELEM *pGuidExt = new GUIDELEM;
  94. if ( pGuidExt == 0 )
  95. return E_OUTOFMEMORY;
  96. pGuidExt->guid = guidExt;
  97. pGuidExt->pSnapinGuids = 0;
  98. pGuidExt->pNext = 0;
  99. //
  100. // Append to end of list
  101. //
  102. if ( pGuidExtTail == 0 )
  103. xGuidElem.Set( pGuidExt );
  104. else
  105. pGuidExtTail->pNext = pGuidExt;
  106. pGuidExtTail = pGuidExt;
  107. //
  108. // Move past '{', then skip until next '{
  109. //
  110. pchCur++;
  111. while ( *pchCur && *pchCur != TEXT('{') )
  112. pchCur++;
  113. if ( !(*pchCur) )
  114. return E_FAIL;
  115. //
  116. // Inner loop over snapin guids
  117. //
  118. GUIDELEM *pGuidSnapinTail = 0;
  119. while ( *pchCur != TEXT(']') )
  120. {
  121. GUID guidSnp;
  122. if ( ValidateGuid( pchCur ) )
  123. StringToGuid( pchCur, &guidSnp );
  124. else
  125. return E_FAIL;
  126. GUIDELEM *pGuidSnapin = new GUIDELEM;
  127. if ( pGuidSnapin == 0 )
  128. return E_OUTOFMEMORY;
  129. pGuidSnapin->guid = guidSnp;
  130. pGuidSnapin->pSnapinGuids = 0;
  131. pGuidSnapin->pNext = 0;
  132. //
  133. // Append to end of list
  134. //
  135. if ( pGuidSnapinTail == 0 )
  136. pGuidExtTail->pSnapinGuids = pGuidSnapin;
  137. else
  138. pGuidSnapinTail->pNext = pGuidSnapin;
  139. pGuidSnapinTail = pGuidSnapin;
  140. while ( *pchCur && *pchCur != TEXT('}') )
  141. pchCur++;
  142. if ( !(*pchCur) )
  143. return E_FAIL;
  144. pchCur++;
  145. if ( *pchCur != TEXT('{') && *pchCur != TEXT(']') )
  146. return E_FAIL;
  147. } // inner while
  148. pchCur++;
  149. } // outer while
  150. m_pExtGuidList = xGuidElem.Acquire();
  151. return S_OK;
  152. }
  153. //*************************************************************
  154. //
  155. // CGuidList::MarshallGuids
  156. //
  157. // Purpose: Converts list of guids to string representation
  158. //
  159. // Parameters: xValueOut - String representation returned here
  160. //
  161. // Returns: S_OK if successful
  162. //
  163. //*************************************************************
  164. HRESULT CGuidList::MarshallGuids( XPtrST<TCHAR>& xValueOut )
  165. {
  166. //
  167. // Get count of guids to allocate sufficient space up front
  168. //
  169. DWORD dwCount = 1;
  170. GUIDELEM *pGuidExt = m_pExtGuidList;
  171. while ( pGuidExt )
  172. {
  173. dwCount++;
  174. GUIDELEM *pGuidSnapin = pGuidExt->pSnapinGuids;
  175. while ( pGuidSnapin )
  176. {
  177. dwCount++;
  178. pGuidSnapin = pGuidSnapin->pNext;
  179. }
  180. pGuidExt = pGuidExt->pNext;
  181. }
  182. LONG lSize = dwCount * (GUID_LENGTH + 6);
  183. TCHAR *pszValue = new TCHAR[lSize];
  184. if ( pszValue == 0 )
  185. return E_OUTOFMEMORY;
  186. xValueOut.Set( pszValue );
  187. TCHAR *pchCur = pszValue;
  188. //
  189. // Actual marshalling
  190. //
  191. if ( m_pExtGuidList == 0 )
  192. {
  193. HRESULT hr;
  194. //
  195. // Adsi doesn't commit null strings, so use ' ' instead
  196. //
  197. hr = StringCchCopy( pchCur, lSize, TEXT(" ") );
  198. return hr;
  199. }
  200. pGuidExt = m_pExtGuidList;
  201. while ( pGuidExt )
  202. {
  203. DmAssert( lSize > GUID_LENGTH * 2 + (pchCur-pszValue) );
  204. *pchCur = TEXT('[');
  205. pchCur++;
  206. GuidToString( &pGuidExt->guid, pchCur );
  207. pchCur += GUID_LENGTH;
  208. GUIDELEM *pGuidSnp = pGuidExt->pSnapinGuids;
  209. while ( pGuidSnp )
  210. {
  211. DmAssert( lSize > GUID_LENGTH + (pchCur-pszValue) );
  212. GuidToString( &pGuidSnp->guid, pchCur );
  213. pchCur += GUID_LENGTH;
  214. pGuidSnp = pGuidSnp->pNext;
  215. }
  216. *pchCur = TEXT(']');
  217. pchCur++;
  218. pGuidExt = pGuidExt->pNext;
  219. }
  220. *pchCur = 0;
  221. return S_OK;
  222. }
  223. //*************************************************************
  224. //
  225. // CGuidList::Update
  226. //
  227. // Purpose: Updates in memory list with guid info
  228. //
  229. // Parameters: bAdd - Add or delete
  230. // pGuidExtension - Extension's guid
  231. // pGuidSnapin - Snapin's guid
  232. //
  233. // Returns: S_OK if successful
  234. //
  235. //*************************************************************
  236. HRESULT CGuidList::Update( BOOL bAdd, GUID *pGuidExtension, GUID *pGuidSnapin )
  237. {
  238. HRESULT hr = E_FAIL;
  239. GUIDELEM *pTrailPtr = NULL;
  240. GUIDELEM *pCurPtr = m_pExtGuidList;
  241. while ( pCurPtr != NULL )
  242. {
  243. if ( *pGuidExtension == pCurPtr->guid )
  244. {
  245. hr = UpdateSnapinGuid( bAdd, pCurPtr, pGuidSnapin );
  246. if ( FAILED(hr) )
  247. return hr;
  248. if ( pCurPtr->pSnapinGuids == NULL )
  249. {
  250. //
  251. // Remove extension from list
  252. //
  253. if ( pTrailPtr == NULL )
  254. m_pExtGuidList = pCurPtr->pNext;
  255. else
  256. pTrailPtr->pNext = pCurPtr->pNext;
  257. delete pCurPtr;
  258. m_bGuidsChanged = TRUE;
  259. }
  260. return S_OK;
  261. }
  262. else if ( CompareGuid( pGuidExtension, &pCurPtr->guid ) < 0 )
  263. {
  264. //
  265. // Since guids are in ascending order,
  266. // pGuidExtension is not in list, add if necessary
  267. //
  268. if ( bAdd )
  269. {
  270. GUIDELEM *pGuidExt = new GUIDELEM;
  271. if ( pGuidExt == 0 )
  272. return E_OUTOFMEMORY;
  273. pGuidExt->pSnapinGuids = new GUIDELEM;
  274. if ( pGuidExt->pSnapinGuids == 0 )
  275. {
  276. delete pGuidExt;
  277. return E_OUTOFMEMORY;
  278. }
  279. pGuidExt->guid = *pGuidExtension;
  280. pGuidExt->pNext = pCurPtr;
  281. pGuidExt->pSnapinGuids->guid = *pGuidSnapin;
  282. pGuidExt->pSnapinGuids->pSnapinGuids = 0;
  283. pGuidExt->pSnapinGuids->pNext = 0;
  284. if ( pTrailPtr == 0)
  285. m_pExtGuidList = pGuidExt;
  286. else
  287. pTrailPtr->pNext = pGuidExt;
  288. m_bGuidsChanged = TRUE;
  289. }
  290. return S_OK;
  291. }
  292. else // compareguid
  293. {
  294. //
  295. // Advance down the list
  296. //
  297. pTrailPtr = pCurPtr;
  298. pCurPtr = pCurPtr->pNext;
  299. }
  300. } // while
  301. //
  302. // End of list or null list, add guid at end if necessary
  303. //
  304. if ( bAdd )
  305. {
  306. GUIDELEM *pGuidExt = new GUIDELEM;
  307. if ( pGuidExt == 0 )
  308. return E_OUTOFMEMORY;
  309. pGuidExt->pSnapinGuids = new GUIDELEM;
  310. if ( pGuidExt->pSnapinGuids == 0 )
  311. {
  312. delete pGuidExt;
  313. return E_OUTOFMEMORY;
  314. }
  315. pGuidExt->guid = *pGuidExtension;
  316. pGuidExt->pNext = 0;
  317. pGuidExt->pSnapinGuids->guid = *pGuidSnapin;
  318. pGuidExt->pSnapinGuids->pSnapinGuids = 0;
  319. pGuidExt->pSnapinGuids->pNext = 0;
  320. if ( pTrailPtr == 0)
  321. m_pExtGuidList = pGuidExt;
  322. else
  323. pTrailPtr->pNext = pGuidExt;
  324. m_bGuidsChanged = TRUE;
  325. }
  326. return S_OK;
  327. }
  328. //*************************************************************
  329. //
  330. // CGuidList::UpdateSnapinGuid
  331. //
  332. // Purpose: Updates snapin list with guid info
  333. //
  334. // Parameters: bAdd - Add or delete
  335. // pExtGuid - Extension's guid ptr
  336. // pGuidSnapin - Snapin's guid
  337. //
  338. // Returns: S_OK if successful
  339. //
  340. //*************************************************************
  341. HRESULT CGuidList::UpdateSnapinGuid( BOOL bAdd, GUIDELEM *pExtGuid,
  342. GUID *pGuidSnapin )
  343. {
  344. GUIDELEM *pTrailPtr = 0;
  345. GUIDELEM *pCurPtr = pExtGuid->pSnapinGuids;
  346. while ( pCurPtr != NULL )
  347. {
  348. if ( *pGuidSnapin == pCurPtr->guid )
  349. {
  350. if ( !bAdd )
  351. {
  352. if ( pTrailPtr == NULL )
  353. pExtGuid->pSnapinGuids = pCurPtr->pNext;
  354. else
  355. pTrailPtr->pNext = pCurPtr->pNext;
  356. delete pCurPtr;
  357. m_bGuidsChanged = TRUE;
  358. }
  359. return S_OK;
  360. }
  361. else if ( CompareGuid( pGuidSnapin, &pCurPtr->guid ) < 0 )
  362. {
  363. //
  364. // Since guids are in ascending order,
  365. // pGuidSnapin is not in list, add if necessary
  366. //
  367. if ( bAdd )
  368. {
  369. GUIDELEM *pGuidSnp = new GUIDELEM;
  370. if ( pGuidSnp == 0 )
  371. return E_OUTOFMEMORY;
  372. pGuidSnp->guid = *pGuidSnapin;
  373. pGuidSnp->pSnapinGuids = 0;
  374. pGuidSnp->pNext = pCurPtr;
  375. if ( pTrailPtr == NULL )
  376. pExtGuid->pSnapinGuids = pGuidSnp;
  377. else
  378. pTrailPtr->pNext = pGuidSnp;
  379. m_bGuidsChanged = TRUE;
  380. }
  381. return S_OK;
  382. }
  383. else
  384. {
  385. //
  386. // Advance down the list
  387. //
  388. pTrailPtr = pCurPtr;
  389. pCurPtr = pCurPtr->pNext;
  390. }
  391. } // while
  392. //
  393. // End of list or null list, add guid at end if necessary
  394. //
  395. if ( bAdd )
  396. {
  397. GUIDELEM *pGuidSnp = new GUIDELEM;
  398. if ( pGuidSnp == 0 )
  399. return E_OUTOFMEMORY;
  400. pGuidSnp->guid = *pGuidSnapin;
  401. pGuidSnp->pSnapinGuids = 0;
  402. pGuidSnp->pNext = 0;
  403. if ( pTrailPtr == 0 )
  404. pExtGuid->pSnapinGuids = pGuidSnp;
  405. else
  406. pTrailPtr->pNext = pGuidSnp;
  407. m_bGuidsChanged = TRUE;
  408. }
  409. return S_OK;
  410. }