From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/regsvr.c | 197 ++++++++++++++++++ dlls/windowscodecs/windowscodecs_wincodec.idl | 7 + 2 files changed, 204 insertions(+)
diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index f9ba2b083eb..dd08a70d320 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -127,6 +127,26 @@ struct regsvr_metadatareader static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list); static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
+struct regsvr_metadatawriter +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR author; + LPCSTR friendlyname; + LPCSTR version; + LPCSTR specversion; + GUID const *vendor; + GUID const *metadata_format; + DWORD requires_fullstream; + DWORD supports_padding; + DWORD requires_fixedsize; +}; + +static HRESULT register_metadatawriters(struct regsvr_metadatawriter const *list); +static HRESULT unregister_metadatawriters(struct regsvr_metadatawriter const *list); + +static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list); +static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list); + struct regsvr_pixelformat { CLSID const *clsid; /* NULL for end of list */ @@ -936,6 +956,165 @@ error_return: return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; }
+static HRESULT register_metadatawriters(struct regsvr_metadatawriter const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + WCHAR buf[39]; + HKEY readers_key; + HKEY instance_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res == ERROR_SUCCESS) { + StringFromGUID2(&CATID_WICMetadataWriter, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &readers_key, NULL); + if (res == ERROR_SUCCESS) + { + res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + if (res != ERROR_SUCCESS) + RegCloseKey(coclass_key); + } + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + HKEY clsid_key; + HKEY instance_clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); + if (res == ERROR_SUCCESS) { + res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, + (const BYTE*)buf, 78); + RegCloseKey(instance_clsid_key); + } + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + if (list->author) { + res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, + (const BYTE*)list->author, + strlen(list->author) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->friendlyname) { + res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, + (const BYTE*)list->friendlyname, + strlen(list->friendlyname) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->vendor) { + StringFromGUID2(list->vendor, buf, 39); + res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, + (const BYTE*)buf, 78); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->metadata_format) { + StringFromGUID2(list->metadata_format, buf, 39); + res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ, + (const BYTE*)buf, 78); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->version) { + res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, + (const BYTE*)list->version, + strlen(list->version) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->specversion) { + res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ, + (const BYTE*)list->version, + strlen(list->version) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD, + (const BYTE*)&list->requires_fullstream, 4); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD, + (const BYTE*)&list->supports_padding, 4); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + if (list->requires_fixedsize) { + res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD, + (const BYTE*)&list->requires_fixedsize, 4); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(instance_key); + RegCloseKey(readers_key); + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +static HRESULT unregister_metadatawriters(struct regsvr_metadatawriter const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + WCHAR buf[39]; + HKEY readers_key; + HKEY instance_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + + if (res == ERROR_SUCCESS) { + StringFromGUID2(&CATID_WICMetadataWriter, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &readers_key, NULL); + if (res == ERROR_SUCCESS) + { + res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + if (res != ERROR_SUCCESS) + RegCloseKey(coclass_key); + } + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + StringFromGUID2(list->clsid, buf, 39); + + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + res = RegDeleteTreeW(instance_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + +error_close_coclass_key: + RegCloseKey(instance_key); + RegCloseKey(readers_key); + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + /*********************************************************************** * register_pixelformats */ @@ -1902,6 +2081,20 @@ static struct regsvr_metadatareader const metadatareader_list[] = { { NULL } /* list terminator */ };
+static struct regsvr_metadatawriter const metadatawriters_list[] = +{ + { + &CLSID_WICUnknownMetadataWriter, + "The Wine Project", + "Unknown Metadata Writer", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatUnknown, + }, + { NULL } /* list terminator */ +}; + static BYTE const channel_mask_1bit[] = { 0x01 }; static BYTE const channel_mask_2bit[] = { 0x03 }; static BYTE const channel_mask_4bit[] = { 0x0f }; @@ -2394,6 +2587,8 @@ HRESULT WINAPI DllRegisterServer(void) hr = register_converters(converter_list); if (SUCCEEDED(hr)) hr = register_metadatareaders(metadatareader_list); + if (SUCCEEDED(hr)) + hr = register_metadatawriters(metadatawriters_list); if (SUCCEEDED(hr)) hr = register_pixelformats(pixelformat_list); return hr; @@ -2416,6 +2611,8 @@ HRESULT WINAPI DllUnregisterServer(void) hr = unregister_converters(converter_list); if (SUCCEEDED(hr)) hr = unregister_metadatareaders(metadatareader_list); + if (SUCCEEDED(hr)) + hr = unregister_metadatawriters(metadatawriters_list); if (SUCCEEDED(hr)) hr = unregister_pixelformats(pixelformat_list); return hr; diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index 122f6d0e007..1c9955557b6 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -153,6 +153,13 @@ coclass WineTgaDecoder { interface IWICBitmapDecoder; } ] coclass WICUnknownMetadataReader { interface IWICMetadataReader; }
+[ + helpstring("WIC Unknown Metadata Writer"), + threading(both), + uuid(a09cca86-27ba-4f39-9053-121fa4dc08fc) +] +coclass WICUnknownMetadataWriter { interface IWICMetadataWriter; } + [ helpstring("WIC Ifd Metadata Reader"), threading(both),