2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/smlib/lookupss.c
12 /**********************************************************************
17 * Read from the registry key
18 * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
19 * the value which name is Name.
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.
32 SmLookupSubsystem (IN PWSTR Name
,
34 IN OUT PULONG DataLength
,
35 IN OUT PULONG DataType
,
36 IN PVOID Environment OPTIONAL
)
38 NTSTATUS Status
= STATUS_SUCCESS
;
39 UNICODE_STRING usKeyName
= { 0, 0, NULL
};
40 OBJECT_ATTRIBUTES Oa
= {0};
41 HANDLE hKey
= (HANDLE
) 0;
43 DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__
, Name
);
45 * Prepare the key name to scan and
46 * related object attributes.
48 RtlInitUnicodeString (& usKeyName
,
49 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
51 InitializeObjectAttributes (& Oa
,
57 * Open the key. This MUST NOT fail, if the
58 * request is for a legitimate subsystem.
60 Status
= NtOpenKey (& hKey
,
63 if(NT_SUCCESS(Status
))
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
;
71 KeyValueInformation
= RtlAllocateHeap (RtlGetProcessHeap(),
73 KeyValueInformationLength
);
74 if (NULL
== KeyValueInformation
)
76 return STATUS_NO_MEMORY
;
78 kvpi
= (PKEY_VALUE_PARTIAL_INFORMATION
) KeyValueInformation
;
79 RtlInitUnicodeString (& usValueName
, Name
);
80 Status
= NtQueryValueKey (hKey
,
82 KeyValuePartialInformation
,
84 KeyValueInformationLength
,
86 if(NT_SUCCESS(Status
))
88 DPRINT("nkvpi.TitleIndex = %lu\n", kvpi
->TitleIndex
);
89 DPRINT("kvpi.Type = %lu\n", kvpi
->Type
);
90 DPRINT("kvpi.DataLength = %lu\n", kvpi
->DataLength
);
92 if((NULL
!= Data
) && (NULL
!= DataLength
) && (NULL
!= DataType
))
94 *DataType
= kvpi
->Type
;
95 if((NULL
!= Environment
) && (REG_EXPAND_SZ
== *DataType
))
97 UNICODE_STRING Source
;
98 PWCHAR DestinationBuffer
= NULL
;
99 UNICODE_STRING Destination
;
102 DPRINT("SM: %s: value will be expanded\n", __FUNCTION__
);
104 DestinationBuffer
= RtlAllocateHeap (RtlGetProcessHeap(),
106 (2 * KeyValueInformationLength
));
107 if (NULL
== DestinationBuffer
)
109 Status
= STATUS_NO_MEMORY
;
113 Source
.Length
= (USHORT
)kvpi
->DataLength
;
114 Source
.MaximumLength
= (USHORT
)kvpi
->DataLength
;
115 Source
.Buffer
= (PWCHAR
) & kvpi
->Data
;
117 Destination
.Length
= 0;
118 Destination
.MaximumLength
= (USHORT
)(2 * KeyValueInformationLength
);
119 Destination
.Buffer
= DestinationBuffer
;
121 Status
= RtlExpandEnvironmentStrings_U (Environment
,
125 if(NT_SUCCESS(Status
))
127 *DataLength
= min(*DataLength
, Destination
.Length
);
128 RtlCopyMemory (Data
, Destination
.Buffer
, *DataLength
);
130 RtlFreeHeap (RtlGetProcessHeap(), 0, DestinationBuffer
);
133 DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__
);
134 *DataLength
= min(*DataLength
, kvpi
->DataLength
);
135 RtlCopyMemory (Data
, & kvpi
->Data
, *DataLength
);
137 *DataType
= kvpi
->Type
;
139 DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__
);
140 Status
= STATUS_INVALID_PARAMETER
;
143 DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__
, Status
);
145 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyValueInformation
);
148 DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__
, Status
);