Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

util-reg.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or
00003  *  modify it under the terms of the GNU General Public License
00004  *  as published by the Free Software Foundation; either version
00005  *  2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 2004 Spiro Trikaliotis
00008  *
00009  */
00010 
00020 #include <wdm.h>
00021 #include "cbm_driver.h"
00022 
00043 NTSTATUS
00044 cbm_registry_open_for_read(OUT PHANDLE HandleKey, IN PUNICODE_STRING Path)
00045 {
00046     OBJECT_ATTRIBUTES objectAttributes;
00047 
00048     NTSTATUS ntStatus;
00049 
00050     FUNC_ENTER();
00051 
00052     FUNC_PARAM((DBG_PREFIX "'%wZ'", Path));
00053 
00054     // Initialize the object attributes for the registry key
00055 
00056     DBG_IRQL( == PASSIVE_LEVEL); //+< according to NT4 DDK; later ones do not have this restriction!
00057     InitializeObjectAttributes(&objectAttributes,
00058         Path, OBJ_CASE_INSENSITIVE , NULL, NULL);
00059 
00060     // Now, open the registry key
00061 
00062     DBG_IRQL( == PASSIVE_LEVEL);
00063     ntStatus = ZwOpenKey(HandleKey, KEY_READ, &objectAttributes);
00064 
00065     FUNC_LEAVE_NTSTATUS(ntStatus);
00066 }
00067 
00095 NTSTATUS
00096 cbm_registry_open_hardwarekey(OUT PHANDLE HandleKey, OUT PDEVICE_OBJECT *Pdo,
00097                               IN PDEVICE_EXTENSION Pdx)
00098 {
00099     IO_STATUS_BLOCK ioStatusBlock;
00100     NTSTATUS ntStatus;
00101     KEVENT event;
00102     PIRP irp;
00103 
00104     FUNC_ENTER();
00105 
00106     // Initialize the event which might be needed for waiting for completion
00107 
00108     // no IRQL restrictions apply
00109     KeInitializeEvent(&event, NotificationEvent, FALSE);
00110 
00111     // first of all, build an IRP with IRP_MJ_PNP/IRP_MN_QUERY_DEVICE_RELATIONS
00112 
00113     DBG_IRQL( == PASSIVE_LEVEL);
00114     irp = IoBuildSynchronousFsdRequest(
00115         IRP_MJ_PNP,
00116         Pdx->ParallelPortFdo,
00117         NULL,
00118         0,
00119         NULL,
00120         &event,
00121         &ioStatusBlock);
00122 
00123     if (!irp)
00124     {
00125         // Acquiring the IRP failed, report this back to the caller
00126 
00127         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
00128     }
00129     else
00130     {
00131         PIO_STACK_LOCATION irpSp;
00132 
00133         // set up some values for the called driver
00134 
00135         // We need to write the first IRP stack location, thus, get
00136         // it. On a new IRP, this means we want to write the "next"
00137         // stack location.
00138 
00139         DBG_IRQL( <= DISPATCH_LEVEL);
00140         irpSp = IoGetNextIrpStackLocation(irp);
00141 
00142         if (irpSp)
00143         {
00144             // Find the PDO of the parallel port driver
00145 
00146             irpSp->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
00147             irpSp->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
00148             irpSp->FileObject = Pdx->ParallelPortFileObject;
00149 
00150             // call the driver to get the handle for the hardware registry key
00151 
00152             DBG_IRQL( <= DISPATCH_LEVEL);
00153             ntStatus = IoCallDriver(Pdx->ParallelPortFdo, irp);
00154         }
00155         else
00156         {
00157             // Well... We could allocate an IRP, but we could not
00158             // get the appropriate stack location? Can this ever happen?
00159             // I doubt it, but to be sure, mark it as an error
00160 
00161             ntStatus = STATUS_INSUFFICIENT_RESOURCES;
00162         }
00163 
00164         // If the called driver pended this IRP, wait for the completion
00165 
00166         if (ntStatus == STATUS_PENDING)
00167         {
00168             DBG_IRQL( < DISPATCH_LEVEL);
00169             KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
00170         }
00171 
00172         if (NT_SUCCESS(ntStatus))
00173         {
00174             PDEVICE_RELATIONS deviceRelations;
00175             PDEVICE_OBJECT pdo;
00176 
00177             // use deviceRelations for better readability
00178 
00179             deviceRelations = (PDEVICE_RELATIONS) ioStatusBlock.Information;
00180             DBG_ASSERT(deviceRelations);
00181 
00182             if (deviceRelations)
00183             {
00184                 // take the pdo out of the return value
00185 
00186                 pdo = deviceRelations->Objects[0];
00187 
00188                 // get a registry handle for the hardware key of the parallel port
00189 
00190                 DBG_IRQL( == PASSIVE_LEVEL);
00191                 ntStatus = CbmOpenDeviceRegistryKey(
00192                     pdo,
00193                     PLUGPLAY_REGKEY_DEVICE,
00194                     KEY_ALL_ACCESS,
00195                     HandleKey);
00196 
00197                 // give the pdo back to the caller, so that it can be dereferenced when it
00198                 // is not longer needed
00199 
00200                 *Pdo = pdo;
00201 
00202                 // free the memory which is no longer needed
00203 
00204                 DBG_IRQL( < DISPATCH_LEVEL);
00205                 ExFreePool(deviceRelations);
00206             }
00207         }
00208     }
00209 
00210 
00211     FUNC_LEAVE_NTSTATUS(ntStatus);
00212 }
00213 
00230 NTSTATUS
00231 cbm_registry_close(IN HANDLE HandleKey)
00232 {
00233     NTSTATUS ntStatus;
00234 
00235     FUNC_ENTER();
00236 
00237     // Close the registry key
00238 
00239     DBG_IRQL( == PASSIVE_LEVEL);
00240     ntStatus = ZwClose(HandleKey);
00241 
00242     FUNC_LEAVE_NTSTATUS(ntStatus);
00243 }
00244 
00260 NTSTATUS
00261 cbm_registry_close_hardwarekey(IN HANDLE HandleKey, IN PDEVICE_OBJECT Pdo)
00262 {
00263     NTSTATUS ntStatus;
00264 
00265     FUNC_ENTER();
00266 
00267     // First of all, close the registry key
00268 
00269     ntStatus = cbm_registry_close(HandleKey);
00270 
00271     // Dereference the pdo, as we do not need it anymore.
00272 
00273     DBG_IRQL( <= DISPATCH_LEVEL);
00274     ObDereferenceObject(Pdo);
00275 
00276     FUNC_LEAVE_NTSTATUS(ntStatus);
00277 }
00278 
00299 NTSTATUS
00300 cbm_registry_read_ulong(IN HANDLE HandleKey, IN PCWSTR KeyName, OUT PULONG Value)
00301 {
00302     PKEY_VALUE_PARTIAL_INFORMATION p;
00303     UNICODE_STRING keyNameUnicode;
00304     NTSTATUS ntStatus;
00305     ULONG retValueSize;
00306     CHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)];
00307 
00308     FUNC_ENTER();
00309 
00310     FUNC_PARAM((DBG_PREFIX "'%ws'", KeyName));
00311 
00312     p = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
00313 
00314     RtlInitUnicodeString(&keyNameUnicode, KeyName);
00315 
00316     ntStatus = ZwQueryValueKey(HandleKey, &keyNameUnicode, 
00317         KeyValuePartialInformation, 
00318         buffer, sizeof(buffer), &retValueSize);
00319 
00320     if (NT_SUCCESS(ntStatus))
00321     {
00322         if (p->Type == REG_DWORD && p->DataLength == sizeof(ULONG))
00323         {
00324             ULONG retValue = *((PULONG) &p->Data);
00325 
00326             FUNC_PARAM((DBG_PREFIX "Return-Value: %08x", retValue));
00327 
00328             if (Value)
00329             {
00330                 *Value = retValue;
00331             }
00332         }
00333     }
00334 
00335     FUNC_LEAVE_NTSTATUS(ntStatus);
00336 }
00337 
00356 NTSTATUS
00357 cbm_registry_write_ulong(IN HANDLE HandleKey, IN PCWSTR KeyName, IN ULONG Value)
00358 {
00359     PKEY_VALUE_PARTIAL_INFORMATION p;
00360     UNICODE_STRING keyNameUnicode;
00361     NTSTATUS ntStatus;
00362     ULONG retValueSize;
00363     CHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)];
00364 
00365     FUNC_ENTER();
00366 
00367     FUNC_PARAM((DBG_PREFIX "'%ws'", KeyName));
00368 
00369     p = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
00370 
00371     RtlInitUnicodeString(&keyNameUnicode, KeyName);
00372 
00373     ntStatus = ZwSetValueKey(HandleKey, &keyNameUnicode,
00374         0, REG_DWORD, &Value, sizeof(Value));
00375 
00376     FUNC_LEAVE_NTSTATUS(ntStatus);
00377 }

Generated on Sun Apr 30 18:46:00 2006 for opencbm by  doxygen 1.4.2