* Sync up to trunk head (r64921).
[reactos.git] / dll / win32 / smdll / query.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/smdll/query.c
5 * PURPOSE: Call SM API SM_API_QUERY_INFORMATION (not in NT)
6 */
7
8 #include "precomp.h"
9
10 #define NTOS_MODE_USER
11 #include <ndk/lpctypes.h>
12 #include <ndk/lpcfuncs.h>
13 #include <sm/helper.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18
19 /**********************************************************************
20 * NAME EXPORTED
21 * SmQueryInformation/5
22 *
23 * DESCRIPTION
24 * Ask the SM to collect some data from its internal data
25 * structures and send it back.
26 *
27 * ARGUMENTS
28 * hSmApiPort: handle returned by SmConnectApiPort;
29 * SmInformationClass: an SM information class ID:
30 * SM_BASIC_INFORMATION: the number of registered subsystems
31 * Data: pointer to storage for the information to request;
32 * DataLength: length in bytes of the Data buffer; it must be
33 * set and must match the SmInformationClass info size;
34 * ReturnedDataLength: optional pointer to storage to receive
35 * the size of the returnede data.
36 *
37 * RETURN VALUE
38 * STATUS_SUCCESS: OK you get what you asked for;
39 * STATUS_INFO_LENGTH_MISMATCH: you set DataLength to 0 or to a
40 * value that does not match whet the SmInformationClass
41 * requires;
42 * STATUS_INVALID_PARAMETER_2: bad information class;
43 * A port error.
44 *
45 */
46 NTSTATUS WINAPI
47 SmQueryInformation (IN HANDLE hSmApiPort,
48 IN SM_INFORMATION_CLASS SmInformationClass,
49 IN OUT PVOID Data,
50 IN ULONG DataLength,
51 IN OUT PULONG ReturnedDataLength OPTIONAL)
52 {
53 NTSTATUS Status = STATUS_SUCCESS;
54 SM_PORT_MESSAGE SmReqMsg;
55
56
57 if(0 == DataLength)
58 {
59 return STATUS_INFO_LENGTH_MISMATCH;
60 }
61 /* Marshal data in the port message */
62 switch (SmInformationClass)
63 {
64 case SmBasicInformation:
65 if(DataLength != sizeof (SM_BASIC_INFORMATION))
66 {
67 return STATUS_INFO_LENGTH_MISMATCH;
68 }
69 SmReqMsg.Request.QryInfo.SmInformationClass = SmBasicInformation;
70 SmReqMsg.Request.QryInfo.DataLength = DataLength;
71 SmReqMsg.Request.QryInfo.BasicInformation.SubSystemCount = 0;
72 break;
73 case SmSubSystemInformation:
74 if(DataLength != sizeof (SM_SUBSYSTEM_INFORMATION))
75 {
76 return STATUS_INFO_LENGTH_MISMATCH;
77 }
78 SmReqMsg.Request.QryInfo.SmInformationClass = SmSubSystemInformation;
79 SmReqMsg.Request.QryInfo.DataLength = DataLength;
80 SmReqMsg.Request.QryInfo.SubSystemInformation.SubSystemId =
81 ((PSM_SUBSYSTEM_INFORMATION)Data)->SubSystemId;
82 break;
83 default:
84 return STATUS_INVALID_PARAMETER_2;
85 }
86 /* SM API to invoke */
87 SmReqMsg.SmHeader.ApiIndex = SM_API_QUERY_INFORMATION;
88
89 /* Prepare the port request message */
90 SmReqMsg.Header.u2.s2.Type = LPC_NEW_MESSAGE;
91 SmReqMsg.Header.u1.s1.DataLength = SM_PORT_DATA_SIZE(SmReqMsg.Request);
92 SmReqMsg.Header.u1.s1.TotalLength = SM_PORT_MESSAGE_SIZE;
93 Status = NtRequestWaitReplyPort (hSmApiPort, (PPORT_MESSAGE) & SmReqMsg, (PPORT_MESSAGE) & SmReqMsg);
94 if (NT_SUCCESS(Status))
95 {
96 /* Unmarshal data */
97 RtlCopyMemory (Data, & SmReqMsg.Reply.QryInfo.BasicInformation, SmReqMsg.Reply.QryInfo.DataLength);
98 /* Use caller provided storage to store data size */
99 if(NULL != ReturnedDataLength)
100 {
101 *ReturnedDataLength = SmReqMsg.Reply.QryInfo.DataLength;
102 }
103 return SmReqMsg.SmHeader.Status;
104 }
105 DPRINT("SMLIB: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);
106 return Status;
107 }
108 /* EOF */