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.

316 lines
8.2 KiB

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