Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenresource.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS 00004 * FILE: drivers/wdm/audio/backpln/portcls/resource.cpp 00005 * PURPOSE: Port Class driver / ResourceList implementation 00006 * PROGRAMMER: Andrew Greenwood 00007 * Johannes Anderwald 00008 * HISTORY: 00009 * 27 Jan 07 Created 00010 */ 00011 00012 #include "private.hpp" 00013 00014 class CResourceList : public IResourceList 00015 { 00016 public: 00017 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 00018 00019 STDMETHODIMP_(ULONG) AddRef() 00020 { 00021 InterlockedIncrement(&m_Ref); 00022 return m_Ref; 00023 } 00024 STDMETHODIMP_(ULONG) Release() 00025 { 00026 InterlockedDecrement(&m_Ref); 00027 00028 if (!m_Ref) 00029 { 00030 delete this; 00031 return 0; 00032 } 00033 return m_Ref; 00034 } 00035 00036 IMP_IResourceList; 00037 00038 CResourceList(IUnknown * OuterUnknown) : m_OuterUnknown(OuterUnknown), m_PoolType(NonPagedPool), m_TranslatedResourceList(0), m_UntranslatedResourceList(0), m_NumberOfEntries(0), m_MaxEntries(0), m_Ref(0) {} 00039 virtual ~CResourceList(); 00040 00041 public: 00042 PUNKNOWN m_OuterUnknown; 00043 POOL_TYPE m_PoolType; 00044 PCM_RESOURCE_LIST m_TranslatedResourceList; 00045 PCM_RESOURCE_LIST m_UntranslatedResourceList; 00046 ULONG m_NumberOfEntries; 00047 ULONG m_MaxEntries; 00048 LONG m_Ref; 00049 }; 00050 00051 CResourceList::~CResourceList() 00052 { 00053 if (m_TranslatedResourceList) 00054 { 00055 /* Free resource list */ 00056 FreeItem(m_TranslatedResourceList, TAG_PORTCLASS); 00057 } 00058 00059 if (m_UntranslatedResourceList) 00060 { 00061 /* Free resource list */ 00062 FreeItem(m_UntranslatedResourceList, TAG_PORTCLASS); 00063 } 00064 } 00065 00066 NTSTATUS 00067 NTAPI 00068 CResourceList::QueryInterface( 00069 IN REFIID refiid, 00070 OUT PVOID* Output) 00071 { 00072 UNICODE_STRING GuidString; 00073 00074 if (IsEqualGUIDAligned(refiid, IID_IResourceList) || 00075 IsEqualGUIDAligned(refiid, IID_IUnknown)) 00076 { 00077 *Output = PVOID(PRESOURCELIST(this)); 00078 PUNKNOWN(*Output)->AddRef(); 00079 return STATUS_SUCCESS; 00080 } 00081 00082 if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) 00083 { 00084 DPRINT1("IResourceList_QueryInterface no interface!!! iface %S\n", GuidString.Buffer); 00085 RtlFreeUnicodeString(&GuidString); 00086 } 00087 00088 return STATUS_UNSUCCESSFUL; 00089 } 00090 00091 ULONG 00092 NTAPI 00093 CResourceList::NumberOfEntries() 00094 { 00095 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00096 00097 return m_NumberOfEntries; 00098 } 00099 00100 ULONG 00101 NTAPI 00102 CResourceList::NumberOfEntriesOfType( 00103 IN CM_RESOURCE_TYPE Type) 00104 { 00105 ULONG Index, Count = 0; 00106 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; 00107 00108 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00109 00110 /* Is there a resource list? */ 00111 if (!m_UntranslatedResourceList) 00112 { 00113 /* No resource list provided */ 00114 return 0; 00115 } 00116 00117 for (Index = 0; Index < m_NumberOfEntries; Index ++ ) 00118 { 00119 00120 /* Get descriptor */ 00121 PartialDescriptor = &m_UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[Index]; 00122 if (PartialDescriptor->Type == Type) 00123 { 00124 /* Yay! Finally found one that matches! */ 00125 Count++; 00126 } 00127 } 00128 00129 DPRINT("Found %d type %d\n", Count, Type); 00130 return Count; 00131 } 00132 00133 PCM_PARTIAL_RESOURCE_DESCRIPTOR 00134 NTAPI 00135 CResourceList::FindTranslatedEntry( 00136 IN CM_RESOURCE_TYPE Type, 00137 IN ULONG Index) 00138 { 00139 ULONG DescIndex, Count = 0; 00140 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; 00141 00142 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00143 00144 /* Is there a resource list? */ 00145 if (!m_TranslatedResourceList) 00146 { 00147 /* No resource list */ 00148 return NULL; 00149 } 00150 00151 for (DescIndex = 0; DescIndex < m_NumberOfEntries; DescIndex ++ ) 00152 { 00153 /* Get descriptor */ 00154 PartialDescriptor = &m_TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; 00155 00156 if (PartialDescriptor->Type == Type) 00157 { 00158 /* Found type, is it the requested index? */ 00159 if (Index == Count) 00160 { 00161 /* Found */ 00162 return PartialDescriptor; 00163 } 00164 00165 /* Need to continue search */ 00166 Count++; 00167 } 00168 } 00169 00170 /* No such descriptor */ 00171 return NULL; 00172 } 00173 00174 PCM_PARTIAL_RESOURCE_DESCRIPTOR 00175 NTAPI 00176 CResourceList::FindUntranslatedEntry( 00177 IN CM_RESOURCE_TYPE Type, 00178 IN ULONG Index) 00179 { 00180 ULONG DescIndex, Count = 0; 00181 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; 00182 00183 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00184 00185 /* Is there a resource list? */ 00186 if (!m_UntranslatedResourceList) 00187 { 00188 /* Empty resource list */ 00189 return NULL; 00190 } 00191 00192 /* Search descriptors */ 00193 for (DescIndex = 0; DescIndex < m_NumberOfEntries; DescIndex ++ ) 00194 { 00195 /* Get descriptor */ 00196 PartialDescriptor = &m_UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; 00197 00198 if (PartialDescriptor->Type == Type) 00199 { 00200 /* Found type, is it the requested index? */ 00201 if (Index == Count) 00202 { 00203 /* Found */ 00204 return PartialDescriptor; 00205 } 00206 00207 /* Need to continue search */ 00208 Count++; 00209 } 00210 } 00211 00212 /* No such descriptor */ 00213 return NULL; 00214 } 00215 00216 NTSTATUS 00217 NTAPI 00218 CResourceList::AddEntry( 00219 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, 00220 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Untranslated) 00221 { 00222 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; 00223 00224 /* Sanity check */ 00225 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00226 00227 00228 /* Is there still room for another entry */ 00229 if (m_NumberOfEntries >= m_MaxEntries) 00230 { 00231 /* No more space */ 00232 return STATUS_INSUFFICIENT_RESOURCES; 00233 } 00234 00235 /* Get free descriptor */ 00236 PartialDescriptor = &m_UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[m_NumberOfEntries]; 00237 00238 /* Copy descriptor */ 00239 RtlCopyMemory(PartialDescriptor, Untranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); 00240 00241 /* Get free descriptor */ 00242 PartialDescriptor = &m_TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[m_NumberOfEntries]; 00243 00244 /* Copy descriptor */ 00245 RtlCopyMemory(PartialDescriptor, Translated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); 00246 00247 /* Add entry count */ 00248 m_NumberOfEntries++; 00249 m_UntranslatedResourceList->List[0].PartialResourceList.Count++; 00250 m_TranslatedResourceList->List[0].PartialResourceList.Count++; 00251 00252 /* Done */ 00253 return STATUS_SUCCESS; 00254 } 00255 00256 NTSTATUS 00257 NTAPI 00258 CResourceList::AddEntryFromParent( 00259 IN IResourceList* Parent, 00260 IN CM_RESOURCE_TYPE Type, 00261 IN ULONG Index) 00262 { 00263 PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, Untranslated; 00264 00265 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00266 00267 /* Get entries from parent */ 00268 Translated = Parent->FindTranslatedEntry(Type, Index); 00269 Untranslated = Parent->FindUntranslatedEntry(Type, Index); 00270 00271 /* Are both found? */ 00272 if (Translated && Untranslated) 00273 { 00274 /* Add entry from parent */ 00275 return AddEntry(Translated, Untranslated); 00276 } 00277 00278 /* Entry not found */ 00279 return STATUS_INVALID_PARAMETER; 00280 } 00281 00282 PCM_RESOURCE_LIST 00283 NTAPI 00284 CResourceList::TranslatedList() 00285 { 00286 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00287 00288 return m_TranslatedResourceList; 00289 } 00290 00291 PCM_RESOURCE_LIST 00292 NTAPI 00293 CResourceList::UntranslatedList() 00294 { 00295 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00296 00297 return m_UntranslatedResourceList; 00298 } 00299 00300 00301 PORTCLASSAPI 00302 NTSTATUS 00303 NTAPI 00304 PcNewResourceList( 00305 OUT PRESOURCELIST* OutResourceList, 00306 IN PUNKNOWN OuterUnknown OPTIONAL, 00307 IN POOL_TYPE PoolType, 00308 IN PCM_RESOURCE_LIST TranslatedResourceList, 00309 IN PCM_RESOURCE_LIST UntranslatedResourceList) 00310 { 00311 PCM_RESOURCE_LIST NewUntranslatedResources, NewTranslatedResources; 00312 ULONG ResourceSize, ResourceCount; 00313 CResourceList* NewList; 00314 NTSTATUS Status; 00315 00316 if (!TranslatedResourceList) 00317 { 00318 /* If the untranslated resource list is also not provided, it becomes an empty resource list */ 00319 if (UntranslatedResourceList) 00320 { 00321 /* Invalid parameter mix */ 00322 return STATUS_INVALID_PARAMETER; 00323 } 00324 } 00325 else 00326 { 00327 /* If the translated resource list is also not provided, it becomes an empty resource list */ 00328 if (!UntranslatedResourceList) 00329 { 00330 /* Invalid parameter mix */ 00331 return STATUS_INVALID_PARAMETER; 00332 } 00333 } 00334 00335 /* Allocate resource list */ 00336 NewList = new(PoolType, TAG_PORTCLASS)CResourceList(OuterUnknown); 00337 if (!NewList) 00338 return STATUS_INSUFFICIENT_RESOURCES; 00339 00340 /* Query resource list */ 00341 Status = NewList->QueryInterface(IID_IResourceList, (PVOID*)OutResourceList); 00342 if (!NT_SUCCESS(Status)) 00343 { 00344 /* Ouch, FIX ME */ 00345 delete NewList; 00346 return STATUS_INVALID_PARAMETER; 00347 } 00348 00349 /* Is there a resource list */ 00350 if (!TranslatedResourceList) 00351 { 00352 /* Empty resource list */ 00353 return STATUS_SUCCESS; 00354 } 00355 00356 /* Sanity check */ 00357 ASSERT(UntranslatedResourceList->List[0].PartialResourceList.Count == TranslatedResourceList->List[0].PartialResourceList.Count); 00358 00359 /* Get resource count */ 00360 ResourceCount = UntranslatedResourceList->List[0].PartialResourceList.Count; 00361 #ifdef _MSC_VER 00362 ResourceSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); 00363 #else 00364 ResourceSize = sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + (ResourceCount) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); 00365 #endif 00366 00367 /* Allocate translated resource list */ 00368 NewTranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(PoolType, ResourceSize, TAG_PORTCLASS); 00369 if (!NewTranslatedResources) 00370 { 00371 /* No memory */ 00372 delete NewList; 00373 return STATUS_INSUFFICIENT_RESOURCES; 00374 } 00375 00376 /* Allocate untranslated resource list */ 00377 NewUntranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(PoolType, ResourceSize, TAG_PORTCLASS); 00378 if (!NewUntranslatedResources) 00379 { 00380 /* No memory */ 00381 delete NewList; 00382 FreeItem(NewTranslatedResources, TAG_PORTCLASS); 00383 return STATUS_INSUFFICIENT_RESOURCES; 00384 } 00385 00386 /* Copy resource lists */ 00387 RtlCopyMemory(NewTranslatedResources, TranslatedResourceList, ResourceSize); 00388 RtlCopyMemory(NewUntranslatedResources, UntranslatedResourceList, ResourceSize); 00389 00390 /* Init resource list */ 00391 NewList->m_TranslatedResourceList= NewTranslatedResources; 00392 NewList->m_UntranslatedResourceList = NewUntranslatedResources; 00393 NewList->m_NumberOfEntries = ResourceCount; 00394 NewList->m_MaxEntries = ResourceCount; 00395 NewList->m_PoolType = PoolType; 00396 00397 /* Done */ 00398 return STATUS_SUCCESS; 00399 } 00400 00401 PORTCLASSAPI 00402 NTSTATUS 00403 NTAPI 00404 PcNewResourceSublist( 00405 OUT PRESOURCELIST* OutResourceList, 00406 IN PUNKNOWN OuterUnknown OPTIONAL, 00407 IN POOL_TYPE PoolType, 00408 IN PRESOURCELIST ParentList, 00409 IN ULONG MaximumEntries) 00410 { 00411 CResourceList* NewList; 00412 ULONG ResourceSize; 00413 00414 if (!OutResourceList || !ParentList || !MaximumEntries) 00415 return STATUS_INVALID_PARAMETER; 00416 00417 /* Allocate new list */ 00418 NewList = new(PoolType, TAG_PORTCLASS) CResourceList(OuterUnknown); 00419 if (!NewList) 00420 return STATUS_INSUFFICIENT_RESOURCES; 00421 00422 /* Get resource size */ 00423 #ifdef _MSC_VER 00424 ResourceSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[MaximumEntries]); 00425 #else 00426 ResourceSize = sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + (MaximumEntries) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); 00427 #endif 00428 00429 /* Allocate resource list */ 00430 NewList->m_TranslatedResourceList = (PCM_RESOURCE_LIST)AllocateItem(PoolType, ResourceSize, TAG_PORTCLASS); 00431 if (!NewList->m_TranslatedResourceList) 00432 { 00433 /* No memory */ 00434 delete NewList; 00435 return STATUS_INSUFFICIENT_RESOURCES; 00436 } 00437 00438 /* Allocate resource list */ 00439 NewList->m_UntranslatedResourceList = (PCM_RESOURCE_LIST)AllocateItem(PoolType, ResourceSize, TAG_PORTCLASS); 00440 if (!NewList->m_UntranslatedResourceList) 00441 { 00442 /* No memory */ 00443 delete NewList; 00444 return STATUS_INSUFFICIENT_RESOURCES; 00445 } 00446 00447 /* Copy resource lists */ 00448 RtlCopyMemory(NewList->m_TranslatedResourceList, ParentList->TranslatedList(), sizeof(CM_RESOURCE_LIST)); 00449 RtlCopyMemory(NewList->m_UntranslatedResourceList, ParentList->UntranslatedList(), sizeof(CM_RESOURCE_LIST)); 00450 00451 /* Resource list is empty */ 00452 NewList->m_UntranslatedResourceList->List[0].PartialResourceList.Count = 0; 00453 NewList->m_TranslatedResourceList->List[0].PartialResourceList.Count = 0; 00454 00455 /* Store members */ 00456 NewList->m_OuterUnknown = OuterUnknown; 00457 NewList->m_PoolType = PoolType; 00458 NewList->m_Ref = 1; 00459 NewList->m_NumberOfEntries = 0; 00460 NewList->m_MaxEntries = MaximumEntries; 00461 00462 /* Store result */ 00463 *OutResourceList = (IResourceList*)NewList; 00464 00465 /* Done */ 00466 return STATUS_SUCCESS; 00467 } Generated on Sat May 26 2012 04:27:12 for ReactOS by
1.7.6.1
|