ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

registry.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.