[CONUTILS] Make the headers C++ compatible.
[reactos.git] / sdk / lib / smlib / lookupss.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/smlib/lookupss.c
5 */
6
7 #include "precomp.h"
8
9 #define NDEBUG
10 #include <debug.h>
11
12 /**********************************************************************
13 * NAME EXPORTED
14 * SmLookupSubsystem/6
15 *
16 * DESCRIPTION
17 * Read from the registry key
18 * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
19 * the value which name is Name.
20 *
21 * ARGUMENTS
22 * Name: name of the program to run, that is a value's name in
23 * the SM registry key SubSystems;
24 * Data: what the registry gave back for Name;
25 * DataLength: how much Data the registry returns;
26 * DataType: what is Data?
27 * Environment: set it if you want this function to use it
28 * to possibly expand Data before giving it back; if set
29 * to NULL, no expansion will be performed.
30 */
31 NTSTATUS WINAPI
32 SmLookupSubsystem (IN PWSTR Name,
33 IN OUT PWSTR Data,
34 IN OUT PULONG DataLength,
35 IN OUT PULONG DataType,
36 IN PVOID Environment OPTIONAL)
37 {
38 NTSTATUS Status = STATUS_SUCCESS;
39 UNICODE_STRING usKeyName = { 0, 0, NULL };
40 OBJECT_ATTRIBUTES Oa = {0};
41 HANDLE hKey = (HANDLE) 0;
42
43 DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);
44 /*
45 * Prepare the key name to scan and
46 * related object attributes.
47 */
48 RtlInitUnicodeString (& usKeyName,
49 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
50
51 InitializeObjectAttributes (& Oa,
52 & usKeyName,
53 OBJ_CASE_INSENSITIVE,
54 NULL,
55 NULL);
56 /*
57 * Open the key. This MUST NOT fail, if the
58 * request is for a legitimate subsystem.
59 */
60 Status = NtOpenKey (& hKey,
61 MAXIMUM_ALLOWED,
62 & Oa);
63 if(NT_SUCCESS(Status))
64 {
65 UNICODE_STRING usValueName = { 0, 0, NULL };
66 PWCHAR KeyValueInformation = NULL;
67 ULONG KeyValueInformationLength = 1024;
68 ULONG ResultLength = 0L;
69 PKEY_VALUE_PARTIAL_INFORMATION kvpi = NULL;
70
71 KeyValueInformation = RtlAllocateHeap (RtlGetProcessHeap(),
72 0,
73 KeyValueInformationLength);
74 if (NULL == KeyValueInformation)
75 {
76 return STATUS_NO_MEMORY;
77 }
78 kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
79 RtlInitUnicodeString (& usValueName, Name);
80 Status = NtQueryValueKey (hKey,
81 & usValueName,
82 KeyValuePartialInformation,
83 KeyValueInformation,
84 KeyValueInformationLength,
85 & ResultLength);
86 if(NT_SUCCESS(Status))
87 {
88 DPRINT("nkvpi.TitleIndex = %lu\n", kvpi->TitleIndex);
89 DPRINT("kvpi.Type = %lu\n", kvpi->Type);
90 DPRINT("kvpi.DataLength = %lu\n", kvpi->DataLength);
91
92 if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))
93 {
94 *DataType = kvpi->Type;
95 if((NULL != Environment) && (REG_EXPAND_SZ == *DataType))
96 {
97 UNICODE_STRING Source;
98 PWCHAR DestinationBuffer = NULL;
99 UNICODE_STRING Destination;
100 ULONG Length = 0;
101
102 DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);
103
104 DestinationBuffer = RtlAllocateHeap (RtlGetProcessHeap(),
105 0,
106 (2 * KeyValueInformationLength));
107 if (NULL == DestinationBuffer)
108 {
109 Status = STATUS_NO_MEMORY;
110 }
111 else
112 {
113 Source.Length = (USHORT)kvpi->DataLength;
114 Source.MaximumLength = (USHORT)kvpi->DataLength;
115 Source.Buffer = (PWCHAR) & kvpi->Data;
116
117 Destination.Length = 0;
118 Destination.MaximumLength = (USHORT)(2 * KeyValueInformationLength);
119 Destination.Buffer = DestinationBuffer;
120
121 Status = RtlExpandEnvironmentStrings_U (Environment,
122 & Source,
123 & Destination,
124 & Length);
125 if(NT_SUCCESS(Status))
126 {
127 *DataLength = min(*DataLength, Destination.Length);
128 RtlCopyMemory (Data, Destination.Buffer, *DataLength);
129 }
130 RtlFreeHeap (RtlGetProcessHeap(), 0, DestinationBuffer);
131 }
132 }else{
133 DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);
134 *DataLength = min(*DataLength, kvpi->DataLength);
135 RtlCopyMemory (Data, & kvpi->Data, *DataLength);
136 }
137 *DataType = kvpi->Type;
138 }else{
139 DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);
140 Status = STATUS_INVALID_PARAMETER;
141 }
142 }else{
143 DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
144 }
145 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyValueInformation);
146 NtClose (hKey);
147 }else{
148 DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
149 }
150 return Status;
151 }
152
153 /* EOF */