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

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

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