enumXmlBuffer.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #include "main.h"
  2. #include "./enumXmlBuffer.h"
  3. #include "./service.h"
  4. #include "./ifc_omservicehost.h"
  5. #include "./ifc_omstorage.h"
  6. #include "./ifc_wasabihelper.h"
  7. #include "../xml/obj_xml.h"
  8. #include <shlwapi.h>
  9. #include <strsafe.h>
  10. #define XMLSIG "<?xml"
  11. #define XMLSIG_LEN 5
  12. ULONG ref;
  13. const void *buffer;
  14. size_t bufferSize;
  15. size_t cursor;
  16. obj_xml *reader;
  17. INT readerError;
  18. XmlResponseParser parser;
  19. Dispatchable *bufferOwner;
  20. EnumXmlBuffer::EnumXmlBuffer(obj_xml *xmlReader, const void *buffer, size_t bufferSize, Dispatchable *bufferOwner, ifc_omservicehost *serviceHost)
  21. : ref(1), buffer(buffer), bufferSize(bufferSize), cursor(0), reader(xmlReader), readerError(OBJ_XML_SUCCESS), bufferOwner(bufferOwner)
  22. {
  23. if (NULL != reader)
  24. reader->AddRef();
  25. if (NULL != bufferOwner)
  26. bufferOwner->AddRef();
  27. parser.Initialize(reader, serviceHost);
  28. }
  29. EnumXmlBuffer::~EnumXmlBuffer()
  30. {
  31. parser.Finish();
  32. if (NULL != reader)
  33. {
  34. if (OBJ_XML_SUCCESS == readerError)
  35. {
  36. reader->xmlreader_feed(0, 0);
  37. }
  38. reader->xmlreader_close();
  39. ifc_wasabihelper *wasabi;
  40. if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)))
  41. {
  42. wasabi->ReleaseWasabiInterface(&obj_xmlGUID, reader);
  43. wasabi->Release();
  44. }
  45. }
  46. if (NULL != bufferOwner)
  47. bufferOwner->Release();
  48. }
  49. HRESULT EnumXmlBuffer::CheckXmlHeader(const void *buffer, size_t bufferSize)
  50. {
  51. if (NULL == buffer)
  52. return E_INVALIDARG;
  53. if (bufferSize >= XMLSIG_LEN)
  54. {
  55. if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE, XMLSIG, XMLSIG_LEN, (LPSTR)buffer, XMLSIG_LEN) ||
  56. CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, WTEXT(XMLSIG), XMLSIG_LEN, (LPWSTR)buffer, XMLSIG_LEN))
  57. {
  58. return S_OK;
  59. }
  60. }
  61. return OMSTORAGE_E_UNKNOWN_FORMAT;
  62. }
  63. HRESULT EnumXmlBuffer::CreateInstance(const void *buffer, size_t bufferSize, Dispatchable *bufferOwner, ifc_omservicehost *host, EnumXmlBuffer **instance)
  64. {
  65. if (NULL == instance) return E_POINTER;
  66. *instance = NULL;
  67. HRESULT hr = CheckXmlHeader(buffer, bufferSize);
  68. if (SUCCEEDED(hr))
  69. {
  70. ifc_wasabihelper *wasabi;
  71. hr = Plugin_GetWasabiHelper(&wasabi);
  72. if (SUCCEEDED(hr))
  73. {
  74. obj_xml *reader;
  75. wasabi->QueryWasabiInterface(&obj_xmlGUID, (void**)&reader);
  76. if (NULL != reader && OBJ_XML_SUCCESS == reader->xmlreader_open())
  77. {
  78. *instance = new EnumXmlBuffer(reader, buffer, bufferSize, bufferOwner, host);
  79. if (NULL == *instance)
  80. {
  81. hr = E_OUTOFMEMORY;
  82. // reader stil has no support for AddRef()/Release()
  83. wasabi->ReleaseWasabiInterface(&obj_xmlGUID, reader);
  84. }
  85. reader->Release();
  86. }
  87. else
  88. {
  89. hr = E_UNEXPECTED;
  90. }
  91. wasabi->Release();
  92. }
  93. }
  94. return hr;
  95. }
  96. size_t EnumXmlBuffer::AddRef()
  97. {
  98. return InterlockedIncrement((LONG*)&ref);
  99. }
  100. size_t EnumXmlBuffer::Release()
  101. {
  102. if (0 == ref)
  103. return ref;
  104. LONG r = InterlockedDecrement((LONG*)&ref);
  105. if (0 == r)
  106. delete(this);
  107. return r;
  108. }
  109. int EnumXmlBuffer::QueryInterface(GUID interface_guid, void **object)
  110. {
  111. if (NULL == object) return E_POINTER;
  112. if (IsEqualIID(interface_guid, IFC_OmServiceEnum))
  113. *object = static_cast<ifc_omserviceenum*>(this);
  114. else if (IsEqualIID(interface_guid, IFC_OmXmlServiceEnum))
  115. *object = static_cast<ifc_omxmlserviceenum*>(this);
  116. else
  117. {
  118. *object = NULL;
  119. return E_NOINTERFACE;
  120. }
  121. if (NULL == *object)
  122. return E_UNEXPECTED;
  123. AddRef();
  124. return S_OK;
  125. }
  126. HRESULT EnumXmlBuffer::Next(ULONG listSize, ifc_omservice **elementList, ULONG *elementCount)
  127. {
  128. if(NULL != elementCount)
  129. *elementCount = 0;
  130. if (0 == listSize || NULL == elementList)
  131. return E_INVALIDARG;
  132. ULONG counter = 0;
  133. HRESULT hr = S_OK;
  134. ifc_omservice *service;
  135. while(counter < listSize)
  136. {
  137. hr = parser.PeekService(&service);
  138. if (FAILED(hr)) return hr;
  139. if (S_OK == hr)
  140. {
  141. elementList[counter] = service;
  142. counter++;
  143. }
  144. else
  145. {
  146. if (cursor < bufferSize)
  147. {
  148. readerError = reader->xmlreader_feed((BYTE*)buffer + cursor, bufferSize - cursor);
  149. if (OBJ_XML_SUCCESS != readerError) return E_FAIL;
  150. cursor = bufferSize;
  151. }
  152. else
  153. {
  154. if (OBJ_XML_SUCCESS == readerError)
  155. reader->xmlreader_feed(0, 0);
  156. break;
  157. }
  158. }
  159. }
  160. if(NULL != elementCount)
  161. *elementCount = counter;
  162. return (counter > 0) ? S_OK : S_FALSE;
  163. }
  164. HRESULT EnumXmlBuffer::Reset(void)
  165. {
  166. cursor = 0;
  167. readerError = OBJ_XML_SUCCESS;
  168. reader->xmlreader_reset();
  169. parser.Reset();
  170. return E_NOTIMPL;
  171. }
  172. HRESULT EnumXmlBuffer::Skip(ULONG elementCount)
  173. {
  174. return E_NOTIMPL;
  175. }
  176. HRESULT EnumXmlBuffer::GetStatusCode(UINT *code)
  177. {
  178. return parser.GetCode(code);
  179. }
  180. HRESULT EnumXmlBuffer::GetStatusText(LPWSTR pszBuffer, UINT cchBufferMax)
  181. {
  182. return parser.GetText(pszBuffer, cchBufferMax);
  183. }
  184. #define CBCLASS EnumXmlBuffer
  185. START_MULTIPATCH;
  186. START_PATCH(MPIID_OMSERVICEENUM)
  187. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, ADDREF, AddRef);
  188. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, RELEASE, Release);
  189. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, QUERYINTERFACE, QueryInterface);
  190. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_NEXT, Next);
  191. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_RESET, Reset);
  192. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_SKIP, Skip);
  193. NEXT_PATCH(MPIID_OMXMLSERVICEENUM)
  194. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, ADDREF, AddRef);
  195. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, RELEASE, Release);
  196. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, QUERYINTERFACE, QueryInterface);
  197. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, API_GETSTATUSCODE, GetStatusCode);
  198. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, API_GETSTATUSTEXT, GetStatusText);
  199. END_PATCH
  200. END_MULTIPATCH;
  201. #undef CBCLASS