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.

864 lines
23 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1997
  4. *
  5. * TITLE: CFactory.Cpp
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 26 Dec, 1997
  12. *
  13. * DESCRIPTION:
  14. * Class factory implementation for ImageIn.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #include "stiexe.h"
  19. //#include <assert.h>
  20. #include "wiacfact.h"
  21. #include <sddl.h>
  22. extern HINSTANCE g_hInst;
  23. BOOL setValue(LPCTSTR, LPCTSTR, LPCTSTR);
  24. BOOL setBinValue(LPCTSTR, LPCTSTR, DWORD, BYTE*);
  25. BOOL setKeyAndValue(LPCTSTR, LPCTSTR, LPCTSTR);
  26. BOOL SubkeyExists(LPCTSTR, LPCTSTR);
  27. LONG recursiveDeleteKey(HKEY, LPCTSTR);
  28. BOOL GetWiaDefaultDCOMSecurityDescriptor(
  29. VOID **ppSecurityDescriptor,
  30. ULONG *pulSize)
  31. {
  32. ULONG ulAclSize = 0;
  33. BOOL bRet = FALSE;
  34. //
  35. // Create our security descriptor. We do this using a string format security
  36. // descriptor, which we then convert to a real security descriptor.
  37. //
  38. // NOTE: Caller has to free the security descriptor with LocalFree...
  39. //
  40. if ( ConvertStringSecurityDescriptorToSecurityDescriptor(wszDefaultDaclForDCOMAccessPermission,
  41. SDDL_REVISION_1,
  42. (PSECURITY_DESCRIPTOR*)ppSecurityDescriptor,
  43. pulSize)) {
  44. bRet = TRUE;
  45. } else {
  46. DBG_ERR(("ConvertStringSecurityDescriptorToSecurityDescriptor Failed"));
  47. }
  48. return bRet;
  49. }
  50. /*******************************************************************************
  51. *
  52. * RegisterServer
  53. *
  54. * DESCRIPTION:
  55. * Register a COM component in the Registry. From Inside COM.
  56. *
  57. * PARAMETERS:
  58. *
  59. *******************************************************************************/
  60. HRESULT RegisterServer(
  61. LPCTSTR szModuleFileName,
  62. const CLSID* pclsid,
  63. LPCTSTR szFriendlyName,
  64. LPCTSTR szVerIndProgID,
  65. LPCTSTR szProgID,
  66. LPCTSTR szService,
  67. const GUID* plibid,
  68. BOOLEAN bOutProc)
  69. {
  70. BOOL bResult = TRUE;
  71. //
  72. // Fill in the path to the module file name.
  73. //
  74. TCHAR szModule[MAX_PATH] = {0};
  75. if (!GetModuleFileName(g_hInst, szModule, sizeof(szModule)/sizeof(szModule[0]) - 1)) {
  76. #ifdef DEBUG
  77. OutputDebugString(TEXT("Error extracting service module name."));
  78. #endif
  79. return E_FAIL;
  80. }
  81. //
  82. // Strip the filename from the path
  83. //
  84. TCHAR *pChar = &szModule[lstrlen(szModule)];
  85. while ((pChar > szModule) && (*pChar != '\\')) {
  86. pChar--;
  87. }
  88. if (pChar == szModule) {
  89. #ifdef DEBUG
  90. OutputDebugString(TEXT("Error extracting Still Image service path."));
  91. #endif
  92. return E_FAIL;
  93. } else {
  94. pChar++;
  95. *pChar = '\0';
  96. }
  97. if (szModuleFileName) {
  98. if (lstrlen(szModuleFileName) > (int)((sizeof(szModule) / sizeof(szModule[0]) - lstrlen(szModule)))) {
  99. #ifdef DEBUG
  100. OutputDebugString(TEXT("szModuleFileName parameter is too long."));
  101. #endif
  102. return E_INVALIDARG;
  103. }
  104. } else {
  105. #ifdef DEBUG
  106. OutputDebugString(TEXT("NULL szModuleFileName parameter"));
  107. #endif
  108. return E_INVALIDARG;
  109. }
  110. //
  111. // Concatenate server module name (XXXXX.exe) with path
  112. //
  113. if( lstrcat(szModule, szModuleFileName) == NULL)
  114. {
  115. #ifdef DEBUG
  116. OutputDebugString(TEXT("Error concatenating module file name and path"));
  117. #endif
  118. return E_FAIL;
  119. }
  120. // Convert the CLSID into a char.
  121. LPOLESTR pszCLSID;
  122. LPOLESTR pszLIBID;
  123. TCHAR szCLSID[64];
  124. TCHAR szLIBID[64];
  125. HRESULT hr = StringFromCLSID(*pclsid, &pszCLSID);
  126. if (FAILED(hr)) {
  127. return hr;
  128. }
  129. hr = StringFromCLSID(*plibid, &pszLIBID);
  130. if (FAILED(hr)) {
  131. return hr;
  132. }
  133. #ifdef UNICODE
  134. lstrcpy(szCLSID, pszCLSID);
  135. lstrcpy(szLIBID, pszLIBID);
  136. #else
  137. WideCharToMultiByte(CP_ACP,
  138. 0,
  139. pszCLSID,
  140. -1,
  141. szCLSID,
  142. sizeof(szCLSID),
  143. NULL,
  144. NULL);
  145. WideCharToMultiByte(CP_ACP,
  146. 0,
  147. pszLIBID,
  148. -1,
  149. szLIBID,
  150. sizeof(szLIBID),
  151. NULL,
  152. NULL);
  153. #endif
  154. // Build the key CLSID\\{...}
  155. TCHAR szKey[64] = TEXT("CLSID\\");
  156. lstrcat(szKey, szCLSID);
  157. // Add the CLSID to the registry.
  158. bResult &= setKeyAndValue(szKey, NULL, szFriendlyName) ;
  159. // Add the server filename subkey under the CLSID key.
  160. if (bOutProc) {
  161. bResult &= setKeyAndValue(szKey, TEXT("LocalServer32"), szModule);
  162. // If the server is implemented as a service add the service
  163. // AppID keys and values.
  164. if (szService) {
  165. // Add the service AppID value to the CLSID key.
  166. bResult &= setValue(szKey, TEXT("AppID"), szCLSID);
  167. // Add the AppID key.
  168. TCHAR szAppID[64] = TEXT("AppID\\");
  169. lstrcat(szAppID, szCLSID);
  170. bResult &= setKeyAndValue(szAppID, NULL, szFriendlyName);
  171. bResult &= setValue(szAppID, TEXT("LocalService"), szService);
  172. //
  173. // Add an ACL to protect instantiation.
  174. //
  175. DWORD dwSize = 0;
  176. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  177. if (GetWiaDefaultDCOMSecurityDescriptor((VOID**)&pSecurityDescriptor, &dwSize)) {
  178. //
  179. // Write this self-relative security descriptor to the AccessPermission value
  180. // under our AppID
  181. //
  182. setBinValue(szAppID, TEXT("AccessPermission"), dwSize, (BYTE*)pSecurityDescriptor);
  183. LocalFree(pSecurityDescriptor);
  184. pSecurityDescriptor = NULL;
  185. } else {
  186. DBG_ERR(("GetWiaDefaultDCOMSecurityDescriptor failed"));
  187. }
  188. }
  189. }
  190. else {
  191. bResult &= setKeyAndValue(szKey, TEXT("InprocServer32"), szModule);
  192. }
  193. // Add the ProgID subkey under the CLSID key.
  194. bResult &= setKeyAndValue(szKey, TEXT("ProgID"), szProgID) ;
  195. // Add the version-independent ProgID subkey under CLSID key.
  196. bResult &= setKeyAndValue(szKey, TEXT("VersionIndependentProgID"),
  197. szVerIndProgID) ;
  198. // Add the Type Library ID subkey under the CLSID key.
  199. bResult &= setKeyAndValue(szKey, TEXT("TypeLib"), szLIBID) ;
  200. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  201. bResult &= setKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;
  202. bResult &= setKeyAndValue(szVerIndProgID, TEXT("CLSID"), szCLSID) ;
  203. bResult &= setKeyAndValue(szVerIndProgID, TEXT("CurVer"), szProgID) ;
  204. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  205. bResult &= setKeyAndValue(szProgID, NULL, szFriendlyName) ;
  206. bResult &= setKeyAndValue(szProgID, TEXT("CLSID"), szCLSID) ;
  207. CoTaskMemFree(pszCLSID);
  208. CoTaskMemFree(pszLIBID);
  209. if (bResult) {
  210. return S_OK;
  211. }
  212. else {
  213. return E_FAIL;
  214. }
  215. }
  216. /*******************************************************************************
  217. *
  218. * UnregisterServer
  219. *
  220. * DESCRIPTION:
  221. * Remove a COM component from the registry. From Inside COM.
  222. *
  223. * PARAMETERS:
  224. *
  225. *******************************************************************************/
  226. HRESULT UnregisterServer(
  227. const CLSID* pclsid,
  228. LPCTSTR szVerIndProgID,
  229. LPCTSTR szProgID,
  230. LPCTSTR szService)
  231. {
  232. // Convert the CLSID into a char.
  233. LPOLESTR pszCLSID;
  234. HRESULT hr = StringFromCLSID(*pclsid, &pszCLSID);
  235. if (FAILED(hr) || !pszCLSID) {
  236. return E_UNEXPECTED;
  237. }
  238. TCHAR szCLSID[64];
  239. #ifdef UNICODE
  240. lstrcpy(szCLSID, pszCLSID);
  241. #else
  242. WideCharToMultiByte(CP_ACP,
  243. 0,
  244. pszCLSID,
  245. -1,
  246. szCLSID,
  247. sizeof(szCLSID),
  248. NULL,
  249. NULL);
  250. #endif
  251. // Build the key CLSID\\{...}
  252. TCHAR szKey[64] = TEXT("CLSID\\");
  253. lstrcat(szKey, szCLSID) ;
  254. // Delete the CLSID Key - CLSID\{...}
  255. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
  256. if ((lResult != ERROR_SUCCESS) &&
  257. (lResult != ERROR_FILE_NOT_FOUND)) {
  258. return HRESULT_FROM_WIN32(lResult);
  259. }
  260. // Delete the AppID Key - AppID\{...}
  261. if (szService) {
  262. TCHAR szAppID[64] = TEXT("AppID\\");
  263. lstrcat(szAppID, szCLSID) ;
  264. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szAppID);
  265. if ((lResult != ERROR_SUCCESS) &&
  266. (lResult != ERROR_FILE_NOT_FOUND)) {
  267. return HRESULT_FROM_WIN32(lResult);
  268. }
  269. }
  270. // Delete the version-independent ProgID Key.
  271. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
  272. if ((lResult != ERROR_SUCCESS) &&
  273. (lResult != ERROR_FILE_NOT_FOUND)) {
  274. return HRESULT_FROM_WIN32(lResult);
  275. }
  276. // Delete the ProgID key.
  277. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
  278. if ((lResult != ERROR_SUCCESS) &&
  279. (lResult != ERROR_FILE_NOT_FOUND)) {
  280. return HRESULT_FROM_WIN32(lResult);
  281. }
  282. CoTaskMemFree(pszCLSID);
  283. return S_OK ;
  284. }
  285. /*******************************************************************************
  286. *
  287. * recursiveDeleteKey
  288. *
  289. * DESCRIPTION:
  290. * Delete a key and all of its descendents. From Inside COM.
  291. * PARAMETERS:
  292. *
  293. *******************************************************************************/
  294. LONG recursiveDeleteKey(
  295. HKEY hKeyParent,
  296. LPCTSTR lpszKeyChild
  297. )
  298. {
  299. // Open the child.
  300. HKEY hKeyChild ;
  301. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  302. KEY_ALL_ACCESS, &hKeyChild) ;
  303. if (lRes != ERROR_SUCCESS)
  304. {
  305. return lRes ;
  306. }
  307. // Enumerate all of the decendents of this child.
  308. FILETIME time ;
  309. TCHAR szBuffer[256] ;
  310. DWORD dwSize = 256 ;
  311. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  312. NULL, NULL, &time) == S_OK)
  313. {
  314. // Delete the decendents of this child.
  315. lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
  316. if (lRes != ERROR_SUCCESS)
  317. {
  318. // Cleanup before exiting.
  319. RegCloseKey(hKeyChild) ;
  320. return lRes;
  321. }
  322. dwSize = 256 ;
  323. }
  324. // Close the child.
  325. RegCloseKey(hKeyChild) ;
  326. // Delete this child.
  327. return RegDeleteKey(hKeyParent, lpszKeyChild) ;
  328. }
  329. /*******************************************************************************
  330. *
  331. * SubkeyExists
  332. *
  333. * DESCRIPTION:
  334. * Determine if a particular subkey exists. From Inside COM.
  335. *
  336. * PARAMETERS:
  337. *
  338. *******************************************************************************/
  339. BOOL SubkeyExists(
  340. LPCTSTR pszPath,
  341. LPCTSTR szSubkey
  342. )
  343. {
  344. HKEY hKey ;
  345. TCHAR szKeyBuf[80];
  346. UINT uSubKeyChars = 0;
  347. if (!pszPath) {
  348. return FALSE;
  349. }
  350. if (szSubkey)
  351. {
  352. // The "+1" is for the TEXT("\\")
  353. uSubKeyChars = lstrlen(szSubkey) + 1;
  354. }
  355. if ((lstrlen(pszPath)+uSubKeyChars) > (sizeof(szKeyBuf) / sizeof(szKeyBuf[0]) - 1)) {
  356. return FALSE;
  357. }
  358. // Copy keyname into buffer.
  359. lstrcpy(szKeyBuf, pszPath) ;
  360. // Add subkey name to buffer.
  361. if (szSubkey != NULL)
  362. {
  363. lstrcat(szKeyBuf, TEXT("\\")) ;
  364. lstrcat(szKeyBuf, szSubkey ) ;
  365. }
  366. // Determine if key exists by trying to open it.
  367. LONG lResult = ::RegOpenKeyEx(HKEY_CLASSES_ROOT,
  368. szKeyBuf,
  369. 0,
  370. KEY_READ,
  371. &hKey) ;
  372. if (lResult == ERROR_SUCCESS)
  373. {
  374. RegCloseKey(hKey) ;
  375. return TRUE ;
  376. }
  377. return FALSE ;
  378. }
  379. /*******************************************************************************
  380. *
  381. * setKeyAndValue
  382. *
  383. * DESCRIPTION:
  384. * Create a key and set its value. From Inside OLE.
  385. *
  386. * PARAMETERS:
  387. *
  388. *******************************************************************************/
  389. BOOL setKeyAndValue(
  390. LPCTSTR szKey,
  391. LPCTSTR szSubkey,
  392. LPCTSTR szValue)
  393. {
  394. HKEY hKey;
  395. TCHAR szKeyBuf[1024] ;
  396. BOOL bVal = FALSE;
  397. UINT uSubKeyChars = 0;
  398. if (!szKey) {
  399. return FALSE;
  400. }
  401. if (szSubkey)
  402. {
  403. // the "+1" is for the TEXT("\\")
  404. uSubKeyChars = lstrlen(szSubkey) + 1;
  405. }
  406. if ((lstrlen(szKey)+uSubKeyChars) > (sizeof(szKeyBuf) / sizeof(szKeyBuf[0]) - 1)) {
  407. return FALSE;
  408. }
  409. // Copy keyname into buffer.
  410. lstrcpy(szKeyBuf, szKey) ;
  411. // Add subkey name to buffer.
  412. if (szSubkey != NULL)
  413. {
  414. lstrcat(szKeyBuf, TEXT("\\")) ;
  415. lstrcat(szKeyBuf, szSubkey ) ;
  416. }
  417. // Create and open key and subkey.
  418. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  419. szKeyBuf,
  420. 0, NULL, REG_OPTION_NON_VOLATILE,
  421. KEY_ALL_ACCESS, NULL,
  422. &hKey, NULL) ;
  423. if (lResult != ERROR_SUCCESS)
  424. {
  425. return FALSE ;
  426. }
  427. // Set the Value.
  428. if (szValue != NULL)
  429. {
  430. lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ,
  431. (BYTE *)szValue,
  432. (lstrlen(szValue)+1) * sizeof(TCHAR)) ;
  433. if (lResult == ERROR_SUCCESS) {
  434. bVal = TRUE;
  435. }
  436. }
  437. RegCloseKey(hKey) ;
  438. return bVal;
  439. }
  440. /*******************************************************************************
  441. *
  442. * setValue
  443. *
  444. * DESCRIPTION:
  445. * Create and set a value.
  446. *
  447. * PARAMETERS:
  448. *
  449. *******************************************************************************/
  450. BOOL setValue(
  451. LPCTSTR pszKey,
  452. LPCTSTR pszValueName,
  453. LPCTSTR pszValue)
  454. {
  455. HKEY hKey;
  456. DWORD dwSize;
  457. BOOL bRet = FALSE;
  458. if (RegOpenKey(HKEY_CLASSES_ROOT, pszKey, &hKey) == ERROR_SUCCESS) {
  459. dwSize = (lstrlen(pszValue) + 1) * sizeof(TCHAR);
  460. if (RegSetValueEx(hKey,
  461. pszValueName,
  462. 0,
  463. REG_SZ,
  464. (PBYTE) pszValue,
  465. dwSize) == ERROR_SUCCESS) {
  466. bRet = TRUE;
  467. //
  468. // NOTE: Leak here on failure - this should be moved out of this block
  469. //
  470. RegCloseKey(hKey);
  471. }
  472. }
  473. return bRet;
  474. }
  475. /*******************************************************************************
  476. *
  477. * setBinValue
  478. *
  479. * DESCRIPTION:
  480. * Create and set a binary value.
  481. *
  482. * PARAMETERS:
  483. *
  484. *******************************************************************************/
  485. BOOL setBinValue(
  486. LPCTSTR pszKey,
  487. LPCTSTR pszValueName,
  488. DWORD dwSize,
  489. BYTE *pbValue)
  490. {
  491. HKEY hKey;
  492. BOOL bRet = FALSE;
  493. if (RegOpenKey(HKEY_CLASSES_ROOT, pszKey, &hKey) == ERROR_SUCCESS) {
  494. if (RegSetValueEx(hKey,
  495. pszValueName,
  496. 0,
  497. REG_BINARY,
  498. pbValue,
  499. dwSize) == ERROR_SUCCESS) {
  500. bRet = TRUE;
  501. }
  502. RegCloseKey(hKey);
  503. }
  504. return bRet;
  505. }
  506. /*******************************************************************************
  507. *
  508. * S T A T I C D A T A
  509. *
  510. *******************************************************************************/
  511. LONG CFactory::s_cServerLocks = 0; // Count of server locks
  512. HMODULE CFactory::s_hModule = NULL; // DLL module handle
  513. DWORD CFactory::s_dwThreadID = 0;
  514. /*******************************************************************************
  515. *
  516. * CFactory constructor
  517. *
  518. * DESCRIPTION:
  519. *
  520. * PARAMETERS:
  521. *
  522. *******************************************************************************/
  523. CFactory::CFactory(PFACTORY_DATA pFactoryData): m_cRef(1)
  524. {
  525. m_pFactoryData = pFactoryData;
  526. }
  527. /*******************************************************************************
  528. *
  529. * CFactory::QueryInterface
  530. *
  531. * DESCRIPTION:
  532. * IUnknown implementation.
  533. *
  534. * PARAMETERS:
  535. *
  536. *******************************************************************************/
  537. HRESULT __stdcall CFactory::QueryInterface(REFIID iid, void** ppv)
  538. {
  539. if ((iid == IID_IUnknown) || (iid==IID_IClassFactory)) {
  540. *ppv = (IClassFactory*)this;
  541. }
  542. else {
  543. return E_NOINTERFACE;
  544. }
  545. AddRef();
  546. return S_OK;
  547. }
  548. /*******************************************************************************
  549. *
  550. * CFactory::AddRef
  551. * CFactory::Release
  552. *
  553. * DESCRIPTION:
  554. * Reference counting methods.
  555. *
  556. * PARAMETERS:
  557. *
  558. *******************************************************************************/
  559. ULONG __stdcall CFactory::AddRef()
  560. {
  561. return ::InterlockedIncrement(&m_cRef);
  562. }
  563. ULONG __stdcall CFactory::Release()
  564. {
  565. if (::InterlockedDecrement(&m_cRef) == 0) {
  566. delete this;
  567. return 0 ;
  568. }
  569. return m_cRef;
  570. }
  571. /*******************************************************************************
  572. *
  573. * CreateInstance
  574. * LockServer
  575. *
  576. * DESCRIPTION:
  577. * Class Factory Interface.
  578. *
  579. * PARAMETERS:
  580. *
  581. *******************************************************************************/
  582. HRESULT __stdcall CFactory::CreateInstance(
  583. IUnknown* pOuter,
  584. const IID& iid,
  585. void** ppv
  586. )
  587. {
  588. *ppv = NULL;
  589. // No support for aggregation, if we have an outer class then bail.
  590. if (pOuter) {
  591. return CLASS_E_NOAGGREGATION;
  592. }
  593. return m_pFactoryData->CreateInstance(iid, ppv);
  594. }
  595. HRESULT __stdcall CFactory::LockServer(BOOL bLock)
  596. {
  597. if (bLock) {
  598. CWiaSvc::AddRef();
  599. }
  600. else {
  601. CWiaSvc::Release();
  602. }
  603. return S_OK;
  604. }
  605. /*******************************************************************************
  606. *
  607. * CFactory::CanUnloadNow
  608. *
  609. * DESCRIPTION:
  610. * Determine if the component can be unloaded.
  611. *
  612. * PARAMETERS:
  613. *
  614. *******************************************************************************/
  615. HRESULT CFactory::CanUnloadNow()
  616. {
  617. if (IsLocked()) {
  618. return S_FALSE;
  619. }
  620. else {
  621. return S_OK;
  622. }
  623. }
  624. /*******************************************************************************
  625. *
  626. * CFactory::RegisterUnregisterAll
  627. *
  628. * DESCRIPTION:
  629. * Register/Unregister all components.
  630. *
  631. * PARAMETERS:
  632. *
  633. *******************************************************************************/
  634. HRESULT CFactory::RegisterUnregisterAll(
  635. PFACTORY_DATA pFactoryData,
  636. UINT uiFactoryDataCount,
  637. BOOLEAN bRegister,
  638. BOOLEAN bOutProc
  639. )
  640. {
  641. HRESULT hr = E_FAIL;
  642. UINT i;
  643. for (i = 0; i < uiFactoryDataCount; i++) {
  644. if (bRegister) {
  645. hr = RegisterServer(pFactoryData[i].szModuleFileName,
  646. pFactoryData[i].pclsid,
  647. pFactoryData[i].szRegName,
  648. pFactoryData[i].szVerIndProgID,
  649. pFactoryData[i].szProgID,
  650. pFactoryData[i].szService,
  651. pFactoryData[i].plibid,
  652. bOutProc);
  653. }
  654. else {
  655. hr = UnregisterServer(pFactoryData[i].pclsid,
  656. pFactoryData[i].szVerIndProgID,
  657. pFactoryData[i].szProgID,
  658. pFactoryData[i].szService);
  659. }
  660. if (FAILED(hr)) {
  661. break;
  662. }
  663. }
  664. return hr;
  665. }
  666. /*******************************************************************************
  667. *
  668. * CFactory::StartFactories
  669. *
  670. * DESCRIPTION:
  671. * Start the class factories.
  672. *
  673. * PARAMETERS:
  674. *
  675. *******************************************************************************/
  676. BOOL CFactory::StartFactories(
  677. PFACTORY_DATA pFactoryData,
  678. UINT uiFactoryDataCount
  679. )
  680. {
  681. PFACTORY_DATA pData, pStart = pFactoryData;
  682. PFACTORY_DATA pEnd = &pFactoryData[uiFactoryDataCount - 1];
  683. for (pData = pStart; pData <= pEnd; pData++) {
  684. // Initialize the class factory pointer and cookie.
  685. pData->pIClassFactory = NULL;
  686. pData->dwRegister = NULL;
  687. // Create the class factory for this component.
  688. IClassFactory* pIFactory = new CFactory(pData);
  689. if (pIFactory) {
  690. // Register the class factory.
  691. DWORD dwRegister;
  692. HRESULT hr = ::CoRegisterClassObject(
  693. *(pData->pclsid),
  694. static_cast<IUnknown*>(pIFactory),
  695. CLSCTX_LOCAL_SERVER,
  696. REGCLS_MULTIPLEUSE,
  697. &dwRegister);
  698. if (FAILED(hr)) {
  699. DBG_ERR(("CFactory::StartFactories, CoRegisterClassObject CFactory Failed 0x%X", hr));
  700. pIFactory->Release();
  701. return FALSE;
  702. }
  703. // Set the data.
  704. pData->pIClassFactory = pIFactory;
  705. pData->dwRegister = dwRegister;
  706. }
  707. else {
  708. DBG_ERR(("CFactory::StartFactories, New CFactory Failed"));
  709. }
  710. }
  711. DBG_TRC(("CFactory::StartFactories, Success"));
  712. return TRUE;
  713. }
  714. /*******************************************************************************
  715. *
  716. * CFactory::StopFactories
  717. *
  718. * DESCRIPTION:
  719. * Stop the class factories.
  720. *
  721. * PARAMETERS:
  722. *
  723. *******************************************************************************/
  724. void CFactory::StopFactories(
  725. PFACTORY_DATA pFactoryData,
  726. UINT uiFactoryDataCount
  727. )
  728. {
  729. PFACTORY_DATA pData, pStart = pFactoryData;
  730. PFACTORY_DATA pEnd = &pFactoryData[uiFactoryDataCount - 1];
  731. for (pData = pStart; pData <= pEnd; pData++) {
  732. // Get the magic cookie and stop the factory from running.
  733. DWORD dwRegister = pData->dwRegister;
  734. if (dwRegister != 0) {
  735. ::CoRevokeClassObject(dwRegister);
  736. }
  737. // Release the class factory.
  738. IClassFactory* pIFactory = pData->pIClassFactory ;
  739. if (pIFactory != NULL) {
  740. pIFactory->Release() ;
  741. }
  742. }
  743. }