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.

268 lines
7.4 KiB

  1. /****************************************************************************/
  2. // server.cpp
  3. //
  4. // General COM in-proc server framework code. TSSD-specific code is
  5. // designated by CLSID SPECIFIC comments.
  6. //
  7. // Copyright (C) 2000 Microsoft Corporation
  8. /****************************************************************************/
  9. #include <windows.h>
  10. #include <stdio.h>
  11. #include <time.h>
  12. #include <locale.h>
  13. #include <tchar.h>
  14. #define INITGUID
  15. #include <ole2.h>
  16. #include <objbase.h>
  17. #include <comutil.h>
  18. #include <comdef.h>
  19. #include <adoid.h>
  20. #include <adoint.h>
  21. #include <initguid.h>
  22. #include "factory.h"
  23. #include "trace.h"
  24. /****************************************************************************/
  25. // CLSID SPECIFIC section
  26. //
  27. // Provider-specific includes, unique CLSID, other info.
  28. /****************************************************************************/
  29. // For new components, this is the only area that needs to be modified in this
  30. // file. Include any appropriate header files, a unique CLSID and update
  31. // the macros.
  32. #include "tssd.h"
  33. // {005a9c68-e216-4b27-8f59-b336829b3868}
  34. DEFINE_GUID(CLSID_TSSDJET,
  35. 0x005a9c68, 0xe216, 0x4b27, 0x8f, 0x59, 0xb3, 0x36, 0x82, 0x9b, 0x38, 0x68);
  36. // {ec98d957-48ad-436d-90be-bc291f42709c}
  37. DEFINE_GUID(CLSID_TSSDJETEX,
  38. 0xec98d957, 0x48ad, 0x436d, 0x90, 0xbe, 0xbc, 0x29, 0x1f, 0x42, 0x70, 0x9c);
  39. #define IMPLEMENTED_CLSID CLSID_TSSDJET
  40. #define IMPLEMENTED_CLSIDEX CLSID_TSSDJETEX
  41. #define SERVER_REGISTRY_COMMENT L"Terminal Server Session Directory Interface"
  42. #define CPP_CLASS_NAME CTSSessionDirectory
  43. #define INTERFACE_CAST (ITSSessionDirectory *)
  44. /****************************************************************************/
  45. // End CLSID SPECIFIC section
  46. /****************************************************************************/
  47. HINSTANCE g_hInstance;
  48. long g_lLocks = 0;
  49. long g_lObjects = 0;
  50. /****************************************************************************/
  51. // DllMain
  52. //
  53. // Standard DLL entry point. Returns FALSE on failure.
  54. /****************************************************************************/
  55. BOOL WINAPI DllMain(
  56. HINSTANCE hInstDLL,
  57. DWORD dwReason,
  58. LPVOID lpReserved)
  59. {
  60. if (dwReason == DLL_PROCESS_ATTACH) {
  61. setlocale(LC_ALL, ""); // Set to the 'current' locale
  62. g_hInstance = hInstDLL;
  63. DisableThreadLibraryCalls(hInstDLL);
  64. }
  65. return TRUE;
  66. }
  67. /****************************************************************************/
  68. // DllGetClassObject
  69. //
  70. // Standard OLE In-Process Server entry point to return an class factory
  71. // instance.
  72. //***************************************************************************
  73. STDAPI DllGetClassObject(
  74. REFCLSID rclsid,
  75. REFIID riid,
  76. LPVOID *ppv)
  77. {
  78. CClassFactory *pClassFactory;
  79. HRESULT hr;
  80. TRC2((TB,"DllGetClassObject"));
  81. // Verify the caller is asking for our type of object
  82. if (rclsid == IMPLEMENTED_CLSID || rclsid == IMPLEMENTED_CLSIDEX) {
  83. // Create the class factory.
  84. pClassFactory = new CClassFactory;
  85. if (pClassFactory != NULL) {
  86. hr = pClassFactory->QueryInterface(riid, ppv);
  87. if (FAILED(hr)) {
  88. ERR((TB,"DllGetClassObject: GUID not found"));
  89. delete pClassFactory;
  90. }
  91. }
  92. else {
  93. ERR((TB,"DllGetClassObject: Failed alloc class factory"));
  94. hr = E_OUTOFMEMORY;
  95. }
  96. }
  97. else {
  98. ERR((TB,"DllGetClassObject: Failed alloc class factory"));
  99. hr = CLASS_E_CLASSNOTAVAILABLE;
  100. }
  101. return hr;
  102. }
  103. /****************************************************************************/
  104. // DllCanUnloadNow
  105. //
  106. // Standard COM entry point for COM server shutdown request. Allows shutdown
  107. // only if no outstanding objects or locks are present.
  108. /****************************************************************************/
  109. STDAPI DllCanUnloadNow(void)
  110. {
  111. HRESULT hr;
  112. if (g_lLocks == 0 && g_lObjects == 0)
  113. hr = S_OK;
  114. else
  115. hr = S_FALSE;
  116. return hr;
  117. }
  118. /****************************************************************************/
  119. // DllRegisterServer
  120. //
  121. // Standard COM entry point for registering the server.
  122. /****************************************************************************/
  123. HRESULT RegisterCLSID(CLSID clsid)
  124. {
  125. HRESULT hr = E_FAIL;
  126. wchar_t *pGuidStr = 0;
  127. wchar_t KeyPath[1024];
  128. wchar_t Path[1024];
  129. // Get the DLL's filename
  130. GetModuleFileNameW(g_hInstance, Path, 1024);
  131. TRC2((TB,"RegisterCLSID: %S", KeyPath));
  132. // Convert CLSID to string.
  133. if( SUCCEEDED( StringFromCLSID(clsid, &pGuidStr) ) )
  134. {
  135. swprintf(KeyPath, L"Software\\Classes\\CLSID\\\\%s", pGuidStr);
  136. // Place it in registry.
  137. // CLSID\\CLSID_Nt5PerProvider_v1 : <no_name> : "name"
  138. // \\CLSID_Nt5PerProvider_v1\\InProcServer32 :
  139. // <no_name> : "path to DLL"
  140. // ThreadingModel : "both"
  141. HKEY hKey;
  142. LONG lRes = RegCreateKeyW(HKEY_LOCAL_MACHINE, KeyPath, &hKey);
  143. if (lRes == 0) {
  144. wchar_t *pName = SERVER_REGISTRY_COMMENT;
  145. RegSetValueExW(hKey, 0, 0, REG_SZ, (const BYTE *)pName,
  146. wcslen(pName) * 2 + 2);
  147. HKEY hSubkey;
  148. lRes = RegCreateKeyW(hKey, L"InprocServer32", &hSubkey);
  149. RegSetValueExW(hSubkey, 0, 0, REG_SZ, (const BYTE *) Path,
  150. wcslen(Path) * 2 + 2);
  151. RegSetValueExW(hSubkey, L"ThreadingModel", 0, REG_SZ,
  152. (const BYTE *) L"Both", wcslen(L"Both") * 2 + 2);
  153. RegCloseKey(hSubkey);
  154. RegCloseKey(hKey);
  155. }
  156. else {
  157. TRC2((TB,"RegisterCLSID: Failed to Create key: %x", lRes));
  158. }
  159. CoTaskMemFree(pGuidStr);
  160. hr = HRESULT_FROM_WIN32( lRes );
  161. }
  162. else {
  163. TRC2((TB,"RegisterCLSID failed"));
  164. }
  165. return hr;
  166. }
  167. STDAPI DllRegisterServer(void)
  168. {
  169. HRESULT hr = E_FAIL;
  170. hr = RegisterCLSID(IMPLEMENTED_CLSID);
  171. hr = RegisterCLSID(IMPLEMENTED_CLSIDEX);
  172. return hr;
  173. }
  174. /****************************************************************************/
  175. // DllUnregisterServer
  176. //
  177. // Standard COM entry point for unregistering the server.
  178. /****************************************************************************/
  179. HRESULT UnregisterCLSID(REFCLSID rclsid)
  180. {
  181. wchar_t *pGuidStr = 0;
  182. HKEY hKey;
  183. wchar_t KeyPath[256];
  184. HRESULT hr = E_FAIL;
  185. if( SUCCEEDED( StringFromCLSID(rclsid, &pGuidStr) ) )
  186. {
  187. swprintf(KeyPath, L"Software\\Classes\\CLSID\\\\%s", pGuidStr);
  188. // Delete InProcServer32 subkey.
  189. LONG lRes = RegOpenKeyW(HKEY_LOCAL_MACHINE, KeyPath, &hKey);
  190. if (!lRes) {
  191. RegDeleteKeyW(hKey, L"InprocServer32");
  192. RegCloseKey(hKey);
  193. // Delete CLSID GUID key.
  194. lRes = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID", &hKey);
  195. if (!lRes) {
  196. RegDeleteKeyW(hKey, pGuidStr);
  197. RegCloseKey(hKey);
  198. }
  199. }
  200. CoTaskMemFree(pGuidStr);
  201. hr = HRESULT_FROM_WIN32( lRes );
  202. }
  203. return hr;
  204. }
  205. STDAPI DllUnregisterServer(void)
  206. {
  207. wchar_t *pGuidStr = 0;
  208. HKEY hKey;
  209. wchar_t KeyPath[256];
  210. HRESULT hr = E_FAIL;
  211. hr = UnregisterCLSID(IMPLEMENTED_CLSID);
  212. hr = UnregisterCLSID(IMPLEMENTED_CLSIDEX);
  213. return hr;
  214. }