[SHELL32] Fix Control_RunDLLW (#5400)
[reactos.git] / drivers / bus / acpi / cmbatt / cmexec.c
1 /*
2 * PROJECT: ReactOS ACPI-Compliant Control Method Battery
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/drivers/bus/acpi/cmbatt/cmexec.c
5 * PURPOSE: ACPI Method Execution/Evaluation Glue
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "cmbatt.h"
12
13 #include <acpiioct.h>
14 #include <debug.h>
15
16 /* FUNCTIONS ******************************************************************/
17
18 NTSTATUS
19 NTAPI
20 GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument,
21 OUT PULONG Value)
22 {
23 NTSTATUS Status;
24
25 /* Must have an integer */
26 if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER)
27 {
28 /* Not an integer, fail */
29 Status = STATUS_ACPI_INVALID_DATA;
30 if (CmBattDebug & 0x4C)
31 DbgPrint("GetDwordElement: Object contained wrong data type - %d\n",
32 Argument->Type);
33 }
34 else
35 {
36 /* Read the integer value */
37 *Value = Argument->Argument;
38 Status = STATUS_SUCCESS;
39 }
40
41 /* Return status */
42 return Status;
43 }
44
45 NTSTATUS
46 NTAPI
47 GetStringElement(IN PACPI_METHOD_ARGUMENT Argument,
48 OUT PCHAR Value)
49 {
50 NTSTATUS Status;
51
52 /* Must have a string of buffer */
53 if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) ||
54 (Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER))
55 {
56 /* String must be less than 256 characters */
57 if (Argument->DataLength < 256)
58 {
59 /* Copy the buffer */
60 RtlCopyMemory(Value, Argument->Data, Argument->DataLength);
61 Status = STATUS_SUCCESS;
62 }
63 else
64 {
65 /* The buffer is too small (the string is too large) */
66 Status = STATUS_BUFFER_TOO_SMALL;
67 if (CmBattDebug & 0x4C)
68 DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength);
69 }
70 }
71 else
72 {
73 /* Not valid string data */
74 Status = STATUS_ACPI_INVALID_DATA;
75 if (CmBattDebug & 0x4C)
76 DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type);
77 }
78
79 /* Return the status */
80 return Status;
81 }
82
83 NTSTATUS
84 NTAPI
85 CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject,
86 IN ULONG IoControlCode,
87 IN PVOID InputBuffer,
88 IN ULONG InputBufferLength,
89 IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer,
90 IN ULONG OutputBufferLength)
91 {
92 PIRP Irp;
93 NTSTATUS Status;
94 KEVENT Event;
95 IO_STATUS_BLOCK IoStatusBlock;
96 PAGED_CODE();
97
98 /* Initialize our wait event */
99 KeInitializeEvent(&Event, SynchronizationEvent, 0);
100
101 /* Allocate the IRP */
102 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
103 DeviceObject,
104 InputBuffer,
105 InputBufferLength,
106 OutputBuffer,
107 OutputBufferLength,
108 0,
109 &Event,
110 &IoStatusBlock);
111 if (!Irp)
112 {
113 /* No IRP, fail */
114 if (CmBattDebug & 0x4C)
115 DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n");
116 return STATUS_INSUFFICIENT_RESOURCES;
117 }
118
119 /* Call ACPI */
120 if (CmBattDebug & 0x40)
121 DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n",
122 Irp, KeGetCurrentThread());
123 Status = IoCallDriver(DeviceObject, Irp);
124 if (Status == STATUS_PENDING)
125 {
126 /* Wait for completion */
127 KeWaitForSingleObject(&Event,
128 Executive,
129 KernelMode,
130 FALSE,
131 NULL);
132 Status = Irp->IoStatus.Status;
133 }
134
135 /* Check if caller wanted output */
136 if (OutputBuffer)
137 {
138 /* Make sure it's valid ACPI output buffer */
139 if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) ||
140 !(OutputBuffer->Count))
141 {
142 /* It isn't, so set failure code */
143 Status = STATUS_ACPI_INVALID_DATA;
144 }
145 }
146
147 /* Return status */
148 if (CmBattDebug & 0x40)
149 DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
150 Irp, Status, KeGetCurrentThread());
151 return Status;
152 }
153
154 NTSTATUS
155 NTAPI
156 CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject,
157 OUT PULONG PsrData)
158 {
159 NTSTATUS Status;
160 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
161 ACPI_EVAL_INPUT_BUFFER InputBuffer;
162 PAGED_CODE();
163 if (CmBattDebug & 0x40)
164 DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n",
165 DeviceObject, KeGetCurrentThread());
166
167 /* Initialize to zero */
168 ASSERT(PsrData != NULL);
169 *PsrData = 0;
170
171 /* Request the _PSR method */
172 *(PULONG)InputBuffer.MethodName = 'RSP_';
173 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
174
175 /* Send it to ACPI */
176 Status = CmBattSendDownStreamIrp(DeviceObject,
177 IOCTL_ACPI_EVAL_METHOD,
178 &InputBuffer,
179 sizeof(InputBuffer),
180 &OutputBuffer,
181 sizeof(OutputBuffer));
182 if (NT_SUCCESS(Status))
183 {
184 /* Read the result */
185 Status = GetDwordElement(OutputBuffer.Argument, PsrData);
186 if (CmBattDebug & 0x440)
187 DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData);
188 }
189 else if (CmBattDebug & 0x44C)
190 {
191 /* Failure */
192 DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status);
193 }
194
195 /* Return status */
196 return Status;
197 }
198
199 NTSTATUS
200 NTAPI
201 CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject,
202 OUT PULONG StaData)
203 {
204 NTSTATUS Status;
205 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
206 ACPI_EVAL_INPUT_BUFFER InputBuffer;
207 PAGED_CODE();
208 if (CmBattDebug & 0x40)
209 DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n",
210 DeviceObject, KeGetCurrentThread());
211
212 /* Initialize to zero */
213 ASSERT(StaData != NULL);
214 *StaData = 0;
215
216 /* Request the _PSR method */
217 *(PULONG)InputBuffer.MethodName = 'ATS_';
218 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
219
220 /* Send it to ACPI */
221 Status = CmBattSendDownStreamIrp(DeviceObject,
222 IOCTL_ACPI_EVAL_METHOD,
223 &InputBuffer,
224 sizeof(InputBuffer),
225 &OutputBuffer,
226 sizeof(OutputBuffer));
227 if (NT_SUCCESS(Status))
228 {
229 /* Read the result */
230 Status = GetDwordElement(OutputBuffer.Argument, StaData);
231 if (CmBattDebug & 0x440)
232 DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData);
233 }
234 else if (CmBattDebug & 0x44C)
235 {
236 /* Failure */
237 DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status);
238 Status = STATUS_NO_SUCH_DEVICE;
239 }
240
241 /* Return status */
242 return Status;
243 }
244
245 NTSTATUS
246 NTAPI
247 CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject,
248 OUT PULONG UniqueId)
249 {
250 NTSTATUS Status;
251 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
252 ACPI_EVAL_INPUT_BUFFER InputBuffer;
253 PAGED_CODE();
254 if (CmBattDebug & 0x40)
255 DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n",
256 DeviceObject, KeGetCurrentThread());
257
258 /* Initialize to zero */
259 ASSERT(UniqueId != NULL);
260 *UniqueId = 0;
261
262 /* Request the _PSR method */
263 *(PULONG)InputBuffer.MethodName = 'DIU_';
264 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
265
266 /* Send it to ACPI */
267 Status = CmBattSendDownStreamIrp(DeviceObject,
268 IOCTL_ACPI_EVAL_METHOD,
269 &InputBuffer,
270 sizeof(InputBuffer),
271 &OutputBuffer,
272 sizeof(OutputBuffer));
273 if (NT_SUCCESS(Status))
274 {
275 /* Read the result */
276 Status = GetDwordElement(OutputBuffer.Argument, UniqueId);
277 if (CmBattDebug & 0x440)
278 DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId);
279 }
280 else if (CmBattDebug & 0x44C)
281 {
282 /* Failure */
283 DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status);
284 Status = STATUS_NO_SUCH_DEVICE;
285 }
286
287 /* Return status */
288 return Status;
289 }
290
291 NTSTATUS
292 NTAPI
293 CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
294 IN ULONG AlarmValue)
295 {
296 NTSTATUS Status;
297 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer;
298 PAGED_CODE();
299 if (CmBattDebug & 0x440)
300 DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
301 AlarmValue, DeviceExtension->DeviceId, KeGetCurrentThread);
302
303 /* Request the _BTP method */
304 *(PULONG)InputBuffer.MethodName = 'PTB_';
305 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
306 InputBuffer.IntegerArgument = AlarmValue;
307
308 /* Send it to ACPI */
309 Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice,
310 IOCTL_ACPI_EVAL_METHOD,
311 &InputBuffer,
312 sizeof(InputBuffer),
313 NULL,
314 0);
315 if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0x440))
316 DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
317 DeviceExtension->DeviceId, Status);
318
319 /* Return status */
320 return Status;
321 }
322
323 NTSTATUS
324 NTAPI
325 CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
326 PACPI_BIF_DATA BifData)
327 {
328 UNIMPLEMENTED;
329 return STATUS_NOT_IMPLEMENTED;
330 }
331
332 NTSTATUS
333 NTAPI
334 CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
335 PACPI_BST_DATA BstData)
336 {
337 UNIMPLEMENTED;
338 return STATUS_NOT_IMPLEMENTED;
339 }
340
341 /* EOF */