From 20466b7f2f04790db89ef6c4ca61be70b98e7678 Mon Sep 17 00:00:00 2001 From: Artfunkel Date: Sat, 12 Nov 2016 16:55:11 +0000 Subject: [PATCH] Added IThumbnailProvider implementation Upgraded to the latest version of TagLib Added event tracing Added a warning when the module is registered within the user folder (search indexing won't work when this happens) Upgraded to Visual Studio 2015 Changed apartment mode to "Both" for improved search indexing performance Fixed various improper COM behaviours --- .gitignore | 14 + DllRegister.cpp | 19 +- README.txt | 31 +- TagLibHandler.cpp | 407 ++++++++++++++++++++++---- TagLibHandler.sln | 85 +++++- TagLibHandler.vcproj | 391 ------------------------- TagLibHandler.vcxproj | 234 +++++++++++++++ TagLibHandler.vcxproj.filters | 61 ++++ events.man | 166 +++++++++++ exttag.cpp | 26 +- exttagtest/exttagtest.vcproj | 204 ------------- exttagtest/exttagtest.vcxproj | 177 +++++++++++ exttagtest/exttagtest.vcxproj.filters | 30 ++ propdump/propdump.vcproj | 219 -------------- propdump/propdump.vcxproj | 176 +++++++++++ propdump/propdump.vcxproj.filters | 30 ++ resource.h | Bin 384 -> 804 bytes setup/tlhsetup2.vcproj | 223 -------------- setup/tlhsetup2.vcxproj | 113 +++++++ setup/tlhsetup2.vcxproj.filters | 46 +++ tlh.rc | Bin 2284 -> 4022 bytes 21 files changed, 1506 insertions(+), 1146 deletions(-) create mode 100644 .gitignore delete mode 100644 TagLibHandler.vcproj create mode 100644 TagLibHandler.vcxproj create mode 100644 TagLibHandler.vcxproj.filters create mode 100644 events.man delete mode 100644 exttagtest/exttagtest.vcproj create mode 100644 exttagtest/exttagtest.vcxproj create mode 100644 exttagtest/exttagtest.vcxproj.filters delete mode 100644 propdump/propdump.vcproj create mode 100644 propdump/propdump.vcxproj create mode 100644 propdump/propdump.vcxproj.filters delete mode 100644 setup/tlhsetup2.vcproj create mode 100644 setup/tlhsetup2.vcxproj create mode 100644 setup/tlhsetup2.vcxproj.filters diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5db2c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +**/ipch +events.rc +events.h +*.aps +*.bin +*.user +*.VC.* +**/.vs +**/x64/ +**/Debug/ +**/Release/ +/taglib +/taglib_build_* +/boost diff --git a/DllRegister.cpp b/DllRegister.cpp index 3c5a2ca..d1c944d 100644 --- a/DllRegister.cpp +++ b/DllRegister.cpp @@ -1,4 +1,5 @@ #include "dllregister.h" +#include LONG createRegKey(const HKEY base, const LPCWSTR name, HKEY& out) { @@ -63,6 +64,14 @@ HRESULT CreateRegKeyAndSetValue(const REGISTRY_ENTRY &pRegistryEntry, HRESULT doRegistration(LPWSTR szModuleName, LONG createKey(const HKEY,const LPCWSTR,HKEY &)) { + { + wchar_t user_profile[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, user_profile))) { + if (wcsstr(szModuleName, user_profile) == szModuleName) + std::cout << "WARNING: you are registering this module within your user folder. Search indexing will not work unless it is registered from a system-wide path." << std::endl; + } + } + // List of property-handler specific registry entries we need to create const REGISTRY_ENTRY rgRegistryEntries[] = { @@ -75,14 +84,6 @@ HRESULT doRegistration(LPWSTR szModuleName, SZ_TAGLIBPROPERTYHANDLER, 0 }, - { - HKEY_CLASSES_ROOT, - L"CLSID\\" SZ_CLSID_US, - L"ManualSafeSave", - REG_DWORD, - NULL, - 1 - }, { HKEY_CLASSES_ROOT, L"CLSID\\" SZ_CLSID_US L"\\InProcServer32", @@ -96,7 +97,7 @@ HRESULT doRegistration(LPWSTR szModuleName, L"CLSID\\" SZ_CLSID_US L"\\InProcServer32", L"ThreadingModel", REG_SZ, - L"Apartment", + L"Both", 0 }, diff --git a/README.txt b/README.txt index 8e2f7f4..e38fde1 100644 --- a/README.txt +++ b/README.txt @@ -11,14 +11,13 @@ Please report any problems, no matter how small. -- Manual install instructions: -1) Register the 32-bit TagLibHandler.dll (from this directory), ie. +1) Place TagLibHandler.dll in a system directory (i.e. NOT your user folder) - > regsvr32 TagLibHandler.dll - - This will give an illogical error message if not run with sufficient permissions. Possibly: - > The module "TagLibHandler.dll" was loaded but the call to DllRegisterServer failed with error code 0x80070005. +2) Open an administrator command prompt and register the module: -1a) If you are using a 64-bit OS, also register the x64 version of the component. + > regsvr32 TagLibHandler.dll + +1a) If you are using a 64-bit OS, consider also registering the x86 version of the component. It's worth having both installed as frequently you'll use x32 apps without realising. @@ -30,11 +29,15 @@ Please report any problems, no matter how small. ie. create a Key called HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.ogg and set it's (Default) value to {66AC53F1-EB5D-4af9-861E-E3AE9C07EF14}. + + It's safe to replace the system associations, such as .mp3, although, at this stage, you will lose functionality by doing so. -3) It's safe to replace the system associations, such as .mp3, although, at this stage, you will lose functionality by doing so. + You may want to back-up any data you overwrite. - You may want to back-up any data you overwrite. +3) Register TagLibHandler as the thumbnail provider for whichever formats you like. For OGG thumbnails: + a) Create the key HKEY_CLASSES_ROOT/.ogg/ShellEx/{e357fccd-a995-4576-b01f-234630154e96} + b) Set its (Default) to {66AC53F1-EB5D-4af9-861E-E3AE9C07EF14}. -- Lost functionality by using Taglib Handler instead of the Windows Default. @@ -42,13 +45,15 @@ Please report any problems, no matter how small. You will gain: The ability to read a whole new set of tags, including id3v2.4 tags with utf-8. -- Development environment: - - Vista SP2. - - VS2008 SP1. - - Header-only libraries from Boost 1.40. + - Windows 10 + - VS 2015 + - taglib master branch at ./taglib (last known good revision: d53ca6f7369dc7299c2991fa1fb9e4d80f534cf3) + - taglib CMake build output(s) at ./taglib_build_$(PlatformTarget) + - Header-only libraries from Boost 1.62 at ./boost + + For the installer: - loki-0.1.7.7 - http://wtl.svn.sourceforge.net/svnroot/wtl/trunk/wtl@404 - - taglib "branch": 0e2057cc9d1918d893a7dacfdf927dd9253b12c1, off - svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglibb@1035209 (after 1.6 release) -- License (MIT): diff --git a/TagLibHandler.cpp b/TagLibHandler.cpp index 0fc98bc..ac6b0ad 100644 --- a/TagLibHandler.cpp +++ b/TagLibHandler.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include @@ -11,26 +13,89 @@ #include // System PROPERTYKEY definitions #include // PROPVARIANT and VARIANT helper APIs +#include +#include + #include #include #include "exttag.h" +#include "events.h" + +template +class COMWrapper +{ + T* comPtr; +public: + COMWrapper(T * const comPtr = nullptr) : comPtr(comPtr) {} + COMWrapper(const COMWrapper& other) : comPtr(other) + { + if (other) + other->AddRef(); + } + ~COMWrapper() + { + Release(); + } + + T* operator->() const { return comPtr; } + operator T*() const { return comPtr; } + + void operator=(T* newPtr) + { + if (comPtr == newPtr) + return; + + Release(); + comPtr = newPtr; // don't add a reference + } + T** GetForModify() + { + assert(!comPtr); // this method should be used only to initialise an empty COMWrapper. + return &comPtr; + } + + void Release() + { + if (comPtr) comPtr->Release(); + comPtr = nullptr; + } +}; + +std::string HResultMessage(HRESULT hr) +{ + char errorBuf[256]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorBuf, 256, nullptr); + return errorBuf; +} -// -// Releases the specified pointer if not NULL -// -#define SAFE_RELEASE(p) \ - if (p) \ - { \ - (p)->Release(); \ - (p) = NULL; \ +#include "toolkit/tdebuglistener.h" +class DebugListener : TagLib::DebugListener +{ + static std::string LastError; +public: + + DebugListener() + { + TagLib::setDebugListener(this); } + void printMessage(const TagLib::String &msg) override + { + LastError = msg.to8Bit(); + } + + static std::string GetLastError() { return LastError; } +}; + +std::string DebugListener::LastError = "No errors recorded"; + // DLL lifetime management functions void DllAddRef(); void DllRelease(); const PROPERTYKEY keys[] = { + // If you change this array, also change the "PropertyNames" map in events.man. PKEY_Music_AlbumTitle, PKEY_Music_Artist, PKEY_Music_TrackNumber, PKEY_Music_Genre, PKEY_Title, PKEY_Media_Year, PKEY_Audio_ChannelCount, @@ -43,12 +108,33 @@ const PROPERTYKEY keys[] = { PKEY_Keywords, PKEY_Comment, PKEY_Media_DateReleased }; +bool operator<(const PROPERTYKEY& a, const PROPERTYKEY& b) +{ + const int guid_compare = memcmp(&a.fmtid, &b.fmtid, sizeof(GUID)); + + if (guid_compare == 0) + return a.pid < b.pid; + else + return guid_compare < 0; +} +typedef std::map KeyMap; +static KeyMap KeyIDs = [] +{ + KeyMap out; + for (size_t i = 0; i < ARRAYSIZE(keys); ++i) + { + out[keys[i]] = (unsigned int)i; + } + return out; +}(); // Debug property handler class definition class CTagLibPropertyStore : public IPropertyStore, public IPropertyStoreCapabilities, - public IInitializeWithStream + public IThumbnailProvider, + public IInitializeWithStream, + public IInitializeWithFile { public: static HRESULT CreateInstance(REFIID riid, void **ppv); @@ -59,7 +145,9 @@ class CTagLibPropertyStore : static const QITAB qit[] = { QITABENT(CTagLibPropertyStore, IPropertyStore), QITABENT(CTagLibPropertyStore, IPropertyStoreCapabilities), + QITABENT(CTagLibPropertyStore, IThumbnailProvider), QITABENT(CTagLibPropertyStore, IInitializeWithStream), + QITABENT(CTagLibPropertyStore, IInitializeWithFile), { 0 }, }; return QISearch(this, qit, riid, ppv); @@ -92,59 +180,67 @@ class CTagLibPropertyStore : // IPropertyStoreCapabilities IFACEMETHODIMP IsPropertyWritable(REFPROPERTYKEY key); + // IThumbnailProvider + IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha); + // IInitializeWithStream IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode); + // IInitializeWithFile + IFACEMETHODIMP Initialize(LPCWSTR pszFilePath, DWORD grfMode); + protected: - CTagLibPropertyStore() : _cRef(1), _pStream(NULL), _grfMode(0) + CTagLibPropertyStore() : _cRef(1), _pStream(NULL), _grfMode(0), taglibfile() { + EventRegisterTagLibHandler(); + EventWriteStartup(); + DllAddRef(); - if (FAILED(PSCreateMemoryPropertyStore(IID_PPV_ARGS(&_pCache)))) - OutputDebugStr(L"TaglibHandler: PSCreateMemoryPropertyStore failed"); - + HRESULT hr = PSCreateMemoryPropertyStore(IID_PPV_ARGS(_pCache.GetForModify())); + if (FAILED(hr)) + EventWriteStartupError((std::string("PSCreateMemoryPropertyStore failed: ") + HResultMessage(hr)).c_str()); + PROPVARIANT pv = {}; pv.vt = VT_EMPTY; for (size_t i = 0; i < ARRAYSIZE(keys); ++i) + { _pCache->SetValue(keys[i], pv); + } + } ~CTagLibPropertyStore() { - SAFE_RELEASE(_pStream); - SAFE_RELEASE(_pCache); + EventWriteShutdown(); + EventUnregisterTagLibHandler(); } - IStream* _pStream; // data stream passed in to Initialize, and saved to on Commit - IPropertyStoreCache* _pCache; + IStream* _pStream; // data stream passed in to Initialize, and saved to on Commit. We don't manage the lifetime of this object so just use a raw pointer. + COMWrapper _pCache; DWORD _grfMode; // STGM mode passed to Initialize TagLib::FileRef taglibfile; private: - + DebugListener _listener; long _cRef; }; -bool operator==(REFPROPERTYKEY left, REFPROPERTYKEY right) -{ - return IsEqualPropertyKey(left, right); -} - struct Dbstr { const BSTR val; Dbstr(const std::wstring &str) : val(SysAllocString(str.c_str())) { - OutputDebugStr(L"bstr()"); + OutputDebugString(L"bstr()"); } ~Dbstr() { - OutputDebugStr(L"~bstr"); + OutputDebugString(L"~bstr"); SysFreeString(val); } operator BSTR() { - OutputDebugStr(L"op bstr"); + OutputDebugString(L"op bstr"); return val; } }; @@ -178,12 +274,12 @@ HRESULT CTagLibPropertyStore::GetValue(REFPROPERTYKEY key, PROPVARIANT *pPropVar } else if (ap && key == PKEY_Media_Duration) { - pPropVar->ulVal = ap->length()*10000000; + pPropVar->ulVal = ap->length() * 10000000; pPropVar->vt = VT_UI8; } else if (ap && key == PKEY_Audio_EncodingBitrate) { - pPropVar->uintVal = ap->bitrate()*1024; + pPropVar->uintVal = ap->bitrate() * 1024; pPropVar->vt = VT_UI4; } else if (ap && key == PKEY_Audio_SampleRate) @@ -234,7 +330,7 @@ HRESULT CTagLibPropertyStore::GetValue(REFPROPERTYKEY key, PROPVARIANT *pPropVar pPropVar->vt = VT_ARRAY | VT_BSTR; SAFEARRAYBOUND aDim[1] = {}; - aDim[0].cElements = keys.size(); + aDim[0].cElements = (ULONG)keys.size(); pPropVar->parray = SafeArrayCreate(VT_BSTR, 1, aDim); if (!pPropVar->parray) @@ -290,12 +386,32 @@ HRESULT CTagLibPropertyStore::GetValue(REFPROPERTYKEY key, PROPVARIANT *pPropVar else if (tag && key == PKEY_Music_PartOfSet) TRY_BSTR(partofset) else + { + EventWriteReadProperty_Unknown(&key.fmtid, key.pid); return S_FALSE; + } + + switch (pPropVar->vt) + { + case VT_LPWSTR: + EventWriteReadPropertyString(KeyIDs[key], pPropVar->pwszVal); + break; + case VT_UI4: + EventWriteReadPropertyInt(KeyIDs[key], pPropVar->uintVal); + break; + case VT_EMPTY: + EventWriteReadPropertyEmpty(KeyIDs[key]); + break; + } return S_OK; } catch (std::exception &e) { OutputDebugStringA(e.what()); + EventWriteReadProperty_Error(KeyIDs[key], e.what()); +#if MESSAGE_BOXES + MessageBoxA(0, e.what(), "TagLibHandler fatal error", 0); +#endif pPropVar->vt = VT_EMPTY; return ERROR_INTERNAL_ERROR; } @@ -306,21 +422,158 @@ HRESULT CTagLibPropertyStore::GetValue(REFPROPERTYKEY key, PROPVARIANT *pPropVar // caught it, there's a chance of a complete crash here, otoh, with a non-abort(), // the app/system may deal gracefully. OutputDebugString(L"TaglibHandler encountered unexpected exception in GetValue"); +#if MESSAGE_BOXES + MessageBoxA(0, "Unknown error", "TagLibHandler fatal error", 0); +#endif + EventWriteReadProperty_Error(KeyIDs[key], "Unknown error."); pPropVar->vt = VT_EMPTY; return ERROR_INTERNAL_ERROR; } } -HRESULT CTagLibPropertyStore::CreateInstance(REFIID riid, void **ppv) +inline void Verify(HRESULT hr) +{ + if (hr != S_OK) + throw std::runtime_error(HResultMessage(hr)); +} + +#include "Wincodec.h" +#include + +static HRESULT ExtractImage(char* data, size_t dataSize, UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) +{ +#if MESSAGE_BOXES + MessageBoxA(nullptr, "ExtractImage", "TagLibHandler debug", 0); +#endif + if (data == nullptr) + throw std::runtime_error("data cannot be null"); + if (dataSize > std::numeric_limits().max()) + throw std::overflow_error("dataSize is too large."); + + const COMWrapper stream = SHCreateMemStream((BYTE*)data, (UINT)dataSize); + + COMWrapper pImgFac; + Verify(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(pImgFac.GetForModify()))); + + COMWrapper pDecoder; + // The WIC system can deduce the format of a stream. + Verify(pImgFac->CreateDecoderFromStream(stream, nullptr, WICDecodeMetadataCacheOnLoad, pDecoder.GetForModify())); + + COMWrapper albumArt; + { + COMWrapper frame; + Verify(pDecoder->GetFrame(0, frame.GetForModify())); + Verify(WICConvertBitmapSource(GUID_WICPixelFormat24bppBGR, frame, albumArt.GetForModify())); + } + + UINT width, height; + Verify(albumArt->GetSize(&width, &height)); + + if (width > cx || height > cx) + { + float scale = 1.0f / (std::max(width, height) / (float)cx); + LONG NewWidth = (LONG)(width *scale); + LONG NewHeight = (LONG)(height *scale); + + BITMAPINFO bmi = {}; + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biWidth = NewWidth; + bmi.bmiHeader.biHeight = -NewHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 24; + bmi.bmiHeader.biCompression = BI_RGB; + + BYTE* pBits; + HBITMAP ResizedHBmp = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); + Verify(ResizedHBmp ? S_OK : E_OUTOFMEMORY); + + try + { + COMWrapper pIScaler; + Verify(pImgFac->CreateBitmapScaler(pIScaler.GetForModify())); + Verify(pIScaler->Initialize(albumArt, NewWidth, NewHeight, WICBitmapInterpolationModeFant)); + Verify(pIScaler->CopyPixels(nullptr, NewWidth * 3, NewWidth * NewHeight * 3, pBits)); + } + catch (...) + { + DeleteObject(ResizedHBmp); + throw; + } + *phbmp = ResizedHBmp; + } + else + { + auto pixels = std::vector(width*height * 3); + Verify(albumArt->CopyPixels(nullptr, width * 3, (UINT)pixels.size(), &pixels.front())); + *phbmp = CreateBitmap(width, height, 1, 24, &pixels.front()); + } + *pdwAlpha = WTSAT_RGB; + return S_OK; +} + + +#include +#include +#include + +#include +#include + +#include +#include +#include + +IFACEMETHODIMP CTagLibPropertyStore::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) { - HRESULT hr = E_OUTOFMEMORY; - CTagLibPropertyStore *pNew = new CTagLibPropertyStore(); - if (pNew) + EventWriteRequestThumbnail(cx); + try { - hr = pNew->QueryInterface(riid, ppv); - SAFE_RELEASE(pNew); + auto ogg = dynamic_cast(taglibfile.tag()); + if (ogg) + for (auto picture : ogg->pictureList()) + if (picture->data().size()) + return ExtractImage(picture->data().data(), picture->data().size(), cx, phbmp, pdwAlpha); + + auto flac = dynamic_cast(&taglibfile); + if (flac) + for (auto picture : flac->pictureList()) + if (picture->data().size()) + return ExtractImage(picture->data().data(), picture->data().size(), cx, phbmp, pdwAlpha); + + auto mpeg = dynamic_cast(&taglibfile); + if (mpeg && mpeg->ID3v2Tag()) // ID3v1 doesn't support album art + for (auto frame : mpeg->ID3v2Tag()->frameListMap()["APIC"]) + { + auto apic = dynamic_cast(frame); + if (apic && apic->picture().size()) + return ExtractImage(apic->picture().data(), apic->picture().size(), cx, phbmp, pdwAlpha); + } + + auto asf = dynamic_cast(taglibfile.tag()); + if (asf) + for (auto picture : asf->attributeListMap()["WM/Picture"]) + if (picture.toPicture().dataSize()) + return ExtractImage(picture.toPicture().picture().data(), picture.toPicture().dataSize(), cx, phbmp, pdwAlpha); + } + catch (const std::exception& err) + { + OutputDebugStringA(err.what()); + EventWriteRequestThumbnail_Error(err.what()); +#if MESSAGE_BOXES + MessageBoxA(0, err.what(), "TagLibHandler fatal error", 0); +#endif + return ERROR_INTERNAL_ERROR; } - return hr; + + EventWriteRequestThumbnail_Error("File format unsupported."); + + return S_FALSE; +} + +HRESULT CTagLibPropertyStore::CreateInstance(REFIID riid, void **ppv) +{ + COMWrapper pNew = new CTagLibPropertyStore(); + return pNew ? pNew->QueryInterface(riid, ppv) : E_OUTOFMEMORY; } HRESULT CTagLibPropertyStore_CreateInstance(REFIID riid, void **ppv) @@ -336,6 +589,10 @@ HRESULT CTagLibPropertyStore::GetCount(__out DWORD *pcProps) HRESULT CTagLibPropertyStore::GetAt(DWORD iProp, __out PROPERTYKEY *pkey) { +#if MESSAGE_BOXES + MessageBoxA(nullptr, "GetAt", "TagLibHandler debug", 0); +#endif + EventWriteGetKey((UCHAR)iProp); return _pCache->GetAt(iProp, pkey); } @@ -358,7 +615,7 @@ HRESULT CTagLibPropertyStore::IsPropertyWritable(REFPROPERTYKEY) return S_FALSE; } -struct IStreamAccessor : public TagLib::FileAccessor +struct IStreamAccessor : public TagLib::IOStream { IStreamAccessor(IStream *stream) : stream(stream) {} IStream *stream; @@ -367,44 +624,41 @@ struct IStreamAccessor : public TagLib::FileAccessor return true; } - size_t fread(void *pv, size_t s1, size_t s2) const + TagLib::ByteVector readBlock(unsigned long length) override { ULONG read = 0; - stream->Read(pv, s1*s2, &read); - return read; + TagLib::ByteVector out((unsigned int)length); + stream->Read(out.data(), length, &read); + return out; } - size_t fwrite(const void *,size_t,size_t) + long length() override { - return 0; - } + ULARGE_INTEGER prevpos, endpos; + LARGE_INTEGER dist = {}; - int fseek(long distance, int direction) - { - LARGE_INTEGER dist; - dist.QuadPart = distance; - return FAILED(stream->Seek(dist, direction, NULL)); // 0 on success. + stream->Seek(dist, STREAM_SEEK_CUR, &prevpos); // record current position + stream->Seek(dist, STREAM_SEEK_END, &endpos); // record end position + stream->Seek(dist, STREAM_SEEK_SET, &prevpos); // return to current position + return (long)endpos.QuadPart; } - void clearError() + void seek(long offset, Position p = Beginning) override { - // Uh oh. + LARGE_INTEGER dist; + dist.QuadPart = offset; + stream->Seek(dist, (DWORD)p, nullptr); } - long tell() const + long tell() const override { ULARGE_INTEGER newpos; LARGE_INTEGER dist = {}; stream->Seek(dist, STREAM_SEEK_CUR, &newpos); - return newpos.QuadPart; - } - - int truncate(long length) - { - return -1; // error + return (long)newpos.QuadPart; } - TagLib::FileNameHandle name() const + TagLib::FileName name() const override { STATSTG a; if (FAILED(stream->Stat(&a, STATFLAG_DEFAULT))) @@ -412,18 +666,47 @@ struct IStreamAccessor : public TagLib::FileAccessor return TagLib::FileName(a.pwcsName); } - bool readOnly() const - { - return true; - } + bool readOnly() const override { return true; } + + // Unsupported write operations + void writeBlock(const TagLib::ByteVector &data) override { } + void insert(const TagLib::ByteVector &data, unsigned long start = 0, unsigned long replace = 0) {} + void truncate(long length) override {} + void removeBlock(unsigned long start = 0, unsigned long length = 0) {} + void clear() override {} }; // Initialize populates the internal value cache with data from the specified stream // S_OK | E_UNEXPECTED | ERROR_READ_FAULT | ERROR_FILE_CORRUPT | ERROR_INTERNAL_ERROR HRESULT CTagLibPropertyStore::Initialize(IStream *pStream, DWORD grfMode) { + if (!taglibfile.isNull()) + HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); + + EventWriteInitWithStream(); + _pStream = pStream; taglibfile = TagLib::FileRef(new IStreamAccessor(pStream)); + if (taglibfile.isNull()) + { + EventWriteInitError(DebugListener::GetLastError().c_str()); return ERROR_FILE_CORRUPT; + } + return S_OK; +} + +IFACEMETHODIMP CTagLibPropertyStore::Initialize(LPCWSTR pszFilePath, DWORD grfMode) +{ + if (!taglibfile.isNull()) + HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); + + EventWriteInitWithFile(pszFilePath); + taglibfile = TagLib::FileRef(pszFilePath); + + if (taglibfile.isNull()) + { + EventWriteInitError(DebugListener::GetLastError().c_str()); + return ERROR_FILE_CORRUPT; + } return S_OK; } diff --git a/TagLibHandler.sln b/TagLibHandler.sln index 7f6e44c..e516319 100644 --- a/TagLibHandler.sln +++ b/TagLibHandler.sln @@ -1,25 +1,51 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TagLibHandler", "TagLibHandler.vcproj", "{DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TagLibHandler", "TagLibHandler.vcxproj", "{DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}" + ProjectSection(ProjectDependencies) = postProject + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} = {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} + {39FC0674-33FB-38DD-8E1C-364E4943FAB1} = {39FC0674-33FB-38DD-8E1C-364E4943FAB1} + EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tlhsetup2", "setup\tlhsetup2.vcproj", "{AD28C3EB-E7CE-45A9-A241-088D1D93164B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tlhsetup2", "setup\tlhsetup2.vcxproj", "{AD28C3EB-E7CE-45A9-A241-088D1D93164B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "propdump", "propdump\propdump.vcproj", "{EC5DAAFF-7257-426D-8346-331DF97A8A15}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "propdump", "propdump\propdump.vcxproj", "{EC5DAAFF-7257-426D-8346-331DF97A8A15}" + ProjectSection(ProjectDependencies) = postProject + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} = {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} + {39FC0674-33FB-38DD-8E1C-364E4943FAB1} = {39FC0674-33FB-38DD-8E1C-364E4943FAB1} + EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exttagtest", "exttagtest\exttagtest.vcproj", "{59364043-893F-4B54-9C34-0B9D35CD4A69}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exttagtest", "exttagtest\exttagtest.vcxproj", "{59364043-893F-4B54-9C34-0B9D35CD4A69}" + ProjectSection(ProjectDependencies) = postProject + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} = {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854} + {39FC0674-33FB-38DD-8E1C-364E4943FAB1} = {39FC0674-33FB-38DD-8E1C-364E4943FAB1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tag", "taglib_build_x64\taglib\tag.vcxproj", "{85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "x86", "x86", "{32F7939D-4C51-4414-8216-CF02594A07FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tag", "taglib_build_x86\taglib\tag.vcxproj", "{39FC0674-33FB-38DD-8E1C-364E4943FAB1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 + MinSizeRel|Win32 = MinSizeRel|Win32 + MinSizeRel|x64 = MinSizeRel|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|Win32.ActiveCfg = Debug|Win32 {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|Win32.Build.0 = Debug|Win32 - {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|x64.ActiveCfg = Debug|x64 - {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|x64.Build.0 = Debug|x64 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|x64.ActiveCfg = Release|x64 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Debug|x64.Build.0 = Release|x64 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.MinSizeRel|Win32.ActiveCfg = Release|Win32 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.MinSizeRel|Win32.Build.0 = Release|Win32 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.MinSizeRel|x64.ActiveCfg = Release|x64 + {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.MinSizeRel|x64.Build.0 = Release|x64 {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Release|Win32.ActiveCfg = Release|Win32 {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Release|Win32.Build.0 = Release|Win32 {DE0C2C95-FBC4-469E-BDEB-7F2CC2B43D82}.Release|x64.ActiveCfg = Release|x64 @@ -27,23 +53,58 @@ Global {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Debug|Win32.ActiveCfg = Debug|Win32 {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Debug|Win32.Build.0 = Debug|Win32 {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Debug|x64.ActiveCfg = Debug|Win32 + {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.MinSizeRel|Win32.ActiveCfg = Release|Win32 + {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.MinSizeRel|x64.ActiveCfg = Release|Win32 {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Release|Win32.ActiveCfg = Release|Win32 {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Release|Win32.Build.0 = Release|Win32 {AD28C3EB-E7CE-45A9-A241-088D1D93164B}.Release|x64.ActiveCfg = Release|Win32 {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Debug|Win32.ActiveCfg = Debug|Win32 {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Debug|Win32.Build.0 = Debug|Win32 - {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Debug|x64.ActiveCfg = Debug|Win32 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Debug|x64.ActiveCfg = Release|x64 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Debug|x64.Build.0 = Release|x64 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.MinSizeRel|Win32.ActiveCfg = Release|Win32 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.MinSizeRel|Win32.Build.0 = Release|Win32 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.MinSizeRel|x64.ActiveCfg = Release|x64 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.MinSizeRel|x64.Build.0 = Release|x64 {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Release|Win32.ActiveCfg = Release|Win32 {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Release|Win32.Build.0 = Release|Win32 - {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Release|x64.ActiveCfg = Release|Win32 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Release|x64.ActiveCfg = Release|x64 + {EC5DAAFF-7257-426D-8346-331DF97A8A15}.Release|x64.Build.0 = Release|x64 {59364043-893F-4B54-9C34-0B9D35CD4A69}.Debug|Win32.ActiveCfg = Debug|Win32 {59364043-893F-4B54-9C34-0B9D35CD4A69}.Debug|Win32.Build.0 = Debug|Win32 - {59364043-893F-4B54-9C34-0B9D35CD4A69}.Debug|x64.ActiveCfg = Debug|Win32 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.Debug|x64.ActiveCfg = Release|x64 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.Debug|x64.Build.0 = Release|x64 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.MinSizeRel|Win32.ActiveCfg = Release|Win32 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.MinSizeRel|Win32.Build.0 = Release|Win32 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.MinSizeRel|x64.ActiveCfg = Release|x64 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.MinSizeRel|x64.Build.0 = Release|x64 {59364043-893F-4B54-9C34-0B9D35CD4A69}.Release|Win32.ActiveCfg = Release|Win32 {59364043-893F-4B54-9C34-0B9D35CD4A69}.Release|Win32.Build.0 = Release|Win32 - {59364043-893F-4B54-9C34-0B9D35CD4A69}.Release|x64.ActiveCfg = Release|Win32 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.Release|x64.ActiveCfg = Release|x64 + {59364043-893F-4B54-9C34-0B9D35CD4A69}.Release|x64.Build.0 = Release|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Debug|Win32.ActiveCfg = Debug|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Debug|x64.ActiveCfg = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Debug|x64.Build.0 = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.MinSizeRel|x64.ActiveCfg = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.MinSizeRel|x64.Build.0 = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Release|Win32.ActiveCfg = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Release|x64.ActiveCfg = RelWithDebInfo|x64 + {85B2642D-E3E4-3B5C-A80D-2FE6C2E2C854}.Release|x64.Build.0 = RelWithDebInfo|x64 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Debug|Win32.ActiveCfg = Debug|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Debug|Win32.Build.0 = Debug|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Debug|x64.ActiveCfg = RelWithDebInfo|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.MinSizeRel|x64.ActiveCfg = RelWithDebInfo|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Release|Win32.ActiveCfg = RelWithDebInfo|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Release|Win32.Build.0 = RelWithDebInfo|Win32 + {39FC0674-33FB-38DD-8E1C-364E4943FAB1}.Release|x64.ActiveCfg = RelWithDebInfo|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {39FC0674-33FB-38DD-8E1C-364E4943FAB1} = {32F7939D-4C51-4414-8216-CF02594A07FF} + EndGlobalSection EndGlobal diff --git a/TagLibHandler.vcproj b/TagLibHandler.vcproj deleted file mode 100644 index 228bca6..0000000 --- a/TagLibHandler.vcproj +++ /dev/null @@ -1,391 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TagLibHandler.vcxproj b/TagLibHandler.vcxproj new file mode 100644 index 0000000..4e61228 --- /dev/null +++ b/TagLibHandler.vcxproj @@ -0,0 +1,234 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {DE0C2C95-FBC4-469e-BDEB-7F2CC2B43D82} + TagLibHandler + Win32Proj + + + + DynamicLibrary + v140 + Unicode + true + + + DynamicLibrary + v140 + Unicode + + + DynamicLibrary + v140 + Unicode + true + + + DynamicLibrary + v140 + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + + + + Disabled + true + EnableFastChecks + MultiThreadedDebug + + $(OutDir)$(ProjectName).pdb + Level4 + EditAndContinue + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + _WINDLL;TAGLIB_STATIC;MESSAGE_BOXES;%(PreprocessorDefinitions) + + + shlwapi.lib;shell32.lib;crypt32.lib;propsys.lib;msxml6.lib;ole32.lib;comsupp.lib;windowscodecs.lib;tag.lib;%(AdditionalDependencies) + TagLibHandler.def + true + Windows + MachineX86 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\Debug + + + copy "$(TargetPath)" "$(ProgramFiles)\TaglibHandler\" + + + + + X64 + + + Disabled + true + EnableFastChecks + MultiThreadedDebugDLL + + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + CompileAsCpp + true + _WINDLL;TAGLIB_STATIC;MESSAGE_BOXES;%(PreprocessorDefinitions) + + + shlwapi.lib;shell32.lib;crypt32.lib;propsys.lib;msxml6.lib;ole32.lib;comsupp.lib;windowscodecs.lib;tag.lib;%(AdditionalDependencies) + TagLibHandler.def + true + Windows + MachineX64 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\Debug + + + copy "$(TargetPath)" "$(ProgramW6432)\TaglibHandler\" + + + + + MaxSpeed + _WINDLL;TAGLIB_STATIC;%(PreprocessorDefinitions) + MultiThreadedDLL + + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + + + shlwapi.lib;shell32.lib;crypt32.lib;propsys.lib;msxml6.lib;ole32.lib;comsupp.lib;windowscodecs.lib;tag.lib;%(AdditionalDependencies) + TagLibHandler.def + true + Windows + true + true + MachineX86 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\RelWithDebInfo + + + copy "$(TargetPath)" "$(ProgramFiles)\TaglibHandler\" + + + + + X64 + + + MaxSpeed + _WINDLL;TAGLIB_STATIC;%(PreprocessorDefinitions) + MultiThreadedDLL + + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + true + + + shlwapi.lib;shell32.lib;crypt32.lib;propsys.lib;msxml6.lib;ole32.lib;comsupp.lib;windowscodecs.lib;tag.lib;%(AdditionalDependencies) + TagLibHandler.def + Windows + true + true + MachineX64 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\RelWithDebInfo + + + copy "$(TargetPath)" "$(ProgramW6432)\TaglibHandler\" + + + + + 4838 + + + + + 4838 + + + + + Document + mc -um "%(FullPath)" + mc -um "%(FullPath)" + mc -um "%(FullPath)" + mc -um "%(FullPath)" + events.rc + events.rc + events.rc + events.rc + Designer + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TagLibHandler.vcxproj.filters b/TagLibHandler.vcxproj.filters new file mode 100644 index 0000000..54915e3 --- /dev/null +++ b/TagLibHandler.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + + \ No newline at end of file diff --git a/events.man b/events.man new file mode 100644 index 0000000..a9ab17b --- /dev/null +++ b/events.man @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/exttag.cpp b/exttag.cpp index d5ab519..5c439e7 100644 --- a/exttag.cpp +++ b/exttag.cpp @@ -6,14 +6,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace TagLib; @@ -151,7 +151,7 @@ unsigned char normaliseRating(int rat) return static_cast(rat*100/255.f); } } - return RATING_UNRATED_SET; + return 0; } unsigned char readrating(const APE::Tag *tag) @@ -159,7 +159,7 @@ unsigned char readrating(const APE::Tag *tag) const StringList& lst = tag->itemListMap()[L"rating"].values(); if (lst.size()) return normaliseRating(lst[0].toInt()); - return RATING_UNRATED_SET; + return 0; } @@ -211,7 +211,7 @@ unsigned char readrating(const Ogg::XiphComment *tag) for (StringList::ConstIterator it = sl.begin(); it != sl.end(); ++it) if (int i = it->toInt()) return normaliseRating(i); - return RATING_UNRATED_SET; + return 0; } std::wstring readalbumArtist(const APE::Tag *tag) @@ -313,7 +313,7 @@ SYSTEMTIME parseDate(const wstrvec_t &vec) for (wstrvec_t::const_iterator it = vec.begin(); it != vec.end(); ++it) // more than just the year, fill it in full. - if (it->size() >= string("xxxx-xx-xx").size()) + if (it->size() >= std::string("xxxx-xx-xx").size()) { try { @@ -603,7 +603,7 @@ std::wstring readpartofset(const Ogg::XiphComment *tag) return readString(tag, "DISCNUMBER"); } -READER_FUNC(unsigned char, rating, return RATING_UNRATED_SET) +READER_FUNC(unsigned char, rating, return 0) READER_FUNC(std::wstring, albumArtist, throw std::domain_error("not good")) READER_FUNC(wstrvec_t, keywords, return wstrvec_t()) READER_FUNC(SYSTEMTIME, releasedate, return SYSTEMTIME()) diff --git a/exttagtest/exttagtest.vcproj b/exttagtest/exttagtest.vcproj deleted file mode 100644 index 9b2ffc5..0000000 --- a/exttagtest/exttagtest.vcproj +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/exttagtest/exttagtest.vcxproj b/exttagtest/exttagtest.vcxproj new file mode 100644 index 0000000..8253809 --- /dev/null +++ b/exttagtest/exttagtest.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {59364043-893F-4B54-9C34-0B9D35CD4A69} + exttagtest + Win32Proj + + + + Application + v140 + Unicode + true + + + Application + v140 + Unicode + true + + + Application + v140 + Unicode + + + Application + v140 + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;TAGLIB_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + Level3 + EditAndContinue + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + + + tag.lib;%(AdditionalDependencies) + true + Console + MachineX86 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\Debug + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;TAGLIB_STATIC;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + + + tag.lib;%(AdditionalDependencies) + true + Console + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\Debug + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;TAGLIB_STATIC;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + + + tag.lib;%(AdditionalDependencies) + true + Console + true + true + MachineX86 + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\RelWithDebInfo + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;TAGLIB_STATIC;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\asf;$(SolutionDir)taglib\flac;$(SolutionDir)taglib\mpeg\id3v2;$(SolutionDir)taglib\mpeg\id3v2\frames;$(SolutionDir)taglib\toolkit;$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)taglib_build_$(Processor_Architecture);$(SolutionDir)boost + + + tag.lib;%(AdditionalDependencies) + true + Console + true + true + $(SolutionDir)taglib_build_$(PlatformTarget)\taglib\RelWithDebInfo + + + + + + + + + + + + + \ No newline at end of file diff --git a/exttagtest/exttagtest.vcxproj.filters b/exttagtest/exttagtest.vcxproj.filters new file mode 100644 index 0000000..5027bf5 --- /dev/null +++ b/exttagtest/exttagtest.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/propdump/propdump.vcproj b/propdump/propdump.vcproj deleted file mode 100644 index fea6133..0000000 --- a/propdump/propdump.vcproj +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/propdump/propdump.vcxproj b/propdump/propdump.vcxproj new file mode 100644 index 0000000..5b5c8fc --- /dev/null +++ b/propdump/propdump.vcxproj @@ -0,0 +1,176 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {EC5DAAFF-7257-426D-8346-331DF97A8A15} + propdump + Win32Proj + + + + Application + v140 + Unicode + true + + + Application + v140 + Unicode + true + + + Application + v140 + Unicode + + + Application + v140 + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + $(SolutionDir)taglib;$(SolutionDir)taglib\toolkit + + + propsys.lib;%(AdditionalDependencies) + true + Console + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\toolkit + + + propsys.lib;%(AdditionalDependencies) + true + Console + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\toolkit + + + propsys.lib;%(AdditionalDependencies) + true + Console + true + true + MachineX86 + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + $(SolutionDir)taglib;$(SolutionDir)taglib\toolkit + + + propsys.lib;%(AdditionalDependencies) + true + Console + true + true + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/propdump/propdump.vcxproj.filters b/propdump/propdump.vcxproj.filters new file mode 100644 index 0000000..a2532e4 --- /dev/null +++ b/propdump/propdump.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/resource.h b/resource.h index 8debb8723a51bc41eb66946b2278e0e7f7882a59..67c7d1caa63962d14001ec6ae2fd9f650ea932b1 100644 GIT binary patch literal 804 zcmb7?TT8=05QWdP;D1=~Q7{(#12OGGuuY{gMW2GbL@T9%T)ZIub@kg_3(<#A88$mR zIdkUhNxnV<1$rkEO_gh?k*-;Z%MwM3Ii>m_j&%e!kkLdNEmf&h%_`JTn^UXR>Rww; zkxmJt2d%YZRn!~y6}1hOC8(CunsY&AOLo?okiq5A3%!A9Kskgk~K0#UGR2CpZoJn<~3~yrRR?O5n z*%clQU9a!h_4LfZhM=ePj&+CUDbI;6sf@|}Tz?1alyxZonVr)!(k&WtS)P=hj4UG0 zQ4+$Ck()m;(76T&Ge@vah>&T+US6XMm~H%zJ>dp3ci%qM23F60s3+b@`z`u;tv_8) O>_574-`Y?5ef|cgIC8uI literal 384 zcmZ|J&1%Ci3&c{vJUoH}cG7K>zWbbQmzGW!!CyZK zMbYKLg=Ba@&X8w0*4JwgMNsO&&TduZWD6kU8(f3$iUY zH-idOCU|j_^|5>wMID5GtPO$myOQH;BP*;$TV*J_v}h6jDv6T^HWOu;a&}AMDUScq ays1QSr<2FnKZy5-0e;>fGinutzwI0NxNr>s diff --git a/setup/tlhsetup2.vcproj b/setup/tlhsetup2.vcproj deleted file mode 100644 index 4a21e35..0000000 --- a/setup/tlhsetup2.vcproj +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/setup/tlhsetup2.vcxproj b/setup/tlhsetup2.vcxproj new file mode 100644 index 0000000..0080202 --- /dev/null +++ b/setup/tlhsetup2.vcxproj @@ -0,0 +1,113 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AD28C3EB-E7CE-45A9-A241-088D1D93164B} + taglibhandlersetup2 + Win32Proj + + + + Application + v140 + Unicode + true + + + Application + v140 + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + $(OutDir)$(ProjectName).pdb + Level3 + EditAndContinue + + + KtmW32.lib;%(AdditionalDependencies) + RequireAdministrator + true + Windows + MachineX86 + + + + + MaxSpeed + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + true + + $(OutDir)$(ProjectName).pdb + Level3 + ProgramDatabase + + + KtmW32.lib;%(AdditionalDependencies) + RequireAdministrator + true + Windows + true + true + MachineX86 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/tlhsetup2.vcxproj.filters b/setup/tlhsetup2.vcxproj.filters new file mode 100644 index 0000000..1d177f1 --- /dev/null +++ b/setup/tlhsetup2.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tlh.rc b/tlh.rc index 9e065cfb9f3368ade6e76025f879fceb3f18477f..e1103fc1ca9a781fd112b0ff241877ccd426fb88 100644 GIT binary patch literal 4022 zcmds)YfBqJ6o${|LjS`yeo-nKqm&j(LCvMXXhdUbp&)9mkS3CisL; z34X9;+05+BxxME$lRv*VZPNlfw60y-&;}Orwrs>&owd+z?b3RD?b~~vz}nWdKJSqA z5o3e3A*1+inO!pv_>#1)-9WQpZ|x0QHr=?wYMGNp~EVP@?;B&cg~M3 z$EkR%+O8Gt+%D_{eWzAM#|iN(u#&e5kL3R12~s(0$T+bQ90faKTyt70tm^BGvBXY* ztZ2p4RjiE0ueQ$KDRg_O6c_9s%wSPI2+^(`!(D?SkGv{Yl+jyfc7WFWKN9UY>NTuB z2aizf;}PL1Oi+kU?-t1CQwDB-51x{fA?jfK%&(pwmK|4+;um>LT)8E6q{-V}THerp zkoi%S$5_(ztdJRfvNg*1h+cL6yj<}fetn(6TOd0m%KjM^dLgE}$t; zrKhe&j>c6|q)Nm+y`#L-y0`;oWpc1ELlcl2>tv08Bidu+SIM6<^0xLY4lljvD!+tv zht%^al^Y=a-nOaminAo@U%uwmn+o)cGjcp>XDlg_ur=Xt(n&-7^fY~Tir(i?lB0@! zk?b98)Uz|@iM>^`?{p>gJfX-v+K;+jlFDnIU%BdyRs1T?WUyf5PE4H-MWWsVSDDDS zh<~z5=1cQ6l$4sakJ$UkA-du>DJkZe*IE3oAM3N%74hstvERhU_*LcI}E2NOm=x7l&v* z#+m`vs-{NRtJCShS=GdDoy+&`4DL@VZoa3Uwl7(;-mV;Xlpdc@mPo+}*fwcGwz47#E@r_*lm7VI1w_4S`(n`q zW_D(F=KE%6RTZ9+InVNJQNS$8HzWn)_7-BwC?^GtfYUtN@HvHi&XaY~MXHK!5;jja z5d~$x+FdFL-9&VeFbev_^8?dz!ztEH*Rfwi@AYZm+Me*e;v+LrRTwp?E_k+rVoAZr zFTUj%c3@)YHx>MsI$3N*_GRK%OiH4&VFHLRP`Ek_fLWX-`4U<|cie3^73YGJWC6b_ zUZR#hd=Z>@ZZI`)XxergK0e@h(buP=5Idu`^piz|&z5u7N4D;a0)2!*env=)nv-}%V4g)ZT$7l#di~#h5s$J+q@t>I#Qg?MuUO8^9b@zA*vJ++>IWer z)H~Jy8sL%TAP~<{Kfh@T!j6eh|Dy5X7${9MDR2CZDOIp0#NEXZ=d5d}L^>k%Pxzo8 zL1;#Ko@A^NEum8G*9tdp9%QJS9h6j(%?d9hEoaylSXL-v*HH`vHSF3H)y>n4~H{#C2g z{QI1+JS9a%qqY^D(}A9Vp$S>ekdq^QaadpX8bampKfQ{6a>#yj58pMnQh5(wdyJhR K%(CLl;QR+YPBTjY