copyfiles_post.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "main.h"
  2. #include "./copyfiles.h"
  3. #include "./copyinternal.h"
  4. #include "./resource.h"
  5. #include "../nu/trace.h"
  6. #include <api/service/waServiceFactory.h>
  7. #include <shlwapi.h>
  8. #include <strsafe.h>
  9. typedef struct _FILEMETA
  10. {
  11. LPWSTR pszArtist;
  12. LPWSTR pszAlbum;
  13. LPWSTR pszTitle;
  14. LPWSTR pszGenre;
  15. LPWSTR pszAlbumArtist;
  16. INT nYear;
  17. INT nTrackNum;
  18. INT nTrackCount;
  19. LPWSTR pszDisc;
  20. } FILEMETA;
  21. // sets part and parts to -1 or 0 on fail/missing (e.g. parts will be -1 on "1", but 0 on "1/")
  22. static void ParseIntSlashInt(wchar_t *string, int *part, int *parts)
  23. {
  24. *part = -1;
  25. *parts = -1;
  26. if (string && string[0])
  27. {
  28. *part = _wtoi(string);
  29. while (string && *string && *string != '/')
  30. {
  31. string++;
  32. }
  33. if (*string == '/')
  34. {
  35. string++;
  36. *parts = _wtoi(string);
  37. }
  38. }
  39. }
  40. #define READFILEINFO(__fileName, __tag, __result, __pszBuffer, __cchBuffer)\
  41. (pReader->GetExtendedFileInfo((__fileName), (__tag), (__pszBuffer), (__cchBuffer)) && L'\0' != *(__pszBuffer))
  42. static void CopyFiles_ReadFileMeta(FILEMETA *pMeta, api_metadata *pReader, LPCWSTR pszFileName)
  43. {
  44. WCHAR szBuffer[2048] = {0};
  45. #define GETFILEINFO_STR(__tag, __result, __resId)\
  46. { szBuffer[0] = L'\0';\
  47. READFILEINFO(pszFileName, __tag, __result, szBuffer, ARRAYSIZE(szBuffer));\
  48. if (TEXT('\0') == *szBuffer)\
  49. { if (IS_INTRESOURCE(__resId)) WASABI_API_LNGSTRINGW_BUF(((UINT)(UINT_PTR)(__resId)), szBuffer, ARRAYSIZE(szBuffer));\
  50. else StringCchCopyEx(szBuffer, ARRAYSIZE(szBuffer), (__resId), NULL, NULL, STRSAFE_IGNORE_NULLS);\
  51. }\
  52. (__result) = _wcsdup(szBuffer); }
  53. #define GETFILEINFO_INT(__tag, __result) { szBuffer[0] = L'\0';\
  54. if (READFILEINFO(pszFileName, __tag, __result, szBuffer, ARRAYSIZE(szBuffer)))\
  55. {(__result) = _wtoi(szBuffer); }}
  56. #define GETFILEINFO_INTINT(__tag, __result1, __result2) { szBuffer[0] = L'\0';\
  57. if (READFILEINFO(pszFileName, __tag, __result, szBuffer, ARRAYSIZE(szBuffer)))\
  58. {ParseIntSlashInt(szBuffer, (__result1), (__result2)); }}
  59. if (!pMeta) return;
  60. ZeroMemory(pMeta, sizeof(FILEMETA));
  61. #pragma warning(push)
  62. #pragma warning(disable : 4127)
  63. GETFILEINFO_STR(L"artist", pMeta->pszArtist, MAKEINTRESOURCE(IDS_UNKNOWN_ARTIST));
  64. GETFILEINFO_STR(L"album", pMeta->pszAlbum, MAKEINTRESOURCE(IDS_UNKNOWN_ALBUM));
  65. GETFILEINFO_STR(L"title", pMeta->pszTitle, MAKEINTRESOURCE(IDS_UNKNOWN));
  66. GETFILEINFO_STR(L"albumartist", pMeta->pszAlbumArtist, pMeta->pszArtist);
  67. GETFILEINFO_STR(L"genre", pMeta->pszGenre, MAKEINTRESOURCE(IDS_UNKNOWN_GENRE));
  68. GETFILEINFO_INT(L"year", pMeta->nYear);
  69. GETFILEINFO_INTINT(L"track", &pMeta->nTrackNum, &pMeta->nTrackCount);
  70. GETFILEINFO_STR(L"disc", pMeta->pszDisc, MAKEINTRESOURCE(IDS_UNKNOWN));
  71. #pragma warning(pop)
  72. }
  73. static void CopyFiles_ReleaseFileMeta(FILEMETA *pMeta)
  74. {
  75. if (pMeta->pszArtist) free(pMeta->pszArtist);
  76. if (pMeta->pszAlbum) free(pMeta->pszAlbum);
  77. if (pMeta->pszTitle) free(pMeta->pszTitle);
  78. if (pMeta->pszGenre) free(pMeta->pszGenre);
  79. if (pMeta->pszDisc) free(pMeta->pszDisc);
  80. if (pMeta->pszAlbumArtist) free(pMeta->pszAlbumArtist);
  81. ZeroMemory(pMeta, sizeof(FILEMETA));
  82. }
  83. static BOOL CopyFiles_GetFormattedName(LPTSTR pszBuffer, INT cchBufferMax, LPCTSTR pszFileToFormat, LPCTSTR pszOrigFileName, LPCTSTR pszFormat, api_metadata *pMetaReader)
  84. {
  85. HRESULT hr;
  86. FILEMETA meta;
  87. CopyFiles_ReadFileMeta(&meta, pMetaReader, pszFileToFormat);
  88. WCHAR szYear[16] = {0};
  89. StringCchPrintf(szYear, ARRAYSIZE(szYear), TEXT("%d"), meta.nYear);
  90. pszBuffer[0] = TEXT('\0');
  91. hr = FormatFileName(pszBuffer, cchBufferMax, pszFormat,
  92. meta.nTrackNum, meta.pszAlbumArtist,
  93. meta.pszAlbum, meta.pszTitle,
  94. meta.pszGenre, szYear, meta.pszArtist,
  95. pszOrigFileName, meta.pszDisc);
  96. CopyFiles_ReleaseFileMeta(&meta);
  97. if (S_OK != hr)
  98. {
  99. SetLastError(ERROR_OUTOFMEMORY);
  100. return FALSE;
  101. }
  102. return TRUE;
  103. }
  104. BOOL CopyFiles_FormatFileName(LPTSTR pszNewFileName, INT cchBufferMax, LPCTSTR pszFileToRename, LPCTSTR pszOrigFileName, LPCTSTR pszDestination, LPCTSTR pszFormat, api_metadata *pMetaReader)
  105. {
  106. StringCchCopy(pszNewFileName, cchBufferMax, pszDestination);
  107. INT l = lstrlen(pszNewFileName);
  108. if (l) { pszNewFileName[l] = TEXT('\\'); pszNewFileName[l + 1] = TEXT('\0'); l++; }
  109. if (!CopyFiles_GetFormattedName(pszNewFileName + l, cchBufferMax - l, pszFileToRename, pszOrigFileName, pszFormat, pMetaReader))
  110. return FALSE;
  111. LPTSTR p = PathFindFileName(pszNewFileName);
  112. if (p && p > pszNewFileName)
  113. {
  114. *(p - 1) = TEXT('\0');
  115. if (!CopyFiles_CreateDirectory(pszNewFileName)) return FALSE;
  116. *(p - 1) = TEXT('\\');
  117. }
  118. return TRUE;
  119. }