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.

307 lines
7.7 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996
  5. //
  6. // File: csenum.cxx
  7. //
  8. // Contents: Per Class Container Package Enumeration
  9. //
  10. //
  11. // History: 09-09-96 DebiM created
  12. // 11-01-97 DebiM modified, moved to cstore
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "cstore.hxx"
  16. //IEnumPackage implementation.
  17. HRESULT CEnumPackage::QueryInterface(REFIID riid, void** ppObject)
  18. {
  19. if (riid==IID_IUnknown || riid==IID_IEnumPackage)
  20. {
  21. *ppObject=(IEnumPackage *) this;
  22. }
  23. else
  24. {
  25. return E_NOINTERFACE;
  26. }
  27. AddRef();
  28. return S_OK;
  29. }
  30. ULONG CEnumPackage::AddRef()
  31. {
  32. InterlockedIncrement((long*) &m_dwRefCount);
  33. return m_dwRefCount;
  34. }
  35. ULONG CEnumPackage::Release()
  36. {
  37. ULONG dwRefCount=m_dwRefCount-1;
  38. if (InterlockedDecrement((long*) &m_dwRefCount)==0)
  39. {
  40. delete this;
  41. return 0;
  42. }
  43. return dwRefCount;
  44. }
  45. //
  46. // CEnumPackage::Next
  47. // ------------------
  48. //
  49. //
  50. //
  51. // Synopsis: This method returns the next celt number of packages
  52. // within the scope of the enumeration.
  53. // Packages are returned in the alphabetical name order.
  54. //
  55. // Arguments: [in] celt - Number of package details to fetch
  56. // INSTALLINFO *rgelt - Package detail structure
  57. // ULONG *pceltFetched - Number of packages returned
  58. //
  59. // Returns: S_OK or S_FALSE if short of packages
  60. //
  61. //
  62. //
  63. HRESULT CEnumPackage::Next(ULONG celt,
  64. PACKAGEDISPINFO *rgelt,
  65. ULONG *pceltFetched)
  66. {
  67. ULONG cgot = 0, i, j;
  68. HRESULT hr = S_OK;
  69. if ((celt > 1) && (!pceltFetched))
  70. return E_INVALIDARG;
  71. if (pceltFetched)
  72. (*pceltFetched) = 0;
  73. if (!IsValidPtrOut(rgelt, sizeof(PACKAGEDISPINFO)*celt))
  74. return E_INVALIDARG;
  75. if (gDebug)
  76. {
  77. WCHAR Name[32];
  78. DWORD NameSize = 32;
  79. if ( ! GetUserName( Name, &NameSize ) )
  80. CSDBGPrint((L"CEnumPackage::Next GetUserName failed 0x%x", GetLastError()));
  81. else
  82. CSDBGPrint((L"CEnumPackage::Next as %s", Name));
  83. }
  84. hr = FetchPackageInfo (m_hADs, m_hADsSearchHandle,
  85. m_dwAppFlags,
  86. m_pPlatform, celt, &cgot, rgelt,
  87. &m_fFirst);
  88. ERROR_ON_FAILURE(hr);
  89. m_dwPosition += cgot;
  90. if (pceltFetched)
  91. *pceltFetched = cgot;
  92. if (cgot != celt)
  93. hr = S_FALSE;
  94. else
  95. hr = S_OK;
  96. for (i=0; i < cgot; ++i)
  97. {
  98. memcpy (&(rgelt[i].GpoId), &m_PolicyId, sizeof(GUID));
  99. if (m_szPolicyName[0])
  100. {
  101. rgelt[i].pszPolicyName = (LPOLESTR) CoTaskMemAlloc(sizeof(WCHAR) * (1+wcslen(&m_szPolicyName[0])));
  102. if (rgelt[i].pszPolicyName)
  103. wcscpy (rgelt[i].pszPolicyName, &m_szPolicyName[0]);
  104. else {
  105. for (j = 0; j < cgot; j++)
  106. ReleasePackageInfo(rgelt+j);
  107. if (pceltFetched)
  108. *pceltFetched = 0;
  109. return E_OUTOFMEMORY;
  110. }
  111. }
  112. }
  113. return hr;
  114. Error_Cleanup:
  115. return RemapErrorCode(hr, m_szPackageName);
  116. }
  117. HRESULT CEnumPackage::Skip(ULONG celt)
  118. {
  119. ULONG celtFetched = NULL, i;
  120. HRESULT hr = S_OK;
  121. PACKAGEDISPINFO *pIf = NULL;
  122. pIf = new PACKAGEDISPINFO[celt];
  123. hr = Next(celt, pIf, &celtFetched);
  124. for (i = 0; i < celtFetched; i++)
  125. ReleasePackageInfo(pIf+i);
  126. delete pIf;
  127. return hr;
  128. }
  129. HRESULT CEnumPackage::Reset()
  130. {
  131. HRESULT hr = S_OK;
  132. m_dwPosition = 0;
  133. m_fFirst = TRUE;
  134. // execute the search and keep the handle returned.
  135. if (m_hADsSearchHandle)
  136. {
  137. ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
  138. m_hADsSearchHandle = NULL;
  139. }
  140. hr = ADSIExecuteSearch(m_hADs, m_szfilter, pszPackageInfoAttrNames,
  141. cPackageInfoAttr, &m_hADsSearchHandle);
  142. return RemapErrorCode(hr, m_szPackageName);
  143. }
  144. HRESULT CEnumPackage::Clone(IEnumPackage **ppenum)
  145. {
  146. CEnumPackage *pClone = new CEnumPackage;
  147. HRESULT hr = S_OK;
  148. hr = pClone->Initialize(m_szPackageName, m_szfilter, m_dwAppFlags, m_pPlatform);
  149. if (FAILED(hr)) {
  150. delete pClone;
  151. return hr;
  152. }
  153. hr = pClone->QueryInterface(IID_IEnumPackage, (void **)ppenum);
  154. if (m_dwPosition)
  155. pClone->Skip(m_dwPosition);
  156. // we do not want to return the error code frm skip.
  157. return hr;
  158. }
  159. CEnumPackage::CEnumPackage()
  160. {
  161. m_dwRefCount = 0;
  162. m_fFirst = TRUE;
  163. m_szfilter = NULL;
  164. wcscpy(m_szPackageName, L"");
  165. m_dwPosition = 0;
  166. m_dwAppFlags = 0;
  167. m_pPlatform = NULL;
  168. m_hADs = NULL;
  169. m_hADsSearchHandle = NULL;
  170. memset (&m_PolicyId, 0, sizeof(GUID));
  171. m_szPolicyName[0] = NULL;
  172. }
  173. CEnumPackage::CEnumPackage(GUID PolicyId, LPOLESTR pszPolicyName)
  174. {
  175. m_dwRefCount = 0;
  176. m_fFirst = TRUE;
  177. m_szfilter = NULL;
  178. wcscpy(m_szPackageName, L"");
  179. m_dwPosition = 0;
  180. m_dwAppFlags = 0;
  181. m_pPlatform = NULL;
  182. m_hADs = NULL;
  183. m_hADsSearchHandle = NULL;
  184. memcpy (&m_PolicyId, &PolicyId, sizeof(GUID));
  185. m_szPolicyName[0] = NULL;
  186. if (pszPolicyName)
  187. wcscpy (&m_szPolicyName[0], pszPolicyName);
  188. }
  189. HRESULT CEnumPackage::Initialize(WCHAR *szPackageName,
  190. WCHAR *szfilter,
  191. DWORD dwAppFlags,
  192. CSPLATFORM *pPlatform)
  193. {
  194. HRESULT hr = S_OK;
  195. ADS_SEARCHPREF_INFO SearchPrefs[2];
  196. m_szfilter = (LPOLESTR)CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(szfilter)+1));
  197. if (!m_szfilter)
  198. return E_OUTOFMEMORY;
  199. // copy the filters, package name, flags and locale.
  200. wcscpy(m_szfilter, szfilter);
  201. wcscpy(m_szPackageName, szPackageName);
  202. m_dwAppFlags = dwAppFlags;
  203. if (gDebug)
  204. {
  205. WCHAR Name[32];
  206. DWORD NameSize = 32;
  207. if ( ! GetUserName( Name, &NameSize ) )
  208. CSDBGPrint((L"CEnumPackage::Initialize GetUserName failed 0x%x", GetLastError()));
  209. else
  210. CSDBGPrint((L"CEnumPackage::Initialize as %s", Name));
  211. }
  212. // open the package container.
  213. hr = ADSIOpenDSObject(szPackageName, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
  214. &m_hADs);
  215. ERROR_ON_FAILURE(hr);
  216. // set the search preference.
  217. SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  218. SearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER;
  219. SearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  220. SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  221. SearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER;
  222. SearchPrefs[1].vValue.Integer = 20;
  223. hr = ADSISetSearchPreference(m_hADs, SearchPrefs, 2);
  224. ERROR_ON_FAILURE(hr);
  225. // copy platform
  226. if (pPlatform)
  227. {
  228. m_pPlatform = (CSPLATFORM *) CoTaskMemAlloc(sizeof(CSPLATFORM));
  229. if (!m_pPlatform)
  230. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  231. memcpy (m_pPlatform, pPlatform, sizeof(CSPLATFORM));
  232. }
  233. // execute the search and keep the handle returned.
  234. hr = ADSIExecuteSearch(m_hADs, szfilter, pszPackageInfoAttrNames,
  235. cPackageInfoAttr, &m_hADsSearchHandle);
  236. Error_Cleanup:
  237. return RemapErrorCode(hr, m_szPackageName);
  238. }
  239. CEnumPackage::~CEnumPackage()
  240. {
  241. if (m_hADsSearchHandle)
  242. ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
  243. if (m_hADs)
  244. ADSICloseDSObject(m_hADs);
  245. if (m_szfilter)
  246. CoTaskMemFree(m_szfilter);
  247. if (m_pPlatform)
  248. CoTaskMemFree(m_pPlatform);
  249. }