enumIniFile.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "main.h"
  2. #include "./enumIniFile.h"
  3. #include "./service.h"
  4. #include "./ifc_omservicehost.h"
  5. #include "./ifc_omstorage.h"
  6. #include "./ifc_omstoragehandlerenum.h"
  7. #include "./ifc_omstorageext.h"
  8. #include "./ifc_omfilestorage.h"
  9. #include <shlwapi.h>
  10. #include <strsafe.h>
  11. #define OMS_GROUP "OnlineService"
  12. #define OMS_ID "id"
  13. #define OMS_NAME "name"
  14. #define OMS_URL "url"
  15. #define OMS_ICON "icon"
  16. #define OMS_FLAGS "flags"
  17. #define OMS_RATING "rating"
  18. #define OMS_VERSION "version"
  19. #define OMS_DESCRIPTION "description"
  20. #define OMS_AUTHORFIRST "authorFirst"
  21. #define OMS_AUTHORLAST "authorLast"
  22. #define OMS_PUBLISHED "publishedDate"
  23. #define OMS_UPDATED "updatedDate"
  24. #define OMS_THUMBNAIL "thumbnail"
  25. #define OMS_SCREENSHOT "screenshot"
  26. #define OMS_GENERATION "generation"
  27. EnumIniFile::EnumIniFile(LPCWSTR pszAddress, ifc_omservicehost *serviceHost)
  28. : ref(1), address(NULL), host(serviceHost), hFind(NULL)
  29. {
  30. address = Plugin_CopyString(pszAddress);
  31. if (NULL != host)
  32. {
  33. host->AddRef();
  34. ifc_omstorageext *storageExt = NULL;
  35. if (SUCCEEDED(host->QueryInterface(IFC_OmStorageExt, (void**)&storageExt)) && storageExt != NULL)
  36. {
  37. ifc_omstoragehandlerenum *handlerEnum = NULL;
  38. if (SUCCEEDED(storageExt->Enumerate(&SUID_OmStorageIni, &handlerEnum)) && handlerEnum != NULL)
  39. {
  40. reader.RegisterHandlers(handlerEnum);
  41. handlerEnum->Release();
  42. }
  43. storageExt->Release();
  44. }
  45. }
  46. }
  47. EnumIniFile::~EnumIniFile()
  48. {
  49. Plugin_FreeString(address);
  50. if (NULL != host)
  51. host->Release();
  52. if (NULL != hFind)
  53. FindClose(hFind);
  54. }
  55. HRESULT EnumIniFile::CreateInstance(LPCWSTR pszAddress, ifc_omservicehost *host, EnumIniFile **instance)
  56. {
  57. if (NULL == instance)
  58. return E_POINTER;
  59. WCHAR szBuffer[MAX_PATH * 2] = {0};
  60. HRESULT hr = Plugin_ResolveRelativePath(pszAddress, host, szBuffer, ARRAYSIZE(szBuffer));
  61. if (FAILED(hr)) return hr;
  62. // test if we can load this one
  63. if (FALSE == PathIsDirectory(szBuffer) && PathFileExists(szBuffer))
  64. {
  65. UINT id = GetPrivateProfileInt(TEXT(OMS_GROUP), WTEXT(OMS_ID), 0, pszAddress);
  66. if (0 == id) return OMSTORAGE_E_UNKNOWN_FORMAT;
  67. }
  68. *instance = new EnumIniFile(szBuffer, host);
  69. if (NULL == *instance) return E_OUTOFMEMORY;
  70. return S_OK;
  71. }
  72. size_t EnumIniFile::AddRef()
  73. {
  74. return InterlockedIncrement((LONG*)&ref);
  75. }
  76. size_t EnumIniFile::Release()
  77. {
  78. if (0 == ref)
  79. return ref;
  80. LONG r = InterlockedDecrement((LONG*)&ref);
  81. if (0 == r)
  82. delete(this);
  83. return r;
  84. }
  85. int EnumIniFile::QueryInterface(GUID interface_guid, void **object)
  86. {
  87. if (NULL == object) return E_POINTER;
  88. if (IsEqualIID(interface_guid, IFC_OmServiceEnum))
  89. *object = static_cast<ifc_omserviceenum*>(this);
  90. else
  91. {
  92. *object = NULL;
  93. return E_NOINTERFACE;
  94. }
  95. if (NULL == *object)
  96. return E_UNEXPECTED;
  97. AddRef();
  98. return S_OK;
  99. }
  100. HRESULT EnumIniFile::Next(ULONG listSize, ifc_omservice **elementList, ULONG *elementCount)
  101. {
  102. if(NULL != elementCount)
  103. *elementCount = 0;
  104. if (0 == listSize || NULL == elementList)
  105. return E_INVALIDARG;
  106. ULONG counter = 0;
  107. BOOL bFoundNext = FALSE;
  108. HRESULT hr = S_OK;
  109. if (NULL == hFind)
  110. {
  111. hFind = FindFirstFile(address, &fData);
  112. if (INVALID_HANDLE_VALUE == hFind)
  113. {
  114. DWORD error = GetLastError();
  115. return HRESULT_FROM_WIN32(error);
  116. }
  117. bFoundNext = TRUE;
  118. }
  119. else
  120. {
  121. bFoundNext = FindNextFile(hFind, &fData);
  122. }
  123. if (bFoundNext)
  124. {
  125. do
  126. {
  127. LPCWSTR p = address;
  128. while(p && L'.' == *p && L'\0' != *p) p++;
  129. if (p && L'\0' != *p)
  130. {
  131. WCHAR base[MAX_PATH] = {0};
  132. StringCchCopy(base, MAX_PATH, address);
  133. PathRemoveFileSpec(base);
  134. int baseLen = lstrlen(base);
  135. base[baseLen] = L'\0';
  136. if (!PathAppend(base, fData.cFileName))
  137. {
  138. base[baseLen] = L'\0';
  139. PathAppend(base, fData.cAlternateFileName);
  140. }
  141. hr = reader.Load(base, host, &elementList[counter]);
  142. if (S_OK == hr)
  143. {
  144. listSize--;
  145. counter++;
  146. if (0 == listSize) break;
  147. }
  148. }
  149. bFoundNext = FindNextFile(hFind, &fData);
  150. } while(bFoundNext);
  151. }
  152. if(NULL != elementCount)
  153. *elementCount = counter;
  154. return (counter > 0) ? S_OK : S_FALSE;
  155. }
  156. HRESULT EnumIniFile::Reset(void)
  157. {
  158. if (NULL != hFind)
  159. {
  160. FindClose(hFind);
  161. hFind = NULL;
  162. }
  163. return S_OK;
  164. }
  165. HRESULT EnumIniFile::Skip(ULONG elementCount)
  166. {
  167. return E_NOTIMPL;
  168. }
  169. #define CBCLASS EnumIniFile
  170. START_DISPATCH;
  171. CB(ADDREF, AddRef)
  172. CB(RELEASE, Release)
  173. CB(QUERYINTERFACE, QueryInterface)
  174. CB(API_NEXT, Next)
  175. CB(API_RESET, Reset)
  176. CB(API_SKIP, Skip)
  177. END_DISPATCH;
  178. #undef CBCLASS