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.

402 lines
11 KiB

  1. /**************************************************************************
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR TFPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE TFPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  7. **************************************************************************/
  8. /**************************************************************************
  9. File: BandObjs.cpp
  10. Description: Contains DLLMain and standard OLE COM object creation stuff.
  11. **************************************************************************/
  12. /**************************************************************************
  13. include statements
  14. **************************************************************************/
  15. #include "private.h"
  16. #include <ole2.h>
  17. #include <comcat.h>
  18. #include <olectl.h>
  19. #include "ClsFact.h"
  20. #include "regsvr.h"
  21. #include "lbmenu.h"
  22. #include "inatlib.h"
  23. #include "immxutil.h"
  24. #include "cuilib.h"
  25. #include "utbtray.h"
  26. #include "mui.h"
  27. #include "cregkey.h"
  28. #include "ciccs.h"
  29. /**************************************************************************
  30. GUID stuff
  31. **************************************************************************/
  32. //this part is only done once
  33. //if you need to use the GUID in another file, just include Guid.h
  34. #pragma data_seg(".text")
  35. #define INITGUID
  36. #include <initguid.h>
  37. #include <shlguid.h>
  38. #include "Guid.h"
  39. #pragma data_seg()
  40. /**************************************************************************
  41. private function prototypes
  42. **************************************************************************/
  43. extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
  44. BOOL RegisterComCat(CLSID, CATID, BOOL);
  45. BOOL IsDeskBandFromReg();
  46. /**************************************************************************
  47. global variables
  48. **************************************************************************/
  49. extern HINSTANCE g_hOle32;
  50. HINSTANCE g_hInst;
  51. UINT g_DllRefCount;
  52. CCicCriticalSectionStatic g_cs;
  53. #ifdef DEBUG
  54. DWORD g_dwThreadDllMain = 0;
  55. #endif
  56. UINT g_wmTaskbarCreated;
  57. DECLARE_OSVER()
  58. /**************************************************************************
  59. ProcessAttach
  60. **************************************************************************/
  61. BOOL ProcessAttach(HINSTANCE hInstance)
  62. {
  63. if (!g_cs.Init())
  64. return FALSE;
  65. CcshellGetDebugFlags();
  66. Dbg_MemInit(TEXT("MSUIMUI"), NULL);
  67. g_hInst = hInstance;
  68. InitOSVer();
  69. TFInitLib_PrivateForCiceroOnly(Internal_CoCreateInstance);
  70. InitUIFLib();
  71. TF_InitMlngInfo();
  72. CTrayIconWnd::RegisterClass();
  73. MuiLoadResource(hInstance, TEXT("msutb.dll"));
  74. g_wmTaskbarCreated = RegisterWindowMessage(TEXT("TaskbarCreated"));
  75. return TRUE;
  76. }
  77. /**************************************************************************
  78. ProcessDettach
  79. **************************************************************************/
  80. void ProcessDettach(HINSTANCE hInstance)
  81. {
  82. DoneUIFLib();
  83. TFUninitLib();
  84. Dbg_MemUninit();
  85. g_cs.Delete();
  86. // Issue: MuiFreeResource is unsafe because it can call FreeLibrary
  87. // we may not need to bother because we are only loaded in the ctfmon.exe process
  88. // and are never unloaded until the process is shutdown
  89. //MuiFreeResource(hInstance);
  90. MuiClearResource();
  91. }
  92. /**************************************************************************
  93. DllMain
  94. **************************************************************************/
  95. extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance,
  96. DWORD dwReason,
  97. LPVOID lpReserved)
  98. {
  99. BOOL bRet = TRUE;
  100. #ifdef DEBUG
  101. g_dwThreadDllMain = GetCurrentThreadId();
  102. #endif
  103. switch(dwReason)
  104. {
  105. case DLL_PROCESS_ATTACH:
  106. //
  107. // Now real DllEntry point is _DllMainCRTStartup.
  108. // _DllMainCRTStartup does not call our DllMain(DLL_PROCESS_DETACH)
  109. // if our DllMain(DLL_PROCESS_ATTACH) fails.
  110. // So we have to clean this up.
  111. //
  112. if (!ProcessAttach(hInstance))
  113. {
  114. ProcessDettach(hInstance);
  115. bRet = FALSE;
  116. }
  117. break;
  118. case DLL_PROCESS_DETACH:
  119. ProcessDettach(hInstance);
  120. break;
  121. }
  122. #ifdef DEBUG
  123. g_dwThreadDllMain = 0;
  124. #endif
  125. return bRet;
  126. }
  127. /**************************************************************************
  128. DllCanUnloadNow
  129. **************************************************************************/
  130. STDAPI DllCanUnloadNow(void)
  131. {
  132. return (g_DllRefCount ? S_FALSE : S_OK);
  133. }
  134. /**************************************************************************
  135. DllGetClassObject
  136. **************************************************************************/
  137. STDAPI DllGetClassObject( REFCLSID rclsid,
  138. REFIID riid,
  139. LPVOID *ppReturn)
  140. {
  141. *ppReturn = NULL;
  142. //if we don't support this classid, return the proper error code
  143. if( !IsEqualCLSID(rclsid, CLSID_MSUTBDeskBand))
  144. return CLASS_E_CLASSNOTAVAILABLE;
  145. //create a CClassFactory object and check it for validity
  146. CClassFactory *pClassFactory = new CClassFactory(rclsid);
  147. if(NULL == pClassFactory)
  148. return E_OUTOFMEMORY;
  149. //get the QueryInterface return for our return value
  150. HRESULT hResult = pClassFactory->QueryInterface(riid, ppReturn);
  151. //call Release to decement the ref count - creating the object set it to one
  152. //and QueryInterface incremented it - since its being used externally
  153. //(not by us), we only want the ref count to be 1
  154. pClassFactory->Release();
  155. //return the result from QueryInterface
  156. return hResult;
  157. }
  158. /**************************************************************************
  159. DllRegisterServer
  160. **************************************************************************/
  161. STDAPI DllRegisterServer(void)
  162. {
  163. TCHAR achPath[MAX_PATH+1];
  164. HRESULT hr = E_FAIL;
  165. if (IsOnNT51())
  166. {
  167. if (GetModuleFileName(g_hInst, achPath, ARRAYSIZE(achPath)) == 0)
  168. goto Exit;
  169. if (!RegisterServerW(CLSID_MSUTBDeskBand,
  170. CRStr(IDS_LANGBAND),
  171. AtoW(achPath),
  172. L"Apartment",
  173. NULL,
  174. CRStr(IDS_LANGBANDMENUTEXTPUI)))
  175. goto Exit;
  176. }
  177. hr = S_OK;
  178. Exit:
  179. return hr;
  180. }
  181. /**************************************************************************
  182. DllUnregisterServer
  183. **************************************************************************/
  184. STDAPI DllUnregisterServer(void)
  185. {
  186. if (IsOnNT51())
  187. {
  188. //Register the desk band object.
  189. if (!RegisterServer(CLSID_MSUTBDeskBand, NULL, NULL, NULL, NULL))
  190. return SELFREG_E_CLASS;
  191. }
  192. return S_OK;
  193. }
  194. /**************************************************************************
  195. RegisterComCat
  196. **************************************************************************/
  197. const TCHAR c_szCatEnum[] = "Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum";
  198. const TCHAR c_szIESubKey[] = "Software\\Microsoft\\Internet Explorer";
  199. BOOL IsIE5()
  200. {
  201. CMyRegKey key;
  202. BOOL bRet = FALSE;
  203. if (key.Open(HKEY_LOCAL_MACHINE, c_szIESubKey, KEY_READ) == S_OK)
  204. {
  205. char szValue[16];
  206. if (key.QueryValueCch(szValue, "Version", ARRAYSIZE(szValue)) == S_OK)
  207. {
  208. if (!strncmp("5.00", szValue, 4))
  209. bRet = TRUE;
  210. }
  211. }
  212. return bRet;
  213. }
  214. BOOL RegisterComCat(CLSID clsid, CATID CatID, BOOL fSet)
  215. {
  216. ICatRegister *pcr;
  217. HRESULT hr = S_OK ;
  218. hr = CoInitialize(NULL);
  219. if (FAILED(hr))
  220. return FALSE;
  221. hr = CoCreateInstance( CLSID_StdComponentCategoriesMgr,
  222. NULL,
  223. CLSCTX_INPROC_SERVER,
  224. IID_ICatRegister,
  225. (LPVOID*)&pcr);
  226. if(SUCCEEDED(hr))
  227. {
  228. if (fSet)
  229. hr = pcr->RegisterClassImplCategories(clsid, 1, &CatID);
  230. else
  231. hr = pcr->UnRegisterClassImplCategories(clsid, 1, &CatID);
  232. pcr->Release();
  233. }
  234. CoUninitialize();
  235. //
  236. // IE5.0 shipped with a bug in the component category cache code,
  237. // such that the cache is never refreshed (so we don't pick up newly
  238. // registered toolbars). The bug is fixed in versions 5.01 and greater.
  239. //
  240. // We need to delete the following reg key as part of your setup:
  241. //
  242. // HKCR\Component Categories\{00021492-0000-0000-C000-000000000046}\Enum
  243. //
  244. if (IsIE5())
  245. {
  246. RegDeleteKey(HKEY_CLASSES_ROOT, c_szCatEnum);
  247. }
  248. return SUCCEEDED(hr);
  249. }
  250. //+---------------------------------------------------------------------------
  251. //
  252. // IsDeskbandFromReg
  253. //
  254. //+---------------------------------------------------------------------------
  255. BOOL IsDeskBandFromReg()
  256. {
  257. CMyRegKey keyUTB;
  258. DWORD dwValue;
  259. BOOL bRet = FALSE;
  260. if (keyUTB.Open(HKEY_CURRENT_USER, c_szUTBKey, KEY_READ) == S_OK)
  261. {
  262. if (IsOnNT51() && keyUTB.QueryValue(dwValue, c_szShowDeskBand) == S_OK)
  263. bRet = dwValue ? TRUE : FALSE;
  264. }
  265. return bRet;
  266. }
  267. //+---------------------------------------------------------------------------
  268. //
  269. // SetDeskbandFromReg
  270. //
  271. //+---------------------------------------------------------------------------
  272. void SetDeskBandToReg(BOOL fShow)
  273. {
  274. CMyRegKey keyUTB;
  275. if (keyUTB.Open(HKEY_CURRENT_USER, c_szUTBKey, KEY_ALL_ACCESS) == S_OK)
  276. {
  277. keyUTB.SetValue((DWORD)fShow ? 1 : 0, c_szShowDeskBand);
  278. }
  279. }
  280. //+---------------------------------------------------------------------------
  281. //
  282. // SetRegisterLangBand
  283. //
  284. //+---------------------------------------------------------------------------
  285. STDAPI SetRegisterLangBand(BOOL bSetReg)
  286. {
  287. BOOL fShowDeskBand = IsDeskBandFromReg();
  288. if (!IsOnNT51())
  289. return E_FAIL;
  290. if (fShowDeskBand == bSetReg)
  291. return S_OK;
  292. SetDeskBandToReg(bSetReg);
  293. if (bSetReg)
  294. {
  295. //
  296. // we don't care if this deskband is registered or not.
  297. // Win95 without IE4 shell does not support deskband.
  298. //
  299. if (!RegisterComCat(CLSID_MSUTBDeskBand, CATID_DeskBand, TRUE))
  300. return SELFREG_E_CLASS;
  301. }
  302. else
  303. {
  304. //Register the component categories for the desk band object.
  305. if (!RegisterComCat(CLSID_MSUTBDeskBand, CATID_DeskBand, FALSE))
  306. return SELFREG_E_CLASS;
  307. }
  308. return S_OK;
  309. }