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.

340 lines
8.5 KiB

  1. //
  2. // Author: DebiM
  3. // Date: September 1996
  4. //
  5. //
  6. // Class Store Schema creation and access using ADs
  7. //
  8. // This source file contains implementations for IClassAccess,
  9. // interface for CClassAccess object.
  10. //
  11. //
  12. //---------------------------------------------------------------------
  13. #include "cstore.hxx"
  14. HRESULT CreateContainer (HANDLE pParent,
  15. LPOLESTR szName,
  16. LPOLESTR szDesc
  17. )
  18. {
  19. HRESULT hr;
  20. int l;
  21. ADS_ATTR_INFO Attr[3];
  22. //
  23. // Use the Parent Container interface to Create the child.
  24. //
  25. PackStrToAttr(Attr, OBJECTCLASS, CLASS_CS_CONTAINER);
  26. PackStrToAttr(Attr+1, DESCRIPTION, szDesc);
  27. //
  28. // Set its schema version
  29. //
  30. //PackDWToAttr(Attr+2, STOREVERSION, SCHEMA_VERSION_NUMBER);
  31. hr = ADSICreateDSObject(pParent, szName, Attr, 2);
  32. return hr;
  33. }
  34. HRESULT CreateRepository(LPOLESTR szParentPath, LPOLESTR szStoreName, LPOLESTR szPolicyDn)
  35. {
  36. HRESULT hr = S_OK;
  37. HANDLE hADsParent = NULL;
  38. HANDLE hADsContainer = NULL;
  39. HANDLE hADsPolicy = NULL;
  40. LPOLESTR szContainerName = NULL;
  41. LPOLESTR szPolicyName = NULL;
  42. int l;
  43. WCHAR szPath [_MAX_PATH];
  44. WCHAR * szFullName = NULL;
  45. WCHAR szUsn[30];
  46. ADS_ATTR_INFO pAttr[4];
  47. DWORD cGot = 0, cModified = 0;
  48. BOOL fCreatedContainer = FALSE,
  49. fCreatedCategories = FALSE,
  50. fCreatedClasses = FALSE;
  51. LPOLESTR AttrName = GPNAME;
  52. ADS_ATTR_INFO * pGetAttr = NULL;
  53. if (!szParentPath)
  54. {
  55. hr = GetRootPath(szPath);
  56. //
  57. // If failed go away
  58. //
  59. if (FAILED(hr))
  60. {
  61. return hr;
  62. }
  63. szParentPath = szPath;
  64. }
  65. //
  66. // First get the PolicyName
  67. //
  68. if (szPolicyDn)
  69. {
  70. hr = ADSIOpenDSObject(szPolicyDn, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  71. &hADsPolicy);
  72. RETURN_ON_FAILURE(hr);
  73. //
  74. // Get the PolicyName
  75. //
  76. hr = ADSIGetObjectAttributes(hADsPolicy, &AttrName, 1, &pGetAttr, &cGot);
  77. if (SUCCEEDED(hr) && (cGot))
  78. UnpackStrAllocFrom(pGetAttr[0], &szPolicyName);
  79. if (pGetAttr)
  80. FreeADsMem(pGetAttr);
  81. pGetAttr = NULL;
  82. ADSICloseDSObject(hADsPolicy);
  83. }
  84. hr = ADSIOpenDSObject(szParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  85. &hADsParent);
  86. RETURN_ON_FAILURE(hr);
  87. hr = CreateContainer(hADsParent,
  88. szStoreName,
  89. L"Application Store");
  90. //
  91. // handle this error correctly
  92. // see if a broken class store is left behind
  93. // this could happen due to DS going down after incomplete creation etc.
  94. // from the class store container property you could tell
  95. //
  96. if ((hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) ||
  97. (hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS)))
  98. {
  99. //
  100. // There is a Class Store already
  101. // See if it is a good one.
  102. DWORD dwStoreVersion = 0;
  103. hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
  104. if (!SUCCEEDED(hr))
  105. return CS_E_OBJECT_ALREADY_EXISTS;
  106. hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  107. &hADsContainer);
  108. FreeADsMem(szFullName);
  109. if (!SUCCEEDED(hr))
  110. return CS_E_OBJECT_ALREADY_EXISTS;
  111. AttrName = STOREVERSION;
  112. //
  113. // Get the Store Version
  114. //
  115. hr = ADSIGetObjectAttributes(hADsContainer, &AttrName, 1, &pGetAttr, &cGot);
  116. if (SUCCEEDED(hr) && (cGot))
  117. UnpackDWFrom(pGetAttr[0], &dwStoreVersion);
  118. if (pGetAttr)
  119. FreeADsMem(pGetAttr);
  120. ADSICloseDSObject(hADsContainer);
  121. if (dwStoreVersion == SCHEMA_VERSION_NUMBER)
  122. return CS_E_OBJECT_ALREADY_EXISTS;
  123. // if it is zero, then it was aborted in the middle.
  124. if (dwStoreVersion != 0)
  125. return CS_E_SCHEMA_MISMATCH;
  126. // If it is a bad one try to delete it
  127. DeleteRepository(szParentPath, szStoreName);
  128. //
  129. // Then again try to create it and proceed if successful
  130. //
  131. hr = CreateContainer(hADsParent,
  132. szStoreName,
  133. L"Application Store");
  134. }
  135. ERROR_ON_FAILURE(hr);
  136. fCreatedContainer = TRUE;
  137. hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
  138. ERROR_ON_FAILURE(hr);
  139. hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  140. &hADsContainer);
  141. ERROR_ON_FAILURE(hr);
  142. //
  143. // Create the class container
  144. //
  145. hr = CreateContainer (hADsContainer,
  146. CLASSCONTAINERNAME,
  147. L"Application Object Classes");
  148. ERROR_ON_FAILURE(hr);
  149. fCreatedClasses = TRUE;
  150. //
  151. // Create the category container
  152. //
  153. hr = CreateContainer (hADsContainer,
  154. CATEGORYCONTAINERNAME,
  155. L"Component Categories");
  156. ERROR_ON_FAILURE(hr);
  157. fCreatedCategories = TRUE;
  158. //
  159. // Create the package container
  160. //
  161. hr = CreateContainer (hADsContainer,
  162. PACKAGECONTAINERNAME,
  163. L"Application Packages");
  164. ERROR_ON_FAILURE(hr);
  165. //
  166. // Store the USN and PolicyID properties
  167. //
  168. GetCurrentUsn(szUsn);
  169. PackStrToAttr(&pAttr[0], STOREUSN, szUsn);
  170. PackStrToAttr(&pAttr[1], POLICYDN, szPolicyDn);
  171. PackStrToAttr(&pAttr[2], POLICYNAME, szPolicyName);
  172. PackDWToAttr(&pAttr[3], STOREVERSION, SCHEMA_VERSION_NUMBER);
  173. hr = ADSISetObjectAttributes(hADsContainer, pAttr, 4, &cModified);
  174. FreeAttr(pAttr[0]);
  175. FreeAttr(pAttr[1]);
  176. FreeAttr(pAttr[2]);
  177. FreeAttr(pAttr[3]);
  178. ADSICloseDSObject(hADsContainer);
  179. ADSICloseDSObject(hADsParent);
  180. FreeADsMem(szFullName);
  181. CoTaskMemFree(szPolicyName);
  182. return RemapErrorCode(hr, szParentPath);
  183. Error_Cleanup:
  184. if (fCreatedCategories)
  185. ADSIDeleteDSObject(hADsContainer, CATEGORYCONTAINERNAME);
  186. if (fCreatedClasses)
  187. ADSIDeleteDSObject(hADsContainer, CLASSCONTAINERNAME);
  188. if (hADsContainer)
  189. ADSICloseDSObject(hADsContainer);
  190. if (fCreatedContainer)
  191. ADSIDeleteDSObject(hADsParent, szStoreName);
  192. if (hADsParent)
  193. ADSICloseDSObject(hADsParent);
  194. if (szFullName)
  195. FreeADsMem(szFullName);
  196. if (szPolicyName)
  197. CoTaskMemFree(szPolicyName);
  198. return RemapErrorCode(hr, szParentPath);
  199. }
  200. HRESULT DeleteRepository(LPOLESTR szParentPath, LPOLESTR szStoreName)
  201. {
  202. HRESULT hr = S_OK;
  203. HANDLE hADsParent = NULL;
  204. HANDLE hADsContainer = NULL;
  205. WCHAR * szFullName = NULL;
  206. hr = ADSIOpenDSObject(szParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  207. &hADsParent);
  208. RETURN_ON_FAILURE(hr);
  209. hr = BuildADsPathFromParent(szParentPath, szStoreName, &szFullName);
  210. hr = ADSIOpenDSObject(szFullName, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  211. &hADsContainer);
  212. FreeADsMem(szFullName);
  213. ERROR_ON_FAILURE(hr);
  214. ADSIDeleteDSObject(hADsContainer, CATEGORYCONTAINERNAME);
  215. ADSIDeleteDSObject(hADsContainer, CLASSCONTAINERNAME);
  216. ADSIDeleteDSObject(hADsContainer, PACKAGECONTAINERNAME);
  217. ADSICloseDSObject(hADsContainer);
  218. ADSIDeleteDSObject(hADsParent, szStoreName);
  219. ADSICloseDSObject(hADsParent);
  220. return S_OK;
  221. Error_Cleanup:
  222. if (hADsContainer)
  223. ADSICloseDSObject(hADsContainer);
  224. if (hADsParent)
  225. ADSICloseDSObject(hADsParent);
  226. return hr;
  227. }
  228. HRESULT GetRootPath(LPOLESTR szContainer)
  229. {
  230. HRESULT hr = S_OK;
  231. ULONG cGot = 0;
  232. HANDLE hADs = NULL;
  233. LPOLESTR AttrName = {L"defaultNamingContext"}, pDN = NULL;
  234. ADS_ATTR_INFO * pAttr = NULL;
  235. szContainer[0] = L'\0';
  236. //
  237. // Do a bind to the machine by a GetObject for the Path
  238. //
  239. hr = ADSIOpenDSObject(L"LDAP://rootdse", NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
  240. &hADs);
  241. RETURN_ON_FAILURE(hr);
  242. hr = ADSIGetObjectAttributes(hADs, &AttrName, 1, &pAttr, &cGot);
  243. if (SUCCEEDED(hr) && (cGot))
  244. UnpackStrFrom(pAttr[0], &pDN);
  245. else
  246. pDN = L"\0";
  247. wsprintf(szContainer, L"%s%s", LDAPPREFIX, pDN);
  248. ADSICloseDSObject(hADs);
  249. if (pAttr)
  250. FreeADsMem(pAttr);
  251. return S_OK;
  252. }