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.

252 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. smsbapi.c
  5. Abstract:
  6. Session Manager stubs which call subsystems.
  7. Author:
  8. Mark Lucovsky (markl) 04-Oct-1989
  9. Revision History:
  10. --*/
  11. #include "smsrvp.h"
  12. #if DBG
  13. PCHAR SmpSubSystemNames[] = {
  14. "Unknown",
  15. "Native",
  16. "Windows",
  17. "Posix",
  18. "OS/2"
  19. };
  20. #endif
  21. NTSTATUS
  22. SmpSbCreateSession (
  23. IN PSMPSESSION SourceSession OPTIONAL,
  24. IN PSMPKNOWNSUBSYS CreatorSubsystem OPTIONAL,
  25. IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
  26. IN ULONG DebugSession OPTIONAL,
  27. IN PCLIENT_ID DebugUiClientId OPTIONAL
  28. )
  29. {
  30. NTSTATUS st;
  31. PSMPKNOWNSUBSYS KnownSubSys;
  32. SBAPIMSG SbApiMsg;
  33. PSBCREATESESSION args;
  34. ULONG SessionId;
  35. PSMPPROCESS Process;
  36. ULONG MuSessionId;
  37. args = &SbApiMsg.u.CreateSession;
  38. args->ProcessInformation = *ProcessInformation;
  39. args->DebugSession = DebugSession;
  40. if (ARGUMENT_PRESENT(DebugUiClientId)) {
  41. args->DebugUiClientId = *DebugUiClientId;
  42. } else {
  43. args->DebugUiClientId.UniqueProcess = NULL;
  44. args->DebugUiClientId.UniqueThread = NULL;
  45. }
  46. //
  47. // Get MuSessionId for the target process.
  48. //
  49. SmpGetProcessMuSessionId( ProcessInformation->Process, &MuSessionId );
  50. if ( !SmpCheckDuplicateMuSessionId( MuSessionId ) ) {
  51. NtClose(ProcessInformation->Process);
  52. NtClose(ProcessInformation->Thread);
  53. KdPrint(( "SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND ));
  54. return( STATUS_OBJECT_NAME_NOT_FOUND );
  55. }
  56. KnownSubSys = SmpLocateKnownSubSysByType(
  57. MuSessionId,
  58. ProcessInformation->ImageInformation.SubSystemType
  59. );
  60. //
  61. // If we can't find the sybsystem, we just fail.
  62. //
  63. if ( !KnownSubSys ) {
  64. if (ProcessInformation->ImageInformation.SubSystemType !=
  65. IMAGE_SUBSYSTEM_NATIVE ) {
  66. #if DBG
  67. DbgPrint( "SMSS: %s SubSystem has not been started.\n",
  68. SmpSubSystemNames[ ProcessInformation->ImageInformation.SubSystemType ]
  69. );
  70. #endif
  71. NtClose(ProcessInformation->Process);
  72. NtClose(ProcessInformation->Thread);
  73. return STATUS_UNSUCCESSFUL;
  74. }
  75. if ( args->DebugUiClientId.UniqueProcess != NULL ||
  76. args->DebugUiClientId.UniqueThread != NULL ) {
  77. if ( SmpDbgSsLoaded ) {
  78. //
  79. // This is a native process.
  80. // Create a process and insert it in the hash list.
  81. //
  82. Process = RtlAllocateHeap(SmpHeap, MAKE_TAG( SM_TAG ), sizeof(SMPPROCESS));
  83. if (! Process) {
  84. #if DBG
  85. DbgPrint("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
  86. ProcessInformation->ClientId.UniqueProcess,
  87. ProcessInformation->ClientId.UniqueThread);
  88. #endif
  89. NtClose(ProcessInformation->Process);
  90. NtClose(ProcessInformation->Thread);
  91. return STATUS_NO_MEMORY;
  92. }
  93. Process->DebugUiClientId = args->DebugUiClientId;
  94. Process->ConnectionKey = ProcessInformation->ClientId;
  95. InsertHeadList(&NativeProcessList,&Process->Links);
  96. #if DBG
  97. DbgPrint("Native Debug App %lx.%lx\n",
  98. Process->ConnectionKey.UniqueProcess,
  99. Process->ConnectionKey.UniqueThread
  100. );
  101. #endif
  102. //
  103. // Process is being debugged, so set up debug port.
  104. //
  105. st = NtSetInformationProcess(
  106. ProcessInformation->Process,
  107. ProcessDebugPort,
  108. &SmpDebugPort,
  109. sizeof(HANDLE)
  110. );
  111. ASSERT(NT_SUCCESS(st));
  112. }
  113. }
  114. //
  115. // Start closing handles.
  116. //
  117. NtClose(ProcessInformation->Process);
  118. NtResumeThread(ProcessInformation->Thread,NULL);
  119. NtClose(ProcessInformation->Thread);
  120. return STATUS_SUCCESS;
  121. }
  122. //
  123. // Transfer the handles to the subsystem responsible for this process.
  124. //
  125. st = NtDuplicateObject(
  126. NtCurrentProcess(),
  127. ProcessInformation->Process,
  128. KnownSubSys->Process,
  129. &args->ProcessInformation.Process,
  130. PROCESS_ALL_ACCESS,
  131. 0,
  132. 0
  133. );
  134. if ( !NT_SUCCESS(st) ) {
  135. #if DBG
  136. DbgPrint("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n",st);
  137. #endif
  138. NtClose(ProcessInformation->Process);
  139. NtClose(ProcessInformation->Thread);
  140. RtlEnterCriticalSection( &SmpKnownSubSysLock );
  141. SmpDeferenceKnownSubSys(KnownSubSys);
  142. RtlLeaveCriticalSection( &SmpKnownSubSysLock );
  143. return st;
  144. }
  145. st = NtDuplicateObject(
  146. NtCurrentProcess(),
  147. ProcessInformation->Thread,
  148. KnownSubSys->Process,
  149. &args->ProcessInformation.Thread,
  150. THREAD_ALL_ACCESS,
  151. 0,
  152. 0
  153. );
  154. if ( !NT_SUCCESS(st) ) {
  155. //
  156. // Need to do more here.
  157. //
  158. NtClose(ProcessInformation->Process);
  159. NtClose(ProcessInformation->Thread);
  160. RtlEnterCriticalSection( &SmpKnownSubSysLock );
  161. SmpDeferenceKnownSubSys(KnownSubSys);
  162. RtlLeaveCriticalSection( &SmpKnownSubSysLock );
  163. #if DBG
  164. DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n",st);
  165. #endif
  166. return st;
  167. }
  168. NtClose(ProcessInformation->Process);
  169. NtClose(ProcessInformation->Thread);
  170. SessionId = SmpAllocateSessionId(
  171. KnownSubSys,
  172. CreatorSubsystem
  173. );
  174. args->SessionId = SessionId;
  175. SbApiMsg.ApiNumber = SbCreateSessionApi;
  176. SbApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  177. SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
  178. SbApiMsg.h.u2.ZeroInit = 0L;
  179. st = NtRequestWaitReplyPort(
  180. KnownSubSys->SbApiCommunicationPort,
  181. (PPORT_MESSAGE) &SbApiMsg,
  182. (PPORT_MESSAGE) &SbApiMsg
  183. );
  184. if ( NT_SUCCESS(st) ) {
  185. st = SbApiMsg.ReturnedStatus;
  186. } else {
  187. #if DBG
  188. DbgPrint("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n",st);
  189. #endif
  190. }
  191. if ( !NT_SUCCESS(st) ) {
  192. SmpDeleteSession(SessionId);
  193. }
  194. RtlEnterCriticalSection( &SmpKnownSubSysLock );
  195. SmpDeferenceKnownSubSys(KnownSubSys);
  196. RtlLeaveCriticalSection( &SmpKnownSubSysLock );
  197. return st;
  198. }