xref: /reactos/drivers/filters/fltmgr/Registry.c (revision 8a978a17)
1 /*
2  * PROJECT:         Filesystem Filter Manager
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            drivers/filters/fltmgr/Misc.c
5  * PURPOSE:         Uncataloged functions
6  * PROGRAMMERS:     Ged Murphy (gedmurphy@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "fltmgr.h"
12 #include "fltmgrint.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 
18 /* DATA *********************************************************************/
19 
20 #define REG_SERVICES_KEY    L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
21 #define REG_PATH_LENGTH     512
22 
23 
24 /* INTERNAL FUNCTIONS ******************************************************/
25 
26 
27 NTSTATUS
28 FltpOpenFilterServicesKey(
29     _In_ PFLT_FILTER Filter,
30     _In_ ACCESS_MASK DesiredAccess,
31     _In_opt_ PUNICODE_STRING SubKey,
32     _Out_ PHANDLE Handle)
33 {
34     OBJECT_ATTRIBUTES ObjectAttributes;
35     UNICODE_STRING ServicesKey;
36     UNICODE_STRING Path;
37     WCHAR Buffer[REG_PATH_LENGTH];
38 
39     /* Setup a local buffer to hold the services key path */
40     Path.Length = 0;
41     Path.MaximumLength = REG_PATH_LENGTH;
42     Path.Buffer = Buffer;
43 
44     /* Build up the serices key name */
45     RtlInitUnicodeString(&ServicesKey, REG_SERVICES_KEY);
46     RtlCopyUnicodeString(&Path, &ServicesKey);
47     RtlAppendUnicodeStringToString(&Path, &Filter->Name);
48 
49     if (SubKey)
50     {
51         /* Tag on any child key */
52         RtlAppendUnicodeToString(&Path, L"\\");
53         RtlAppendUnicodeStringToString(&Path, SubKey);
54     }
55 
56     InitializeObjectAttributes(&ObjectAttributes,
57                                &Path,
58                                OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
59                                NULL,
60                                NULL);
61 
62     /* Open and return the key handle param*/
63     return ZwOpenKey(Handle, DesiredAccess, &ObjectAttributes);
64 }
65 
66 NTSTATUS
67 FltpReadRegistryValue(_In_ HANDLE KeyHandle,
68                       _In_ PUNICODE_STRING ValueName,
69                       _In_opt_ ULONG Type,
70                       _Out_writes_bytes_(BufferSize) PVOID Buffer,
71                       _In_ ULONG BufferSize,
72                       _Out_opt_ PULONG BytesRequired)
73 {
74     PKEY_VALUE_PARTIAL_INFORMATION Value = NULL;
75     ULONG ValueLength = 0;
76     NTSTATUS Status;
77 
78     PAGED_CODE();
79 
80     /* Get the size of the buffer required to hold the string */
81     Status = ZwQueryValueKey(KeyHandle,
82                              ValueName,
83                              KeyValuePartialInformation,
84                              NULL,
85                              0,
86                              &ValueLength);
87     if (Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW)
88     {
89         return Status;
90     }
91 
92     /* Allocate the buffer */
93     Value = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool,
94                                                                   ValueLength,
95                                                                   FM_TAG_TEMP_REGISTRY);
96     if (Value == NULL)
97     {
98         Status = STATUS_INSUFFICIENT_RESOURCES;
99         goto Quit;
100     }
101 
102     /* Now read in the value */
103     Status = ZwQueryValueKey(KeyHandle,
104                              ValueName,
105                              KeyValuePartialInformation,
106                              Value,
107                              ValueLength,
108                              &ValueLength);
109     if (!NT_SUCCESS(Status))
110     {
111         goto Quit;
112     }
113 
114     /* Make sure we got the type expected */
115     if (Value->Type != Type)
116     {
117         Status = STATUS_INVALID_PARAMETER;
118         goto Quit;
119     }
120 
121     if (BytesRequired)
122     {
123         *BytesRequired = Value->DataLength;
124     }
125 
126     /* Make sure the caller buffer is big enough to hold the data */
127     if (!BufferSize || BufferSize < Value->DataLength)
128     {
129         Status = STATUS_BUFFER_TOO_SMALL;
130         goto Quit;
131     }
132 
133     /* Copy the data into the caller buffer */
134     RtlCopyMemory(Buffer, Value->Data, Value->DataLength);
135 
136 Quit:
137 
138     if (Value)
139         ExFreePoolWithTag(Value, FM_TAG_TEMP_REGISTRY);
140 
141     return Status;
142 }
143