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

nt4/PortEnum.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 <initguid.h>
00021 #include <ntddk.h>
00022 
00023 #define PENUMERATE_DEFINED 
00024 typedef struct ENUMERATE_NT4 *PENUMERATE;
00025 #include "cbm_driver.h"
00026 
00027 #undef ExFreePool
00028 
00033 typedef
00034 struct ENUMERATE_NT4
00035 {
00037     UNICODE_STRING DriverPrefix;
00038 
00040     UNICODE_STRING DriverNumber;
00041 
00043     UNICODE_STRING CompleteDriverName;
00044 
00046     ULONG Count;
00047 
00049     ULONG MaxCount;
00050 
00051 } ENUMERATE, *PENUMERATE;
00052 
00053 
00074 NTSTATUS
00075 ParPortEnumerateOpen(PENUMERATE *EnumStruct)
00076 {
00077     PENUMERATE enumStruct;
00078     NTSTATUS ntStatus;
00079 
00080     FUNC_ENTER();
00081 
00082     // Allocate memory for the enumStruct
00083 
00084     DBG_IRQL( < DISPATCH_LEVEL);
00085     enumStruct = ExAllocatePoolWithTag(PagedPool, 
00086         sizeof(ENUMERATE), MTAG_SENUMERATE);
00087 
00088     if (enumStruct)
00089     {
00090         // Zero the complete enumStruct
00091 
00092         RtlZeroMemory(enumStruct, sizeof(*enumStruct));
00093 
00094         enumStruct->Count = 0;
00095 
00096         // Get the maximum number of parallel port devices
00097 
00098         DBG_IRQL( == PASSIVE_LEVEL);
00099         enumStruct->MaxCount = IoGetConfigurationInformation()->ParallelCount;
00100 
00101         // If the maximum number is bigger than 999, we have a severe problem...
00102         // Who would put more than 999 parallel ports into one machine?
00103         // Anyway, make sure we have no problems with this.
00104 
00105         if (enumStruct->MaxCount > 999)
00106         {
00107             DBG_WARN((DBG_PREFIX "IoGetConfigurationInformation()->ParallelCount "
00108                 "returned %u, truncating to 999", enumStruct->MaxCount));
00109 
00110             enumStruct->MaxCount = 999;
00111         }
00112 
00113         // prepare the strings for later usage
00114 
00115         DBG_IRQL( <= DISPATCH_LEVEL);
00116         RtlInitUnicodeString(&enumStruct->DriverPrefix, L"\\Device\\" DD_PARALLEL_PORT_BASE_NAME_U);
00117 
00118         // Allocate memory for storing the number
00119         // Assume the number is < 999, that is, not more than 3 digits big
00120         // If it is bigger, make the numbers 3 and 4 greater
00121         // The length has to be set here because the allocation for 
00122         // enumStruct->CompleteDriverName below depends upon the length!
00123 
00124         enumStruct->DriverNumber.Length = 3*sizeof(wchar_t);
00125         enumStruct->DriverNumber.MaximumLength = 4*sizeof(wchar_t);
00126         enumStruct->DriverNumber.Buffer = ExAllocatePoolWithTag(PagedPool,
00127             enumStruct->DriverNumber.MaximumLength, MTAG_SENUMERATE);
00128 
00129         // allocate memory for the complete name
00130 
00131         enumStruct->CompleteDriverName.Length = 0;
00132         enumStruct->CompleteDriverName.MaximumLength = 
00133             enumStruct->DriverPrefix.Length + enumStruct->DriverNumber.Length;
00134 
00135         enumStruct->CompleteDriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
00136             enumStruct->CompleteDriverName.MaximumLength, MTAG_SENUMERATE);
00137 
00138         // Test if both above allocations were successfull:
00139 
00140         if (enumStruct->DriverNumber.Buffer != NULL 
00141             && enumStruct->CompleteDriverName.Buffer != NULL)
00142         {
00143             ntStatus = STATUS_SUCCESS;
00144         }
00145         else
00146         {
00147             // We have not had luck with allocating both strings,
00148             // thus, return an appropriate error value
00149 
00150             ntStatus = STATUS_INSUFFICIENT_RESOURCES;
00151 
00152             // Free all resources that have been successfully allocated
00153 
00154             ParPortEnumerateClose(enumStruct);
00155 
00156             // return that there was no enumStruct allocated
00157 
00158             enumStruct = NULL;
00159         }
00160     }
00161     else
00162     {
00163         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
00164     }
00165 
00166     // return the enumStruct to the caller
00167 
00168     *EnumStruct = enumStruct;
00169 
00170     FUNC_LEAVE_NTSTATUS(ntStatus);
00171 }
00172 
00196 NTSTATUS
00197 ParPortEnumerate(PENUMERATE EnumStruct, PCWSTR *DriverName)
00198 {
00199     NTSTATUS ntStatus;
00200     PCWSTR retDriver;
00201 
00202     FUNC_ENTER();
00203 
00204     DBG_ASSERT(EnumStruct != NULL);
00205     DBG_ASSERT(EnumStruct->Count < 1000);
00206 
00207     retDriver = NULL;
00208 
00209     // Assume: There are no more entries available
00210 
00211     ntStatus = STATUS_NO_MORE_ENTRIES;
00212 
00213     if (EnumStruct->Count < EnumStruct->MaxCount)
00214     {
00215         // Counvert EnumStruct->Count to a UNICODE_STRING
00216 
00217         DBG_IRQL( == PASSIVE_LEVEL);
00218         ntStatus = RtlIntegerToUnicodeString(EnumStruct->Count, 10, 
00219             &EnumStruct->DriverNumber);
00220 
00221         if (NT_SUCCESS(ntStatus)) 
00222         {
00223             // Copy the parts to form the full name:
00224 
00225             DBG_IRQL( < DISPATCH_LEVEL);
00226             RtlCopyUnicodeString(&EnumStruct->CompleteDriverName, &EnumStruct->DriverPrefix);
00227             RtlAppendUnicodeStringToString(&EnumStruct->CompleteDriverName, &EnumStruct->DriverNumber);
00228 
00229             retDriver = EnumStruct->CompleteDriverName.Buffer;
00230 
00231             // advance to the next driver
00232 
00233             ++EnumStruct->Count;
00234         }
00235     }
00236     else
00237     {
00238         // we are after the last entry: return empty string
00239 
00240         EnumStruct->CompleteDriverName.Buffer[0] = 0;
00241         retDriver = EnumStruct->CompleteDriverName.Buffer;
00242     }
00243 
00244     *DriverName = retDriver;
00245 
00246     FUNC_LEAVE_NTSTATUS(ntStatus);
00247 }
00248 
00264 VOID
00265 ParPortEnumerateClose(PENUMERATE EnumStruct)
00266 {
00267     FUNC_ENTER();
00268 
00269     DBG_ASSERT(EnumStruct != NULL);
00270 
00271     DBG_IRQL( == PASSIVE_LEVEL);
00272 
00273     // Free the DriverNumber buffer, if that was allocated
00274 
00275     if (EnumStruct->DriverNumber.Buffer != NULL)
00276     {
00277         DBG_IRQL( < DISPATCH_LEVEL);
00278         ExFreePool(EnumStruct->DriverNumber.Buffer);
00279     }
00280 
00281     // Free the CompleteDriverName buffer, if that was allocated
00282 
00283     if (EnumStruct->CompleteDriverName.Buffer != NULL)
00284     {
00285         DBG_IRQL( < DISPATCH_LEVEL);
00286         ExFreePool(EnumStruct->CompleteDriverName.Buffer);
00287     }
00288 
00289     // Free the EnumStruct
00290 
00291     DBG_IRQL( < DISPATCH_LEVEL);
00292     ExFreePool(EnumStruct);
00293 
00294     FUNC_LEAVE();
00295 }
00296 
00303 NTSTATUS 
00304 CbmOpenDeviceRegistryKey(IN PDEVICE_OBJECT a, IN ULONG b, IN ACCESS_MASK c, OUT PHANDLE d)
00305 {
00306     FUNC_ENTER();
00307 
00308     DBG_ASSERT(1==0);
00309 
00310     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00311 }

Generated on Sun Apr 30 18:45:57 2006 for opencbm by  doxygen 1.4.2