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.

293 lines
6.9 KiB

  1. // RAssistance.cpp : Implementation of DLL Exports.
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f RAssistanceps.mk in the project directory.
  5. #include "stdafx.h"
  6. #include "resource.h"
  7. #include <initguid.h>
  8. #include "RAssistance.h"
  9. #include "RAssistance_i.c"
  10. #include "RASettingProperty.h"
  11. #include "RARegSetting.h"
  12. #include "RAEventLog.h"
  13. #include <SHlWapi.h>
  14. extern "C" void
  15. AttachDebuggerIfAsked(HINSTANCE hInst);
  16. CComModule _Module;
  17. HINSTANCE g_hInst = NULL;
  18. BEGIN_OBJECT_MAP(ObjectMap)
  19. OBJECT_ENTRY(CLSID_RASettingProperty, CRASettingProperty)
  20. OBJECT_ENTRY(CLSID_RARegSetting, CRARegSetting)
  21. OBJECT_ENTRY(CLSID_RAEventLog, CRAEventLog)
  22. END_OBJECT_MAP()
  23. DWORD
  24. SetupEventViewerSource();
  25. DWORD
  26. RemoveEventViewerSource();
  27. /////////////////////////////////////////////////////////////////////////////
  28. // DLL Entry Point
  29. extern "C"
  30. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
  31. {
  32. if (dwReason == DLL_PROCESS_ATTACH)
  33. {
  34. g_hInst = hInstance;
  35. _Module.Init(ObjectMap, hInstance, &LIBID_RASSISTANCELib);
  36. DisableThreadLibraryCalls(hInstance);
  37. }
  38. else if (dwReason == DLL_PROCESS_DETACH)
  39. _Module.Term();
  40. return TRUE; // ok
  41. }
  42. /////////////////////////////////////////////////////////////////////////////
  43. // Used to determine whether the DLL can be unloaded by OLE
  44. STDAPI DllCanUnloadNow(void)
  45. {
  46. return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
  47. }
  48. /////////////////////////////////////////////////////////////////////////////
  49. // Returns a class factory to create an object of the requested type
  50. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  51. {
  52. return _Module.GetClassObject(rclsid, riid, ppv);
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // DllRegisterServer - Adds entries to the system registry
  56. STDAPI DllRegisterServer(void)
  57. {
  58. SetupEventViewerSource();
  59. // registers object, typelib and all interfaces in typelib
  60. return _Module.RegisterServer(TRUE);
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. // DllUnregisterServer - Removes entries from the system registry
  64. STDAPI DllUnregisterServer(void)
  65. {
  66. SHDeleteKey( HKEY_LOCAL_MACHINE, REMOTEASSISTANCE_EVENT_SOURCE );
  67. return _Module.UnregisterServer(TRUE);
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. //
  71. DWORD
  72. SetupEventViewerSource()
  73. {
  74. HKEY hKey = NULL;
  75. DWORD dwData;
  76. TCHAR szBuffer[MAX_PATH + 2];
  77. DWORD dwStatus;
  78. _stprintf(
  79. szBuffer,
  80. _TEXT("%s\\%s"),
  81. REGKEY_SYSTEM_EVENTSOURCE,
  82. REMOTEASSISTANCE_EVENT_NAME
  83. );
  84. // Add your source name as a subkey under the Application
  85. // key in the EventLog registry key.
  86. dwStatus = RegCreateKey(
  87. HKEY_LOCAL_MACHINE,
  88. szBuffer,
  89. &hKey
  90. );
  91. if( ERROR_SUCCESS != dwStatus )
  92. {
  93. goto CLEANUPANDEXIT;
  94. }
  95. dwStatus = GetModuleFileName(
  96. g_hInst,
  97. szBuffer,
  98. MAX_PATH+1
  99. );
  100. if( 0 == dwStatus )
  101. {
  102. goto CLEANUPANDEXIT;
  103. }
  104. szBuffer[dwStatus] = L'\0';
  105. // Add the name to the EventMessageFile subkey.
  106. dwStatus = RegSetValueEx(
  107. hKey,
  108. L"EventMessageFile",
  109. 0,
  110. REG_SZ,
  111. (LPBYTE) szBuffer,
  112. (_tcslen(szBuffer)+1)*sizeof(TCHAR)
  113. );
  114. if( ERROR_SUCCESS != dwStatus )
  115. {
  116. goto CLEANUPANDEXIT;
  117. }
  118. // Set the supported event types in the TypesSupported subkey.
  119. dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
  120. dwStatus = RegSetValueEx(
  121. hKey,
  122. L"TypesSupported",
  123. 0,
  124. REG_DWORD,
  125. (LPBYTE) &dwData,
  126. sizeof(DWORD)
  127. );
  128. CLEANUPANDEXIT:
  129. if( NULL != hKey )
  130. {
  131. RegCloseKey(hKey);
  132. }
  133. return dwStatus;
  134. }
  135. void
  136. AttachDebugger(
  137. LPCTSTR pszDebugger
  138. )
  139. /*++
  140. Routine Description:
  141. Attach debugger to our process or process hosting our DLL.
  142. Parameters:
  143. pszDebugger : Debugger command, e.g. ntsd -d -g -G -p %d
  144. Returns:
  145. None.
  146. Note:
  147. Must have "-p %d" since we don't know debugger's parameter for process.
  148. --*/
  149. {
  150. //
  151. // Attach debugger
  152. //
  153. if( !IsDebuggerPresent() ) {
  154. TCHAR szCommand[256];
  155. PROCESS_INFORMATION ProcessInfo;
  156. STARTUPINFO StartupInfo;
  157. //
  158. // ntsd -d -g -G -p %d
  159. //
  160. wsprintf( szCommand, pszDebugger, GetCurrentProcessId() );
  161. ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  162. StartupInfo.cb = sizeof(StartupInfo);
  163. if (!CreateProcess(NULL, szCommand, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) {
  164. return;
  165. }
  166. else {
  167. CloseHandle(ProcessInfo.hProcess);
  168. CloseHandle(ProcessInfo.hThread);
  169. while (!IsDebuggerPresent())
  170. {
  171. Sleep(500);
  172. }
  173. }
  174. } else {
  175. DebugBreak();
  176. }
  177. return;
  178. }
  179. void
  180. AttachDebuggerIfAsked(HINSTANCE hInst)
  181. /*++
  182. Routine Description:
  183. Check if debug enable flag in our registry HKLM\Software\Microsoft\Remote Desktop\<module name>,
  184. if enable, attach debugger to running process.
  185. Parameter :
  186. hInst : instance handle.
  187. Returns:
  188. None.
  189. --*/
  190. {
  191. CRegKey regKey;
  192. DWORD dwStatus;
  193. TCHAR szModuleName[MAX_PATH+1];
  194. TCHAR szFileName[MAX_PATH+1];
  195. CComBSTR bstrRegKey(_TEXT("Software\\Microsoft\\Remote Desktop\\"));
  196. TCHAR szDebugCmd[256];
  197. DWORD cbDebugCmd = sizeof(szDebugCmd)/sizeof(szDebugCmd[0]);
  198. dwStatus = GetModuleFileName( hInst, szModuleName, MAX_PATH+1 );
  199. if( 0 == dwStatus ) {
  200. //
  201. // Can't attach debugger with name.
  202. //
  203. return;
  204. }
  205. szModuleName[dwStatus] = L'\0';
  206. _tsplitpath( szModuleName, NULL, NULL, szFileName, NULL );
  207. bstrRegKey += szFileName;
  208. //
  209. // Check if we are asked to attach/break into debugger
  210. //
  211. dwStatus = regKey.Open( HKEY_LOCAL_MACHINE, bstrRegKey );
  212. if( 0 != dwStatus ) {
  213. return;
  214. }
  215. dwStatus = regKey.QueryValue( szDebugCmd, _TEXT("Debugger"), &cbDebugCmd );
  216. if( 0 != dwStatus || cbDebugCmd > 200 ) {
  217. // 200 chars is way too much for debugger command.
  218. return;
  219. }
  220. AttachDebugger( szDebugCmd );
  221. return;
  222. }