Create the AHCI branch for Aman's work
[reactos.git] / sdk / lib / smlib / smclient.c
1 /*
2 * PROJECT: ReactOS Windows-Compatible Session Manager
3 * LICENSE: BSD 2-Clause License
4 * FILE: lib/smlib/smclient.c
5 * PURPOSE: SMSS Client Library Stubs for calling SM APIs from a client
6 * PROGRAMMERS: Alex Ionescu
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "precomp.h"
12 #include <sm/smmsg.h> // To go in precomp.h after
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* FUNCTIONS ******************************************************************/
18
19 NTSTATUS
20 NTAPI
21 SmExecPgm(IN HANDLE SmApiPort,
22 IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
23 IN BOOLEAN DebugFlag)
24 {
25 NTSTATUS Status;
26 SM_API_MSG SmApiMsg;
27
28 #if 0 //def _WIN64 // You can take care of this Timo
29 /* 64-bit SMSS needs to talk to 32-bit processes so do the LPC conversion */
30 if (SmpIsWow64Process())
31 {
32 return SmpWow64ExecPgm(SmApiPort, ProcessInformation, DebugFlag);
33 }
34 #endif
35
36 /* Initialize the generic LPC header */
37 SmApiMsg.h.u2.ZeroInit = 0;
38 SmApiMsg.h.u1.s1.DataLength = sizeof(SM_EXEC_PGM_MSG) + 8;
39 SmApiMsg.h.u1.s1.TotalLength = sizeof(SmApiMsg);
40
41 /* Initialize this specific API's parameters */
42 SmApiMsg.ApiNumber = SmpExecPgmApi;
43 RtlCopyMemory(&SmApiMsg.u.ExecPgm.ProcessInformation,
44 ProcessInformation,
45 sizeof(SmApiMsg.u.ExecPgm.ProcessInformation));
46 SmApiMsg.u.ExecPgm.DebugFlag = DebugFlag;
47
48 /* Send the message to SMSS */
49 Status = NtRequestWaitReplyPort(SmApiPort, &SmApiMsg.h, &SmApiMsg.h);
50 if (!NT_SUCCESS(Status))
51 {
52 DPRINT1("SmExecPgm: NtRequestWaitReply Failed %lx\n", Status);
53 }
54 else
55 {
56 /* Upon success, we use the API's return value */
57 Status = SmApiMsg.ReturnValue;
58 }
59
60 /* Close the handles that the parent passed in and return status */
61 NtClose(ProcessInformation->ProcessHandle);
62 NtClose(ProcessInformation->ThreadHandle);
63 return Status;
64 }
65
66 NTSTATUS
67 NTAPI
68 SmConnectToSm(IN PUNICODE_STRING SbApiPortName,
69 IN HANDLE SbApiPort,
70 IN ULONG ImageType,
71 OUT PHANDLE SmApiPort)
72 {
73 NTSTATUS Status;
74 SB_CONNECTION_INFO ConnectInfo;
75 UNICODE_STRING PortName;
76 SECURITY_QUALITY_OF_SERVICE SecurityQos;
77 ULONG ConnectInfoLength = sizeof(ConnectInfo);
78
79 /* Setup the QoS structure */
80 SecurityQos.ImpersonationLevel = SecurityIdentification;
81 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
82 SecurityQos.EffectiveOnly = TRUE;
83
84 /* Set the SM API port name */
85 RtlInitUnicodeString(&PortName, L"\\SmApiPort");
86
87 /* Check if this is a client connecting to SMSS, or SMSS to itself */
88 if (SbApiPortName)
89 {
90 /* A client SB port as well as an image type must be present */
91 if (!(SbApiPort) || !(ImageType)) return STATUS_INVALID_PARAMETER_MIX;
92
93 /* Copy the client port name, and NULL-terminate it */
94 RtlCopyMemory(ConnectInfo.SbApiPortName,
95 SbApiPortName->Buffer,
96 SbApiPortName->Length);
97 ConnectInfo.SbApiPortName[SbApiPortName->Length /
98 sizeof(WCHAR)] = UNICODE_NULL;
99
100 /* Save the subsystem type */
101 ConnectInfo.SubsystemType = ImageType;
102 }
103 else
104 {
105 /* No client port, and the subsystem type is not set */
106 ConnectInfo.SbApiPortName[0] = UNICODE_NULL;
107 ConnectInfo.SubsystemType = IMAGE_SUBSYSTEM_UNKNOWN;
108 }
109
110 /* Connect to SMSS and exchange connection information */
111 Status = NtConnectPort(SmApiPort,
112 &PortName,
113 &SecurityQos,
114 NULL,
115 NULL,
116 NULL,
117 &ConnectInfo,
118 &ConnectInfoLength);
119 if (!NT_SUCCESS(Status))
120 {
121 DPRINT1("SmConnectToSm: Connect to Sm failed %lx\n", Status);
122 }
123 else
124 {
125 /* Treat a warning or informational status as success */
126 Status = STATUS_SUCCESS;
127 }
128
129 /* Return if the connection was successful or not */
130 return Status;
131 }
132
133 NTSTATUS
134 NTAPI
135 SmSessionComplete(IN HANDLE SmApiPort,
136 IN ULONG SessionId,
137 IN NTSTATUS SessionStatus)
138 {
139 NTSTATUS Status;
140 SM_API_MSG ApiMessage;
141 PSM_SESSION_COMPLETE_MSG SessionComplete = &ApiMessage.u.SessionComplete;
142
143 /* Set the message data */
144 SessionComplete->SessionId = SessionId;
145 SessionComplete->SessionStatus = SessionStatus;
146
147 /* Set the API Message Port Message header */
148 ApiMessage.ApiNumber = SmpSessionCompleteApi;
149 ApiMessage.h.u1.s1.DataLength = sizeof(SM_SESSION_COMPLETE_MSG) + 8;
150 ApiMessage.h.u1.s1.TotalLength = sizeof(SM_API_MSG);
151 ApiMessage.h.u2.ZeroInit = 0;
152
153 /* Sent the message and wait for a reply */
154 Status = NtRequestWaitReplyPort(SmApiPort,
155 &ApiMessage.h,
156 &ApiMessage.h);
157 if (NT_SUCCESS(Status))
158 {
159 /* Return the real status */
160 Status = ApiMessage.ReturnValue;
161 }
162 else
163 {
164 DPRINT1("SmCompleteSession: NtRequestWaitReply failed\n");
165 }
166
167 /* Return status */
168 return Status;
169 }