123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880 |
- #include "main.h"
- #include "WMInformation.h"
- #include "resource.h"
- #include <exception>
- #include <strsafe.h>
- class AutoByte
- {
- public:
- AutoByte(size_t bytes)
- : data(0)
- {
- data = new BYTE[bytes];
- }
- ~AutoByte()
- {
- if (data)
- delete[] data;
- data = 0;
- }
- operator void *()
- {
- return (void *)data;
- }
- BYTE *data;
- };
- static void StoreData(WMT_ATTR_DATATYPE type, BYTE *value, DWORD length, wchar_t *valueStr, size_t len)
- {
- switch (type)
- {
- case WMT_TYPE_DWORD:
- StringCchPrintf(valueStr, len, L"%lu", *(DWORD *)value);
- break;
- case WMT_TYPE_STRING:
- lstrcpyn(valueStr, (wchar_t *)value, len);
- break;
- case -1: // hack // if (attrName == L"WM/Text")
- StringCchPrintf(valueStr, len, L"%s/%s", UserTextDescription(value, length), UserTextString(value, length));
- break;
- case WMT_TYPE_BINARY:
- BinaryString(value, length, valueStr, len);
- break;
- case WMT_TYPE_BOOL:
- if (*(BOOL *)value)
- {
- lstrcpyn(valueStr, L"True", len);
- }
- else
- {
- lstrcpyn(valueStr, L"False", len);
- }
- break;
- case WMT_TYPE_QWORD:
- StringCchPrintf(valueStr, len, L"%I64u", *(QWORD *)value);
- break;
- case WMT_TYPE_WORD:
- StringCchPrintf(valueStr, len, L"%hu", *(WORD *)value);
- break;
- case WMT_TYPE_GUID:
- GuidString(*(GUID *)value, valueStr, len);
- break;
- default:
- WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN,valueStr,len);
- break;
- }
- }
- WMInformation::WMInformation(const wchar_t *fileName, bool noBlock)
- : editor(0), editor2(0), header(0), header3(0), reader(0), header2(0), openError(false)
- {
- if (fileName && fileName[0]
- && WMCreateEditor(&editor) == S_OK)
- {
- if (SUCCEEDED(editor->QueryInterface(&editor2)))
- {
- if (SUCCEEDED(editor2->OpenEx(fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE)))
- {
- // good to go
- editor2->QueryInterface(&header);
- editor->QueryInterface(&header2);
- editor2->QueryInterface(&header3);
- return ;
- }
- }
- else
- {
- editor2 = 0;
- if (SUCCEEDED(editor->Open(fileName)))
- {
- // good to go
- editor->QueryInterface(&header);
- editor->QueryInterface(&header2);
- editor->QueryInterface(&header3);
- return ;
- }
- }
- // can't open it through the metadata editor interface, let's open a reader
- if (editor)
- editor->Release();
- editor = 0;
- if (editor2)
- editor2->Release();
- editor2 = 0;
- if (FAILED(WMCreateReader(0, WMT_RIGHT_PLAYBACK, &reader)))
- {
- reader = 0;
- return ;
- }
- hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- callback >> this;
- if (FAILED(reader->Open(fileName, &callback, 0)))
- {
- reader->Release();
- reader = 0;
- return ;
- }
- if (noBlock)
- WaitForEvent(hEvent, INFINITE);
- else
- WaitForSingleObject(hEvent, INFINITE);
- CloseHandle(hEvent);
- if (openError)
- {
- reader->Release();
- reader = 0;
- }
- else
- {
- reader->QueryInterface(&header);
- reader->QueryInterface(&header2);
- reader->QueryInterface(&header3);
- }
- }
- }
- WMInformation::WMInformation(IWMReader *_reader)
- : reader(0), // reader is if we create an internal reader, we don't want to save the passed one (so we don't close it on someone else :)
- editor(0), editor2(0), header(0),
- header3(0), header2(0),
- openError(false), hEvent(NULL)
- {
- if (FAILED(_reader->QueryInterface(&header)))
- header = 0;
- if (FAILED(_reader->QueryInterface(&header2)))
- header2 = 0;
- if (FAILED(_reader->QueryInterface(&header3)))
- header3 = 0; // this error is OK, we can deal with it.
- }
- /*
- WMInformation::WMInformation(IWMSyncReader *reader)
- : editor(0), editor2(0), header(0), header3(0)
- {
- reader->QueryInterface(&header);
- reader->QueryInterface(&header3);
- }*/
- WMInformation::WMInformation(IWMMetadataEditor *_editor)
- : editor(_editor), editor2(0), header(0),
- header3(0), reader(0), header2(0),
- openError(false), hEvent(NULL)
- {
- editor->AddRef();
- editor->QueryInterface(&editor2);
- editor->QueryInterface(&header);
- editor->QueryInterface(&header2);
- editor->QueryInterface(&header3);
- }
- WMInformation::~WMInformation()
- {
- if (editor)
- {
- editor->Close();
- editor->Release();
- editor = 0;
- }
- if (editor2)
- editor2->Release();
- editor2 = 0;
- if (header)
- header->Release();
- header = 0;
- if (header2)
- header2->Release();
- header2 = 0;
- if (header3)
- header3->Release();
- header3 = 0;
- if (reader)
- {
- reader->Close();
- reader->Release();
- reader = 0;
- }
- }
- bool WMInformation::GetDataType(const wchar_t *name, WMT_ATTR_DATATYPE &type)
- {
- if (!name)
- return false;
- WORD stream = 0;
- WORD dataLen = 0;
- if (header && SUCCEEDED(header->GetAttributeByName(&stream, name, &type, 0, &dataLen)))
- return true;
- else
- return false;
- }
- void WMInformation::DeleteAttribute(const wchar_t *attrName)
- {
- WORD indexCount = 0;
- if (header3 && SUCCEEDED(header3->GetAttributeIndices(0, attrName, NULL, 0, &indexCount)))
- {
- WORD *indices = new WORD[indexCount];
- if (SUCCEEDED(header3->GetAttributeIndices(0, attrName, NULL, indices, &indexCount)))
- {
- for (size_t i = 0;i != indexCount;i++)
- {
- header3->DeleteAttribute(0, indices[i]);
- }
- }
- }
- }
- void WMInformation::SetAttribute_BinString(const wchar_t *attrName, wchar_t *value)
- {
- if (!header || !attrName || !value)
- return ;
- if (!*value)
- {
- DeleteAttribute(attrName);
- return ;
- }
- AutoChar data(value);
- header->SetAttribute(0, attrName, WMT_TYPE_BINARY, (BYTE *)(char *)data, (WORD)strlen(data));
- }
- void WMInformation::GetAttribute_BinString(const wchar_t attrName[], wchar_t *valueStr, size_t len)
- {
- if (!header)
- {
- valueStr[0]=0;
- return ;
- }
- WMT_ATTR_DATATYPE type;
- WORD length = 0;
- HRESULT hr;
- WORD streamNum = 0;
- if (!header || FAILED(header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- 0,
- &length)))
- {
- valueStr[0]=0;
- return ;
- }
- AutoByte v(length);
- BYTE *value = v.data;
- hr = header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- value,
- &length);
- if (FAILED(hr))
- {
- valueStr[0]=0;
- return ;
- }
- int converted = MultiByteToWideChar(CP_ACP, 0, (const char *)value, length, valueStr, len-1);
- valueStr[converted]=0;
- }
- void WMInformation::SetAttribute(const wchar_t *attrName, wchar_t *value, WMT_ATTR_DATATYPE defaultType)
- {
- if (!header || !attrName || !value)
- return ;
- if (!*value)
- {
- DeleteAttribute(attrName);
- return ;
- }
- WMT_ATTR_DATATYPE type;
- if (!GetDataType(attrName, type))
- type = defaultType;
- switch (type)
- {
- case WMT_TYPE_DWORD:
- {
- DWORD dwordValue = wcstoul(value, 0, 10);
- header->SetAttribute(0, attrName, WMT_TYPE_DWORD, (BYTE *) &dwordValue, sizeof(dwordValue));
- }
- break;
- case WMT_TYPE_STRING:
- {
- WORD size = static_cast<WORD>((lstrlen(value) + 1) * sizeof(wchar_t));
- header->SetAttribute(0, attrName, WMT_TYPE_STRING, (BYTE *)value, size);
- }
- break;
- case WMT_TYPE_BINARY:
- {
- // TODO
- }
- break;
- case WMT_TYPE_BOOL:
- {
- BOOL boolValue;
- if (!_wcsicmp(L"true", value))
- boolValue = TRUE;
- else
- boolValue = FALSE;
- header->SetAttribute(0, attrName, WMT_TYPE_BOOL, (BYTE *)&boolValue, sizeof(boolValue));
- }
- break;
- case WMT_TYPE_QWORD:
- {
- {
- QWORD qwordValue = _wcstoui64(value, 0, 10);
- header->SetAttribute(0, attrName, WMT_TYPE_QWORD, (BYTE *) &qwordValue, sizeof(qwordValue));
- }
- }
- break;
- case WMT_TYPE_WORD:
- {
- {
- WORD wordValue = static_cast<WORD>(wcstoul(value, 0, 10));
- header->SetAttribute(0, attrName, WMT_TYPE_WORD, (BYTE *) &wordValue, sizeof(wordValue));
- }
- }
- break;
- case WMT_TYPE_GUID:
- {
- GUID guidValue = StringGUID(value);
- header->SetAttribute(0, attrName, WMT_TYPE_GUID, (BYTE *) &guidValue, sizeof(guidValue));
- }
- break;
- }
- }
- bool WMInformation::GetAttributeSize(const wchar_t *name, size_t &size)
- {
- WORD stream = 0;
- WORD resultSize;
- WMT_ATTR_DATATYPE type;
- if (!header || FAILED(header->GetAttributeByName(&stream, name, &type, 0, &resultSize)))
- {
- return false;
- }
- size = resultSize;
- return true;
- }
- DWORD WMInformation::GetDWORDAttr(const wchar_t name[])
- {
- WORD stream = 0;
- DWORD result;
- WORD resultSizeWord = sizeof(result);
- DWORD resultSize = sizeof(result);
- WMT_ATTR_DATATYPE type = WMT_TYPE_DWORD;
- WORD count = 1;
- WORD indices[1] = {0};
- if ((!header3
- || FAILED(header3->GetAttributeIndices(0, name, NULL, indices, &count))
- || FAILED(header3->GetAttributeByIndexEx(0, indices[0], 0, 0, &type, NULL, (BYTE *) &result, &resultSize)))
- &&
- (!header || FAILED(header->GetAttributeByName(&stream, name, &type, (BYTE *)&result, &resultSizeWord))))
- return 0;
- else
- return result;
- }
- long WMInformation::GetLongAttr(const wchar_t name[])
- {
- WORD stream = 0;
- long result;
- WORD resultSize = sizeof(result);
- WMT_ATTR_DATATYPE type;
- if (!header || FAILED(header->GetAttributeByName(&stream, name, &type, (BYTE *)&result, &resultSize)))
- {
- return 0;
- }
- return result;
- }
- bool WMInformation::GetBoolAttr(const wchar_t name[])
- {
- WORD stream = 0;
- BOOL result;
- WORD resultSize = sizeof(result);
- WMT_ATTR_DATATYPE type;
- if (!header || FAILED(header->GetAttributeByName(&stream, name, &type, (BYTE *)&result, &resultSize)))
- {
- return false;
- }
- return !!result;
- }
- bool WMInformation::IsSeekable()
- {
- return GetBoolAttr(g_wszWMSeekable);
- }
- long WMInformation::GetLengthMilliseconds()
- {
- WORD stream = 0;
- long long duration = 0;
- WORD resultSize = sizeof(duration);
- WMT_ATTR_DATATYPE type;
- if (!header || FAILED(header->GetAttributeByName(&stream, g_wszWMDuration, &type, (BYTE *)&duration, &resultSize)))
- {
- return -1000;
- }
- duration /= 10000LL;
- return (long)duration;
- }
- long WMInformation::GetBitrate()
- {
- return GetDWORDAttr(g_wszWMCurrentBitrate);
- }
- WORD WMInformation::GetNumberAttributes()
- {
- WORD numAttr = 0;
- if ((!header3 || FAILED(header3->GetAttributeCountEx(0, &numAttr)))
- && (!header || FAILED(header->GetAttributeCount(0, &numAttr))))
- return 0;
- else
- return numAttr;
- }
- void WMInformation::GetAttribute(WORD index, wchar_t *attrName, size_t attrLen, wchar_t *valueStr, size_t valueStrLen)
- {
- wchar_t _attrName[1025] = {0};
- WORD nameLen = sizeof(_attrName) / sizeof(_attrName[0]);
- WMT_ATTR_DATATYPE type;
- WORD lang;
- WORD stream = 0;
- DWORD length = 0;
- WORD lengthWord = 0;
- if ((!header3 || FAILED(header3->GetAttributeByIndexEx(0, index, _attrName, &nameLen, &type, &lang, 0, &length)))
- && (!header || FAILED(header->GetAttributeByIndex(index, &stream, _attrName, &nameLen, &type, 0, &lengthWord))))
- {
- attrName[0]=0;
- valueStr[0]=0;
- return ;
- }
- if (lengthWord)
- length = lengthWord;
- AutoByte v(length);
- BYTE *value = v.data;
- lstrcpyn(attrName, _attrName, attrLen);
- if ((!header3 || FAILED(header3->GetAttributeByIndexEx(0, index, _attrName, &nameLen, &type, &lang, value, &length)))
- && (!header || FAILED(header->GetAttributeByIndex(index, &stream, _attrName, &nameLen, &type, value, &lengthWord))))
- {
- attrName[0]=0;
- valueStr[0]=0;
- return ;
- }
- if (attrName == L"WM/Text")
- {
- type = (WMT_ATTR_DATATYPE)-1; // hack
- StringCchCat(attrName, attrLen, L":");
- StringCchCat(attrName, attrLen, UserTextDescription(value, length));
- }
- StoreData(type, value, length, valueStr, valueStrLen);
- }
- void WMInformation::GetAttribute(const wchar_t attrName[], wchar_t *valueStr, size_t len)
- {
- if (!header)
- {
- valueStr[0]=0;
- return ;
- }
- WMT_ATTR_DATATYPE type;
- WORD length = 0;
- HRESULT hr;
- WORD streamNum = 0;
- if (!header || FAILED(header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- 0,
- &length)))
- {
- valueStr[0]=0;
- return ;
- }
- AutoByte v(length);
- BYTE *value = v.data;
- hr = header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- value,
- &length);
- if (FAILED(hr))
- {
- valueStr[0]=0;
- return ;
- }
- if (attrName == L"WM/Text")
- type = (WMT_ATTR_DATATYPE)-1; // hack
- StoreData(type, value, length, valueStr, len);
- }
- bool WMInformation::MakeWritable(const wchar_t *fileName)
- {
- if (!editor || !editor2)
- return false;
- if (FAILED(editor2->OpenEx(fileName, GENERIC_READ | GENERIC_WRITE, 0)))
- {
- return false;
- }
- return true;
- }
- bool WMInformation::Flush()
- {
- if (!editor2 || FAILED(editor->Flush()))
- return false;
- return true;
- }
- bool WMInformation::IsAttribute(const wchar_t attrName[])
- {
- WMT_ATTR_DATATYPE type = WMT_TYPE_BOOL;
- WORD length = sizeof(BOOL);
- WORD streamNum = 0;
- BOOL value;
- if (!header || FAILED(header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- (BYTE *)&value,
- &length)))
- {
- return false;
- }
- else
- {
- return !!value;
- }
- }
- bool WMInformation::IsNotAttribute(const wchar_t attrName[])
- {
- if (!header)
- {
- return false;
- }
- WMT_ATTR_DATATYPE type = WMT_TYPE_BOOL;
- WORD length = sizeof(BOOL);
- WORD streamNum = 0;
- BOOL value;
- if (!header || FAILED(header->GetAttributeByName(&streamNum,
- attrName,
- &type,
- (BYTE *)&value,
- &length)))
- {
- return false;
- }
- else
- {
- return !value;
- }
- }
- bool WMInformation::MakeReadOnly(const wchar_t *fileName)
- {
- if (!editor || !editor2)
- return false;
- //editor->Close();
- if (FAILED(editor2->OpenEx(fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE)))
- {
- return false;
- }
- return true;
- }
- bool WMInformation::NonWritable()
- {
- if (!editor2)
- return true;
- else
- return false;
- }
- void WMInformation::DeleteUserText(const wchar_t *description)
- {
- WORD indexCount = 0;
- WMT_ATTR_DATATYPE type = WMT_TYPE_BOOL;
- WORD nameLen = 128;
- if (header3 && SUCCEEDED(header3->GetAttributeIndices(0, L"WM/Text", NULL, 0, &indexCount)))
- {
- WORD *indices = new WORD[indexCount];
- if (SUCCEEDED(header3->GetAttributeIndices(0, L"WM/Text", NULL, indices, &indexCount)))
- {
- for (size_t index = 0;index != indexCount;index++)
- {
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD lang = 0;
- DWORD length = 0;
- wchar_t _attrName[128] = L"WM/Text";
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, 0, &length)))
- {
- AutoByte v(length);
- BYTE *value = v.data;
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, value, &length)))
- {
- if (UserTextDescription(value, length) == description)
- {
- header3->DeleteAttribute(0, indices[index]);
- }
- }
- }
- }
- }
- }
- }
- void WMInformation::SetUserText(const wchar_t *description, const wchar_t *valueStr)
- {
- if (!header3 || !description || !valueStr)
- return;
- WM_USER_TEXT userText;
- userText.pwszDescription = (LPWSTR)description;
- userText.pwszText = (LPWSTR) valueStr;
- WORD index;
- header3->AddAttribute(0, L"WM/Text", &index, WMT_TYPE_BINARY, 0, (BYTE *) &userText, sizeof(userText));
- }
- void WMInformation::ClearAllAttributes()
- {
- WORD numAttrs;
- header3->GetAttributeCountEx(0xFFFF, &numAttrs);
- while (numAttrs--)
- {
- header3->DeleteAttribute(0xFFFF, numAttrs);
- }
- }
- bool WMInformation::GetCodecName(wchar_t *storage, size_t len)
- {
- if (!header2)
- return false;
- DWORD codecs=0;
- header2->GetCodecInfoCount(&codecs);
- for (DWORD i=0;i!=codecs;i++)
- {
- WORD nameLen=0, descriptionLen=0, infoLen = 0;
- WMT_CODEC_INFO_TYPE type;
- header2->GetCodecInfo(i, &nameLen, 0, &descriptionLen, 0, &type, &infoLen, 0);
- if (type == WMT_CODECINFO_AUDIO)
- {
- wchar_t *name = new wchar_t[nameLen];
- wchar_t *description = new wchar_t[descriptionLen];
- BYTE *info = new BYTE[infoLen];
- header2->GetCodecInfo(i, &nameLen, name, &descriptionLen, description, &type, &infoLen, info);
- lstrcpynW(storage, name, len);
- delete[] name;
- delete[]description;
- delete[] info;
- return true;
- }
- }
- return false;
- }
- bool WMInformation::GetPicture(void **data, size_t *len, wchar_t **mimeType, int pictype)
- {
- WORD indexCount = 0;
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD nameLen = 128;
- if (header3 && SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, 0, &indexCount)))
- {
- WORD *indices = new WORD[indexCount];
- if (SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, indices, &indexCount)))
- {
- for (size_t index = 0;index != indexCount;index++)
- {
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD lang = 0;
- DWORD length = 0;
- wchar_t _attrName[128] = {0};
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, 0, &length)))
- {
- AutoByte v(length);
- BYTE *value = v.data;
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, value, &length)))
- {
- WM_PICTURE *picture = (WM_PICTURE *)value;
- if (picture->bPictureType == pictype)
- {
- *len = picture->dwDataLen;
- *data = WASABI_API_MEMMGR->sysMalloc(*len);
- memcpy(*data, picture->pbData, *len);
- wchar_t *type=0;
- if (picture->pwszMIMEType)
- type = wcschr(picture->pwszMIMEType, L'/');
- if (type && *type)
- {
- type++;
- wchar_t *type2 = wcschr(type, L'/');
- if (type2 && *type2) type2++;
- else type2 = type;
- size_t mimelen = wcslen(type2)+1;
- *mimeType = (wchar_t *)WASABI_API_MEMMGR->sysMalloc(mimelen*sizeof(wchar_t));
- StringCchCopyW(*mimeType, mimelen, type2);
- }
- else
- *mimeType = 0; // unknown!
- delete[] indices;
- return true;
- }
- }
- }
- }
- }
- delete[] indices;
- }
- return false;
- }
- bool WMInformation::SetPicture(void *data, size_t len, const wchar_t *mimeType, int type)
- {
- WM_PICTURE picture;
- picture.bPictureType = type;
- picture.dwDataLen = len;
- picture.pbData = (BYTE *)data;
- picture.pwszDescription=L"";
- wchar_t mt[32] = {0};
- if (wcsstr(mimeType, L"/") != 0)
- {
- StringCchCopyW(mt, 32, mimeType);
- }
- else
- {
- StringCchPrintfW(mt, 32, L"image/%s", mimeType);
- }
- picture.pwszMIMEType = mt;
- return SUCCEEDED(header->SetAttribute(0, g_wszWMPicture, WMT_TYPE_BINARY, (const BYTE *)&picture, sizeof(picture)));
- }
- bool WMInformation::HasPicture(int pictype)
- {
- WORD indexCount = 0;
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD nameLen = 128;
- if (header3 && SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, 0, &indexCount)))
- {
- WORD *indices = new WORD[indexCount];
- if (SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, indices, &indexCount)))
- {
- for (size_t index = 0;index != indexCount;index++)
- {
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD lang = 0;
- DWORD length = 0;
- wchar_t _attrName[128] = {0};
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, 0, &length)))
- {
- AutoByte v(length);
- BYTE *value = v.data;
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, value, &length)))
- {
- WM_PICTURE *picture = (WM_PICTURE *)value;
- if (picture->bPictureType == pictype)
- {
- delete[] indices;
- return true;
- }
- }
- }
- }
- }
- delete[] indices;
- }
- return false;
- }
- bool WMInformation::DeletePicture(int pictype)
- {
- WORD indexCount = 0;
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD nameLen = 128;
- if (header3 && SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, 0, &indexCount)))
- {
- WORD *indices = new WORD[indexCount];
- if (SUCCEEDED(header3->GetAttributeIndices(0, g_wszWMPicture, NULL, indices, &indexCount)))
- {
- for (size_t index = 0;index != indexCount;index++)
- {
- WMT_ATTR_DATATYPE type = WMT_TYPE_BINARY;
- WORD lang = 0;
- DWORD length = 0;
- wchar_t _attrName[128] = {0};
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, 0, &length)))
- {
- AutoByte v(length);
- BYTE *value = v.data;
- if (SUCCEEDED(header3->GetAttributeByIndexEx(0, indices[index], _attrName, &nameLen, &type, &lang, value, &length)))
- {
- WM_PICTURE *picture = (WM_PICTURE *)value;
- if (picture->bPictureType == pictype)
- {
- header3->DeleteAttribute(0, indices[index]);
- delete[] indices;
- return true;
- }
- }
- }
- }
- }
- delete[] indices;
- }
- return false;
- }
|