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.

512 lines
12 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1999
  5. //
  6. // File: enumapp.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. //
  74. // Clear up this structure in case our fetch fails --
  75. // we don't want callers freeing invalid memory
  76. //
  77. memset(rgelt, 0, sizeof(*rgelt) * celt);
  78. hr = FetchPackageInfo (
  79. m_hADs,
  80. m_hADsSearchHandle,
  81. m_dwAppFlags,
  82. m_dwQuerySpec,
  83. m_pPlatform,
  84. celt,
  85. &cgot,
  86. rgelt,
  87. &m_fFirst,
  88. &m_PolicyId,
  89. m_szGpoPath,
  90. m_pRsopUserToken);
  91. if (FAILED(hr))
  92. {
  93. //
  94. // Clear up this structure so that callers don't
  95. // try to free invalid memory when this fails
  96. //
  97. memset(rgelt, 0, sizeof(*rgelt) * celt);
  98. cgot = 0;
  99. if ( ( ( APPQUERY_RSOP_ARP == m_dwQuerySpec ) || ( APPQUERY_USERDISPLAY == m_dwQuerySpec ) ) &&
  100. ( hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT) ) )
  101. {
  102. hr = S_FALSE;
  103. }
  104. }
  105. ERROR_ON_FAILURE(hr);
  106. m_dwPosition += cgot;
  107. if (pceltFetched)
  108. *pceltFetched = cgot;
  109. if (cgot != celt)
  110. hr = S_FALSE;
  111. else
  112. hr = S_OK;
  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. LPOLESTR* ppszAttrs;
  133. DWORD cAttrs;
  134. m_dwPosition = 0;
  135. m_fFirst = TRUE;
  136. // execute the search and keep the handle returned.
  137. if (m_hADsSearchHandle)
  138. {
  139. ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
  140. m_hADsSearchHandle = NULL;
  141. }
  142. ppszAttrs = GetAttributesFromQuerySpec(
  143. m_dwQuerySpec,
  144. &cAttrs);
  145. if ( ppszAttrs )
  146. {
  147. hr = ADSIExecuteSearch(
  148. m_hADs,
  149. m_szfilter,
  150. ppszAttrs,
  151. cAttrs,
  152. &m_hADsSearchHandle);
  153. }
  154. else
  155. {
  156. hr = E_INVALIDARG;
  157. }
  158. return RemapErrorCode(hr, m_szPackageName);
  159. }
  160. CEnumPackage::CEnumPackage(CServerContext* pServerContext, GUID PolicyId, LPOLESTR pszPolicyName, LPOLESTR pszClassStorePath, PRSOPTOKEN pRsopToken )
  161. {
  162. m_dwRefCount = 0;
  163. m_fFirst = TRUE;
  164. m_szfilter = NULL;
  165. m_dwPosition = 0;
  166. m_dwAppFlags = 0;
  167. m_pPlatform = NULL;
  168. m_hADs = NULL;
  169. m_hADsSearchHandle = NULL;
  170. memcpy (&m_PolicyId, &PolicyId, sizeof(GUID));
  171. m_szPolicyName[0] = NULL;
  172. m_pRsopUserToken = pRsopToken;
  173. m_szPackageName[0] = L'\0';
  174. if (pszPolicyName)
  175. {
  176. (void) StringCchCopy (m_szPolicyName, _MAX_PATH, pszPolicyName);
  177. }
  178. if ( pServerContext )
  179. {
  180. HRESULT hrContext;
  181. hrContext = m_ServerContext.Initialize( pServerContext );
  182. //
  183. // If this fails, we will skip subsequent initialization as well,
  184. // and any operations with this object will fail because those
  185. // intiailziations are not complete
  186. //
  187. if ( FAILED(hrContext) )
  188. {
  189. return;
  190. }
  191. }
  192. //
  193. // Remember the path of the gpo from which we are originating
  194. // This information is needed for RSOP to determine where
  195. // the package came from
  196. //
  197. // Note that if this fails, no operations on this object will succeed
  198. //
  199. m_szGpoPath = AllocGpoPathFromClassStorePath( pszClassStorePath );
  200. }
  201. HRESULT CEnumPackage::Initialize(
  202. WCHAR *szPackageName,
  203. WCHAR *szfilter,
  204. DWORD dwAppFlags,
  205. BOOL bPlanning,
  206. CSPLATFORM *pPlatform)
  207. {
  208. HRESULT hr = S_OK;
  209. ADS_SEARCHPREF_INFO SearchPrefs[3];
  210. LPOLESTR* ppszAttrs;
  211. DWORD cAttrs;
  212. LONG lSecurityFlags;
  213. DWORD cPrefs;
  214. cPrefs = 2;
  215. //
  216. // Be sure we're properly initialized
  217. //
  218. if ( ! m_szGpoPath )
  219. {
  220. return E_OUTOFMEMORY;
  221. }
  222. //
  223. // Set the security of our communications based on the preference
  224. // of the caller
  225. //
  226. lSecurityFlags = GetDsFlags();
  227. m_szfilter = (LPOLESTR)CsMemAlloc (sizeof(WCHAR) * (wcslen(szfilter)+1));
  228. if (!m_szfilter)
  229. return E_OUTOFMEMORY;
  230. // copy the filters, package name, flags and locale.
  231. hr = StringCchCopy(m_szfilter, wcslen(szfilter)+1, szfilter);
  232. ERROR_ON_FAILURE(hr);
  233. hr = StringCchCopy(m_szPackageName, _MAX_PATH, szPackageName);
  234. ERROR_ON_FAILURE(hr);
  235. m_dwAppFlags = ClientSideFilterFromQuerySpec( dwAppFlags, bPlanning );
  236. m_dwQuerySpec = dwAppFlags;
  237. // open the package container.
  238. hr = DSServerOpenDSObject(&m_ServerContext, szPackageName, lSecurityFlags,
  239. &m_hADs);
  240. ERROR_ON_FAILURE(hr);
  241. // set the search preference.
  242. SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  243. SearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER;
  244. SearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  245. SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  246. SearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER;
  247. SearchPrefs[1].vValue.Integer = SEARCHPAGESIZE;
  248. //
  249. // For RSOP, we need to add an extra search pref to obtain the security
  250. // descriptor
  251. //
  252. if ( ( APPQUERY_RSOP_ARP == dwAppFlags ) ||
  253. ( APPQUERY_RSOP_LOGGING == dwAppFlags ) )
  254. {
  255. SearchPrefs[2].dwSearchPref = ADS_SEARCHPREF_SECURITY_MASK;
  256. SearchPrefs[2].vValue.dwType = ADSTYPE_INTEGER;
  257. //
  258. // Request everything but the SACL
  259. //
  260. SearchPrefs[2].vValue.Integer =
  261. OWNER_SECURITY_INFORMATION |
  262. GROUP_SECURITY_INFORMATION |
  263. DACL_SECURITY_INFORMATION;
  264. cPrefs ++;
  265. }
  266. hr = ADSISetSearchPreference(m_hADs, SearchPrefs, cPrefs);
  267. ERROR_ON_FAILURE(hr);
  268. // copy platform
  269. if (pPlatform)
  270. {
  271. m_pPlatform = (CSPLATFORM *) CsMemAlloc(sizeof(CSPLATFORM));
  272. if (!m_pPlatform)
  273. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  274. memcpy (m_pPlatform, pPlatform, sizeof(CSPLATFORM));
  275. }
  276. ppszAttrs = GetAttributesFromQuerySpec(
  277. m_dwQuerySpec,
  278. &cAttrs);
  279. // execute the search and keep the handle returned.
  280. hr = ADSIExecuteSearch(
  281. m_hADs,
  282. szfilter,
  283. ppszAttrs,
  284. cAttrs,
  285. &m_hADsSearchHandle);
  286. Error_Cleanup:
  287. return RemapErrorCode(hr, m_szPackageName);
  288. }
  289. CEnumPackage::~CEnumPackage()
  290. {
  291. if (m_hADsSearchHandle)
  292. ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
  293. if (m_hADs)
  294. ADSICloseDSObject(m_hADs);
  295. if (m_szfilter)
  296. CsMemFree(m_szfilter);
  297. if (m_pPlatform)
  298. CsMemFree(m_pPlatform);
  299. if (m_szGpoPath)
  300. CsMemFree(m_szGpoPath);
  301. }
  302. //--------------------------------------------------------------
  303. CMergedEnumPackage::CMergedEnumPackage()
  304. {
  305. m_pcsEnum = NULL;
  306. m_cEnum = 0;
  307. m_csnum = 0;
  308. m_dwRefCount = 0;
  309. }
  310. CMergedEnumPackage::~CMergedEnumPackage()
  311. {
  312. ULONG i;
  313. for (i = 0; i < m_cEnum; i++)
  314. m_pcsEnum[i]->Release();
  315. CsMemFree(m_pcsEnum);
  316. }
  317. HRESULT __stdcall CMergedEnumPackage::QueryInterface(REFIID riid,
  318. void * * ppObject)
  319. {
  320. *ppObject = NULL; //gd
  321. if ((riid==IID_IUnknown) || (riid==IID_IEnumPackage))
  322. {
  323. *ppObject=(IEnumPackage *) this;
  324. }
  325. else
  326. {
  327. return E_NOINTERFACE;
  328. }
  329. AddRef();
  330. return S_OK;
  331. }
  332. ULONG __stdcall CMergedEnumPackage::AddRef()
  333. {
  334. InterlockedIncrement((long*) &m_dwRefCount);
  335. return m_dwRefCount;
  336. }
  337. ULONG __stdcall CMergedEnumPackage::Release()
  338. {
  339. ULONG dwRefCount;
  340. if ((dwRefCount = InterlockedDecrement((long*) &m_dwRefCount))==0)
  341. {
  342. delete this;
  343. return 0;
  344. }
  345. return dwRefCount;
  346. }
  347. HRESULT __stdcall CMergedEnumPackage::Next(
  348. ULONG celt,
  349. PACKAGEDISPINFO *rgelt,
  350. ULONG *pceltFetched)
  351. {
  352. ULONG count=0, total = 0;
  353. HRESULT hr;
  354. //
  355. // Clear everything
  356. //
  357. memset( rgelt, 0, sizeof(*rgelt) * celt );
  358. for (; m_csnum < m_cEnum; m_csnum++)
  359. {
  360. count = 0;
  361. hr = m_pcsEnum[m_csnum]->Next(celt, rgelt+total, &count);
  362. if (FAILED(hr))
  363. {
  364. //
  365. // Release everything on failure
  366. //
  367. ULONG iAllocated;
  368. for ( iAllocated = 0; iAllocated < total; iAllocated++ )
  369. {
  370. ReleasePackageInfo( rgelt+iAllocated );
  371. }
  372. return hr;
  373. }
  374. total += count;
  375. celt -= count;
  376. if (!celt)
  377. break;
  378. }
  379. if (pceltFetched)
  380. *pceltFetched = total;
  381. if (!celt)
  382. return S_OK;
  383. return S_FALSE;
  384. }
  385. HRESULT __stdcall CMergedEnumPackage::Skip(
  386. ULONG celt)
  387. {
  388. PACKAGEDISPINFO *pPackageInfo = NULL;
  389. HRESULT hr = S_OK;
  390. ULONG cgot = 0, i;
  391. pPackageInfo = (PACKAGEDISPINFO *)CsMemAlloc(sizeof(PACKAGEDISPINFO)*celt);
  392. if (!pPackageInfo)
  393. return E_OUTOFMEMORY;
  394. hr = Next(celt, pPackageInfo, &cgot);
  395. for (i = 0; i < cgot; i++)
  396. ReleasePackageInfo(pPackageInfo+i);
  397. CsMemFree(pPackageInfo);
  398. return hr;
  399. }
  400. HRESULT __stdcall CMergedEnumPackage::Reset()
  401. {
  402. ULONG i;
  403. for (i = 0; ((i <= m_csnum) && (i < m_cEnum)); i++)
  404. m_pcsEnum[i]->Reset(); // ignoring all error values
  405. m_csnum = 0;
  406. return S_OK;
  407. }
  408. HRESULT CMergedEnumPackage::Initialize(IEnumPackage **pcsEnum, ULONG cEnum)
  409. {
  410. ULONG i;
  411. m_csnum = 0;
  412. m_pcsEnum = (IEnumPackage **)CsMemAlloc(sizeof(IEnumPackage *) * cEnum);
  413. if (!m_pcsEnum)
  414. return E_OUTOFMEMORY;
  415. for (i = 0; i < cEnum; i++)
  416. m_pcsEnum[i] = pcsEnum[i];
  417. m_cEnum = cEnum;
  418. return S_OK;
  419. }