Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmethods.c
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/ksfilter/ks/methods.c 00005 * PURPOSE: KS Allocator functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "priv.h" 00010 00011 NTSTATUS 00012 FindMethodHandler( 00013 IN PIO_STATUS_BLOCK IoStatus, 00014 IN const KSMETHOD_SET* MethodSet, 00015 IN ULONG MethodSetCount, 00016 IN PKSMETHOD Method, 00017 IN ULONG InputBufferLength, 00018 IN ULONG OutputBufferLength, 00019 OUT PVOID OutputBuffer, 00020 OUT PFNKSHANDLER *MethodHandler, 00021 OUT PKSMETHOD_SET * Set) 00022 { 00023 ULONG Index, ItemIndex; 00024 00025 for(Index = 0; Index < MethodSetCount; Index++) 00026 { 00027 ASSERT(MethodSet[Index].Set); 00028 00029 if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set)) 00030 { 00031 for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount; ItemIndex++) 00032 { 00033 if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id) 00034 { 00035 if (MethodSet[Index].MethodItem[ItemIndex].MinMethod > InputBufferLength) 00036 { 00037 /* too small input buffer */ 00038 IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinMethod; 00039 return STATUS_INVALID_PARAMETER; 00040 } 00041 00042 if (MethodSet[Index].MethodItem[ItemIndex].MinData > OutputBufferLength) 00043 { 00044 /* too small output buffer */ 00045 IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinData; 00046 return STATUS_MORE_ENTRIES; 00047 } 00048 if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT) 00049 { 00050 PULONG Flags; 00051 PKSPROPERTY_DESCRIPTION Description; 00052 00053 if (sizeof(ULONG) > OutputBufferLength) 00054 { 00055 /* too small buffer */ 00056 return STATUS_INVALID_PARAMETER; 00057 } 00058 00059 /* get output buffer */ 00060 Flags = (PULONG)OutputBuffer; 00061 00062 /* set flags flags */ 00063 *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags; 00064 00065 IoStatus->Information = sizeof(ULONG); 00066 00067 if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) 00068 { 00069 /* get output buffer */ 00070 Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer; 00071 00072 /* store result */ 00073 Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); 00074 Description->PropTypeSet.Set = KSPROPTYPESETID_General; 00075 Description->PropTypeSet.Id = 0; 00076 Description->PropTypeSet.Flags = 0; 00077 Description->MembersListCount = 0; 00078 Description->Reserved = 0; 00079 00080 IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION); 00081 } 00082 return STATUS_SUCCESS; 00083 } 00084 *MethodHandler = MethodSet[Index].MethodItem[ItemIndex].MethodHandler; 00085 *Set = (PKSMETHOD_SET)&MethodSet[Index]; 00086 return STATUS_SUCCESS; 00087 } 00088 } 00089 } 00090 } 00091 return STATUS_NOT_FOUND; 00092 } 00093 00094 NTSTATUS 00095 NTAPI 00096 KspMethodHandlerWithAllocator( 00097 IN PIRP Irp, 00098 IN ULONG MethodSetsCount, 00099 IN const KSMETHOD_SET *MethodSet, 00100 IN PFNKSALLOCATOR Allocator OPTIONAL, 00101 IN ULONG MethodItemSize OPTIONAL) 00102 { 00103 PKSMETHOD Method; 00104 PKSMETHOD_SET Set; 00105 PIO_STACK_LOCATION IoStack; 00106 NTSTATUS Status; 00107 PFNKSHANDLER MethodHandler = NULL; 00108 ULONG Index; 00109 LPGUID Guid; 00110 00111 /* get current irp stack */ 00112 IoStack = IoGetCurrentIrpStackLocation(Irp); 00113 00114 /* check if inputbuffer at least holds KSMETHOD item */ 00115 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD)) 00116 { 00117 /* invalid parameter */ 00118 Irp->IoStatus.Information = sizeof(KSPROPERTY); 00119 return STATUS_INVALID_BUFFER_SIZE; 00120 } 00121 00122 /* FIXME probe the input / output buffer if from user mode */ 00123 00124 /* get input property request */ 00125 Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00126 00127 // DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); 00128 00129 /* sanity check */ 00130 ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM)); 00131 00132 /* find the method handler */ 00133 Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &MethodHandler, &Set); 00134 00135 if (NT_SUCCESS(Status) && MethodHandler) 00136 { 00137 /* call method handler */ 00138 KSMETHOD_SET_IRP_STORAGE(Irp) = Set; 00139 Status = MethodHandler(Irp, Method, Irp->UserBuffer); 00140 00141 if (Status == STATUS_BUFFER_TOO_SMALL) 00142 { 00143 /* output buffer is too small */ 00144 if (Allocator) 00145 { 00146 /* allocate the requested amount */ 00147 Status = Allocator(Irp, Irp->IoStatus.Information, FALSE); 00148 00149 /* check if the block was allocated */ 00150 if (!NT_SUCCESS(Status)) 00151 { 00152 /* no memory */ 00153 return STATUS_INSUFFICIENT_RESOURCES; 00154 } 00155 00156 /* re-call method handler */ 00157 Status = MethodHandler(Irp, Method, Irp->UserBuffer); 00158 } 00159 } 00160 } 00161 else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) && Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT) 00162 { 00163 // store output size 00164 Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount; 00165 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * MethodSetsCount) 00166 { 00167 // buffer too small 00168 return STATUS_MORE_ENTRIES; 00169 } 00170 00171 // get output buffer 00172 Guid = (LPGUID)Irp->UserBuffer; 00173 00174 // copy property guids from property sets 00175 for(Index = 0; Index < MethodSetsCount; Index++) 00176 { 00177 RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID)); 00178 } 00179 return STATUS_SUCCESS; 00180 } 00181 00182 /* done */ 00183 return Status; 00184 } 00185 00186 /* 00187 @implemented 00188 */ 00189 KSDDKAPI 00190 NTSTATUS 00191 NTAPI 00192 KsMethodHandler( 00193 IN PIRP Irp, 00194 IN ULONG MethodSetsCount, 00195 IN PKSMETHOD_SET MethodSet) 00196 { 00197 return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, NULL, 0); 00198 } 00199 00200 /* 00201 @implemented 00202 */ 00203 KSDDKAPI 00204 NTSTATUS 00205 NTAPI 00206 KsMethodHandlerWithAllocator( 00207 IN PIRP Irp, 00208 IN ULONG MethodSetsCount, 00209 IN PKSMETHOD_SET MethodSet, 00210 IN PFNKSALLOCATOR Allocator OPTIONAL, 00211 IN ULONG MethodItemSize OPTIONAL) 00212 { 00213 return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, Allocator, MethodItemSize); 00214 } 00215 00216 00217 NTSTATUS 00218 FindFastMethodHandler( 00219 IN ULONG FastIoCount, 00220 IN const KSFASTMETHOD_ITEM * FastIoTable, 00221 IN PKSMETHOD MethodId, 00222 OUT PFNKSFASTHANDLER * FastPropertyHandler) 00223 { 00224 ULONG Index; 00225 00226 /* iterate through all items */ 00227 for(Index = 0; Index < FastIoCount; Index++) 00228 { 00229 if (MethodId->Id == FastIoTable[Index].MethodId) 00230 { 00231 if (FastIoTable[Index].MethodSupported) 00232 { 00233 *FastPropertyHandler = FastIoTable[Index].MethodHandler; 00234 return STATUS_SUCCESS; 00235 } 00236 } 00237 00238 } 00239 /* no fast property handler found */ 00240 return STATUS_NOT_FOUND; 00241 } 00242 00243 00244 /* 00245 @implemented 00246 */ 00247 KSDDKAPI 00248 BOOLEAN 00249 NTAPI 00250 KsFastMethodHandler( 00251 IN PFILE_OBJECT FileObject, 00252 IN PKSMETHOD UNALIGNED Method, 00253 IN ULONG MethodLength, 00254 IN OUT PVOID UNALIGNED Data, 00255 IN ULONG DataLength, 00256 OUT PIO_STATUS_BLOCK IoStatus, 00257 IN ULONG MethodSetsCount, 00258 IN const KSMETHOD_SET* MethodSet) 00259 { 00260 KSMETHOD MethodRequest; 00261 KPROCESSOR_MODE Mode; 00262 NTSTATUS Status = STATUS_SUCCESS; 00263 ULONG Index; 00264 PFNKSFASTHANDLER FastMethodHandler; 00265 00266 if (MethodLength < sizeof(KSPROPERTY)) 00267 { 00268 /* invalid request */ 00269 return FALSE; 00270 } 00271 00272 /* get previous mode */ 00273 Mode = ExGetPreviousMode(); 00274 00275 if (Mode == KernelMode) 00276 { 00277 /* just copy it */ 00278 RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); 00279 } 00280 else 00281 { 00282 /* need to probe the buffer */ 00283 _SEH2_TRY 00284 { 00285 ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR)); 00286 RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); 00287 } 00288 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00289 { 00290 /* Exception, get the error code */ 00291 Status = _SEH2_GetExceptionCode(); 00292 }_SEH2_END; 00293 00294 if (!NT_SUCCESS(Status)) 00295 return FALSE; 00296 } 00297 00298 /* are there any property sets provided */ 00299 if (MethodSetsCount) 00300 { 00301 /* iterate through all property sets count */ 00302 Index = 0; 00303 do 00304 { 00305 /* does the property id match */ 00306 if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set)) 00307 { 00308 /* try to find a fast property handler */ 00309 Status = FindFastMethodHandler(MethodSet[Index].FastIoCount, MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler); 00310 00311 if (NT_SUCCESS(Status)) 00312 { 00313 /* call fast property handler */ 00314 ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property length is bigger -> copy params */ 00315 ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output buffer */ 00316 return FastMethodHandler(FileObject, &MethodRequest, sizeof(KSMETHOD), Data, DataLength, IoStatus); 00317 } 00318 } 00319 /* move to next item */ 00320 Index++; 00321 }while(Index < MethodSetsCount); 00322 } 00323 return FALSE; 00324 } Generated on Sun May 27 2012 04:27:53 for ReactOS by
1.7.6.1
|