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.

211 lines
6.1 KiB

  1. #include "stdafx.h"
  2. #include <initguid.h>
  3. #include "stobject.h"
  4. #include "cfact.h"
  5. #define DECL_CRTFREE
  6. #include <crtfree.h>
  7. // One lock for each running component + one lock per LockServer call
  8. long g_cLocks = 0;
  9. HINSTANCE g_hinstDll = NULL;
  10. const TCHAR g_szThreadModel[] = TEXT("Both");
  11. STDAPI DllCanUnloadNow()
  12. {
  13. return (g_cLocks == 0);
  14. }
  15. STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppvObject)
  16. {
  17. HRESULT hr = S_OK;
  18. BOOL fRunTrayOnConstruct;
  19. *ppvObject = NULL;
  20. if (clsid == CLSID_SysTray)
  21. {
  22. // The SysTray object is being requested - we don't actually launch the tray thread until
  23. // told to do so though IOleCommandTarget
  24. fRunTrayOnConstruct = FALSE;
  25. }
  26. else if (clsid == CLSID_SysTrayInvoker)
  27. {
  28. // The simple invoker object is being requested - the tray thread will be launched immediately
  29. fRunTrayOnConstruct = TRUE;
  30. }
  31. else
  32. {
  33. // We don't support this object!
  34. hr = CLASS_E_CLASSNOTAVAILABLE;
  35. }
  36. // If one of the two objects we support was requested:
  37. if (SUCCEEDED(hr))
  38. {
  39. // Try to create the object
  40. CSysTrayFactory* ptrayfact = new CSysTrayFactory(fRunTrayOnConstruct);
  41. if (ptrayfact != NULL)
  42. {
  43. hr = ptrayfact->QueryInterface(iid, ppvObject);
  44. ptrayfact->Release();
  45. }
  46. else
  47. {
  48. hr = E_OUTOFMEMORY;
  49. }
  50. }
  51. return hr;
  52. }
  53. BOOL RegisterComponent(const CLSID& clsid, const TCHAR* szProgID)
  54. {
  55. // Build a CLSID string for the registry
  56. BOOL fSuccess = FALSE;
  57. TCHAR szSubkey[MAX_PATH];
  58. TCHAR szCLSID[GUIDSTR_MAX];
  59. TCHAR szModule[MAX_PATH];
  60. HKEY hkeyCLSID = NULL;
  61. HKEY hkeyInproc = NULL;
  62. DWORD dwDisp;
  63. TCHAR* pszNameOnly;
  64. // Try and get all the strings we need
  65. if (StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID)) != 0)
  66. {
  67. if ((GetModuleFileName(g_hinstDll, szModule, ARRAYSIZE(szModule)) != 0) &&
  68. (pszNameOnly = PathFindFileName(szModule)))
  69. {
  70. if (wnsprintf(szSubkey, ARRAYSIZE(szSubkey), TEXT("CLSID\\%s"), szCLSID) > 0)
  71. {
  72. // We've built our strings, so write stuff to the registry
  73. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CLASSES_ROOT, szSubkey, 0,
  74. NULL, 0, KEY_WRITE, NULL, &hkeyCLSID, &dwDisp))
  75. {
  76. RegSetValueEx(hkeyCLSID, NULL, 0, REG_SZ, (const BYTE*) szProgID,
  77. (lstrlen(szProgID) + 1) * sizeof(TCHAR));
  78. if (ERROR_SUCCESS == RegCreateKeyEx(hkeyCLSID, TEXT("InprocServer32"),
  79. 0, NULL, 0, KEY_SET_VALUE, NULL, &hkeyInproc, &dwDisp))
  80. {
  81. RegSetValueEx(hkeyInproc, NULL, 0, REG_SZ,
  82. (const BYTE*) szModule, (lstrlen(szModule) + 1) * sizeof(TCHAR));
  83. RegSetValueEx(hkeyInproc, TEXT("ThreadingModel"), 0, REG_SZ,
  84. (const BYTE*) g_szThreadModel, sizeof(g_szThreadModel));
  85. fSuccess = TRUE;
  86. }
  87. }
  88. }
  89. }
  90. }
  91. if (hkeyCLSID != NULL)
  92. RegCloseKey(hkeyCLSID);
  93. if (hkeyInproc != NULL)
  94. RegCloseKey(hkeyInproc);
  95. return fSuccess;
  96. }
  97. BOOL UnregisterComponent(const CLSID& clsid)
  98. {
  99. // Build a CLSID string for the registry
  100. BOOL fSuccess = FALSE;
  101. TCHAR szSubkey[MAX_PATH];
  102. TCHAR szCLSID[GUIDSTR_MAX];
  103. HKEY hkeyCLSID = NULL;
  104. // Try and get all the strings we need
  105. if (StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID)) != 0)
  106. {
  107. if (wnsprintf(szSubkey, ARRAYSIZE(szSubkey), TEXT("CLSID\\%s"), szCLSID) > 0)
  108. {
  109. // We've built our strings, so delete our registry stuff
  110. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, szSubkey, 0,
  111. KEY_WRITE, &hkeyCLSID))
  112. {
  113. RegDeleteKey(hkeyCLSID, TEXT("InprocServer32"));
  114. RegCloseKey(hkeyCLSID);
  115. hkeyCLSID = NULL;
  116. RegDeleteKey(HKEY_CLASSES_ROOT, szSubkey);
  117. fSuccess = TRUE;
  118. }
  119. }
  120. }
  121. if (hkeyCLSID != NULL)
  122. RegCloseKey(hkeyCLSID);
  123. return fSuccess;
  124. }
  125. BOOL RegisterShellServiceObject(const CLSID& clsid, const TCHAR* szProgID, BOOL fRegister)
  126. {
  127. const static TCHAR szSubkey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad");
  128. BOOL fSuccess = FALSE;
  129. TCHAR szCLSID[GUIDSTR_MAX];
  130. HKEY hkey = NULL;
  131. // Try and get all the strings we need
  132. if (StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID)) != 0)
  133. {
  134. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubkey, 0,
  135. KEY_WRITE, &hkey))
  136. {
  137. if (fRegister)
  138. {
  139. fSuccess = RegSetValueEx(hkey, szProgID, 0, REG_SZ, (const BYTE*) szCLSID,
  140. (lstrlen(szCLSID) + 1) * sizeof(TCHAR));
  141. }
  142. else
  143. {
  144. fSuccess = RegDeleteValue(hkey, szProgID);
  145. }
  146. }
  147. }
  148. if (hkey != NULL)
  149. RegCloseKey(hkey);
  150. return fSuccess;
  151. }
  152. STDAPI DllRegisterServer()
  153. {
  154. BOOL fSuccess;
  155. fSuccess = RegisterComponent(CLSID_SysTray, TEXT("SysTray"));
  156. fSuccess &= RegisterComponent(CLSID_SysTrayInvoker, TEXT("SysTrayInvoker"));
  157. fSuccess &= RegisterShellServiceObject(CLSID_SysTray, TEXT("SysTray"), TRUE);
  158. return fSuccess;
  159. }
  160. STDAPI DllUnregisterServer()
  161. {
  162. BOOL fSuccess;
  163. fSuccess = UnregisterComponent(CLSID_SysTray);
  164. fSuccess &= UnregisterComponent(CLSID_SysTrayInvoker);
  165. fSuccess &= RegisterShellServiceObject(CLSID_SysTray, TEXT("SysTray"), FALSE);
  166. return fSuccess;
  167. }
  168. STDAPI DllMain(HINSTANCE hModule, DWORD dwReason, void* lpReserved)
  169. {
  170. if (dwReason == DLL_PROCESS_ATTACH)
  171. {
  172. SHFusionInitializeFromModule(hModule);
  173. // Don't have DllMain called for thread init's.
  174. DisableThreadLibraryCalls(hModule);
  175. g_hinstDll = hModule;
  176. }
  177. else if (dwReason == DLL_PROCESS_DETACH)
  178. {
  179. SHFusionUninitialize();
  180. }
  181. return TRUE;
  182. }