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.

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