2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/smlib/lookupss.c
11 /**********************************************************************
16 * Read from the registry key
17 * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
18 * the value which name is Name.
21 * Name: name of the program to run, that is a value's name in
22 * the SM registry key SubSystems;
23 * Data: what the registry gave back for Name;
24 * DataLength: how much Data the registry returns;
25 * DataType: what is Data?
26 * Environment: set it if you want this function to use it
27 * to possibly expand Data before giving it back; if set
28 * to NULL, no expansion will be performed.
31 SmLookupSubsystem (IN PWSTR Name
,
33 IN OUT PULONG DataLength
,
34 IN OUT PULONG DataType
,
35 IN PVOID Environment OPTIONAL
)
37 NTSTATUS Status
= STATUS_SUCCESS
;
38 UNICODE_STRING usKeyName
= { 0, 0, NULL
};
39 OBJECT_ATTRIBUTES Oa
= {0};
40 HANDLE hKey
= (HANDLE
) 0;
42 DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__
, Name
);
44 * Prepare the key name to scan and
45 * related object attributes.
47 RtlInitUnicodeString (& usKeyName
,
48 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
50 InitializeObjectAttributes (& Oa
,
56 * Open the key. This MUST NOT fail, if the
57 * request is for a legitimate subsystem.
59 Status
= NtOpenKey (& hKey
,
62 if(NT_SUCCESS(Status
))
64 UNICODE_STRING usValueName
= { 0, 0, NULL
};
65 PWCHAR KeyValueInformation
= NULL
;
66 ULONG KeyValueInformationLength
= 1024;
67 ULONG ResultLength
= 0L;
68 PKEY_VALUE_PARTIAL_INFORMATION kvpi
= NULL
;
70 KeyValueInformation
= RtlAllocateHeap (RtlGetProcessHeap(),
72 KeyValueInformationLength
);
73 if (NULL
== KeyValueInformation
)
75 return STATUS_NO_MEMORY
;
77 kvpi
= (PKEY_VALUE_PARTIAL_INFORMATION
) KeyValueInformation
;
78 RtlInitUnicodeString (& usValueName
, Name
);
79 Status
= NtQueryValueKey (hKey
,
81 KeyValuePartialInformation
,
83 KeyValueInformationLength
,
85 if(NT_SUCCESS(Status
))
87 DPRINT("nkvpi.TitleIndex = %ld\n", kvpi
->TitleIndex
);
88 DPRINT("kvpi.Type = %ld\n", kvpi
->Type
);
89 DPRINT("kvpi.DataLength = %ld\n", kvpi
->DataLength
);
91 if((NULL
!= Data
) && (NULL
!= DataLength
) && (NULL
!= DataType
))
93 *DataType
= kvpi
->Type
;
94 if((NULL
!= Environment
) && (REG_EXPAND_SZ
== *DataType
))
96 UNICODE_STRING Source
;
97 PWCHAR DestinationBuffer
= NULL
;
98 UNICODE_STRING Destination
;
101 DPRINT("SM: %s: value will be expanded\n", __FUNCTION__
);
103 DestinationBuffer
= RtlAllocateHeap (RtlGetProcessHeap(),
105 (2 * KeyValueInformationLength
));
106 if (NULL
== DestinationBuffer
)
108 Status
= STATUS_NO_MEMORY
;
112 Source
.Length
= kvpi
->DataLength
;
113 Source
.MaximumLength
= kvpi
->DataLength
;
114 Source
.Buffer
= (PWCHAR
) & kvpi
->Data
;
116 Destination
.Length
= 0;
117 Destination
.MaximumLength
= (2 * KeyValueInformationLength
);
118 Destination
.Buffer
= DestinationBuffer
;
120 Status
= RtlExpandEnvironmentStrings_U (Environment
,
124 if(NT_SUCCESS(Status
))
126 *DataLength
= min(*DataLength
, Destination
.Length
);
127 RtlCopyMemory (Data
, Destination
.Buffer
, *DataLength
);
129 RtlFreeHeap (RtlGetProcessHeap(), 0, DestinationBuffer
);
132 DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__
);
133 *DataLength
= min(*DataLength
, kvpi
->DataLength
);
134 RtlCopyMemory (Data
, & kvpi
->Data
, *DataLength
);
136 *DataType
= kvpi
->Type
;
138 DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__
);
139 Status
= STATUS_INVALID_PARAMETER
;
142 DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__
, Status
);
144 RtlFreeHeap (RtlGetProcessHeap(), 0, KeyValueInformation
);
147 DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__
, Status
);