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.

1088 lines
27 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: csmain.cxx
  7. //
  8. // Contents: All the exposed APIs.
  9. //
  10. // Author: DebiM
  11. //
  12. //-------------------------------------------------------------------------
  13. #include "cstore.hxx"
  14. // Globals
  15. //
  16. // Link list pointer for Class Containers Seen
  17. //
  18. // CLASSCONTAINER *gpContainerHead = NULL;
  19. //
  20. // Link list pointer for User Profiles Seen
  21. //
  22. // USERPROFILE *gpUserHead = NULL;
  23. //
  24. // Class Factory Objects
  25. //
  26. CClassContainerCF * g_pCF = NULL;
  27. CAppContainerCF * pCF = NULL; // BUGBUG:: Name should change.
  28. CClassAccessCF * pCSAccessCF = NULL;
  29. // Debugging Output Global values.
  30. DWORD gDebugLog = 0;
  31. DWORD gDebugOut = 0;
  32. DWORD gDebugEventLog = 0;
  33. DWORD gDebug = 0;
  34. //IClassAccess * gpClassAccess = NULL;
  35. //
  36. // Number of objects alive in cstore.dll
  37. //
  38. HINSTANCE g_hInst = NULL;
  39. long ObjectCount = 0;
  40. // ULONG g_ulObjCount = 0;
  41. //
  42. // Critical Section for All Global Objects.
  43. //
  44. CRITICAL_SECTION ClassStoreBindList;
  45. void Uninitialize();
  46. BOOL InitializeClassStore(BOOL fInit);
  47. //
  48. //---------------------------------------------------------------------
  49. // Following are used for Supporting Test Scenarios thru FlushSidCache.
  50. WCHAR pwszDebugPath [_MAX_PATH];
  51. BOOL fDebugPath = FALSE;
  52. //---------------------------------------------------------------------
  53. //-------------------------------------------------------------------
  54. // Function Uninitialize
  55. //
  56. // Synopsis: Class Store Server Uninitialization.
  57. // Disconnects from all Class Containers in use.
  58. // Flushes out all State information using ResetClassStoreState.
  59. // Unregisters Server registrations etc..
  60. //
  61. // Arguments: None
  62. //
  63. // Returns: None
  64. //
  65. //-------------------------------------------------------------------
  66. void Uninitialize()
  67. {
  68. //
  69. // Cleanup all open containers
  70. //
  71. //ResetClassStoreState();
  72. //
  73. // release the Class Factory objects
  74. //
  75. if (pCF)
  76. pCF->Release();
  77. if (pCSAccessCF)
  78. pCSAccessCF->Release();
  79. if (g_pCF)
  80. g_pCF->Release();
  81. //
  82. // get rid of the critical section
  83. //
  84. DeleteCriticalSection(&ClassStoreBindList);
  85. }
  86. //---------------------------------------------------------------------------
  87. // Function: FlushSidCache
  88. //
  89. // Synopsis: Supported for Testing Only. Not exposed thru any header.
  90. // Currently useless and not implemented.
  91. //
  92. // Arguments: pwszNewPath
  93. //
  94. // Returns: S_OK
  95. //
  96. //---------------------------------------------------------------------------
  97. HRESULT FlushSidCache (LPOLESTR pwszNewPath)
  98. {
  99. return S_OK;
  100. }
  101. //+---------------------------------------------------------------
  102. //
  103. // Function: InitDebugValues
  104. //
  105. // Synopsis: Initializes the Debug Values for the class store.
  106. //
  107. // Arguments:
  108. //
  109. // Returns:
  110. // S_OK
  111. //
  112. // Log will go into the Debugger if the first bit is 1.
  113. // If second bit is set, log will go into a log file.
  114. // If third bit is set, log will go into event log.
  115. //----------------------------------------------------------------
  116. void InitDebugValues()
  117. {
  118. DWORD Size;
  119. DWORD Type;
  120. DWORD Status;
  121. HKEY hKey;
  122. DWORD DebugLevel = 0;
  123. Status = ERROR_SUCCESS;
  124. Status = RegOpenKeyEx(
  125. HKEY_LOCAL_MACHINE,
  126. DIAGNOSTICS_KEY,
  127. 0,
  128. KEY_READ,
  129. &hKey );
  130. Size = sizeof(DebugLevel);
  131. if ( ERROR_SUCCESS == Status )
  132. {
  133. Status = RegQueryValueEx(
  134. hKey,
  135. DIAGNOSTICS_APPDEPLOYMENT_VALUE,
  136. NULL,
  137. &Type,
  138. (LPBYTE) &DebugLevel,
  139. &Size );
  140. if ( (ERROR_SUCCESS == Status) && (Type != REG_DWORD) )
  141. DebugLevel = 0;
  142. RegCloseKey(hKey);
  143. }
  144. gDebugEventLog = DebugLevel & 4;
  145. gDebugLog = DebugLevel & 2;
  146. gDebugOut = DebugLevel & 1;
  147. gDebug = (gDebugOut || gDebugLog || gDebugEventLog);
  148. }
  149. //---------------------------------------------------------------------------
  150. //
  151. // Function: InitializeClassStore
  152. //
  153. // History: 7-25-96 DebiM Created
  154. //
  155. // This entry point is called at DLL attach
  156. //----------------------------------------------------------------------------
  157. BOOL InitializeClassStore(BOOL fInit)
  158. {
  159. HRESULT hr;
  160. BOOL bStatus;
  161. ObjectCount = 1;
  162. InitDebugValues();
  163. InitializeLanguageSupport();
  164. pCF = new CAppContainerCF();
  165. pCSAccessCF = new CClassAccessCF();
  166. NTSTATUS status = RtlInitializeCriticalSection(&ClassStoreBindList);
  167. g_pCF = new CClassContainerCF;
  168. if (!pCF || !pCSAccessCF || !g_pCF || !NT_SUCCESS(status))
  169. {
  170. ASSERT(FALSE);
  171. goto fail;
  172. }
  173. return TRUE;
  174. fail:
  175. if (pCF)
  176. delete pCF;
  177. if (pCSAccessCF)
  178. delete pCSAccessCF;
  179. if (g_pCF)
  180. {
  181. delete g_pCF;
  182. g_pCF = NULL;
  183. }
  184. return FALSE;
  185. }
  186. void
  187. GetDefaultPlatform(CSPLATFORM *pPlatform)
  188. {
  189. OSVERSIONINFO VersionInformation;
  190. VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  191. GetVersionEx(&VersionInformation);
  192. pPlatform->dwPlatformId = VersionInformation.dwPlatformId;
  193. pPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
  194. pPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
  195. pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE;
  196. }
  197. /*
  198. void Uninit()
  199. //
  200. // This routine is called at dll detach time
  201. //
  202. {
  203. //
  204. // release the Class Factory object
  205. //
  206. if (g_pCF)
  207. g_pCF->Release();
  208. }
  209. */
  210. //+---------------------------------------------------------------
  211. //
  212. // Function: DllGetClassObject
  213. //
  214. // Synopsis: Standard DLL entrypoint for locating class factories
  215. //
  216. // Arguments:
  217. // [in]
  218. // clsid
  219. // Clsid of the object.
  220. // iid
  221. // Iid of the Class factory
  222. // [out]
  223. // ppv Interface pointer to the Class Factory
  224. //
  225. // Returns:
  226. // S_OK, E_NOINTERFACE, E_OUTOFMEMORY
  227. //
  228. // Gets the corresponding Class Factory Object and QIs with the IID.
  229. //----------------------------------------------------------------
  230. STDAPI
  231. DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv)
  232. {
  233. if (IsEqualCLSID(clsid, CLSID_DirectoryClassBase))
  234. {
  235. return g_pCF->QueryInterface(iid, ppv);
  236. }
  237. if (IsEqualCLSID(clsid, CLSID_ClassAccess))
  238. {
  239. return pCSAccessCF->QueryInterface(iid, ppv);
  240. }
  241. *ppv = NULL;
  242. return E_NOINTERFACE;
  243. }
  244. //+-------------------------------------------------------------------
  245. //
  246. // Function: DllCanUnloadNow
  247. //
  248. // Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
  249. //
  250. // Used By:
  251. // Used by OLE to see whether Dll can be unloaded.
  252. //
  253. // Arguments:
  254. //
  255. // Returns :
  256. // S_FALSE.
  257. //
  258. // Unimplemented currently.
  259. //--------------------------------------------------------------------
  260. STDAPI
  261. DllCanUnloadNow(void)
  262. {
  263. HRESULT hr;
  264. hr = S_FALSE;
  265. //
  266. // BugBug
  267. //
  268. /*
  269. if (ulObjectCount > 0)
  270. hr = S_FALSE;
  271. else
  272. hr = S_OK;
  273. */
  274. return hr;
  275. }
  276. //+-------------------------------------------------------------------
  277. //
  278. // Function: LibMain
  279. //
  280. // Synopsis: Standard DLL initialization entrypoint.
  281. //
  282. // Used By:
  283. // During loading and unloading of the DLL.
  284. //
  285. // Arguments:
  286. // [in]
  287. // hInst:
  288. // module Handle.
  289. // ulReason:
  290. // Reason why the DllMain procedure was called.
  291. // pvReserved:
  292. // Unused parameter.
  293. //
  294. // Returns :
  295. // TRUE.
  296. // initializes the global variables in attach and frees them in detach
  297. //
  298. //--------------------------------------------------------------------
  299. EXTERN_C BOOL __cdecl
  300. LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved)
  301. {
  302. // HRESULT hr;
  303. // DWORD cbSize = _MAX_PATH;
  304. // WCHAR wszUserName [_MAX_PATH];
  305. switch (ulReason)
  306. {
  307. // Loading the Dll from the process.
  308. case DLL_PROCESS_ATTACH:
  309. // prevents thread level attach/detach calls.
  310. DisableThreadLibraryCalls(hInst);
  311. g_hInst = hInst;
  312. //g_pCF = new CClassContainerCF;
  313. InitializeClassStore(FALSE);
  314. break;
  315. // unloading the Dll from the process.
  316. case DLL_PROCESS_DETACH:
  317. //Uninit();
  318. Uninitialize();
  319. break;
  320. // ignoring thread attach and detach.
  321. default:
  322. break;
  323. }
  324. return TRUE;
  325. }
  326. //+-------------------------------------------------------------------
  327. //
  328. // Function: DllMain
  329. //
  330. // Synopsis: entry point for NT
  331. //
  332. // Used By:
  333. // During loading and unloading of the DLL.
  334. //
  335. // *Comments*:
  336. // Calls LibMain
  337. //
  338. // Arguments:
  339. // [in]
  340. // hDll:
  341. // module Handle
  342. // dwReason:
  343. // Reason why the DllMain procedure was called.
  344. // lpReserved:
  345. // Unused parameter.
  346. //
  347. // Returns :
  348. // S_OK, CS_E_XXX errors.
  349. //--------------------------------------------------------------------
  350. BOOL
  351. DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  352. {
  353. return LibMain((HINSTANCE)hDll, dwReason, lpReserved);
  354. }
  355. //+-------------------------------------------------------------------------
  356. //
  357. // Function: CsGetClassAccess
  358. //
  359. // Synopsis: Returns an instantiated interface to the Class Store
  360. // Co-ordinator object in Rpcss.
  361. //
  362. // Arguments: [ppIClassAccess] - where to put class access interface pointer
  363. //
  364. // Returns: S_OK - Got a Class Access Successfully
  365. // E_FAIL
  366. //
  367. //--------------------------------------------------------------------------
  368. STDAPI CsGetClassAccess(
  369. IClassAccess ** ppIClassAccess)
  370. {
  371. HRESULT hr;
  372. *ppIClassAccess = NULL;
  373. hr = pCSAccessCF->CreateInstance( NULL,
  374. IID_IClassAccess,
  375. (void **)ppIClassAccess);
  376. return hr;
  377. }
  378. //+-------------------------------------------------------------------
  379. //
  380. // CsEnumApps (DebiM 11/7/97)
  381. //
  382. // Returns an enumerator for packages in the Class Store (s).
  383. // The enumerator works across all class stores in the calling users profile.
  384. //
  385. //
  386. // This is used by:
  387. // - Add/Remove programs to select Corporate Apps
  388. // - winlogon to obtain the list of assigned apps
  389. //
  390. // Arguments:
  391. // [in]
  392. // pszPackageName : Optional Wildcard string for PackageName
  393. // pLastUsn : Optional Time Stamp for new packages
  394. // pCategory : Optional CategoryId
  395. // dwAppFlags : Per APPINFO_xxx in objbase.h
  396. // [out]
  397. // ppIEnumPackage : Returned Interface Pointer
  398. //
  399. // Returns :
  400. // S_OK or E_NO_CLASSSTORE
  401. //
  402. //--------------------------------------------------------------------
  403. STDAPI
  404. CsEnumApps(
  405. LPOLESTR pszPackageName, // Wildcard string for PackageName
  406. GUID *pCategory, // CategoryId
  407. ULONGLONG *pLastUsn, // Time Stamp for new packages
  408. DWORD dwAppFlags, // Per APPINFO_xxx in objbase.h
  409. IEnumPackage **ppIEnumPackage // Returned Interface Pointer
  410. )
  411. {
  412. HRESULT hr;
  413. IClassAccess * pIClassAccess = NULL;
  414. *ppIEnumPackage = NULL;
  415. //
  416. // Get an IClassAccess
  417. //
  418. hr = CsGetClassAccess(&pIClassAccess);
  419. if (!SUCCEEDED(hr))
  420. return hr;
  421. //
  422. // Get the enumerator
  423. //
  424. hr = pIClassAccess->EnumPackages (
  425. pszPackageName,
  426. pCategory,
  427. pLastUsn,
  428. dwAppFlags,
  429. ppIEnumPackage
  430. );
  431. pIClassAccess->Release();
  432. return hr;
  433. }
  434. //+-------------------------------------------------------------------
  435. //
  436. // Function: CsGetAppInfo
  437. //
  438. // Synopsis: Gets Package Information for a package that matches
  439. // the query.
  440. //
  441. // Used By:
  442. // services. CoCreateInstance (OLE)
  443. //
  444. // Arguments:
  445. // [in]
  446. // pClassSpec:
  447. // The query consisting of the name or clsid or ...
  448. // pQueryContext:
  449. // Execution context, architecture/Platform/locale req'd,
  450. // Default value is the ThreadLocale and the default Platform.
  451. //
  452. // [out]
  453. // pPackageInfo
  454. // Neccessary Package Information.
  455. //
  456. // Returns :
  457. // S_OK, CS_E_XXX errors.
  458. //
  459. // Looks up the given class specification in the DS. If an application for
  460. // this class specification is found, then the application details are returned.
  461. // Gets the IClassAccess Pointer and calls GetAppInfo on it.
  462. //
  463. // Caller needs to FREE the pPackageInfo using the Release APIs.
  464. //--------------------------------------------------------------------
  465. STDAPI
  466. CsGetAppInfo(
  467. uCLSSPEC * pClassSpec, // Class Spec (GUID/Ext/MIME)
  468. QUERYCONTEXT * pQueryContext,
  469. PACKAGEDISPINFO * pPackageInfo
  470. )
  471. {
  472. HRESULT hr = S_OK;
  473. IClassAccess * pIClassAccess = NULL;
  474. // Gets the IClassAccess pointer
  475. hr = CsGetClassAccess(&pIClassAccess);
  476. if (!SUCCEEDED(hr))
  477. return hr;
  478. // Calls the GetAppInfo method
  479. hr = pIClassAccess->GetAppInfo(pClassSpec, pQueryContext, pPackageInfo );
  480. pIClassAccess->Release();
  481. return hr;
  482. }
  483. //+-------------------------------------------------------------------
  484. //
  485. // Function: CsCreateClassStore
  486. //
  487. // Synopsis: Creates the class store.
  488. //
  489. // Used By:
  490. // mmc snapin.
  491. //
  492. // Arguments:
  493. // [in]
  494. // szCSPath:
  495. // Path where a new class store has to be created.
  496. //
  497. // Returns :
  498. // S_OK, CS_E_XXX errors.
  499. //
  500. // Removes the moniker if present, gets the parent containers Name (GPO)
  501. // and the name of the class store. Creates a Class Store with this name
  502. // Below the parent object.
  503. //--------------------------------------------------------------------
  504. STDAPI
  505. CsCreateClassStore(LPOLESTR szCSPath)
  506. {
  507. LPOLESTR szPath = NULL;
  508. LPOLESTR szParentPath=NULL, szStoreName=NULL;
  509. HRESULT hr = S_OK;
  510. LPOLESTR szPolicyName = NULL, szUserMachine = NULL;
  511. // removing moniker ADCS: if present.
  512. if (wcsncmp (szCSPath, L"ADCS:", 5) == 0)
  513. szPath = szCSPath + 5;
  514. else
  515. szPath = szCSPath;
  516. // Getting the path for the parent (Policy object) from the name.
  517. hr = BuildADsParentPath(szPath, &szParentPath, &szStoreName);
  518. ERROR_ON_FAILURE(hr);
  519. // Get the Policy Object
  520. hr = BuildADsParentPath(szParentPath, &szPolicyName, &szUserMachine);
  521. if (!SUCCEEDED(hr))
  522. {
  523. szPolicyName = NULL;
  524. }
  525. if (szUserMachine)
  526. FreeADsMem(szUserMachine);
  527. // creating class store. returns CS_E_XXX errors when it returns.
  528. hr = CreateRepository(szParentPath, szStoreName, szPolicyName);
  529. Error_Cleanup:
  530. if (szPolicyName)
  531. FreeADsMem(szPolicyName);
  532. if (szParentPath)
  533. FreeADsMem(szParentPath);
  534. if (szStoreName)
  535. FreeADsMem(szStoreName);
  536. return hr;
  537. }
  538. //+-------------------------------------------------------------------
  539. //
  540. // Function: CsGetClassStore
  541. //
  542. // Synopsis: Gets the IClassAdmin interface pointer for the input class store.
  543. //
  544. // Used By:
  545. // mmc snapin.
  546. //
  547. // Arguments:
  548. // [in]
  549. // szPath:
  550. // Unicode Path For the Class Store.
  551. //
  552. // [out]
  553. // ppIClassAdmin:
  554. // IClassAdmin interface pointer.
  555. //
  556. //
  557. // Returns :
  558. // S_OK, or CS_E_XXX error codes.
  559. //--------------------------------------------------------------------
  560. STDAPI
  561. CsGetClassStore(LPOLESTR szPath, void **ppIClassAdmin)
  562. {
  563. // removing moniker ADCS: if present.
  564. if (wcsncmp (szPath, L"ADCS:", 5) == 0)
  565. szPath += 5;
  566. return g_pCF->CreateConnectedInstance(
  567. szPath,
  568. ppIClassAdmin);
  569. }
  570. //+---------------------------------------------------------------
  571. //
  572. // Function: CsDeleteClassStore
  573. //
  574. // Synopsis: Public entrypoint for deleting a class store container from DS.
  575. // Not implemented.
  576. //
  577. //----------------------------------------------------------------
  578. STDAPI
  579. CsDeleteClassStore(LPOLESTR szPath)
  580. {
  581. return E_NOTIMPL;
  582. }
  583. //+-------------------------------------------------------------------
  584. //
  585. // Function: CsRegisterAppCategory
  586. //
  587. // Synopsis: Registers a cetegory under the Domain.
  588. //
  589. // Used By:
  590. // This is used by Add/Remove programs.
  591. //
  592. // Arguments:
  593. // [in]
  594. // pAppCategory:
  595. // Category and its details that have to be added.
  596. //
  597. // Returns :
  598. // S_OK or CS_E_XXX error codes.
  599. //--------------------------------------------------------------------
  600. STDAPI
  601. CsRegisterAppCategory(APPCATEGORYINFO *pAppCategory)
  602. {
  603. HRESULT hr = S_OK;
  604. IClassAdmin * pIClassAdmin = NULL;
  605. // get the interface pointer
  606. hr = g_pCF->CreateInstance(
  607. NULL,
  608. IID_IClassAdmin,
  609. (void **)&pIClassAdmin);
  610. if (!SUCCEEDED(hr))
  611. return hr;
  612. // get the app categories list.
  613. hr = pIClassAdmin->RegisterAppCategory(pAppCategory);
  614. // release the interface pointer.
  615. pIClassAdmin->Release();
  616. return hr;
  617. }
  618. //+-------------------------------------------------------------------
  619. //
  620. // Function: CsUnregisterAppCategory
  621. //
  622. // Synopsis: Unregister an AppCategory from the Domain.
  623. //
  624. // Used By:
  625. // This is used by Add/Remove programs.
  626. //
  627. // Arguments:
  628. // [in]
  629. // pAppCategoryId:
  630. // Guid (category) that has to be unregistered.
  631. //
  632. // Returns :
  633. // S_OK or CS_E_XXX error codes.
  634. //--------------------------------------------------------------------
  635. STDAPI
  636. CsUnregisterAppCategory (GUID *pAppCategoryId)
  637. {
  638. HRESULT hr = S_OK;
  639. IClassAdmin * pIClassAdmin = NULL;
  640. // get the interface pointer
  641. hr = g_pCF->CreateInstance(
  642. NULL,
  643. IID_IClassAdmin,
  644. (void **)&pIClassAdmin);
  645. if (!SUCCEEDED(hr))
  646. return hr;
  647. // get the app categories list.
  648. hr = pIClassAdmin->UnregisterAppCategory(pAppCategoryId);
  649. // release the interface pointer.
  650. pIClassAdmin->Release();
  651. return hr;
  652. }
  653. //+-------------------------------------------------------------------
  654. //
  655. // Function: CsGetAppCategories
  656. //
  657. // Synopsis: get the definitive list of Application Categories and descriptions
  658. // based on default Locale.
  659. //
  660. // Used By:
  661. // This is used by Add/Remove programs.
  662. //
  663. // *Comments*:
  664. // The caller needs to free the memory allocated using CoTaskMemFree().
  665. //
  666. // Arguments:
  667. // [out]
  668. // AppCategoryList:
  669. // Returned list of GUIDs and Unicode descriptions
  670. //
  671. // Returns :
  672. // S_OK or CS_E_XXX error codes.
  673. //
  674. // Gets the list of Categories published in the Domain.
  675. // The CALLER needs to FREE the memory using Release API.
  676. //--------------------------------------------------------------------
  677. STDAPI
  678. CsGetAppCategories (APPCATEGORYINFOLIST *pAppCategoryList)
  679. {
  680. HRESULT hr = S_OK;
  681. IClassAdmin * pIClassAdmin = NULL;
  682. // get the interface pointer
  683. hr = g_pCF->CreateInstance(
  684. NULL,
  685. IID_IClassAdmin,
  686. (void **)&pIClassAdmin);
  687. if (!SUCCEEDED(hr))
  688. return hr;
  689. // get the app categories list.
  690. hr = pIClassAdmin->GetAppCategories (
  691. GetUserDefaultLCID(),
  692. pAppCategoryList);
  693. // release the interface pointer.
  694. pIClassAdmin->Release();
  695. return hr;
  696. }
  697. //+-------------------------------------------------------------------
  698. //
  699. // Function: CsGetClassStorePath
  700. //
  701. // Synopsis: Returns the class store path.
  702. //
  703. // Used By:
  704. // Winlogon/mmc snapin.
  705. // Arguments:
  706. // [in]
  707. // DSProfilePath:
  708. // Path For the DS Object given to winlogon.
  709. // This is validated here.
  710. //
  711. // [out]
  712. // pCSPath:
  713. // Unicode Path to the class store.
  714. //
  715. // Returns :
  716. // S_OK, or CS_E_XXX error codes.
  717. //
  718. // Looks at the profile object and gets the DEFAULTCLASSSTOREPATH Property.
  719. // The CALLER needs to FREE the memory allocated using CoTaskMemFree().
  720. //--------------------------------------------------------------------
  721. STDAPI
  722. CsGetClassStorePath(LPOLESTR DSProfilePath, LPOLESTR *pCSPath)
  723. {
  724. HRESULT hr;
  725. //
  726. // Initialize locals
  727. //
  728. hr = S_OK;
  729. //
  730. // Initialize out parameters
  731. //
  732. *pCSPath = NULL;
  733. if (gDebug)
  734. {
  735. WCHAR Name[32];
  736. DWORD NameSize = 32;
  737. if ( ! GetUserName( Name, &NameSize ) )
  738. CSDBGPrint((L"GetClassStorePath GetUserName failed 0x%x", GetLastError()));
  739. else
  740. CSDBGPrint((L"GetClassStorePath as %s", Name));
  741. }
  742. //
  743. // Validate the ds path string -- make sure it's NULL terminated
  744. //
  745. if ((!DSProfilePath) || (IsBadStringPtr(DSProfilePath, _MAX_PATH)))
  746. ERROR_ON_FAILURE(hr = E_INVALIDARG);
  747. //
  748. // Make sure the ldap prefix is there
  749. //
  750. if (wcsncmp (DSProfilePath, LDAPPREFIX, LDAPPREFIXLENGTH) != 0)
  751. ERROR_ON_FAILURE(hr = E_INVALIDARG);
  752. //
  753. // Now build the class store path. It would be nice if we could use
  754. // BuildADsPathFromParent to do this, but it does not allocate memory
  755. // with CoTaskMemalloc, and the interface to this function requires that
  756. // the returned cs path is freed by the caller with CoTaskMemfree -- thus
  757. // we have to do all the memory allocation and copying ourselfves.
  758. //
  759. // First, get memory -- length is just the length of the current ds path
  760. // in addition to the length for a path separator and the name of the class
  761. // store container
  762. //
  763. *pCSPath = (LPOLESTR) CoTaskMemAlloc(
  764. wcslen(DSProfilePath) * sizeof (WCHAR) +
  765. sizeof (WCHAR) +
  766. sizeof (CLASSSTORECONTAINERNAME));
  767. if (!(*pCSPath))
  768. ERROR_ON_FAILURE(hr = E_OUTOFMEMORY);
  769. //
  770. // Get the ds path past the prefix so we can use it
  771. // in creating the new path
  772. //
  773. LPOLESTR DSPathWithoutPrefix;
  774. DSPathWithoutPrefix = DSProfilePath + LDAPPREFIXLENGTH;
  775. //
  776. // currently, prefixing LDAP: at the beginning.
  777. //
  778. wsprintf(*pCSPath,
  779. L"%s%s",
  780. LDAPPREFIX CLASSSTORECONTAINERNAME LDAPPATHSEP,
  781. DSPathWithoutPrefix);
  782. Error_Cleanup:
  783. return RemapErrorCode(hr, DSProfilePath);
  784. }
  785. //+-------------------------------------------------------------------
  786. //
  787. // Function: CsSetClassStorePath
  788. //
  789. // Synopsis: Sets the class store path.
  790. //
  791. // Used By:
  792. // mmc snapin.
  793. //
  794. // Arguments:
  795. // [in]
  796. // DSProfilePath:
  797. // Path For the DS Object given to winlogon.
  798. // This is validated here.
  799. //
  800. // [in]
  801. // pCSPath:
  802. // Unicode Path to the class store.
  803. //
  804. // Returns :
  805. // S_OK, or CS_E_XXX error codes.
  806. //
  807. // Sets The Class Store Path on the Profile Object.
  808. // The CALLER needs to FREE the memory allocated using CoTaskMemFree().
  809. //--------------------------------------------------------------------
  810. STDAPI
  811. CsSetClassStorePath(LPOLESTR DSProfilePath, LPOLESTR szCSPath)
  812. {
  813. HRESULT hr = S_OK;
  814. HANDLE hADs = NULL;
  815. LPWSTR AttrName = {DEFAULTCLASSSTOREPATH};
  816. ADS_ATTR_INFO Attr[1];
  817. DWORD cModified = 0;
  818. if ((!DSProfilePath) || (IsBadStringPtr(DSProfilePath, _MAX_PATH)))
  819. return E_INVALIDARG;
  820. if ((!szCSPath) || (IsBadStringPtr(szCSPath, _MAX_PATH)))
  821. return E_INVALIDARG;
  822. // Packing Class store Path minus LDAP: at the beginning.
  823. if (_wcsnicmp(szCSPath, L"ADCS:", 5) == 0)
  824. szCSPath += 5;
  825. PackStrToAttr(Attr, AttrName, szCSPath+wcslen(LDAPPREFIX));
  826. // binding to the Policy Object.
  827. hr = ADSIOpenDSObject(DSProfilePath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
  828. &hADs);
  829. ERROR_ON_FAILURE(hr);
  830. // setting class store path.
  831. hr = ADSISetObjectAttributes(hADs, Attr, 1, &cModified);
  832. // releasing the interface handle
  833. ADSICloseDSObject(hADs);
  834. Error_Cleanup:
  835. return RemapErrorCode(hr, DSProfilePath);
  836. }
  837. //----------------The release APIs-------------------------
  838. STDAPI
  839. ReleasePackageInfo(PACKAGEDISPINFO *pPackageInfo)
  840. {
  841. DWORD i;
  842. if (pPackageInfo)
  843. {
  844. CoTaskMemFree(pPackageInfo->pszScriptPath);
  845. CoTaskMemFree(pPackageInfo->pszPackageName);
  846. CoTaskMemFree(pPackageInfo->pszPolicyName);
  847. for (i = 0; i < (pPackageInfo->cUpgrades); i++)
  848. CoTaskMemFree(pPackageInfo->prgUpgradeInfoList[i].szClassStore);
  849. CoTaskMemFree(pPackageInfo->prgUpgradeInfoList);
  850. CoTaskMemFree(pPackageInfo->pszPublisher);
  851. }
  852. return S_OK;
  853. }
  854. STDAPI
  855. ReleaseAppCategoryInfoList(APPCATEGORYINFOLIST *pAppCategoryInfoList)
  856. {
  857. DWORD i;
  858. if (pAppCategoryInfoList)
  859. {
  860. for (i = 0; i < (pAppCategoryInfoList->cCategory); i++)
  861. CoTaskMemFree((pAppCategoryInfoList->pCategoryInfo)[i].pszDescription);
  862. CoTaskMemFree(pAppCategoryInfoList->pCategoryInfo);
  863. }
  864. return S_OK;
  865. }
  866. STDAPI
  867. ReleaseInstallInfo(INSTALLINFO *pInstallInfo)
  868. {
  869. DWORD i;
  870. if (pInstallInfo)
  871. {
  872. CoTaskMemFree(pInstallInfo->pszSetupCommand);
  873. CoTaskMemFree(pInstallInfo->pszScriptPath);
  874. CoTaskMemFree(pInstallInfo->pszUrl);
  875. CoTaskMemFree(pInstallInfo->pClsid);
  876. for (i = 0; i < (pInstallInfo->cUpgrades); i++)
  877. CoTaskMemFree(pInstallInfo->prgUpgradeInfoList[i].szClassStore);
  878. CoTaskMemFree(pInstallInfo->prgUpgradeInfoList);
  879. }
  880. return S_OK;
  881. }
  882. void
  883. ReleaseClassDetail(CLASSDETAIL ClassDetail)
  884. {
  885. DWORD i;
  886. for (i = 0; i < ClassDetail.cProgId; i++)
  887. CoTaskMemFree(ClassDetail.prgProgId[i]);
  888. CoTaskMemFree(ClassDetail.prgProgId);
  889. }
  890. STDAPI
  891. ReleasePackageDetail(PACKAGEDETAIL *pPackageDetail)
  892. {
  893. DWORD i;
  894. if (pPackageDetail)
  895. {
  896. if (pPackageDetail->pActInfo)
  897. {
  898. for (i = 0; i < pPackageDetail->pActInfo->cClasses; i++)
  899. ReleaseClassDetail((pPackageDetail->pActInfo->pClasses)[i]);
  900. CoTaskMemFree(pPackageDetail->pActInfo->pClasses);
  901. for (i = 0; i < pPackageDetail->pActInfo->cShellFileExt; i++)
  902. CoTaskMemFree((pPackageDetail->pActInfo->prgShellFileExt)[i]);
  903. CoTaskMemFree(pPackageDetail->pActInfo->prgShellFileExt);
  904. CoTaskMemFree(pPackageDetail->pActInfo->prgPriority);
  905. CoTaskMemFree(pPackageDetail->pActInfo->prgInterfaceId);
  906. CoTaskMemFree(pPackageDetail->pActInfo->prgTlbId);
  907. CoTaskMemFree(pPackageDetail->pActInfo);
  908. }
  909. if (pPackageDetail->pPlatformInfo)
  910. {
  911. CoTaskMemFree(pPackageDetail->pPlatformInfo->prgPlatform);
  912. CoTaskMemFree(pPackageDetail->pPlatformInfo->prgLocale);
  913. CoTaskMemFree(pPackageDetail->pPlatformInfo);
  914. }
  915. if (pPackageDetail->pInstallInfo)
  916. {
  917. ReleaseInstallInfo(pPackageDetail->pInstallInfo);
  918. CoTaskMemFree(pPackageDetail->pInstallInfo);
  919. }
  920. for (i = 0; i < (pPackageDetail->cSources); i++)
  921. CoTaskMemFree(pPackageDetail->pszSourceList[i]);
  922. CoTaskMemFree(pPackageDetail->pszSourceList);
  923. CoTaskMemFree(pPackageDetail->pszPackageName);
  924. CoTaskMemFree(pPackageDetail->rpCategory);
  925. }
  926. return S_OK;
  927. }