Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregistry.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/backpln/portcls/registry.cpp 00005 * PURPOSE: Registry access object 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 class CRegistryKey : public IRegistryKey 00012 { 00013 public: 00014 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 00015 00016 STDMETHODIMP_(ULONG) AddRef() 00017 { 00018 InterlockedIncrement(&m_Ref); 00019 return m_Ref; 00020 } 00021 STDMETHODIMP_(ULONG) Release() 00022 { 00023 InterlockedDecrement(&m_Ref); 00024 00025 if (!m_Ref) 00026 { 00027 delete this; 00028 return 0; 00029 } 00030 return m_Ref; 00031 } 00032 00033 IMP_IRegistryKey; 00034 CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey, BOOL CanDelete) : m_hKey(hKey), m_Deleted(FALSE), m_CanDelete(CanDelete), m_Ref(0){} 00035 virtual ~CRegistryKey(); 00036 00037 protected: 00038 00039 HANDLE m_hKey; 00040 BOOL m_Deleted; 00041 BOOL m_CanDelete; 00042 LONG m_Ref; 00043 }; 00044 00045 CRegistryKey::~CRegistryKey() 00046 { 00047 if (!m_Deleted) 00048 { 00049 // close key only when has not been deleted yet 00050 ZwClose(m_hKey); 00051 } 00052 } 00053 00054 00055 NTSTATUS 00056 NTAPI 00057 CRegistryKey::QueryInterface( 00058 IN REFIID refiid, 00059 OUT PVOID* Output) 00060 { 00061 UNICODE_STRING GuidString; 00062 00063 DPRINT("CRegistryKey::QueryInterface entered\n"); 00064 if (IsEqualGUIDAligned(refiid, IID_IRegistryKey) || 00065 IsEqualGUIDAligned(refiid, IID_IUnknown)) 00066 { 00067 *Output = PVOID(PREGISTRYKEY(this)); 00068 PUNKNOWN(*Output)->AddRef(); 00069 return STATUS_SUCCESS; 00070 } 00071 00072 if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) 00073 { 00074 DPRINT1("CRegistryKey::QueryInterface no interface!!! iface %S\n", GuidString.Buffer); 00075 RtlFreeUnicodeString(&GuidString); 00076 } 00077 00078 return STATUS_UNSUCCESSFUL; 00079 } 00080 00081 NTSTATUS 00082 NTAPI 00083 CRegistryKey::DeleteKey() 00084 { 00085 NTSTATUS Status; 00086 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00087 00088 if (m_Deleted) 00089 { 00090 // key already deleted 00091 return STATUS_INVALID_HANDLE; 00092 } 00093 00094 if (!m_CanDelete) 00095 { 00096 // only general keys can be deleted 00097 return STATUS_ACCESS_DENIED; 00098 } 00099 00100 // delete key 00101 Status = ZwDeleteKey(m_hKey); 00102 if (NT_SUCCESS(Status)) 00103 { 00104 m_Deleted = TRUE; 00105 m_hKey = NULL; 00106 } 00107 return Status; 00108 } 00109 00110 NTSTATUS 00111 NTAPI 00112 CRegistryKey::EnumerateKey( 00113 IN ULONG Index, 00114 IN KEY_INFORMATION_CLASS KeyInformationClass, 00115 OUT PVOID KeyInformation, 00116 IN ULONG Length, 00117 OUT PULONG ResultLength) 00118 { 00119 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00120 00121 if (m_Deleted) 00122 { 00123 return STATUS_INVALID_HANDLE; 00124 } 00125 00126 return ZwEnumerateKey(m_hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength); 00127 } 00128 00129 NTSTATUS 00130 NTAPI 00131 CRegistryKey::EnumerateValueKey( 00132 IN ULONG Index, 00133 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, 00134 OUT PVOID KeyValueInformation, 00135 IN ULONG Length, 00136 OUT PULONG ResultLength) 00137 { 00138 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00139 00140 if (m_Deleted) 00141 { 00142 return STATUS_INVALID_HANDLE; 00143 } 00144 00145 return ZwEnumerateValueKey(m_hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); 00146 } 00147 00148 NTSTATUS 00149 NTAPI 00150 CRegistryKey::NewSubKey( 00151 OUT PREGISTRYKEY *RegistrySubKey, 00152 IN PUNKNOWN OuterUnknown, 00153 IN ACCESS_MASK DesiredAccess, 00154 IN PUNICODE_STRING SubKeyName, 00155 IN ULONG CreateOptions, 00156 OUT PULONG Disposition OPTIONAL) 00157 { 00158 OBJECT_ATTRIBUTES Attributes; 00159 NTSTATUS Status; 00160 HANDLE hKey; 00161 CRegistryKey * RegistryKey; 00162 00163 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00164 00165 DPRINT("CRegistryKey::NewSubKey entered %S\n", SubKeyName->Buffer); 00166 00167 if (m_Deleted) 00168 { 00169 return STATUS_INVALID_HANDLE; 00170 } 00171 00172 InitializeObjectAttributes(&Attributes, SubKeyName, OBJ_INHERIT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_KERNEL_HANDLE, m_hKey, NULL); 00173 Status = ZwCreateKey(&hKey, DesiredAccess, &Attributes, 0, NULL, CreateOptions, Disposition); 00174 if (!NT_SUCCESS(Status)) 00175 { 00176 DPRINT("CRegistryKey::NewSubKey failed with %x\n", Status); 00177 return Status; 00178 } 00179 00180 RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hKey, TRUE); 00181 if (!RegistryKey) 00182 return STATUS_INSUFFICIENT_RESOURCES; 00183 00184 Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)RegistrySubKey); 00185 00186 if (!NT_SUCCESS(Status)) 00187 { 00188 delete RegistryKey; 00189 return Status; 00190 } 00191 00192 DPRINT("CRegistryKey::NewSubKey RESULT %p\n", *RegistrySubKey); 00193 return STATUS_SUCCESS; 00194 } 00195 00196 NTSTATUS 00197 NTAPI 00198 CRegistryKey::QueryKey( 00199 IN KEY_INFORMATION_CLASS KeyInformationClass, 00200 OUT PVOID KeyInformation, 00201 IN ULONG Length, 00202 OUT PULONG ResultLength) 00203 { 00204 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00205 00206 if (m_Deleted) 00207 { 00208 return STATUS_INVALID_HANDLE; 00209 } 00210 00211 return ZwQueryKey(m_hKey, KeyInformationClass, KeyInformation, Length, ResultLength); 00212 } 00213 00214 NTSTATUS 00215 NTAPI 00216 CRegistryKey::QueryRegistryValues( 00217 IN PRTL_QUERY_REGISTRY_TABLE QueryTable, 00218 IN PVOID Context OPTIONAL) 00219 { 00220 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00221 00222 if (m_Deleted) 00223 { 00224 return STATUS_INVALID_HANDLE; 00225 } 00226 00227 return RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, (PCWSTR)m_hKey, QueryTable, Context, NULL); 00228 } 00229 00230 NTSTATUS 00231 NTAPI 00232 CRegistryKey::QueryValueKey( 00233 IN PUNICODE_STRING ValueName, 00234 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, 00235 OUT PVOID KeyValueInformation, 00236 IN ULONG Length, 00237 OUT PULONG ResultLength) 00238 { 00239 NTSTATUS Status; 00240 00241 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00242 00243 if (m_Deleted) 00244 { 00245 return STATUS_INVALID_HANDLE; 00246 } 00247 00248 Status = ZwQueryValueKey(m_hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); 00249 DPRINT("CRegistryKey::QueryValueKey entered %p value %wZ Status %x\n", this, ValueName, Status); 00250 return Status; 00251 } 00252 00253 NTSTATUS 00254 NTAPI 00255 CRegistryKey::SetValueKey( 00256 IN PUNICODE_STRING ValueName OPTIONAL, 00257 IN ULONG Type, 00258 IN PVOID Data, 00259 IN ULONG DataSize 00260 ) 00261 { 00262 DPRINT("CRegistryKey::SetValueKey entered %S\n", ValueName->Buffer); 00263 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00264 00265 if (m_Deleted) 00266 { 00267 return STATUS_INVALID_HANDLE; 00268 } 00269 00270 return ZwSetValueKey(m_hKey, ValueName, 0, Type, Data, DataSize); 00271 } 00272 00273 NTSTATUS 00274 NTAPI 00275 PcNewRegistryKey( 00276 OUT PREGISTRYKEY* OutRegistryKey, 00277 IN PUNKNOWN OuterUnknown OPTIONAL, 00278 IN ULONG RegistryKeyType, 00279 IN ACCESS_MASK DesiredAccess, 00280 IN PVOID DeviceObject OPTIONAL, 00281 IN PVOID SubDevice OPTIONAL, 00282 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00283 IN ULONG CreateOptions OPTIONAL, 00284 OUT PULONG Disposition OPTIONAL) 00285 { 00286 HANDLE hHandle; 00287 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00288 CRegistryKey * RegistryKey; 00289 PPCLASS_DEVICE_EXTENSION DeviceExt; 00290 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; 00291 ISubdevice * Device; 00292 PSYMBOLICLINK_ENTRY SymEntry; 00293 BOOL CanDelete = FALSE; 00294 00295 DPRINT("PcNewRegistryKey entered\n"); 00296 00297 if (!OutRegistryKey) 00298 return STATUS_INVALID_PARAMETER; 00299 00300 if (RegistryKeyType != GeneralRegistryKey && 00301 RegistryKeyType != DeviceRegistryKey && 00302 RegistryKeyType != DriverRegistryKey && 00303 RegistryKeyType != HwProfileRegistryKey && 00304 RegistryKeyType != DeviceInterfaceRegistryKey) 00305 { 00306 return STATUS_INVALID_PARAMETER; 00307 } 00308 00309 // check for the key type 00310 if (RegistryKeyType == GeneralRegistryKey) 00311 { 00312 // do we have the required object attributes 00313 if (!ObjectAttributes) 00314 { 00315 // object attributes is mandatory 00316 return STATUS_INVALID_PARAMETER; 00317 } 00318 // try to create the key 00319 Status = ZwCreateKey(&hHandle, DesiredAccess, ObjectAttributes, 0, NULL, CreateOptions, Disposition); 00320 00321 // key can be deleted 00322 CanDelete = TRUE; 00323 } 00324 else if (RegistryKeyType == DeviceRegistryKey || 00325 RegistryKeyType == DriverRegistryKey || 00326 RegistryKeyType == HwProfileRegistryKey) 00327 { 00328 // check for HwProfileRegistryKey case 00329 if (RegistryKeyType == HwProfileRegistryKey) 00330 { 00331 // IoOpenDeviceRegistryKey used different constant 00332 RegistryKeyType = PLUGPLAY_REGKEY_CURRENT_HWPROFILE | PLUGPLAY_REGKEY_DEVICE; 00333 } 00334 00335 // obtain the new device extension 00336 DeviceExt = (PPCLASS_DEVICE_EXTENSION) ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; 00337 00338 Status = IoOpenDeviceRegistryKey(DeviceExt->PhysicalDeviceObject, RegistryKeyType, DesiredAccess, &hHandle); 00339 } 00340 else if (RegistryKeyType == DeviceInterfaceRegistryKey) 00341 { 00342 if (SubDevice == NULL) 00343 { 00344 // invalid parameter 00345 return STATUS_INVALID_PARAMETER; 00346 } 00347 00348 // look up our undocumented interface 00349 Status = ((PUNKNOWN)SubDevice)->QueryInterface(IID_ISubdevice, (LPVOID*)&Device); 00350 00351 if (!NT_SUCCESS(Status)) 00352 { 00353 DPRINT("No ISubdevice interface\n"); 00354 // invalid parameter 00355 return STATUS_INVALID_PARAMETER; 00356 } 00357 00358 // get the subdevice descriptor 00359 Status = Device->GetDescriptor(&SubDeviceDescriptor); 00360 if (!NT_SUCCESS(Status)) 00361 { 00362 DPRINT("Failed to get subdevice descriptor %x\n", Status); 00363 ((PUNKNOWN)SubDevice)->Release(); 00364 return STATUS_UNSUCCESSFUL; 00365 } 00366 00367 // is there an registered device interface 00368 if (IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList)) 00369 { 00370 DPRINT("No device interface registered\n"); 00371 ((PUNKNOWN)SubDevice)->Release(); 00372 return STATUS_UNSUCCESSFUL; 00373 } 00374 00375 // get the first symbolic link 00376 SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(SubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry); 00377 00378 // open device interface 00379 Status = IoOpenDeviceInterfaceRegistryKey(&SymEntry->SymbolicLink, DesiredAccess, &hHandle); 00380 00381 // release subdevice interface 00382 ((PUNKNOWN)SubDevice)->Release(); 00383 } 00384 00385 // check for success 00386 if (!NT_SUCCESS(Status)) 00387 { 00388 DPRINT1("PcNewRegistryKey failed with %lx\n", Status); 00389 return Status; 00390 } 00391 00392 // allocate new registry key object 00393 RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hHandle, CanDelete); 00394 if (!RegistryKey) 00395 { 00396 // not enough memory 00397 ZwClose(hHandle); 00398 return STATUS_INSUFFICIENT_RESOURCES; 00399 } 00400 00401 // query for interface 00402 Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)OutRegistryKey); 00403 00404 if (!NT_SUCCESS(Status)) 00405 { 00406 // out of memory 00407 delete RegistryKey; 00408 } 00409 00410 DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey); 00411 return STATUS_SUCCESS; 00412 } Generated on Sat May 26 2012 04:27:11 for ReactOS by
1.7.6.1
|