enumXmlFile.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include "main.h"
  2. #include "./enumXmlFile.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. EnumXmlFile::EnumXmlFile(HANDLE xmlHandle, obj_xml *xmlReader, LPCWSTR pszAddress, ifc_omservicehost *serviceHost)
  13. : ref(1), address(NULL), hFile(xmlHandle), reader(xmlReader), readerError(OBJ_XML_SUCCESS),
  14. buffer(NULL), bufferMax(4096)
  15. {
  16. address = Plugin_CopyString(pszAddress);
  17. if (NULL != reader)
  18. reader->AddRef();
  19. parser.Initialize(reader, serviceHost);
  20. }
  21. EnumXmlFile::~EnumXmlFile()
  22. {
  23. Plugin_FreeString(address);
  24. if (NULL != hFile)
  25. CloseHandle(hFile);
  26. parser.Finish();
  27. if (NULL != reader)
  28. {
  29. if (OBJ_XML_SUCCESS == readerError)
  30. {
  31. reader->xmlreader_feed(0, 0);
  32. }
  33. reader->xmlreader_close();
  34. ifc_wasabihelper *wasabi;
  35. if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)))
  36. {
  37. wasabi->ReleaseWasabiInterface(&obj_xmlGUID, reader);
  38. wasabi->Release();
  39. }
  40. }
  41. if (NULL != buffer)
  42. free(buffer);
  43. }
  44. HRESULT EnumXmlFile::CheckXmlHeader(HANDLE hFile)
  45. {
  46. DWORD read = 0;
  47. BYTE szBuffer[XMLSIG_LEN * 2] = {0};
  48. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  49. if (FALSE == ReadFile(hFile, (void*)szBuffer, sizeof(szBuffer), &read, NULL))
  50. {
  51. DWORD error = GetLastError();
  52. return HRESULT_FROM_WIN32(error);
  53. }
  54. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  55. if (read >= XMLSIG_LEN)
  56. {
  57. if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE, XMLSIG, XMLSIG_LEN, (LPSTR)szBuffer, XMLSIG_LEN) ||
  58. CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, WTEXT(XMLSIG), XMLSIG_LEN, (LPWSTR)szBuffer, XMLSIG_LEN))
  59. {
  60. return S_OK;
  61. }
  62. }
  63. return OMSTORAGE_E_UNKNOWN_FORMAT;
  64. }
  65. HRESULT EnumXmlFile::CreateInstance(LPCWSTR pszAddress, ifc_omservicehost *host, EnumXmlFile **instance)
  66. {
  67. if (NULL == instance) return E_POINTER;
  68. *instance = NULL;
  69. HRESULT hr;
  70. WCHAR szBuffer[MAX_PATH * 2] = {0};
  71. hr = Plugin_ResolveRelativePath(pszAddress, host, szBuffer, ARRAYSIZE(szBuffer));
  72. if (FAILED(hr)) return hr;
  73. HANDLE hFile = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  74. if (INVALID_HANDLE_VALUE == hFile)
  75. {
  76. DWORD error = GetLastError();
  77. return HRESULT_FROM_WIN32(error);
  78. }
  79. hr = CheckXmlHeader(hFile);
  80. if (SUCCEEDED(hr))
  81. {
  82. ifc_wasabihelper *wasabi;
  83. hr = Plugin_GetWasabiHelper(&wasabi);
  84. if (SUCCEEDED(hr))
  85. {
  86. obj_xml *reader;
  87. wasabi->QueryWasabiInterface(&obj_xmlGUID, (void**)&reader);
  88. if (NULL != reader && OBJ_XML_SUCCESS == reader->xmlreader_open())
  89. {
  90. *instance = new EnumXmlFile(hFile, reader, szBuffer, host);
  91. if (NULL == *instance)
  92. {
  93. hr = E_OUTOFMEMORY;
  94. // reader stil has no support for AddRef()/Release()
  95. wasabi->ReleaseWasabiInterface(&obj_xmlGUID, reader);
  96. }
  97. reader->Release();
  98. }
  99. else
  100. {
  101. hr = E_UNEXPECTED;
  102. }
  103. wasabi->Release();
  104. }
  105. }
  106. if (FAILED(hr))
  107. {
  108. if (NULL != hFile) CloseHandle(hFile);
  109. }
  110. return hr;
  111. }
  112. size_t EnumXmlFile::AddRef()
  113. {
  114. return InterlockedIncrement((LONG*)&ref);
  115. }
  116. size_t EnumXmlFile::Release()
  117. {
  118. if (0 == ref)
  119. return ref;
  120. LONG r = InterlockedDecrement((LONG*)&ref);
  121. if (0 == r)
  122. delete(this);
  123. return r;
  124. }
  125. int EnumXmlFile::QueryInterface(GUID interface_guid, void **object)
  126. {
  127. if (NULL == object) return E_POINTER;
  128. if (IsEqualIID(interface_guid, IFC_OmServiceEnum))
  129. *object = static_cast<ifc_omserviceenum*>(this);
  130. else if (IsEqualIID(interface_guid, IFC_OmXmlServiceEnum))
  131. *object = static_cast<ifc_omxmlserviceenum*>(this);
  132. else
  133. {
  134. *object = NULL;
  135. return E_NOINTERFACE;
  136. }
  137. if (NULL == *object)
  138. return E_UNEXPECTED;
  139. AddRef();
  140. return S_OK;
  141. }
  142. HRESULT EnumXmlFile::Next(ULONG listSize, ifc_omservice **elementList, ULONG *elementCount)
  143. {
  144. if(NULL != elementCount)
  145. *elementCount = 0;
  146. if (0 == listSize || NULL == elementList)
  147. return E_INVALIDARG;
  148. ULONG counter = 0;
  149. HRESULT hr = S_OK;
  150. ifc_omservice *service;
  151. while(counter < listSize)
  152. {
  153. hr = parser.PeekService(&service);
  154. if (FAILED(hr)) return hr;
  155. if (S_OK == hr)
  156. {
  157. elementList[counter] = service;
  158. counter++;
  159. }
  160. else
  161. {
  162. if (NULL == buffer)
  163. {
  164. buffer = (BYTE*)calloc(bufferMax, sizeof(BYTE));
  165. if (NULL == buffer) return E_OUTOFMEMORY;
  166. }
  167. DWORD read = 0;
  168. if (FALSE == ReadFile(hFile, buffer, bufferMax, &read, NULL))
  169. {
  170. DWORD error = GetLastError();
  171. return HRESULT_FROM_WIN32(error);
  172. }
  173. if (0 == read)
  174. {
  175. if (OBJ_XML_SUCCESS == readerError)
  176. reader->xmlreader_feed(0, 0);
  177. break;
  178. }
  179. readerError = reader->xmlreader_feed(buffer, read);
  180. if (OBJ_XML_SUCCESS != readerError) return E_FAIL;
  181. }
  182. }
  183. if(NULL != elementCount)
  184. *elementCount = counter;
  185. return (counter > 0) ? S_OK : S_FALSE;
  186. }
  187. HRESULT EnumXmlFile::Reset(void)
  188. {
  189. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  190. readerError = OBJ_XML_SUCCESS;
  191. reader->xmlreader_reset();
  192. parser.Reset();
  193. return E_NOTIMPL;
  194. }
  195. HRESULT EnumXmlFile::Skip(ULONG elementCount)
  196. {
  197. return E_NOTIMPL;
  198. }
  199. HRESULT EnumXmlFile::GetStatusCode(UINT *code)
  200. {
  201. return parser.GetCode(code);
  202. }
  203. HRESULT EnumXmlFile::GetStatusText(LPWSTR pszBuffer, UINT cchBufferMax)
  204. {
  205. return parser.GetText(pszBuffer, cchBufferMax);
  206. }
  207. #define CBCLASS EnumXmlFile
  208. START_MULTIPATCH;
  209. START_PATCH(MPIID_OMSERVICEENUM)
  210. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, ADDREF, AddRef);
  211. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, RELEASE, Release);
  212. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, QUERYINTERFACE, QueryInterface);
  213. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_NEXT, Next);
  214. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_RESET, Reset);
  215. M_CB(MPIID_OMSERVICEENUM, ifc_omserviceenum, API_SKIP, Skip);
  216. NEXT_PATCH(MPIID_OMXMLSERVICEENUM)
  217. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, ADDREF, AddRef);
  218. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, RELEASE, Release);
  219. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, QUERYINTERFACE, QueryInterface);
  220. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, API_GETSTATUSCODE, GetStatusCode);
  221. M_CB(MPIID_OMXMLSERVICEENUM, ifc_omxmlserviceenum, API_GETSTATUSTEXT, GetStatusText);
  222. END_PATCH
  223. END_MULTIPATCH;
  224. #undef CBCLASS