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.

817 lines
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998.
  5. //
  6. // File: Cfact.cpp
  7. //
  8. // Contents: Main Dll api and Class Factory interface
  9. //
  10. // Classes: CClassFactory
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. STDAPI DllRegisterServer(void);
  19. STDAPI DllPerUserRegister(void);
  20. STDAPI DllPerUserUnregister(void);
  21. EXTERN_C int APIENTRY mobsyncDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved);
  22. STDAPI mobsyncDllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv);
  23. STDAPI mobsyncDllRegisterServer(void);
  24. STDAPI mobsyncDllUnregisterServer(void);
  25. STDAPI mobsyncDllCanUnloadNow(void);
  26. #define PrxDllMain mobsyncDllMain
  27. #define PrxDllRegisterServer mobsyncDllRegisterServer
  28. #define PrxDllUnregisterServer mobsyncDllUnregisterServer
  29. #define PrxDllMain mobsyncDllMain
  30. #define PrxDllGetClassObject mobsyncDllGetClassObject
  31. #define PrxDllCanUnloadNow mobsyncDllCanUnloadNow
  32. //
  33. // Global variables
  34. //
  35. UINT g_cRefThisDll = 0; // Reference count of this DLL.
  36. HINSTANCE g_hmodThisDll = NULL; // Handle to this DLL itself.
  37. CRITICAL_SECTION g_DllCriticalSection; // Global Critical Section for this DLL
  38. LANGID g_LangIdSystem; // LangId of system we are running on.
  39. // routines for catching WinLogon
  40. EXTERN_C DWORD WINAPI
  41. WinLogonEvent(
  42. LPVOID lpParam
  43. )
  44. {
  45. return 0;
  46. }
  47. EXTERN_C DWORD WINAPI
  48. WinLogoffEvent(
  49. LPVOID lpParam
  50. )
  51. {
  52. return 0;
  53. }
  54. // Setup APIs. Should be moved to another file but wait until after ship.
  55. // declarations for install variables and sections. Any changes
  56. // to these declarations must also have a corresponding changes to .inf
  57. // .inf sections names
  58. #define INSTALLSECTION_MACHINEINSTALL "Reg"
  59. #define INSTALLSECTION_MACHINEUNINSTALL "UnReg"
  60. #define INSTALLSECTION_REGISTERSHORTCUT "RegShortcut"
  61. #define INSTALLSECTION_UNREGISTERSHORTCUT "UnRegShortcut"
  62. #define INSTALLSETCION_PERUSERINSTALL "PerUserInstall"
  63. #define INSTALLSECTION_SETUP_PERUSERINSTALL "SetupPerUserInstall"
  64. #define INSTALLSECTION_REMOVE_PERUSERINSTALL "RemovePerUserInstall"
  65. // Variable declarations
  66. #define MODULEPATH_MAXVALUESIZE MAX_PATH
  67. #define SZ_MODULEPATH "MODULEPATH"
  68. #define ACCESSORIESGROUP_MAXVALUESIZE MAX_PATH
  69. #define SZ_ACCESSORIESGROUP "ACESSORIES_GROUP"
  70. // Synchronize LinkName
  71. #define SYNCHRONIZE_LINKNAME_MAXVALUESIZE MAX_PATH
  72. #define SZ_SYNCHRONIZE_LINKNAME "SYNCHRONIZE_LINKNAME"
  73. // Synchronization PerUserInstall Dislay Name
  74. #define SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE MAX_PATH
  75. #define SZ_SYNCHRONIZE_PERUSERDISPLAYNAME "SYNCHRONIZE_PERUSERDISPLAYNAME"
  76. //+---------------------------------------------------------------------------
  77. //
  78. // function: RunDllRegister, public export
  79. //
  80. // Synopsis: processes cmdlines from Rundll32 cmd
  81. //
  82. // Arguments:
  83. //
  84. // Returns:
  85. //
  86. // Modifies:
  87. //
  88. // History: 08-Dec-97 rogerg Created.
  89. // 27-Oct-98 rogerg Added perUser Flags.
  90. //
  91. //----------------------------------------------------------------------------
  92. // export for how Rundll32 calls us
  93. EXTERN_C void WINAPI RunDllRegister(HWND hwnd,
  94. HINSTANCE hAppInstance,
  95. LPSTR pszCmdLine,
  96. int nCmdShow)
  97. {
  98. char *pCmdLine = pszCmdLine;
  99. // if no cmdLine do a register.
  100. if (!pCmdLine || '\0' == *pCmdLine)
  101. {
  102. DllRegisterServer();
  103. return;
  104. }
  105. // only allow cmdlines inthe form of /
  106. if ('/' != *pCmdLine)
  107. {
  108. AssertSz(0,"Invalid CmdLine");
  109. return;
  110. }
  111. ++pCmdLine;
  112. // command lines we support for .inf installs are
  113. // /u - Uninstall
  114. // /p - perUser Install
  115. // /pu - perUser UnInstall
  116. switch(*pCmdLine)
  117. {
  118. case 'u':
  119. case 'U':
  120. DllUnregisterServer();
  121. break;
  122. case 'p':
  123. case 'P':
  124. ++pCmdLine;
  125. switch(*pCmdLine)
  126. {
  127. case '\0':
  128. DllPerUserRegister();
  129. break;
  130. case 'u':
  131. case 'U':
  132. DllPerUserUnregister();
  133. break;
  134. default:
  135. AssertSz(0,"Unknown PerUser Command");
  136. break;
  137. }
  138. break;
  139. default:
  140. AssertSz(0,"Unknown Cmd Line");
  141. break;
  142. }
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // function: GetAccessoriesGroupName, private
  147. //
  148. // Synopsis: Gets the Name of the Accessories group
  149. // from the registry.
  150. //
  151. // Arguments:
  152. //
  153. // Returns:
  154. //
  155. // Modifies:
  156. //
  157. // History: ??-???-98 rogerg Created.
  158. //
  159. //----------------------------------------------------------------------------
  160. // if can get accessories group name register our shortcut.
  161. // accessories name is located at
  162. // key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion Value = SM_AccessoriesName
  163. // !! MUST ALWAYS RETURN ANSI
  164. HRESULT GetAccessoriesGroupName(char *pszAccessories,DWORD cbSize)
  165. {
  166. HKEY hkeyWindowsCurrentVersion;
  167. BOOL fHaveAccessoriesName = FALSE;
  168. DWORD dwDataSize = cbSize;
  169. if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",0,KEY_READ,
  170. &hkeyWindowsCurrentVersion) )
  171. {
  172. if (ERROR_SUCCESS == SHRegGetValueA(hkeyWindowsCurrentVersion,NULL,"SM_AccessoriesName",SRRF_RT_REG_SZ | SRRF_NOEXPAND, NULL,
  173. (LPBYTE) pszAccessories, &dwDataSize) )
  174. {
  175. fHaveAccessoriesName = TRUE;
  176. }
  177. RegCloseKey(hkeyWindowsCurrentVersion);
  178. }
  179. //AssertSz(fHaveAccessoriesName,"Couldn't Get Accessories Group Name");
  180. return fHaveAccessoriesName ? NOERROR : E_UNEXPECTED;
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // function: GetModulePath, private
  185. //
  186. // Synopsis: Gets the Path to us with our name stripped out.
  187. //
  188. // Note - sets pszModulePath to NULL on error.
  189. //
  190. // Arguments:
  191. //
  192. // Returns:
  193. //
  194. // Modifies:
  195. //
  196. // History: 27-Oct-98 rogerg Created.
  197. //
  198. //----------------------------------------------------------------------------
  199. HRESULT GetModulePath(char *pszModulePath,DWORD cbSize)
  200. {
  201. DWORD dwModuleLen;
  202. Assert(pszModulePath && cbSize >= 1);
  203. if (!pszModulePath || cbSize < 1)
  204. {
  205. AssertSz(0,"Invalid ModulePath Ptr");
  206. return S_FALSE;
  207. }
  208. *pszModulePath = NULL;
  209. // setup the module path based on our dir.
  210. if(dwModuleLen = GetModuleFileNameA(
  211. g_hmodThisDll,
  212. pszModulePath,
  213. cbSize) )
  214. {
  215. char *pszCurChar = pszModulePath + dwModuleLen - 1;
  216. // NEED to strip off dll name from path, walk back until hit a \ or beginning of string.
  217. // call with CharPrev but really shouldn't have to since name is never localized.
  218. // on no match want an empty string, on a match want path + last backslash.
  219. while (pszCurChar)
  220. {
  221. char *pszPrevChar = CharPrevA(pszModulePath,pszCurChar);
  222. if(pszPrevChar <= pszModulePath)
  223. {
  224. *pszModulePath = '\0'; // if got all the way to the end then make an empty string.
  225. break;
  226. }
  227. if (*pszPrevChar == '\\')
  228. {
  229. *pszCurChar = '\0';
  230. break;
  231. }
  232. // check the next character
  233. pszCurChar = pszPrevChar;
  234. }
  235. }
  236. return *pszModulePath ? S_OK : S_FALSE;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // function: SetupInfVariables, private
  241. //
  242. // Synopsis: sets up the variables we pass to the .inf file
  243. // if fail to setup a variable it is set to NULL
  244. //
  245. // Arguments: cbNumEntries - number of entries in the arrays
  246. // pseReg - Array of STRENTRYs
  247. // pdwSizes - Array of String sizes for STRENTRY Values.
  248. //
  249. // Returns:
  250. //
  251. // Modifies:
  252. //
  253. // History: 27-Oct-98 rogerg Created.
  254. //
  255. //----------------------------------------------------------------------------
  256. /*
  257. typedef struct _StrEntry {
  258. LPSTR pszName; // String to substitute
  259. LPSTR pszValue; // Replacement string or string resource
  260. } STRENTRY, *LPSTRENTRY;
  261. */
  262. void SetupInfVariables(DWORD cbNumEntries,STRENTRY *pseReg,DWORD *pdwSizes)
  263. {
  264. STRENTRY *pCurEntry;
  265. DWORD *pCurSize;
  266. Assert(pseReg);
  267. Assert(pdwSizes);
  268. pCurEntry = pseReg;
  269. pCurSize = pdwSizes;
  270. // loop through the entries getting the info.
  271. // Entry names are always in ANSI
  272. while (cbNumEntries--)
  273. {
  274. Assert(*pCurSize);
  275. if (0 < *pCurSize)
  276. {
  277. // null out entry in case of failure
  278. *(pCurEntry->pszValue) = '\0';
  279. // see if it matches a known variable.
  280. if (!lstrcmpA(pCurEntry->pszName,SZ_MODULEPATH))
  281. {
  282. // setup the module path based on our dir.
  283. // GetModulePath sets szModulePath to NULL on error.
  284. GetModulePath(pCurEntry->pszValue,*pCurSize);
  285. }
  286. else if (!lstrcmpA(pCurEntry->pszName,SZ_ACCESSORIESGROUP))
  287. {
  288. if (NOERROR != GetAccessoriesGroupName(pCurEntry->pszValue,*pCurSize))
  289. {
  290. *(pCurEntry->pszValue) = '\0';
  291. }
  292. }
  293. else if (!lstrcmpA(pCurEntry->pszName,SZ_SYNCHRONIZE_LINKNAME))
  294. {
  295. // if size is too small the string will be truncated.
  296. LoadStringA(g_hmodThisDll,IDS_SHORTCUTNAME,pCurEntry->pszValue,*pCurSize);
  297. }
  298. else if (!lstrcmpA(pCurEntry->pszName,SZ_SYNCHRONIZE_PERUSERDISPLAYNAME))
  299. {
  300. // if size is too small the string will be truncated.
  301. LoadStringA(g_hmodThisDll,IDS_SYNCMGR_PERUSERDISPLAYNAME,pCurEntry->pszValue,*pCurSize);
  302. }
  303. else
  304. {
  305. AssertSz(0,"Uknown Setup Variable");
  306. }
  307. }
  308. pCurEntry++;
  309. pCurSize++;
  310. }
  311. }
  312. HRESULT CallRegInstall(LPSTR szSection,STRTABLE *stReg)
  313. {
  314. HRESULT hr = E_FAIL;
  315. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  316. if (hinstAdvPack)
  317. {
  318. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, achREGINSTALL);
  319. if (pfnri)
  320. {
  321. hr = pfnri(g_hmodThisDll, szSection,stReg);
  322. }
  323. FreeLibrary(hinstAdvPack);
  324. }
  325. return hr;
  326. }
  327. STDAPI DllRegisterServer(void)
  328. {
  329. HRESULT hr = NOERROR;
  330. char szModulePath[MODULEPATH_MAXVALUESIZE]; // !!! these must always be ANSI
  331. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  332. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  333. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  334. // register any proxies
  335. HRESULT hRes = PrxDllRegisterServer();
  336. // !!! STRENTRY and CallResInstall are always ANSI
  337. STRENTRY seReg[] = {
  338. { SZ_MODULEPATH, szModulePath},
  339. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  340. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  341. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  342. };
  343. DWORD cbNumEntries = ARRAYSIZE(seReg);
  344. // fill in sizes for how big the string Values are.
  345. DWORD rgdwSizes[] = {
  346. ARRAYSIZE(szModulePath),
  347. ARRAYSIZE(szAccessoriesGroup),
  348. ARRAYSIZE(szSynchronizeLinkName),
  349. ARRAYSIZE(szSynchronizePerUserDisplayName),
  350. };
  351. Assert(ARRAYSIZE(seReg) == ARRAYSIZE(rgdwSizes));
  352. Assert(ARRAYSIZE(seReg) == cbNumEntries);
  353. Assert(4 == cbNumEntries); // to make sure ARRAYSIZE is working properly
  354. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  355. // initialize the variables.
  356. SetupInfVariables(cbNumEntries, seReg, rgdwSizes);
  357. // register the RegKeys pasing in the path to the module
  358. // call even if couldn't get shortcut.
  359. CallRegInstall(INSTALLSECTION_MACHINEINSTALL,&stReg); // reg the reg keys
  360. // if got the accessories and shortcut name, register the shortcut.
  361. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  362. {
  363. CallRegInstall(INSTALLSECTION_REGISTERSHORTCUT,&stReg); // reg the reg keys
  364. }
  365. CallRegInstall(INSTALLSECTION_SETUP_PERUSERINSTALL,&stReg);
  366. //
  367. // Convert the "mobsync.exe /logon" reg value to use a fully-qualified path string.
  368. //
  369. RegFixRunKey();
  370. return hr;
  371. }
  372. /////////////////////////////////////////////////////////////////////////////
  373. // DllUnregisterServer - Removes entries from the system registry
  374. STDAPI DllUnregisterServer(void)
  375. {
  376. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  377. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  378. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  379. // setup variables to pass to .inf
  380. STRENTRY seReg[] = {
  381. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  382. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  383. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  384. };
  385. DWORD cbNumEntries = ARRAYSIZE(seReg);
  386. // fill in sizes for how big the string Values are.
  387. DWORD rgdwSizes[] = {
  388. ARRAYSIZE(szAccessoriesGroup),
  389. ARRAYSIZE(szSynchronizeLinkName),
  390. ARRAYSIZE(szSynchronizePerUserDisplayName),
  391. };
  392. Assert(ARRAYSIZE(seReg) == ARRAYSIZE(rgdwSizes));
  393. Assert(ARRAYSIZE(seReg) == cbNumEntries);
  394. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  395. // initialize the variables.
  396. SetupInfVariables(cbNumEntries, seReg, rgdwSizes);
  397. // remove any schedules the user created
  398. RegUninstallSchedules();
  399. // remove or LCE/SENS registrations
  400. RegRegisterForEvents(TRUE /* fUninstall */);
  401. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, AUTOSYNC_REGKEY); // remove AutoSync key
  402. // remove the proxies
  403. PrxDllUnregisterServer();
  404. CallRegInstall(INSTALLSECTION_REMOVE_PERUSERINSTALL,&stReg);
  405. // unreg our regkeys
  406. CallRegInstall(INSTALLSECTION_MACHINEUNINSTALL,&stReg);
  407. // if got shortcut and accessories group remove shorcut
  408. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  409. {
  410. CallRegInstall(INSTALLSECTION_UNREGISTERSHORTCUT,&stReg); // reg the reg keys
  411. }
  412. // review, should be able to do this from .inf file
  413. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, IDLESYNC_REGKEY); // remove Idle key
  414. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, MANUALSYNC_REGKEY); // remove Manual key
  415. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, PROGRESS_REGKEY); // remove ProgressState key
  416. return S_OK;
  417. }
  418. //+---------------------------------------------------------------------------
  419. //
  420. // function: DllPerUserRegister, private
  421. //
  422. // Synopsis: Handles PerUser Registration
  423. //
  424. // Arguments:
  425. //
  426. // Returns:
  427. //
  428. // Modifies:
  429. //
  430. // History: 27-Oct-98 rogerg Created.
  431. //
  432. //----------------------------------------------------------------------------
  433. STDAPI DllPerUserRegister(void)
  434. {
  435. char szModulePath[MODULEPATH_MAXVALUESIZE]; // !!! these must always be ANSI
  436. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  437. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  438. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  439. // setup variables to pass to .inf
  440. STRENTRY seReg[] = {
  441. { SZ_MODULEPATH, szModulePath},
  442. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  443. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  444. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  445. };
  446. DWORD cbNumEntries = ARRAYSIZE(seReg);
  447. // fill in sizes for how big the string Values are.
  448. DWORD rgdwSizes[] = {
  449. ARRAYSIZE(szModulePath),
  450. ARRAYSIZE(szAccessoriesGroup),
  451. ARRAYSIZE(szSynchronizeLinkName),
  452. ARRAYSIZE(szSynchronizePerUserDisplayName),
  453. };
  454. Assert(ARRAYSIZE(seReg) == ARRAYSIZE(rgdwSizes));
  455. Assert(ARRAYSIZE(seReg) == cbNumEntries);
  456. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  457. // initialize the variables.
  458. SetupInfVariables(cbNumEntries, seReg, rgdwSizes);
  459. // if got the accessories and shortcut name, register the shortcut.
  460. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  461. {
  462. CallRegInstall(INSTALLSECTION_REGISTERSHORTCUT,&stReg); // reg the reg keys
  463. }
  464. return S_OK;
  465. }
  466. //+---------------------------------------------------------------------------
  467. //
  468. // function: DllPerUserUnregister, private
  469. //
  470. // Synopsis: Handles PerUser UnRegistration. Currently not
  471. // used since dll is removed on machine unregister
  472. // there is no dll to call next time user logs on.
  473. //
  474. // Arguments:
  475. //
  476. // Returns:
  477. //
  478. // Modifies:
  479. //
  480. // History: 27-Oct-98 rogerg Created.
  481. //
  482. //----------------------------------------------------------------------------
  483. STDAPI DllPerUserUnregister(void)
  484. {
  485. AssertSz(0,"DllPerUserUnregister Called");
  486. return S_OK;
  487. }
  488. // End of Setup APIs
  489. extern "C" int APIENTRY
  490. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  491. {
  492. int iRet = 0;
  493. if (PrxDllMain(hInstance, dwReason, lpReserved))
  494. {
  495. if (dwReason == DLL_PROCESS_ATTACH)
  496. {
  497. if (InitializeCriticalSectionAndSpinCount(&g_DllCriticalSection, 0))
  498. {
  499. g_hmodThisDll = hInstance;
  500. #ifdef _DEBUG
  501. InitDebugFlags();
  502. #endif // _DEBUG
  503. InitCommonLib();
  504. g_LangIdSystem = GetSystemDefaultLangID(); // find out what lang we are on
  505. //initialize the common controls
  506. INITCOMMONCONTROLSEX controlsEx;
  507. controlsEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  508. controlsEx.dwICC = ICC_USEREX_CLASSES | ICC_WIN95_CLASSES | ICC_NATIVEFNTCTL_CLASS;
  509. InitCommonControlsEx(&controlsEx);
  510. iRet = 1;
  511. }
  512. }
  513. else if (dwReason == DLL_PROCESS_DETACH)
  514. {
  515. UnInitCommonLib();
  516. Assert(0 == g_cRefThisDll);
  517. DeleteCriticalSection(&g_DllCriticalSection);
  518. TRACE("In DLLMain, DLL_PROCESS_DETACH\r\n");
  519. iRet = 1;
  520. }
  521. }
  522. return iRet;
  523. }
  524. //---------------------------------------------------------------------------
  525. // DllCanUnloadNow
  526. //---------------------------------------------------------------------------
  527. STDAPI DllCanUnloadNow(void)
  528. {
  529. HRESULT hr;
  530. TRACE("In DLLCanUnloadNow\r\n");
  531. if (PrxDllCanUnloadNow() != S_OK)
  532. {
  533. return S_FALSE;
  534. }
  535. if (g_cRefThisDll)
  536. {
  537. hr = S_FALSE;
  538. }
  539. else
  540. {
  541. hr = S_OK;
  542. }
  543. return hr;
  544. }
  545. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
  546. {
  547. HRESULT hr = E_OUTOFMEMORY;
  548. TRACE("In DllGetClassObject\r\n");
  549. *ppvOut = NULL;
  550. if (IsEqualIID(rclsid, CLSID_SyncMgr))
  551. {
  552. CClassFactory *pcf = new CClassFactory;
  553. if (NULL != pcf)
  554. {
  555. hr = pcf->QueryInterface(riid, ppvOut);
  556. pcf->Release();
  557. }
  558. }
  559. else
  560. {
  561. hr = PrxDllGetClassObject(rclsid,riid, ppvOut);
  562. }
  563. return hr;
  564. }
  565. CClassFactory::CClassFactory()
  566. {
  567. TRACE("CClassFactory::CClassFactory()\r\n");
  568. m_cRef = 1;
  569. InterlockedIncrement((LONG *)& g_cRefThisDll);
  570. }
  571. CClassFactory::~CClassFactory()
  572. {
  573. InterlockedDecrement((LONG *)& g_cRefThisDll);
  574. }
  575. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,
  576. LPVOID FAR *ppv)
  577. {
  578. TRACE("CClassFactory::QueryInterface()\r\n");
  579. *ppv = NULL;
  580. // Any interface on this object is the object pointer
  581. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  582. {
  583. *ppv = (LPCLASSFACTORY)this;
  584. AddRef();
  585. return NOERROR;
  586. }
  587. return E_NOINTERFACE;
  588. }
  589. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  590. {
  591. ULONG cRefs;
  592. // Increment ref count
  593. cRefs = InterlockedIncrement((LONG *)& m_cRef);
  594. return cRefs;
  595. }
  596. STDMETHODIMP_(ULONG) CClassFactory::Release()
  597. {
  598. ULONG cRefs;
  599. cRefs = InterlockedDecrement( (LONG *) &m_cRef);
  600. if (0 == cRefs)
  601. {
  602. delete this;
  603. }
  604. return cRefs;
  605. }
  606. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
  607. REFIID riid,
  608. LPVOID *ppvObj)
  609. {
  610. HRESULT hr;
  611. TRACE("CClassFactory::CreateInstance()\r\n");
  612. *ppvObj = NULL;
  613. if (pUnkOuter)
  614. return CLASS_E_NOAGGREGATION;
  615. LPSYNCMGRSYNCHRONIZEINVOKE pSyncMgrDllObject = (LPSYNCMGRSYNCHRONIZEINVOKE)
  616. new CSyncMgrSynchronize;
  617. if (NULL == pSyncMgrDllObject)
  618. return E_OUTOFMEMORY;
  619. hr = pSyncMgrDllObject->QueryInterface(riid, ppvObj);
  620. pSyncMgrDllObject->Release();
  621. return hr;
  622. }
  623. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  624. {
  625. if (fLock)
  626. {
  627. InterlockedIncrement( (LONG *) &g_cRefThisDll);
  628. }
  629. else
  630. {
  631. InterlockedDecrement( (LONG *) &g_cRefThisDll);
  632. }
  633. return NOERROR;
  634. }