Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
1.6 KiB

  1. #ifndef __NmEnum_h__
  2. #define __NmEnum_h__
  3. // This is used to create IEnumXXX objects for CSimpleArray<CComPtr<XXX> > objects
  4. template <class TEnum, class TItf>
  5. HRESULT CreateEnumFromSimpleAryOfInterface(CSimpleArray<TItf*>& rObjArray, TEnum** ppEnum)
  6. {
  7. DBGENTRY(CreateEnum);
  8. HRESULT hr = S_OK;
  9. typedef CComEnum<TEnum, &__uuidof(TEnum), TItf*, _CopyInterface<TItf> > enum_type;
  10. enum_type* pComEnum = new CComObject< enum_type >;
  11. if(pComEnum)
  12. {
  13. TItf** apInterface = NULL;
  14. int nItems = rObjArray.GetSize();
  15. if(nItems)
  16. {
  17. apInterface = new TItf*[nItems];
  18. if(apInterface)
  19. {
  20. for(int i = 0; i < rObjArray.GetSize(); ++i)
  21. {
  22. hr = rObjArray[i]->QueryInterface(__uuidof(TItf), reinterpret_cast<void**>(&apInterface[i]));
  23. if(FAILED(hr))
  24. {
  25. delete [] apInterface;
  26. goto end;
  27. }
  28. }
  29. }
  30. else
  31. {
  32. hr = E_OUTOFMEMORY;
  33. }
  34. }
  35. TItf** begin = apInterface;
  36. TItf** end = apInterface + nItems;
  37. if(begin == end)
  38. {
  39. // Hack to get around ATL bug.
  40. // The problem is that for empty enums ATL returns E_FAIL for Next instead of S_FALSE
  41. hr = pComEnum->Init(reinterpret_cast<TItf**>(69), reinterpret_cast<TItf**>(69), NULL, AtlFlagNoCopy);
  42. }
  43. else
  44. {
  45. hr = pComEnum->Init(begin, end, NULL, AtlFlagTakeOwnership);
  46. }
  47. if(SUCCEEDED(hr))
  48. {
  49. hr = pComEnum->QueryInterface(__uuidof(TEnum), reinterpret_cast<void**>(ppEnum));
  50. }
  51. if(FAILED(hr))
  52. {
  53. delete [] apInterface;
  54. }
  55. }
  56. else
  57. {
  58. hr = E_NOINTERFACE;
  59. }
  60. end:
  61. DBGEXIT_HR(CreateEnum,hr);
  62. return hr;
  63. }
  64. #endif // __NmEnum_h__