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