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.

496 lines
12 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. sm6432.c
  5. Abstract:
  6. Session Manager Client Support APIs for Wow64 executable (32-bit images running
  7. on Win64)
  8. Author:
  9. Samer Arafeh (samera) 20-Sep-2001
  10. Revision History:
  11. --*/
  12. #if defined(_X86_)
  13. /*
  14. * Enable LPC port-messages to have compatible layout between the 32-bit and 64-bit worlds.
  15. */
  16. #define USE_LPC6432 1
  17. #define BUILD_WOW6432 1
  18. #include "smdllp.h"
  19. #include "smp6432.h"
  20. #include <string.h>
  21. NTSTATUS
  22. SmpThunkUserProcessInfoTo64 (
  23. IN PRTL_USER_PROCESS_INFORMATION UserProcessInformation32,
  24. OUT PRTL_USER_PROCESS_INFORMATION64 UserProcessInformation64
  25. )
  26. /*++
  27. Routine Description:
  28. This routine thunks RTL_PROCESS_USER_INFORMATION structure from 32-bit
  29. structure offsets in Win64 structure offsets.
  30. Arguments:
  31. UserProcessInformation32 - 32-bit Input structure.
  32. UserProcessInformation64 - 64-bit Output structure allocated by the caller.
  33. Return Value:
  34. NTSTATUS.
  35. --*/
  36. {
  37. NTSTATUS NtStatus = STATUS_SUCCESS;
  38. if (ARGUMENT_PRESENT (UserProcessInformation32)) {
  39. try {
  40. UserProcessInformation64->Length = sizeof (RTL_USER_PROCESS_INFORMATION64);
  41. UserProcessInformation64->Process = (LONGLONG)UserProcessInformation32->Process;
  42. UserProcessInformation64->Thread = (LONGLONG)UserProcessInformation32->Thread;
  43. UserProcessInformation64->ClientId.UniqueProcess = (ULONGLONG)UserProcessInformation32->ClientId.UniqueProcess;
  44. UserProcessInformation64->ClientId.UniqueThread = (ULONGLONG)UserProcessInformation32->ClientId.UniqueThread;
  45. UserProcessInformation64->ImageInformation.TransferAddress = (ULONGLONG)UserProcessInformation32->ImageInformation.TransferAddress;
  46. UserProcessInformation64->ImageInformation.ZeroBits = UserProcessInformation32->ImageInformation.ZeroBits;
  47. UserProcessInformation64->ImageInformation.MaximumStackSize = UserProcessInformation32->ImageInformation.MaximumStackSize;
  48. UserProcessInformation64->ImageInformation.CommittedStackSize = UserProcessInformation32->ImageInformation.CommittedStackSize;
  49. UserProcessInformation64->ImageInformation.SubSystemType = UserProcessInformation32->ImageInformation.SubSystemType;
  50. UserProcessInformation64->ImageInformation.SubSystemVersion = UserProcessInformation32->ImageInformation.SubSystemVersion;
  51. UserProcessInformation64->ImageInformation.GpValue = UserProcessInformation32->ImageInformation.GpValue;
  52. UserProcessInformation64->ImageInformation.ImageCharacteristics = UserProcessInformation32->ImageInformation.ImageCharacteristics;
  53. UserProcessInformation64->ImageInformation.DllCharacteristics = UserProcessInformation32->ImageInformation.DllCharacteristics;
  54. UserProcessInformation64->ImageInformation.Machine = UserProcessInformation32->ImageInformation.Machine;
  55. UserProcessInformation64->ImageInformation.ImageContainsCode = UserProcessInformation32->ImageInformation.ImageContainsCode;
  56. UserProcessInformation64->ImageInformation.Spare1 = UserProcessInformation32->ImageInformation.Spare1;
  57. UserProcessInformation64->ImageInformation.LoaderFlags = UserProcessInformation32->ImageInformation.LoaderFlags;
  58. RtlCopyMemory (&UserProcessInformation64->ImageInformation.Reserved,
  59. &UserProcessInformation32->ImageInformation.Reserved,
  60. sizeof (UserProcessInformation32->ImageInformation.Reserved));
  61. } except (EXCEPTION_EXECUTE_HANDLER) {
  62. NtStatus = GetExceptionCode ();
  63. }
  64. } else {
  65. UserProcessInformation64 = (PRTL_USER_PROCESS_INFORMATION64)UserProcessInformation32;
  66. }
  67. return NtStatus;
  68. }
  69. BOOLEAN
  70. SmpIsWow64Process (
  71. VOID
  72. )
  73. /*++
  74. Routine Description:
  75. This routine detects whether the currently executing process is running inside
  76. Wow64. The routine caches the result.
  77. Arguments:
  78. None.
  79. Return Value:
  80. BOOLEAN.
  81. --*/
  82. {
  83. NTSTATUS NtStatus;
  84. PVOID Peb32;
  85. static BOOLEAN RunningInsideWow64 = -1;
  86. if (RunningInsideWow64 == (BOOLEAN)-1) {
  87. NtStatus = NtQueryInformationProcess (
  88. NtCurrentProcess (),
  89. ProcessWow64Information,
  90. &Peb32,
  91. sizeof (Peb32),
  92. NULL
  93. );
  94. if (NT_SUCCESS (NtStatus)) {
  95. if (Peb32 != NULL) {
  96. RunningInsideWow64 = TRUE;
  97. } else {
  98. RunningInsideWow64 = FALSE;
  99. }
  100. } else {
  101. RunningInsideWow64 = FALSE;
  102. }
  103. }
  104. return RunningInsideWow64;
  105. }
  106. NTSTATUS
  107. SmpWow64ExecPgm(
  108. IN HANDLE SmApiPort,
  109. IN PRTL_USER_PROCESS_INFORMATION ProcessInformation32,
  110. IN BOOLEAN DebugFlag
  111. )
  112. /*++
  113. Routine Description:
  114. This routine allows a process to start a process using the
  115. facilities provided by the NT Session manager.
  116. This function closes all handles passed to it.
  117. Arguments:
  118. SmApiPort - Supplies a handle to a communications port connected
  119. to the Session Manager.
  120. ProcessInformation32 - Supplies a process description as returned
  121. by RtlCreateUserProcess.
  122. DebugFlag - Supplies and optional parameter which if set indicates
  123. that the caller wants to debug this process and act as its
  124. debug user interface.
  125. Return Value:
  126. NSTATUS.
  127. --*/
  128. {
  129. NTSTATUS st;
  130. SMAPIMSG64 SmApiMsg;
  131. PSMEXECPGM64 args;
  132. RTL_USER_PROCESS_INFORMATION64 ProcessInformation64;
  133. args = &SmApiMsg.u.ExecPgm;
  134. st = SmpThunkUserProcessInfoTo64 (ProcessInformation32,
  135. &ProcessInformation64);
  136. if (NT_SUCCESS (st)) {
  137. args->DebugFlag = DebugFlag;
  138. SmApiMsg.ApiNumber = SmExecPgmApi;
  139. SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  140. SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
  141. SmApiMsg.h.u2.ZeroInit = 0L;
  142. st = NtRequestWaitReplyPort(
  143. SmApiPort,
  144. (PPORT_MESSAGE) &SmApiMsg,
  145. (PPORT_MESSAGE) &SmApiMsg
  146. );
  147. if ( NT_SUCCESS(st) ) {
  148. st = SmApiMsg.ReturnedStatus;
  149. } else {
  150. KdPrint(("SmExecPgm: NtRequestWaitReply Failed %lx\n",st));
  151. }
  152. NtClose(ProcessInformation32->Process);
  153. NtClose(ProcessInformation32->Thread);
  154. }
  155. return st;
  156. }
  157. NTSTATUS
  158. SmpWow64LoadDeferedSubsystem(
  159. IN HANDLE SmApiPort,
  160. IN PUNICODE_STRING DeferedSubsystem
  161. )
  162. /*++
  163. Routine Description:
  164. This routine allows a process to start a defered subsystem.
  165. Arguments:
  166. SmApiPort - Supplies a handle to a communications port connected
  167. to the Session Manager.
  168. DeferedSubsystem - Supplies the name of the defered subsystem to load.
  169. Return Value:
  170. NSTATUS.
  171. --*/
  172. {
  173. NTSTATUS st;
  174. SMAPIMSG64 SmApiMsg;
  175. PSMLOADDEFERED args;
  176. if ( DeferedSubsystem->Length >> 1 > SMP_MAXIMUM_SUBSYSTEM_NAME ) {
  177. return STATUS_INVALID_PARAMETER;
  178. }
  179. args = &SmApiMsg.u.LoadDefered;
  180. args->SubsystemNameLength = DeferedSubsystem->Length;
  181. RtlZeroMemory(args->SubsystemName, sizeof (args->SubsystemName));
  182. RtlCopyMemory(args->SubsystemName,DeferedSubsystem->Buffer,DeferedSubsystem->Length);
  183. SmApiMsg.ApiNumber = SmLoadDeferedSubsystemApi;
  184. SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  185. SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
  186. SmApiMsg.h.u2.ZeroInit = 0L;
  187. st = NtRequestWaitReplyPort(
  188. SmApiPort,
  189. (PPORT_MESSAGE) &SmApiMsg,
  190. (PPORT_MESSAGE) &SmApiMsg
  191. );
  192. if ( NT_SUCCESS(st) ) {
  193. st = SmApiMsg.ReturnedStatus;
  194. } else {
  195. KdPrint(("SmExecPgm: NtRequestWaitReply Failed %lx\n",st));
  196. }
  197. return st;
  198. }
  199. NTSTATUS
  200. SmpWow64SessionComplete(
  201. IN HANDLE SmApiPort,
  202. IN ULONG SessionId,
  203. IN NTSTATUS CompletionStatus
  204. )
  205. /*++
  206. Routine Description:
  207. This routine is used to report completion of a session to
  208. the NT Session manager.
  209. Arguments:
  210. SmApiPort - Supplies a handle to a communications port connected
  211. to the Session Manager.
  212. SessionId - Supplies the session id of the session which is now completed.
  213. CompletionStatus - Supplies the completion status of the session.
  214. Return Value:
  215. NSTATUS.
  216. --*/
  217. {
  218. NTSTATUS st;
  219. SMAPIMSG64 SmApiMsg;
  220. PSMSESSIONCOMPLETE args;
  221. args = &SmApiMsg.u.SessionComplete;
  222. args->SessionId = SessionId;
  223. args->CompletionStatus = CompletionStatus;
  224. SmApiMsg.ApiNumber = SmSessionCompleteApi;
  225. SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  226. SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
  227. SmApiMsg.h.u2.ZeroInit = 0L;
  228. st = NtRequestWaitReplyPort(
  229. SmApiPort,
  230. (PPORT_MESSAGE) &SmApiMsg,
  231. (PPORT_MESSAGE) &SmApiMsg
  232. );
  233. if ( NT_SUCCESS(st) ) {
  234. st = SmApiMsg.ReturnedStatus;
  235. } else {
  236. KdPrint(("SmCompleteSession: NtRequestWaitReply Failed %lx\n",st));
  237. }
  238. return st;
  239. }
  240. NTSTATUS
  241. SmpWow64StartCsr(
  242. IN HANDLE SmApiPort,
  243. OUT PULONG pMuSessionId,
  244. IN PUNICODE_STRING InitialCommand,
  245. OUT PULONG_PTR pInitialCommandProcessId,
  246. OUT PULONG_PTR pWindowsSubSysProcessId
  247. )
  248. /*++
  249. Routine Description:
  250. This routine allows TERMSRV to start a new CSR.
  251. Arguments:
  252. SmApiPort - Supplies a handle to a communications port connected
  253. to the Session Manager.
  254. MuSessionId - Hydra Terminal Session Id to start CSR in.
  255. InitialCommand - String for Initial Command (for debug)
  256. pInitialCommandProcessId - pointer to Process Id of initial command.
  257. pWindowsSubSysProcessId - pointer to Process Id of Windows subsystem.
  258. Return Value:
  259. NSTATUS.
  260. --*/
  261. {
  262. NTSTATUS st;
  263. SMAPIMSG64 SmApiMsg;
  264. PSMSTARTCSR64 args;
  265. args = &SmApiMsg.u.StartCsr;
  266. args->MuSessionId = *pMuSessionId; //Sm will reassign the actuall sessionID
  267. if ( InitialCommand &&
  268. ( InitialCommand->Length >> 1 > SMP_MAXIMUM_INITIAL_COMMAND ) ) {
  269. return STATUS_INVALID_PARAMETER;
  270. }
  271. if ( !InitialCommand ) {
  272. args->InitialCommandLength = 0;
  273. }
  274. else {
  275. args->InitialCommandLength = InitialCommand->Length;
  276. RtlZeroMemory(args->InitialCommand, sizeof (args->InitialCommand));
  277. RtlCopyMemory(args->InitialCommand,InitialCommand->Buffer,InitialCommand->Length);
  278. }
  279. SmApiMsg.ApiNumber = SmStartCsrApi;
  280. SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  281. SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
  282. SmApiMsg.h.u2.ZeroInit = 0L;
  283. st = NtRequestWaitReplyPort(
  284. SmApiPort,
  285. (PPORT_MESSAGE) &SmApiMsg,
  286. (PPORT_MESSAGE) &SmApiMsg
  287. );
  288. if ( NT_SUCCESS(st) ) {
  289. st = SmApiMsg.ReturnedStatus;
  290. } else {
  291. DbgPrint("SmStartCsr: NtRequestWaitReply Failed %lx\n",st);
  292. }
  293. *pInitialCommandProcessId = (ULONG)args->InitialCommandProcessId;
  294. *pWindowsSubSysProcessId = (ULONG)args->WindowsSubSysProcessId;
  295. *pMuSessionId = args->MuSessionId;
  296. return st;
  297. }
  298. NTSTATUS
  299. SmpWow64StopCsr(
  300. IN HANDLE SmApiPort,
  301. IN ULONG MuSessionId
  302. )
  303. /*++
  304. Routine Description:
  305. This routine allows TERMSRV to stop a CSR.
  306. Arguments:
  307. SmApiPort - Supplies a handle to a communications port connected
  308. to the Session Manager.
  309. MuSessionId - Terminal Server Session Id to stop
  310. Return Value:
  311. NSTATUS.
  312. --*/
  313. {
  314. NTSTATUS st;
  315. SMAPIMSG64 SmApiMsg;
  316. PSMSTOPCSR args;
  317. args = &SmApiMsg.u.StopCsr;
  318. args->MuSessionId = MuSessionId;
  319. SmApiMsg.ApiNumber = SmStopCsrApi;
  320. SmApiMsg.h.u1.s1.DataLength = sizeof(*args) + 8;
  321. SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
  322. SmApiMsg.h.u2.ZeroInit = 0L;
  323. st = NtRequestWaitReplyPort(
  324. SmApiPort,
  325. (PPORT_MESSAGE) &SmApiMsg,
  326. (PPORT_MESSAGE) &SmApiMsg
  327. );
  328. if ( NT_SUCCESS(st) ) {
  329. st = SmApiMsg.ReturnedStatus;
  330. } else {
  331. DbgPrint("SmStopCsr: NtRequestWaitReply Failed %lx\n",st);
  332. }
  333. return st;
  334. }
  335. #endif // #if defined(_X86_)