1
0

deviceObjectEnum.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "main.h"
  2. #include "./deviceObjectEnum.h"
  3. #include <new>
  4. DeviceObjectEnum::DeviceObjectEnum()
  5. : ref(1), buffer(NULL), size(0), cursor(0)
  6. {
  7. }
  8. DeviceObjectEnum::~DeviceObjectEnum()
  9. {
  10. if (NULL != buffer)
  11. {
  12. while(size--)
  13. {
  14. buffer[size]->Release();
  15. }
  16. }
  17. }
  18. HRESULT DeviceObjectEnum::CreateInstance(ifc_deviceobject **objects,
  19. size_t count,
  20. DeviceObjectEnum **instance)
  21. {
  22. size_t index, size;
  23. void *storage;
  24. ifc_deviceobject *o;
  25. DeviceObjectEnum *enumerator;
  26. if (NULL == instance)
  27. return E_POINTER;
  28. *instance = NULL;
  29. size = sizeof(DeviceObjectEnum) + (sizeof(ifc_deviceobject**) * count);
  30. storage = calloc(1, size);
  31. if (NULL == storage)
  32. return E_OUTOFMEMORY;
  33. enumerator = new(storage) DeviceObjectEnum();
  34. if (NULL == enumerator)
  35. {
  36. free(storage);
  37. return E_FAIL;
  38. }
  39. enumerator->buffer = (ifc_deviceobject**)(((BYTE*)enumerator) + sizeof(DeviceObjectEnum));
  40. for (index = 0; index < count; index++)
  41. {
  42. o = objects[index];
  43. if (NULL != o)
  44. {
  45. enumerator->buffer[enumerator->size] = o;
  46. o->AddRef();
  47. enumerator->size++;
  48. }
  49. }
  50. *instance = enumerator;
  51. return S_OK;
  52. }
  53. size_t DeviceObjectEnum::AddRef()
  54. {
  55. return InterlockedIncrement((LONG*)&ref);
  56. }
  57. size_t DeviceObjectEnum::Release()
  58. {
  59. if (0 == ref)
  60. return ref;
  61. LONG r = InterlockedDecrement((LONG*)&ref);
  62. if (0 == r)
  63. delete(this);
  64. return r;
  65. }
  66. int DeviceObjectEnum::QueryInterface(GUID interface_guid, void **object)
  67. {
  68. if (NULL == object) return E_POINTER;
  69. if (IsEqualIID(interface_guid, IFC_DeviceObjectEnum))
  70. *object = static_cast<ifc_deviceobjectenum*>(this);
  71. else
  72. {
  73. *object = NULL;
  74. return E_NOINTERFACE;
  75. }
  76. if (NULL == *object)
  77. return E_UNEXPECTED;
  78. AddRef();
  79. return S_OK;
  80. }
  81. HRESULT DeviceObjectEnum::Next(ifc_deviceobject **objects, size_t bufferMax, size_t *fetched)
  82. {
  83. size_t available, copied, index;
  84. ifc_deviceobject **source;
  85. if (NULL == objects)
  86. return E_POINTER;
  87. if (0 == bufferMax)
  88. return E_INVALIDARG;
  89. if (cursor >= size)
  90. {
  91. if (NULL != fetched)
  92. *fetched = 0;
  93. return S_FALSE;
  94. }
  95. available = size - cursor;
  96. copied = ((available > bufferMax) ? bufferMax : available);
  97. source = buffer + cursor;
  98. CopyMemory(objects, source, copied * sizeof(ifc_deviceobject*));
  99. for(index = 0; index < copied; index++)
  100. objects[index]->AddRef();
  101. cursor += copied;
  102. if (NULL != fetched)
  103. *fetched = copied;
  104. return (bufferMax == copied) ? S_OK : S_FALSE;
  105. }
  106. HRESULT DeviceObjectEnum::Reset(void)
  107. {
  108. cursor = 0;
  109. return S_OK;
  110. }
  111. HRESULT DeviceObjectEnum::Skip(size_t count)
  112. {
  113. cursor += count;
  114. if (cursor > size)
  115. cursor = size;
  116. return (cursor < size) ? S_OK : S_FALSE;
  117. }
  118. HRESULT DeviceObjectEnum::GetCount(size_t *count)
  119. {
  120. if (NULL == count)
  121. return E_POINTER;
  122. *count = size;
  123. return S_OK;
  124. }
  125. #define CBCLASS DeviceObjectEnum
  126. START_DISPATCH;
  127. CB(ADDREF, AddRef)
  128. CB(RELEASE, Release)
  129. CB(QUERYINTERFACE, QueryInterface)
  130. CB(API_NEXT, Next)
  131. CB(API_RESET, Reset)
  132. CB(API_SKIP, Skip)
  133. CB(API_GETCOUNT, GetCount)
  134. END_DISPATCH;
  135. #undef CBCLASS