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.

1035 lines
26 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. DWORD g_dwPlatformId = 0; // the OSVersion info
  38. CRITICAL_SECTION g_DllCriticalSection; // Global Critical Section for this DLL
  39. OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo,
  40. LANGID g_LangIdSystem; // LangId of system we are running on.
  41. #define _WINLOGON_ 0
  42. #if _WINLOGON_
  43. #include <winwlx.h>
  44. // extern void WINAPI Sleep(DWORD dwMilliseconds);
  45. HRESULT MakeOneStopInstance(PWLX_NOTIFICATION_INFO pNotify,TCHAR *pCommandLine,BOOL fSync)
  46. {
  47. STARTUPINFO si;
  48. PROCESS_INFORMATION ProcessInformation;
  49. if ( 1 /* fuser */ )
  50. {
  51. si.cb = sizeof(STARTUPINFO);
  52. si.lpReserved = NULL;
  53. si.lpTitle = NULL;
  54. si.lpDesktop = NULL;
  55. si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
  56. si.dwFlags = 0;;
  57. si.wShowWindow = SW_SHOW;
  58. si.lpReserved2 = NULL;
  59. si.cbReserved2 = 0;
  60. if (CreateProcessAsUser(pNotify->hToken,NULL, pCommandLine, NULL, NULL, FALSE,
  61. 0, NULL, NULL, &si, &ProcessInformation))
  62. {
  63. // wait until the process terminates
  64. if (fSync)
  65. {
  66. WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
  67. }
  68. CloseHandle(ProcessInformation.hProcess);
  69. CloseHandle(ProcessInformation.hThread);
  70. return NOERROR;
  71. }
  72. }
  73. return NOERROR;
  74. }
  75. #endif // _WINLOGON_
  76. // routines for catching WinLogon
  77. EXTERN_C DWORD WINAPI
  78. WinLogonEvent(
  79. LPVOID lpParam
  80. )
  81. {
  82. #if _WINLOGON_
  83. PWLX_NOTIFICATION_INFO pNotify = (PWLX_NOTIFICATION_INFO) lpParam;
  84. HRESULT hr;
  85. LPUNKNOWN lpUnk;
  86. MakeOneStopInstance(pNotify,"syncmgr.exe /logon",FALSE);
  87. return 0;
  88. // Review - see if have a network connection and Autosync is set up
  89. // before taking the overhead.
  90. CoInitialize(NULL); // Roger, test if this has to be called.
  91. hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_ALL,IID_IUnknown,(void **) &lpUnk);
  92. if (NOERROR == hr)
  93. {
  94. LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
  95. hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
  96. (void **) &pSynchInvoke);
  97. if (NOERROR == hr)
  98. {
  99. hr = pSynchInvoke->Logon();
  100. pSynchInvoke->Release();
  101. }
  102. lpUnk->Release();
  103. }
  104. #endif // _WINLOGON
  105. return 0;
  106. }
  107. EXTERN_C DWORD WINAPI
  108. WinLogoffEvent(
  109. LPVOID lpParam
  110. )
  111. {
  112. #if _WINLOGON_
  113. PWLX_NOTIFICATION_INFO pInfo = (PWLX_NOTIFICATION_INFO) lpParam;
  114. if ( !(pInfo->Flags & 0x02)) // 0x02 is the restart bit, don't sync on this.
  115. {
  116. MakeOneStopInstance(pInfo,"syncmgr.exe /logoff",TRUE);
  117. }
  118. return 0;
  119. #ifdef _OLD
  120. HRESULT hr;
  121. LPUNKNOWN lpUnk;
  122. CoInitialize(NULL); // Roger, test if this has to be called.
  123. hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_ALL,IID_IUnknown,(void **) &lpUnk);
  124. if (NOERROR == hr)
  125. {
  126. LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
  127. hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
  128. (void **) &pSynchInvoke);
  129. if (NOERROR == hr)
  130. {
  131. hr = pSynchInvoke->Logoff();
  132. pSynchInvoke->Release();
  133. }
  134. lpUnk->Release();
  135. }
  136. #endif // _OLD
  137. #endif // _WINLOGON_
  138. return 0;
  139. }
  140. // Setup APIs. Should be moved to another file but wait until after ship.
  141. // declarations for install variables and sections. Any changes
  142. // to these declarations must also have a corresponding changes to .inf
  143. // .inf sections names
  144. #define INSTALLSECTION_MACHINEINSTALL "Reg"
  145. #define INSTALLSECTION_MACHINEUNINSTALL "UnReg"
  146. #define INSTALLSECTION_REGISTERSHORTCUT "RegShortcut"
  147. #define INSTALLSECTION_UNREGISTERSHORTCUT "UnRegShortcut"
  148. #define INSTALLSETCION_PERUSERINSTALL "PerUserInstall"
  149. #define INSTALLSECTION_SETUP_PERUSERINSTALL "SetupPerUserInstall"
  150. #define INSTALLSECTION_REMOVE_PERUSERINSTALL "RemovePerUserInstall"
  151. // Variable declarations
  152. #define MODULEPATH_MAXVALUESIZE MAX_PATH
  153. #define SZ_MODULEPATH "MODULEPATH"
  154. #define ACCESSORIESGROUP_MAXVALUESIZE MAX_PATH
  155. #define SZ_ACCESSORIESGROUP "ACESSORIES_GROUP"
  156. // Synchronize LinkName
  157. #define SYNCHRONIZE_LINKNAME_MAXVALUESIZE MAX_PATH
  158. #define SZ_SYNCHRONIZE_LINKNAME "SYNCHRONIZE_LINKNAME"
  159. // Synchronization PerUserInstall Dislay Name
  160. #define SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE MAX_PATH
  161. #define SZ_SYNCHRONIZE_PERUSERDISPLAYNAME "SYNCHRONIZE_PERUSERDISPLAYNAME"
  162. //+---------------------------------------------------------------------------
  163. //
  164. // function: RunDllRegister, public export
  165. //
  166. // Synopsis: processes cmdlines from Rundll32 cmd
  167. //
  168. // Arguments:
  169. //
  170. // Returns:
  171. //
  172. // Modifies:
  173. //
  174. // History: 08-Dec-97 rogerg Created.
  175. // 27-Oct-98 rogerg Added perUser Flags.
  176. //
  177. //----------------------------------------------------------------------------
  178. // export for how Rundll32 calls us
  179. EXTERN_C void WINAPI RunDllRegister(HWND hwnd,
  180. HINSTANCE hAppInstance,
  181. LPSTR pszCmdLine,
  182. int nCmdShow)
  183. {
  184. char *pCmdLine = pszCmdLine;
  185. // if no cmdLine do a register.
  186. if (!pCmdLine || '\0' == *pCmdLine)
  187. {
  188. DllRegisterServer();
  189. return;
  190. }
  191. // only allow cmdlines inthe form of /
  192. if ('/' != *pCmdLine)
  193. {
  194. AssertSz(0,"Invalid CmdLine");
  195. return;
  196. }
  197. ++pCmdLine;
  198. // command lines we support for .inf installs are
  199. // /u - Uninstall
  200. // /p - perUser Install
  201. // /pu - perUser UnInstall
  202. switch(*pCmdLine)
  203. {
  204. case 'u':
  205. case 'U':
  206. DllUnregisterServer();
  207. break;
  208. case 'p':
  209. case 'P':
  210. ++pCmdLine;
  211. switch(*pCmdLine)
  212. {
  213. case '\0':
  214. DllPerUserRegister();
  215. break;
  216. case 'u':
  217. case 'U':
  218. DllPerUserUnregister();
  219. break;
  220. default:
  221. AssertSz(0,"Unknown PerUser Command");
  222. break;
  223. }
  224. break;
  225. default:
  226. AssertSz(0,"Unknown Cmd Line");
  227. break;
  228. }
  229. }
  230. //+---------------------------------------------------------------------------
  231. //
  232. // function: GetAccessoriesGroupName, private
  233. //
  234. // Synopsis: Gets the Name of the Accessories group
  235. // from the registry.
  236. //
  237. // Arguments:
  238. //
  239. // Returns:
  240. //
  241. // Modifies:
  242. //
  243. // History: ??-???-98 rogerg Created.
  244. //
  245. //----------------------------------------------------------------------------
  246. // if can get accessories group name register our shortcut.
  247. // accessories name is located at
  248. // key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion Value = SM_AccessoriesName
  249. // !! MUST ALWAYS RETURN ANSI
  250. HRESULT GetAccessoriesGroupName(char *pszAccessories,DWORD cbSize)
  251. {
  252. DWORD dwType = REG_SZ;
  253. HKEY hkeyWindowsCurrentVersion;
  254. BOOL fHaveAccessoriesName = FALSE;
  255. DWORD dwDataSize = cbSize;
  256. if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",0,KEY_READ,
  257. &hkeyWindowsCurrentVersion) )
  258. {
  259. if (ERROR_SUCCESS == RegQueryValueExA(hkeyWindowsCurrentVersion,"SM_AccessoriesName",NULL, &dwType,
  260. (LPBYTE) pszAccessories, &dwDataSize) )
  261. {
  262. fHaveAccessoriesName = TRUE;
  263. }
  264. RegCloseKey(hkeyWindowsCurrentVersion);
  265. }
  266. //AssertSz(fHaveAccessoriesName,"Couldn't Get Accessories Group Name");
  267. return fHaveAccessoriesName ? NOERROR : E_UNEXPECTED;
  268. }
  269. //+---------------------------------------------------------------------------
  270. //
  271. // function: GetModulePath, private
  272. //
  273. // Synopsis: Gets the Path to us with our name stripped out.
  274. //
  275. // Note - sets pszModulePath to NULL on error.
  276. //
  277. // Arguments:
  278. //
  279. // Returns:
  280. //
  281. // Modifies:
  282. //
  283. // History: 27-Oct-98 rogerg Created.
  284. //
  285. //----------------------------------------------------------------------------
  286. HRESULT GetModulePath(char *pszModulePath,DWORD cbSize)
  287. {
  288. DWORD dwModuleLen;
  289. Assert(pszModulePath && cbSize >= 1);
  290. if (!pszModulePath || cbSize < 1)
  291. {
  292. AssertSz(0,"Invalid ModulePath Ptr");
  293. return S_FALSE;
  294. }
  295. *pszModulePath = NULL;
  296. // setup the module path based on our dir.
  297. if(dwModuleLen = GetModuleFileNameA(
  298. g_hmodThisDll,
  299. pszModulePath,
  300. cbSize) )
  301. {
  302. char *pszCurChar = pszModulePath + dwModuleLen - 1;
  303. // NEED to strip off dll name from path, walk back until hit a \ or beginning of string.
  304. // call with CharPrev but really shouldn't have to since name is never localized.
  305. // on no match want an empty string, on a match want path + last backslash.
  306. while (pszCurChar)
  307. {
  308. char *pszPrevChar = CharPrevA(pszModulePath,pszCurChar);
  309. if(pszPrevChar <= pszModulePath)
  310. {
  311. *pszModulePath = '\0'; // if got all the way to the end then make an empty string.
  312. break;
  313. }
  314. if (*pszPrevChar == '\\')
  315. {
  316. *pszCurChar = '\0';
  317. break;
  318. }
  319. // check the next character
  320. pszCurChar = pszPrevChar;
  321. }
  322. }
  323. return *pszModulePath ? S_OK : S_FALSE;
  324. }
  325. //+---------------------------------------------------------------------------
  326. //
  327. // function: SetupInfVariables, private
  328. //
  329. // Synopsis: sets up the variables we pass to the .inf file
  330. // if fail to setup a variable it is set to NULL
  331. //
  332. // Arguments: cbNumEntries - number of entries in the arrays
  333. // pseReg - Array of STRENTRYs
  334. // pdwSizes - Array of String sizes for STRENTRY Values.
  335. //
  336. // Returns:
  337. //
  338. // Modifies:
  339. //
  340. // History: 27-Oct-98 rogerg Created.
  341. //
  342. //----------------------------------------------------------------------------
  343. /*
  344. typedef struct _StrEntry {
  345. LPSTR pszName; // String to substitute
  346. LPSTR pszValue; // Replacement string or string resource
  347. } STRENTRY, *LPSTRENTRY;
  348. */
  349. void SetupInfVariables(DWORD cbNumEntries,STRENTRY *pseReg,DWORD *pdwSizes)
  350. {
  351. STRENTRY *pCurEntry;
  352. DWORD *pCurSize;
  353. Assert(pseReg);
  354. Assert(pdwSizes);
  355. pCurEntry = pseReg;
  356. pCurSize = pdwSizes;
  357. // loop through the entries getting the info.
  358. // Entry names are always in ANSI
  359. while (cbNumEntries--)
  360. {
  361. Assert(*pCurSize);
  362. if (0 < *pCurSize)
  363. {
  364. // null out entry in case of failure
  365. *(pCurEntry->pszValue) = '\0';
  366. // see if it matches a known variable.
  367. if (!lstrcmpA(pCurEntry->pszName,SZ_MODULEPATH))
  368. {
  369. // setup the module path based on our dir.
  370. // GetModulePath sets szModulePath to NULL on error.
  371. GetModulePath(pCurEntry->pszValue,*pCurSize);
  372. }
  373. else if (!lstrcmpA(pCurEntry->pszName,SZ_ACCESSORIESGROUP))
  374. {
  375. if (NOERROR != GetAccessoriesGroupName(pCurEntry->pszValue,*pCurSize))
  376. {
  377. *(pCurEntry->pszValue) = '\0';
  378. }
  379. }
  380. else if (!lstrcmpA(pCurEntry->pszName,SZ_SYNCHRONIZE_LINKNAME))
  381. {
  382. // if size is too small the string will be truncated.
  383. LoadStringA(g_hmodThisDll,IDS_SHORTCUTNAME,pCurEntry->pszValue,*pCurSize);
  384. }
  385. else if (!lstrcmpA(pCurEntry->pszName,SZ_SYNCHRONIZE_PERUSERDISPLAYNAME))
  386. {
  387. // if size is too small the string will be truncated.
  388. LoadStringA(g_hmodThisDll,IDS_SYNCMGR_PERUSERDISPLAYNAME,pCurEntry->pszValue,*pCurSize);
  389. }
  390. else
  391. {
  392. AssertSz(0,"Uknown Setup Variable");
  393. }
  394. }
  395. pCurEntry++;
  396. pCurSize++;
  397. }
  398. }
  399. HRESULT CallRegInstall(LPSTR szSection,STRTABLE *stReg)
  400. {
  401. HRESULT hr = E_FAIL;
  402. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  403. if (hinstAdvPack)
  404. {
  405. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, achREGINSTALL);
  406. if (pfnri)
  407. {
  408. hr = pfnri(g_hmodThisDll, szSection,stReg);
  409. }
  410. FreeLibrary(hinstAdvPack);
  411. }
  412. return hr;
  413. }
  414. //+---------------------------------------------------------------------------
  415. //
  416. // function: SystemIsPerUser, private
  417. //
  418. // Synopsis: determines if PerUser registration should be
  419. // done for the current system.
  420. //
  421. // Returns: TRUE if should setupPerUserInformation
  422. //
  423. // Modifies:
  424. //
  425. // History: 27-Oct-98 rogerg Created.
  426. //
  427. //----------------------------------------------------------------------------
  428. BOOL SystemIsPerUser()
  429. {
  430. // only return true if NT and < 5.0
  431. if ((VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId)
  432. && (g_OSVersionInfo.dwMajorVersion < 5) )
  433. {
  434. return TRUE;
  435. }
  436. return FALSE;
  437. }
  438. STDAPI DllRegisterServer(void)
  439. {
  440. HRESULT hr = NOERROR;
  441. char szModulePath[MODULEPATH_MAXVALUESIZE]; // !!! these must always be ANSI
  442. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  443. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  444. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  445. // register any proxies
  446. HRESULT hRes = PrxDllRegisterServer();
  447. // !!! STRENTRY and CallResInstall are always ANSI
  448. STRENTRY seReg[] = {
  449. { SZ_MODULEPATH, szModulePath},
  450. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  451. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  452. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  453. };
  454. DWORD cbNumEntries = ARRAYLEN(seReg);
  455. // fill in sizes for how big the string Values are.
  456. DWORD dwSizes[] = {
  457. ARRAYLEN(szModulePath),
  458. ARRAYLEN(szAccessoriesGroup),
  459. ARRAYLEN(szSynchronizeLinkName),
  460. ARRAYLEN(szSynchronizePerUserDisplayName),
  461. };
  462. Assert(ARRAYLEN(seReg) == ARRAYLEN(dwSizes));
  463. Assert(ARRAYLEN(seReg) == cbNumEntries);
  464. Assert(4 == cbNumEntries); // to make sure ARRAYLEN is working properly
  465. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  466. // initialize the variables.
  467. SetupInfVariables(cbNumEntries,(STRENTRY *) &seReg, (DWORD *) &dwSizes);
  468. // register the RegKeys pasing in the path to the module
  469. // call even if couldn't get shortcut.
  470. CallRegInstall(INSTALLSECTION_MACHINEINSTALL,&stReg); // reg the reg keys
  471. // if got the accessories and shortcut name, register the shortcut.
  472. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  473. {
  474. CallRegInstall(INSTALLSECTION_REGISTERSHORTCUT,&stReg); // reg the reg keys
  475. }
  476. // on NT 4.0 register for PerUser.
  477. if (SystemIsPerUser())
  478. {
  479. CallRegInstall(INSTALLSECTION_SETUP_PERUSERINSTALL,&stReg);
  480. }
  481. else
  482. {
  483. // make sure PerUserKey isn't there on the registration if currenntly
  484. // not on a PerUser System.
  485. // to handle the case that during a previous Register user was running
  486. // under PerUser System but has now upgraded
  487. // If you ever to want to do PerUserRegistration on platforms we
  488. // currently don't do PerUser you will need to increase the PerUserRegistration
  489. // version number in the .inf so it gets run even in case that there are PerUser
  490. // turds left over under HKCU.
  491. RegDeleteKey(HKEY_LOCAL_MACHINE,
  492. TEXT("SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{6295DF27-35EE-11d1-8707-00C04FD93327}"));
  493. }
  494. //
  495. // Convert the "mobsync.exe /logon" reg value to use a fully-qualified path string.
  496. //
  497. RegFixRunKey();
  498. return hr;
  499. }
  500. /////////////////////////////////////////////////////////////////////////////
  501. // DllUnregisterServer - Removes entries from the system registry
  502. STDAPI DllUnregisterServer(void)
  503. {
  504. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  505. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  506. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  507. // setup variables to pass to .inf
  508. STRENTRY seReg[] = {
  509. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  510. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  511. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  512. };
  513. DWORD cbNumEntries = ARRAYLEN(seReg);
  514. // fill in sizes for how big the string Values are.
  515. DWORD dwSizes[] = {
  516. ARRAYLEN(szAccessoriesGroup),
  517. ARRAYLEN(szSynchronizeLinkName),
  518. ARRAYLEN(szSynchronizePerUserDisplayName),
  519. };
  520. Assert(ARRAYLEN(seReg) == ARRAYLEN(dwSizes));
  521. Assert(ARRAYLEN(seReg) == cbNumEntries);
  522. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  523. // initialize the variables.
  524. SetupInfVariables(cbNumEntries,(STRENTRY *) &seReg, (DWORD *) &dwSizes);
  525. // remove any schedules the user created
  526. RegUninstallSchedules();
  527. // remove or LCE/SENS registrations
  528. RegRegisterForEvents(TRUE /* fUninstall */);
  529. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, AUTOSYNC_REGKEY); // remove AutoSync key
  530. // remove the proxies
  531. PrxDllUnregisterServer();
  532. // if System Is PerUser call the PerUserUninstall to setup the proper keys
  533. // if not per user make sure entire InstalledComponents key is gone for our GUID
  534. if (SystemIsPerUser() )
  535. {
  536. CallRegInstall(INSTALLSECTION_REMOVE_PERUSERINSTALL,&stReg);
  537. }
  538. else
  539. {
  540. RegDeleteKey(HKEY_LOCAL_MACHINE,
  541. TEXT("SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{6295DF27-35EE-11d1-8707-00C04FD93327}"));
  542. }
  543. // unreg our regkeys
  544. CallRegInstall(INSTALLSECTION_MACHINEUNINSTALL,&stReg);
  545. // if got shortcut and accessories group remove shorcut
  546. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  547. {
  548. CallRegInstall(INSTALLSECTION_UNREGISTERSHORTCUT,&stReg); // reg the reg keys
  549. }
  550. // review, should be able to do this from .inf file
  551. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, IDLESYNC_REGKEY); // remove Idle key
  552. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, MANUALSYNC_REGKEY); // remove Manual key
  553. RegDeleteKeyNT(HKEY_LOCAL_MACHINE, PROGRESS_REGKEY); // remove ProgressState key
  554. return S_OK;
  555. }
  556. //+---------------------------------------------------------------------------
  557. //
  558. // function: DllPerUserRegister, private
  559. //
  560. // Synopsis: Handles PerUser Registration
  561. //
  562. // Arguments:
  563. //
  564. // Returns:
  565. //
  566. // Modifies:
  567. //
  568. // History: 27-Oct-98 rogerg Created.
  569. //
  570. //----------------------------------------------------------------------------
  571. STDAPI DllPerUserRegister(void)
  572. {
  573. char szModulePath[MODULEPATH_MAXVALUESIZE]; // !!! these must always be ANSI
  574. char szAccessoriesGroup[ACCESSORIESGROUP_MAXVALUESIZE];
  575. char szSynchronizeLinkName[SYNCHRONIZE_LINKNAME_MAXVALUESIZE];
  576. char szSynchronizePerUserDisplayName[SYNCHRONIZE_PERUSERDISPLAYNAME_MAXVALUESIZE];
  577. // setup variables to pass to .inf
  578. STRENTRY seReg[] = {
  579. { SZ_MODULEPATH, szModulePath},
  580. { SZ_ACCESSORIESGROUP, szAccessoriesGroup},
  581. { SZ_SYNCHRONIZE_LINKNAME, szSynchronizeLinkName},
  582. { SZ_SYNCHRONIZE_PERUSERDISPLAYNAME, szSynchronizePerUserDisplayName},
  583. };
  584. DWORD cbNumEntries = ARRAYLEN(seReg);
  585. // fill in sizes for how big the string Values are.
  586. DWORD dwSizes[] = {
  587. ARRAYLEN(szModulePath),
  588. ARRAYLEN(szAccessoriesGroup),
  589. ARRAYLEN(szSynchronizeLinkName),
  590. ARRAYLEN(szSynchronizePerUserDisplayName),
  591. };
  592. Assert(ARRAYLEN(seReg) == ARRAYLEN(dwSizes));
  593. Assert(ARRAYLEN(seReg) == cbNumEntries);
  594. STRTABLE stReg = { cbNumEntries /* Num entries */, seReg };
  595. // initialize the variables.
  596. SetupInfVariables(cbNumEntries,(STRENTRY *) &seReg, (DWORD *) &dwSizes);
  597. // if not on NT 4.0 it must have been an upgrade since only register
  598. // for per User on NT 4.0. If this happens remove the PerUser Setup
  599. // else install the shortcut for this user.
  600. // only case this will happen is where NT 4.0 has been upgraded to NT 5.0
  601. if (!SystemIsPerUser())
  602. {
  603. RegDeleteKey(HKEY_LOCAL_MACHINE,
  604. TEXT("SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{6295DF27-35EE-11d1-8707-00C04FD93327}"));
  605. }
  606. else
  607. {
  608. // if got the accessories and shortcut name, register the shortcut.
  609. if (*szSynchronizeLinkName && *szAccessoriesGroup)
  610. {
  611. CallRegInstall(INSTALLSECTION_REGISTERSHORTCUT,&stReg); // reg the reg keys
  612. }
  613. }
  614. return S_OK;
  615. }
  616. //+---------------------------------------------------------------------------
  617. //
  618. // function: DllPerUserUnregister, private
  619. //
  620. // Synopsis: Handles PerUser UnRegistration. Currently not
  621. // used since dll is removed on machine unregister
  622. // there is no dll to call next time user logs on.
  623. //
  624. // Arguments:
  625. //
  626. // Returns:
  627. //
  628. // Modifies:
  629. //
  630. // History: 27-Oct-98 rogerg Created.
  631. //
  632. //----------------------------------------------------------------------------
  633. STDAPI DllPerUserUnregister(void)
  634. {
  635. AssertSz(0,"DllPerUserUnregister Called");
  636. return S_OK;
  637. }
  638. // End of Setup APIs
  639. extern "C" int APIENTRY
  640. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  641. {
  642. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  643. return FALSE;
  644. if (dwReason == DLL_PROCESS_ATTACH)
  645. {
  646. InitializeCriticalSection(&g_DllCriticalSection);
  647. g_hmodThisDll = hInstance;
  648. #ifdef _DEBUG
  649. InitDebugFlags();
  650. #endif // _DEBUG
  651. // setup widewrap before anything else.
  652. g_OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  653. if (!GetVersionExA(&g_OSVersionInfo))
  654. {
  655. AssertSz(0,"Unabled to GetVersion information");
  656. g_OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
  657. }
  658. g_dwPlatformId = g_OSVersionInfo.dwPlatformId;
  659. BOOL fOSUnicode = (VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId) ? TRUE : FALSE;
  660. InitCommonLib(fOSUnicode);
  661. g_LangIdSystem = GetSystemDefaultLangID(); // find out what lang we are on
  662. //initialize the common controls
  663. INITCOMMONCONTROLSEX controlsEx;
  664. controlsEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  665. controlsEx.dwICC = ICC_USEREX_CLASSES | ICC_WIN95_CLASSES | ICC_NATIVEFNTCTL_CLASS;
  666. InitCommonControlsEx(&controlsEx);
  667. }
  668. else if (dwReason == DLL_PROCESS_DETACH)
  669. {
  670. UnInitCommonLib();
  671. WALKARENA();
  672. Assert(0 == g_cRefThisDll);
  673. DeleteCriticalSection(&g_DllCriticalSection);
  674. TRACE("In DLLMain, DLL_PROCESS_DETACH\r\n");
  675. }
  676. return 1; // ok
  677. }
  678. //---------------------------------------------------------------------------
  679. // DllCanUnloadNow
  680. //---------------------------------------------------------------------------
  681. STDAPI DllCanUnloadNow(void)
  682. {
  683. HRESULT hr;
  684. TRACE("In DLLCanUnloadNow\r\n");
  685. if (PrxDllCanUnloadNow() != S_OK)
  686. {
  687. return S_FALSE;
  688. }
  689. if (g_cRefThisDll)
  690. {
  691. hr = S_FALSE;
  692. }
  693. else
  694. {
  695. hr = S_OK;
  696. }
  697. return hr;
  698. }
  699. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
  700. {
  701. HRESULT hr = E_OUTOFMEMORY;
  702. TRACE("In DllGetClassObject\r\n");
  703. *ppvOut = NULL;
  704. if (IsEqualIID(rclsid, CLSID_SyncMgr))
  705. {
  706. CClassFactory *pcf = new CClassFactory;
  707. if (NULL != pcf)
  708. {
  709. hr = pcf->QueryInterface(riid, ppvOut);
  710. pcf->Release();
  711. }
  712. }
  713. else
  714. {
  715. hr = PrxDllGetClassObject(rclsid,riid, ppvOut);
  716. }
  717. return hr;
  718. }
  719. CClassFactory::CClassFactory()
  720. {
  721. TRACE("CClassFactory::CClassFactory()\r\n");
  722. m_cRef = 1;
  723. InterlockedIncrement((LONG *)& g_cRefThisDll);
  724. }
  725. CClassFactory::~CClassFactory()
  726. {
  727. InterlockedDecrement((LONG *)& g_cRefThisDll);
  728. }
  729. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,
  730. LPVOID FAR *ppv)
  731. {
  732. TRACE("CClassFactory::QueryInterface()\r\n");
  733. *ppv = NULL;
  734. // Any interface on this object is the object pointer
  735. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  736. {
  737. *ppv = (LPCLASSFACTORY)this;
  738. AddRef();
  739. return NOERROR;
  740. }
  741. return E_NOINTERFACE;
  742. }
  743. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  744. {
  745. ULONG cRefs;
  746. // Increment ref count
  747. cRefs = InterlockedIncrement((LONG *)& m_cRef);
  748. return cRefs;
  749. }
  750. STDMETHODIMP_(ULONG) CClassFactory::Release()
  751. {
  752. ULONG cRefs;
  753. cRefs = InterlockedDecrement( (LONG *) &m_cRef);
  754. if (0 == cRefs)
  755. {
  756. delete this;
  757. }
  758. return cRefs;
  759. }
  760. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
  761. REFIID riid,
  762. LPVOID *ppvObj)
  763. {
  764. HRESULT hr;
  765. TRACE("CClassFactory::CreateInstance()\r\n");
  766. *ppvObj = NULL;
  767. if (pUnkOuter)
  768. return CLASS_E_NOAGGREGATION;
  769. LPSYNCMGRSYNCHRONIZEINVOKE pSyncMgrDllObject = (LPSYNCMGRSYNCHRONIZEINVOKE)
  770. new CSyncMgrSynchronize;
  771. if (NULL == pSyncMgrDllObject)
  772. return E_OUTOFMEMORY;
  773. hr = pSyncMgrDllObject->QueryInterface(riid, ppvObj);
  774. pSyncMgrDllObject->Release();
  775. return hr;
  776. }
  777. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  778. {
  779. if (fLock)
  780. {
  781. InterlockedIncrement( (LONG *) &g_cRefThisDll);
  782. }
  783. else
  784. {
  785. InterlockedDecrement( (LONG *) &g_cRefThisDll);
  786. }
  787. return NOERROR;
  788. }