util.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "main.h"
  2. #include "./util.h"
  3. #include "api__ml_downloads.h"
  4. #include <strsafe.h>
  5. LPWSTR Plugin_MallocString(size_t cchLen)
  6. {
  7. return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
  8. }
  9. void Plugin_FreeString(LPWSTR pszString)
  10. {
  11. if (NULL != pszString)
  12. {
  13. free(pszString);
  14. }
  15. }
  16. LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen)
  17. {
  18. return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
  19. }
  20. LPWSTR Plugin_CopyString(LPCWSTR pszSource)
  21. {
  22. if (NULL == pszSource)
  23. return NULL;
  24. INT cchSource = lstrlenW(pszSource) + 1;
  25. LPWSTR copy = Plugin_MallocString(cchSource);
  26. if (NULL != copy)
  27. {
  28. CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
  29. }
  30. return copy;
  31. }
  32. LPSTR Plugin_MallocAnsiString(size_t cchLen)
  33. {
  34. return (LPSTR)calloc(cchLen, sizeof(CHAR));
  35. }
  36. LPSTR Plugin_CopyAnsiString(LPCSTR pszSource)
  37. {
  38. if (NULL == pszSource)
  39. return NULL;
  40. INT cchSource = lstrlenA(pszSource) + 1;
  41. LPSTR copy = Plugin_MallocAnsiString(cchSource);
  42. if (NULL != copy)
  43. {
  44. CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
  45. }
  46. return copy;
  47. }
  48. void Plugin_FreeAnsiString(LPSTR pszString)
  49. {
  50. Plugin_FreeString((LPWSTR)pszString);
  51. }
  52. LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
  53. {
  54. INT cchBuffer = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
  55. if (0 == cchBuffer) return NULL;
  56. LPSTR buffer = Plugin_MallocAnsiString(cchBuffer);
  57. if (NULL == buffer) return NULL;
  58. if (0 == WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar))
  59. {
  60. Plugin_FreeAnsiString(buffer);
  61. return NULL;
  62. }
  63. return buffer;
  64. }
  65. LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte)
  66. {
  67. if (NULL == lpMultiByteStr) return NULL;
  68. INT cchBuffer = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
  69. if (NULL == cchBuffer) return NULL;
  70. if (cbMultiByte > 0) cchBuffer++;
  71. LPWSTR buffer = Plugin_MallocString(cchBuffer);
  72. if (NULL == buffer) return NULL;
  73. if (0 == MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer))
  74. {
  75. Plugin_FreeString(buffer);
  76. return NULL;
  77. }
  78. if (cbMultiByte > 0)
  79. {
  80. buffer[cchBuffer - 1] = L'\0';
  81. }
  82. return buffer;
  83. }
  84. LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource)
  85. {
  86. return (IS_INTRESOURCE(pszResource)) ?
  87. (LPWSTR)pszResource :
  88. Plugin_CopyString(pszResource);
  89. }
  90. void Plugin_FreeResString(LPWSTR pszResource)
  91. {
  92. if (!IS_INTRESOURCE(pszResource))
  93. Plugin_FreeString(pszResource);
  94. }
  95. HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString)
  96. {
  97. if (NULL == pszBuffer)
  98. return E_INVALIDARG;
  99. HRESULT hr = S_OK;
  100. if (NULL == pszString)
  101. {
  102. pszBuffer[0] = L'\0';
  103. }
  104. else if (IS_INTRESOURCE(pszString))
  105. {
  106. if (NULL == WASABI_API_LNG)
  107. hr = E_FAIL;
  108. else
  109. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszString, pszBuffer, cchBufferMax);
  110. }
  111. else
  112. {
  113. hr = StringCchCopy(pszBuffer, cchBufferMax, pszString);
  114. }
  115. return hr;
  116. }
  117. void Plugin_SafeRelease(IUnknown *pUnk)
  118. {
  119. if (NULL != pUnk)
  120. pUnk->Release();
  121. }
  122. HRESULT Plugin_FileExtensionFromUrl(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszUrl, LPCWSTR defaultExtension)
  123. {
  124. LPCWSTR cursor = pszUrl;
  125. while (L'\0' != *cursor && L'?' != *cursor)
  126. cursor = CharNext(cursor);
  127. LPCWSTR end = cursor;
  128. while (cursor != pszUrl && L'/' != *cursor && L'\\' != *cursor && L'.' != *cursor)
  129. cursor = CharPrev(pszUrl, cursor);
  130. if (L'.' == *cursor && cursor != pszUrl)
  131. {
  132. if (CharNext(cursor) < end)
  133. {
  134. INT cchExtension = (INT)(INT_PTR)(end - cursor);
  135. return StringCchCopyN(pszBuffer, cchBufferMax, cursor, cchExtension);
  136. }
  137. }
  138. return StringCchCopy(pszBuffer, cchBufferMax, defaultExtension);
  139. }
  140. void Plugin_ReplaceBadPathChars(LPWSTR pszPath)
  141. {
  142. if (NULL == pszPath)
  143. return;
  144. while (L'\0' != *pszPath)
  145. {
  146. switch(*pszPath)
  147. {
  148. case L'?':
  149. case L'/':
  150. case L'\\':
  151. case L':':
  152. case L'*':
  153. case L'\"':
  154. case L'<':
  155. case L'>':
  156. case L'|':
  157. *pszPath = L'_';
  158. break;
  159. default:
  160. if (*pszPath < 32) *pszPath = L'_';
  161. break;
  162. }
  163. pszPath = CharNextW(pszPath);
  164. }
  165. }
  166. INT Plugin_CleanDirectory(LPWSTR pszPath)
  167. {
  168. if (NULL == pszPath)
  169. return 0;
  170. INT cchPath = lstrlen(pszPath);
  171. LPWSTR cursor = pszPath + cchPath;
  172. while (cursor-- != pszPath && (L' ' == *cursor || L'.' == *cursor))
  173. *cursor = L'\0';
  174. return (cchPath - (INT)(INT_PTR)(cursor - pszPath) - 1);
  175. }
  176. HRESULT Plugin_EnsurePathExist(LPCWSTR pszDirectory)
  177. {
  178. DWORD ec = ERROR_SUCCESS;
  179. UINT errorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  180. if (0 == CreateDirectory(pszDirectory, NULL))
  181. {
  182. ec = GetLastError();
  183. if (ERROR_PATH_NOT_FOUND == ec)
  184. {
  185. LPCWSTR pszBlock = pszDirectory;
  186. WCHAR szBuffer[MAX_PATH] = {0};
  187. LPCTSTR pszCursor = PathFindNextComponent(pszBlock);
  188. ec = (pszCursor == pszBlock || S_OK != StringCchCopyN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock))) ?
  189. ERROR_INVALID_NAME : ERROR_SUCCESS;
  190. pszBlock = pszCursor;
  191. while (ERROR_SUCCESS == ec && NULL != (pszCursor = PathFindNextComponent(pszBlock)))
  192. {
  193. if (pszCursor == pszBlock || S_OK != StringCchCatN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock)))
  194. ec = ERROR_INVALID_NAME;
  195. if (ERROR_SUCCESS == ec && !CreateDirectory(szBuffer, NULL))
  196. {
  197. ec = GetLastError();
  198. if (ERROR_ALREADY_EXISTS == ec) ec = ERROR_SUCCESS;
  199. }
  200. pszBlock = pszCursor;
  201. }
  202. }
  203. if (ERROR_ALREADY_EXISTS == ec)
  204. ec = ERROR_SUCCESS;
  205. }
  206. SetErrorMode(errorMode);
  207. SetLastError(ec);
  208. return HRESULT_FROM_WIN32(ec);
  209. }