mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 12:23:28 +00:00
- Sync rsaenh, schannel, shlwapi, sti, urlmon, usp10, version, windowscodecs, wininet, wintrust to Wine-1.1.43.
- Update README.WINE. svn path=/trunk/; revision=46967
This commit is contained in:
@@ -36,7 +36,7 @@ LpkDllInitialize (
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hDll);
|
||||
/* Tell usp10 it is activated usp10 */
|
||||
LpkPresent();
|
||||
//LpkPresent();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -3354,6 +3354,33 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
|
||||
setup_key(pCryptKey);
|
||||
return TRUE;
|
||||
|
||||
case KP_SALT:
|
||||
switch (pCryptKey->aiAlgid) {
|
||||
case CALG_RC2:
|
||||
case CALG_RC4:
|
||||
if (!pbData)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
/* MSDN: the base provider always sets eleven bytes of
|
||||
* salt value.
|
||||
*/
|
||||
memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen,
|
||||
pbData, 11);
|
||||
pCryptKey->dwSaltLen = 11;
|
||||
setup_key(pCryptKey);
|
||||
/* Strange but true: salt length reset to 0 after setting
|
||||
* it via KP_SALT.
|
||||
*/
|
||||
pCryptKey->dwSaltLen = 0;
|
||||
break;
|
||||
default:
|
||||
SetLastError(NTE_BAD_KEY);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case KP_SALT_EX:
|
||||
{
|
||||
CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData;
|
||||
@@ -3486,8 +3513,16 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
|
||||
pCryptKey->dwBlockLen);
|
||||
|
||||
case KP_SALT:
|
||||
return copy_param(pbData, pdwDataLen,
|
||||
&pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen);
|
||||
switch (pCryptKey->aiAlgid) {
|
||||
case CALG_RC2:
|
||||
case CALG_RC4:
|
||||
return copy_param(pbData, pdwDataLen,
|
||||
&pCryptKey->abKeyValue[pCryptKey->dwKeyLen],
|
||||
pCryptKey->dwSaltLen);
|
||||
default:
|
||||
SetLastError(NTE_BAD_KEY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case KP_PADDING:
|
||||
dwValue = PKCS5_PADDING;
|
||||
|
||||
@@ -273,7 +273,7 @@ static const char sha2_hex_digits[] = "0123456789abcdef";
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void SHA256_Init(SHA256_CTX* context) {
|
||||
if (context == (SHA256_CTX*)0) {
|
||||
if (context == NULL) {
|
||||
return;
|
||||
}
|
||||
MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
|
||||
@@ -465,7 +465,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
||||
}
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
|
||||
assert(context != NULL && data != NULL);
|
||||
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
@@ -490,7 +490,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
||||
}
|
||||
while (len >= SHA256_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA256_Transform(context, (sha2_word32*)data);
|
||||
SHA256_Transform(context, (const sha2_word32*)data);
|
||||
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
||||
len -= SHA256_BLOCK_LENGTH;
|
||||
data += SHA256_BLOCK_LENGTH;
|
||||
@@ -509,10 +509,10 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
unsigned int usedspace;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA256_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_byte*)0) {
|
||||
if (digest != NULL) {
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
/* Convert FROM host byte order */
|
||||
@@ -572,9 +572,9 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) {
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA256_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
if (buffer != NULL) {
|
||||
SHA256_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||
@@ -582,7 +582,7 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) {
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
*buffer = 0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(context));
|
||||
}
|
||||
@@ -601,7 +601,7 @@ char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_S
|
||||
|
||||
/*** SHA-512: *********************************************************/
|
||||
void SHA512_Init(SHA512_CTX* context) {
|
||||
if (context == (SHA512_CTX*)0) {
|
||||
if (context == NULL) {
|
||||
return;
|
||||
}
|
||||
MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
|
||||
@@ -787,7 +787,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
||||
}
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
|
||||
assert(context != NULL && data != NULL);
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
@@ -812,7 +812,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
||||
}
|
||||
while (len >= SHA512_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA512_Transform(context, (sha2_word64*)data);
|
||||
SHA512_Transform(context, (const sha2_word64*)data);
|
||||
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
||||
len -= SHA512_BLOCK_LENGTH;
|
||||
data += SHA512_BLOCK_LENGTH;
|
||||
@@ -871,10 +871,10 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
sha2_word64 *d = (sha2_word64*)digest;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_byte*)0) {
|
||||
if (digest != NULL) {
|
||||
SHA512_Last(context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
@@ -901,9 +901,9 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) {
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
if (buffer != NULL) {
|
||||
SHA512_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
|
||||
@@ -911,7 +911,7 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) {
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
*buffer = 0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(context));
|
||||
}
|
||||
@@ -930,7 +930,7 @@ char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_S
|
||||
|
||||
/*** SHA-384: *********************************************************/
|
||||
void SHA384_Init(SHA384_CTX* context) {
|
||||
if (context == (SHA384_CTX*)0) {
|
||||
if (context == NULL) {
|
||||
return;
|
||||
}
|
||||
MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
|
||||
@@ -946,10 +946,10 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
|
||||
sha2_word64 *d = (sha2_word64*)digest;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA384_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_byte*)0) {
|
||||
if (digest != NULL) {
|
||||
SHA512_Last((SHA512_CTX*)context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
@@ -976,9 +976,9 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) {
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA384_CTX*)0);
|
||||
assert(context != NULL);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
if (buffer != NULL) {
|
||||
SHA384_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
|
||||
@@ -986,7 +986,7 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) {
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
*buffer = 0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(context));
|
||||
}
|
||||
|
||||
@@ -109,6 +109,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] =
|
||||
NULL, /* SetExtendedInformation */
|
||||
NULL, /* SetContextAttributes */
|
||||
NULL, /* SetCredentialsAttributes */
|
||||
NULL, /* ChangeAccountPassword */
|
||||
NULL, /* QueryMetaData */
|
||||
NULL, /* ExchangeMetaData */
|
||||
NULL, /* GetCredUIContext */
|
||||
NULL, /* UpdateCredentials */
|
||||
NULL, /* ValidateTargetInfo */
|
||||
}, {
|
||||
NULL, /* InitializePackage */
|
||||
NULL, /* LsaLogonUser */
|
||||
@@ -139,6 +145,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] =
|
||||
NULL, /* SetExtendedInformation */
|
||||
NULL, /* SetContextAttributes */
|
||||
NULL, /* SetCredentialsAttributes */
|
||||
NULL, /* ChangeAccountPassword */
|
||||
NULL, /* QueryMetaData */
|
||||
NULL, /* ExchangeMetaData */
|
||||
NULL, /* GetCredUIContext */
|
||||
NULL, /* UpdateCredentials */
|
||||
NULL, /* ValidateTargetInfo */
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,7 +162,7 @@ NTSTATUS WINAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG PackageVersion,
|
||||
{
|
||||
TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables);
|
||||
|
||||
*PackageVersion = SECPKG_INTERFACE_VERSION_3;
|
||||
*PackageVersion = SECPKG_INTERFACE_VERSION_6;
|
||||
*pcTables = 2;
|
||||
*ppTables = secPkgFunctionTable;
|
||||
|
||||
|
||||
+229
-147
@@ -42,6 +42,7 @@
|
||||
#include "mmsystem.h"
|
||||
#include "objbase.h"
|
||||
#include "exdisp.h"
|
||||
#include "shdeprecated.h"
|
||||
#include "shlobj.h"
|
||||
#include "shlwapi.h"
|
||||
#include "shellapi.h"
|
||||
@@ -309,24 +310,22 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
BSTR property;
|
||||
IEnumFORMATETC* pIEnumFormatEtc = NULL;
|
||||
VARIANTARG var;
|
||||
HRESULT hRet;
|
||||
IWebBrowserApp* pBrowser = NULL;
|
||||
HRESULT hr;
|
||||
IWebBrowserApp* pBrowser;
|
||||
|
||||
TRACE("(%p, %p)\n", lpBC, lpUnknown);
|
||||
|
||||
/* Get An IWebBrowserApp interface from lpUnknown */
|
||||
hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
|
||||
if (FAILED(hRet) || !pBrowser)
|
||||
return E_NOINTERFACE;
|
||||
hr = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (void**)&pBrowser);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
|
||||
/* The property we get is the browsers clipboard enumerator */
|
||||
property = SysAllocString(szProperty);
|
||||
hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var);
|
||||
hr = IWebBrowserApp_GetProperty(pBrowser, property, &var);
|
||||
SysFreeString(property);
|
||||
if (FAILED(hRet))
|
||||
return hRet;
|
||||
if (FAILED(hr)) goto exit;
|
||||
|
||||
if (V_VT(&var) == VT_EMPTY)
|
||||
{
|
||||
@@ -340,7 +339,10 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
|
||||
if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
|
||||
"Version\\Internet Settings\\Accepted Documents", &hDocs))
|
||||
return E_FAIL;
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get count of values in key */
|
||||
while (!dwRet)
|
||||
@@ -355,7 +357,11 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
/* Note: dwCount = number of items + 1; The extra item is the end node */
|
||||
format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
|
||||
if (!formatList)
|
||||
return E_OUTOFMEMORY;
|
||||
{
|
||||
RegCloseKey(hDocs);
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (dwNumValues > 1)
|
||||
{
|
||||
@@ -372,7 +378,12 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
|
||||
(PBYTE)szValueBuff, &dwValueSize);
|
||||
if (!dwRet)
|
||||
return E_FAIL;
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, formatList);
|
||||
RegCloseKey(hDocs);
|
||||
hr = E_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
format->cfFormat = RegisterClipboardFormatA(szValueBuff);
|
||||
format->ptd = NULL;
|
||||
@@ -385,6 +396,8 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hDocs);
|
||||
|
||||
/* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
|
||||
format->cfFormat = 0;
|
||||
format->ptd = NULL;
|
||||
@@ -393,22 +406,21 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
format->tymed = -1;
|
||||
|
||||
/* Create a clipboard enumerator */
|
||||
hRet = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
|
||||
|
||||
if (FAILED(hRet) || !pIEnumFormatEtc)
|
||||
return hRet;
|
||||
hr = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
|
||||
HeapFree(GetProcessHeap(), 0, formatList);
|
||||
if (FAILED(hr)) goto exit;
|
||||
|
||||
/* Set our enumerator as the browsers property */
|
||||
V_VT(&var) = VT_UNKNOWN;
|
||||
V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
|
||||
|
||||
property = SysAllocString(szProperty);
|
||||
hRet = IWebBrowserApp_PutProperty(pBrowser, property, var);
|
||||
hr = IWebBrowserApp_PutProperty(pBrowser, property, var);
|
||||
SysFreeString(property);
|
||||
if (FAILED(hRet))
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IEnumFORMATETC_Release(pIEnumFormatEtc);
|
||||
goto RegisterDefaultAcceptHeaders_Exit;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,28 +434,26 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
|
||||
|
||||
/* Get an IEnumFormatEtc interface from the variants value */
|
||||
pIEnumFormatEtc = NULL;
|
||||
hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
|
||||
(PVOID)&pIEnumFormatEtc);
|
||||
if (hRet == S_OK && pIEnumFormatEtc)
|
||||
hr = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC, (void**)&pIEnumFormatEtc);
|
||||
if (hr == S_OK && pIEnumFormatEtc)
|
||||
{
|
||||
/* Clone and register the enumerator */
|
||||
hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
|
||||
if (hRet == S_OK && pClone)
|
||||
hr = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
|
||||
if (hr == S_OK && pClone)
|
||||
{
|
||||
RegisterFormatEnumerator(lpBC, pClone, 0);
|
||||
|
||||
IEnumFORMATETC_Release(pClone);
|
||||
}
|
||||
|
||||
/* Release the IEnumFormatEtc interface */
|
||||
IEnumFORMATETC_Release(pIUnknown);
|
||||
}
|
||||
IUnknown_Release(V_UNKNOWN(&var));
|
||||
}
|
||||
|
||||
RegisterDefaultAcceptHeaders_Exit:
|
||||
exit:
|
||||
IWebBrowserApp_Release(pBrowser);
|
||||
return hRet;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -500,7 +510,7 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Did not find a value in the registry or the user buffer is to small */
|
||||
/* Did not find a value in the registry or the user buffer is too small */
|
||||
mylcid = GetUserDefaultLCID();
|
||||
retval = LcidToRfc1766W(mylcid, mystr, mystrlen);
|
||||
len = lstrlenW(mystr);
|
||||
@@ -1201,7 +1211,7 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.169]
|
||||
*
|
||||
* Release an interface.
|
||||
* Release an interface and zero a supplied pointer.
|
||||
*
|
||||
* PARAMS
|
||||
* lpUnknown [I] Object to release
|
||||
@@ -1209,19 +1219,16 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f
|
||||
* RETURNS
|
||||
* Nothing.
|
||||
*/
|
||||
DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
|
||||
void WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
|
||||
{
|
||||
IUnknown *temp;
|
||||
TRACE("(%p)\n", lpUnknown);
|
||||
|
||||
TRACE("(%p)\n",lpUnknown);
|
||||
|
||||
if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
|
||||
temp = *lpUnknown;
|
||||
*lpUnknown = NULL;
|
||||
if(!lpUnknown || !*lpUnknown) return;
|
||||
|
||||
TRACE("doing Release\n");
|
||||
|
||||
return IUnknown_Release(temp);
|
||||
IUnknown_Release(*lpUnknown);
|
||||
*lpUnknown = NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -1258,9 +1265,10 @@ LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
|
||||
*/
|
||||
BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
|
||||
{
|
||||
LPVOID lpUnknown1, lpUnknown2;
|
||||
IUnknown *lpUnknown1, *lpUnknown2;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("%p %p\n", lpInt1, lpInt2);
|
||||
TRACE("(%p %p)\n", lpInt1, lpInt2);
|
||||
|
||||
if (!lpInt1 || !lpInt2)
|
||||
return FALSE;
|
||||
@@ -1268,16 +1276,21 @@ BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
|
||||
if (lpInt1 == lpInt2)
|
||||
return TRUE;
|
||||
|
||||
if (FAILED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown, &lpUnknown1)))
|
||||
if (IUnknown_QueryInterface(lpInt1, &IID_IUnknown, (void**)&lpUnknown1) != S_OK)
|
||||
return FALSE;
|
||||
|
||||
if (FAILED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown, &lpUnknown2)))
|
||||
if (IUnknown_QueryInterface(lpInt2, &IID_IUnknown, (void**)&lpUnknown2) != S_OK)
|
||||
{
|
||||
IUnknown_Release(lpUnknown1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpUnknown1 == lpUnknown2)
|
||||
return TRUE;
|
||||
ret = lpUnknown1 == lpUnknown2;
|
||||
|
||||
return FALSE;
|
||||
IUnknown_Release(lpUnknown1);
|
||||
IUnknown_Release(lpUnknown2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -1337,36 +1350,32 @@ HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.173]
|
||||
*
|
||||
* Call a method on as as yet unidentified object.
|
||||
* Call a SetOwner method of IShellService from specified object.
|
||||
*
|
||||
* PARAMS
|
||||
* pUnk [I] Object supporting the unidentified interface,
|
||||
* arg [I] Argument for the call on the object.
|
||||
* iface [I] Object that supports IShellService
|
||||
* pUnk [I] Argument for the SetOwner call
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK.
|
||||
* Corresponding return value from last call or E_FAIL for null input
|
||||
*/
|
||||
HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
|
||||
HRESULT WINAPI IUnknown_SetOwner(IUnknown *iface, IUnknown *pUnk)
|
||||
{
|
||||
static const GUID guid_173 = {
|
||||
0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
|
||||
};
|
||||
IMalloc *pUnk2;
|
||||
IShellService *service;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%d)\n", pUnk, arg);
|
||||
TRACE("(%p, %p)\n", iface, pUnk);
|
||||
|
||||
/* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
|
||||
* We use this interface as its vtable entry is compatible with the
|
||||
* object in question.
|
||||
* FIXME: Find out what this object is and where it should be defined.
|
||||
*/
|
||||
if (pUnk &&
|
||||
SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
|
||||
if (!iface) return E_FAIL;
|
||||
|
||||
hr = IUnknown_QueryInterface(iface, &IID_IShellService, (void**)&service);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
|
||||
IMalloc_Release(pUnk2);
|
||||
hr = IShellService_SetOwner(service, pUnk);
|
||||
IShellService_Release(service);
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -1473,7 +1482,6 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri
|
||||
if (!lpUnknown)
|
||||
return E_FAIL;
|
||||
|
||||
/* Get an IServiceProvider interface from the object */
|
||||
hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
|
||||
(LPVOID*)&pService);
|
||||
|
||||
@@ -1486,12 +1494,92 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri
|
||||
|
||||
TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
|
||||
|
||||
/* Release the IServiceProvider interface */
|
||||
IUnknown_Release(pService);
|
||||
}
|
||||
return hRet;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.484]
|
||||
*
|
||||
* Calls IOleCommandTarget::Exec() for specified service object.
|
||||
*
|
||||
* PARAMS
|
||||
* lpUnknown [I] Object to get an IServiceProvider interface from
|
||||
* service [I] Service ID for IServiceProvider_QueryService() call
|
||||
* group [I] Group ID for IOleCommandTarget::Exec() call
|
||||
* cmdId [I] Command ID for IOleCommandTarget::Exec() call
|
||||
* cmdOpt [I] Options flags for command
|
||||
* pIn [I] Input arguments for command
|
||||
* pOut [O] Output arguments for command
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. lppOut contains an object providing the requested service
|
||||
* Failure: An HRESULT error code
|
||||
*
|
||||
* NOTES
|
||||
* lpUnknown is expected to support the IServiceProvider interface.
|
||||
*/
|
||||
HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *lpUnknown, REFIID service,
|
||||
const GUID *group, DWORD cmdId, DWORD cmdOpt, VARIANT *pIn, VARIANT *pOut)
|
||||
{
|
||||
IOleCommandTarget *target;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p %s %s %d %08x %p %p\n", lpUnknown, debugstr_guid(service),
|
||||
debugstr_guid(group), cmdId, cmdOpt, pIn, pOut);
|
||||
|
||||
hr = IUnknown_QueryService(lpUnknown, service, &IID_IOleCommandTarget, (void**)&target);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IOleCommandTarget_Exec(target, group, cmdId, cmdOpt, pIn, pOut);
|
||||
IOleCommandTarget_Release(target);
|
||||
}
|
||||
|
||||
TRACE("<-- hr=0x%08x\n", hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.514]
|
||||
*
|
||||
* Calls IProfferService methods to proffer/revoke specified service.
|
||||
*
|
||||
* PARAMS
|
||||
* lpUnknown [I] Object to get an IServiceProvider interface from
|
||||
* service [I] Service ID for IProfferService::Proffer/Revoke calls
|
||||
* pService [I] Service to proffer. If NULL ::Revoke is called
|
||||
* pCookie [IO] Group ID for IOleCommandTarget::Exec() call
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. IProffer method returns S_OK
|
||||
* Failure: An HRESULT error code
|
||||
*
|
||||
* NOTES
|
||||
* lpUnknown is expected to support the IServiceProvider interface.
|
||||
*/
|
||||
HRESULT WINAPI IUnknown_ProfferService(IUnknown *lpUnknown, REFGUID service, IServiceProvider *pService, DWORD *pCookie)
|
||||
{
|
||||
IProfferService *proffer;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p %s %p %p\n", lpUnknown, debugstr_guid(service), pService, pCookie);
|
||||
|
||||
hr = IUnknown_QueryService(lpUnknown, &IID_IProfferService, &IID_IProfferService, (void**)&proffer);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
if (pService)
|
||||
hr = IProfferService_ProfferService(proffer, service, pService, pCookie);
|
||||
else
|
||||
hr = IProfferService_RevokeService(proffer, *pCookie);
|
||||
|
||||
IProfferService_Release(proffer);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.479]
|
||||
*
|
||||
@@ -1546,6 +1634,8 @@ BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
|
||||
{
|
||||
HMENU hMenu;
|
||||
|
||||
TRACE("%p %s\n", hInst, debugstr_w(szName));
|
||||
|
||||
if ((hMenu = LoadMenuW(hInst, szName)))
|
||||
{
|
||||
if (GetSubMenu(hMenu, 0))
|
||||
@@ -1629,6 +1719,9 @@ void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lP
|
||||
DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
|
||||
{
|
||||
int iItemCount = GetMenuItemCount(hMenu) - 1;
|
||||
|
||||
TRACE("%p\n", hMenu);
|
||||
|
||||
while (iItemCount >= 0)
|
||||
{
|
||||
HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
|
||||
@@ -1654,6 +1747,7 @@ DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
|
||||
*/
|
||||
UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
|
||||
{
|
||||
TRACE("%p, %u, %d\n", hMenu, wItemID, bEnable);
|
||||
return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
|
||||
}
|
||||
|
||||
@@ -1672,6 +1766,7 @@ UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
|
||||
*/
|
||||
DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
|
||||
{
|
||||
TRACE("%p, %u, %d\n", hMenu, uID, bCheck);
|
||||
return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
|
||||
}
|
||||
|
||||
@@ -1703,6 +1798,8 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
|
||||
DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
|
||||
POINTL pt = { 0, 0 };
|
||||
|
||||
TRACE("%p %p 0x%08x %p %p\n", pDrop, pDataObj, grfKeyState, lpPt, pdwEffect);
|
||||
|
||||
if (!lpPt)
|
||||
lpPt = &pt;
|
||||
|
||||
@@ -1711,7 +1808,7 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
|
||||
|
||||
IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
|
||||
|
||||
if (*pdwEffect)
|
||||
if (*pdwEffect != DROPEFFECT_NONE)
|
||||
return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
|
||||
|
||||
IDropTarget_DragLeave(pDrop);
|
||||
@@ -1803,7 +1900,7 @@ HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus)
|
||||
IOleControlSite* lpCSite = NULL;
|
||||
HRESULT hRet = E_FAIL;
|
||||
|
||||
TRACE("(%p,%s)\n", lpUnknown, fGotFocus ? "TRUE" : "FALSE");
|
||||
TRACE("(%p, %d)\n", lpUnknown, fGotFocus);
|
||||
if (lpUnknown)
|
||||
{
|
||||
hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
|
||||
@@ -2061,12 +2158,10 @@ VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
|
||||
{
|
||||
TRACE("(%p,%p)\n", lppDest, lpUnknown);
|
||||
|
||||
if (lppDest)
|
||||
IUnknown_AtomicRelease(lppDest); /* Release existing interface */
|
||||
IUnknown_AtomicRelease(lppDest);
|
||||
|
||||
if (lpUnknown)
|
||||
{
|
||||
/* Copy */
|
||||
IUnknown_AddRef(lpUnknown);
|
||||
*lppDest = lpUnknown;
|
||||
}
|
||||
@@ -2256,12 +2351,6 @@ BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
REFIID refid;
|
||||
DWORD indx;
|
||||
} IFACE_INDEX_TBL;
|
||||
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.219]
|
||||
*
|
||||
@@ -2272,22 +2361,22 @@ typedef struct {
|
||||
* Failure: E_POINTER or E_NOINTERFACE.
|
||||
*/
|
||||
HRESULT WINAPI QISearch(
|
||||
LPVOID w, /* [in] Table of interfaces */
|
||||
IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
|
||||
void *base, /* [in] Table of interfaces */
|
||||
const QITAB *table, /* [in] Array of REFIIDs and indexes into the table */
|
||||
REFIID riid, /* [in] REFIID to get interface for */
|
||||
LPVOID *ppv) /* [out] Destination for interface pointer */
|
||||
void **ppv) /* [out] Destination for interface pointer */
|
||||
{
|
||||
HRESULT ret;
|
||||
IUnknown *a_vtbl;
|
||||
IFACE_INDEX_TBL *xmove;
|
||||
const QITAB *xmove;
|
||||
|
||||
TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
|
||||
TRACE("(%p %p %s %p)\n", base, table, debugstr_guid(riid), ppv);
|
||||
if (ppv) {
|
||||
xmove = x;
|
||||
while (xmove->refid) {
|
||||
TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
|
||||
if (IsEqualIID(riid, xmove->refid)) {
|
||||
a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
|
||||
xmove = table;
|
||||
while (xmove->piid) {
|
||||
TRACE("trying (offset %d) %s\n", xmove->dwOffset, debugstr_guid(xmove->piid));
|
||||
if (IsEqualIID(riid, xmove->piid)) {
|
||||
a_vtbl = (IUnknown*)(xmove->dwOffset + (LPBYTE)base);
|
||||
TRACE("matched, returning (%p)\n", a_vtbl);
|
||||
*ppv = a_vtbl;
|
||||
IUnknown_AddRef(a_vtbl);
|
||||
@@ -2297,7 +2386,7 @@ HRESULT WINAPI QISearch(
|
||||
}
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown)) {
|
||||
a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
|
||||
a_vtbl = (IUnknown*)(table->dwOffset + (LPBYTE)base);
|
||||
TRACE("returning first for IUnknown (%p)\n", a_vtbl);
|
||||
*ppv = a_vtbl;
|
||||
IUnknown_AddRef(a_vtbl);
|
||||
@@ -2506,27 +2595,27 @@ HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
|
||||
* dwExStyle [I] Extra style flags
|
||||
* dwStyle [I] Style flags
|
||||
* hMenu [I] Window menu
|
||||
* z [I] Unknown
|
||||
* wnd_extra [I] Window extra bytes value
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The window handle of the newly created window.
|
||||
* Failure: 0.
|
||||
*/
|
||||
HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
|
||||
DWORD dwStyle, HMENU hMenu, LONG z)
|
||||
DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
|
||||
{
|
||||
static const char szClass[] = "WorkerA";
|
||||
WNDCLASSA wc;
|
||||
HWND hWnd;
|
||||
|
||||
TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
|
||||
wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
|
||||
TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n",
|
||||
wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
|
||||
|
||||
/* Create Window class */
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = DefWindowProcA;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 4;
|
||||
wc.cbWndExtra = sizeof(LONG_PTR);
|
||||
wc.hInstance = shlwapi_hInstance;
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
|
||||
@@ -2534,19 +2623,17 @@ HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = szClass;
|
||||
|
||||
SHRegisterClassA(&wc); /* Register class */
|
||||
|
||||
/* FIXME: Set extra bits in dwExStyle */
|
||||
SHRegisterClassA(&wc);
|
||||
|
||||
hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
|
||||
hWndParent, hMenu, shlwapi_hInstance, 0);
|
||||
if (hWnd)
|
||||
{
|
||||
SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
|
||||
SetWindowLongPtrW(hWnd, 0, wnd_extra);
|
||||
|
||||
if (wndProc)
|
||||
SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
|
||||
if (wndProc) SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
|
||||
}
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
@@ -2729,7 +2816,7 @@ BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
|
||||
*/
|
||||
BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
|
||||
{
|
||||
return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id));
|
||||
return SUCCEEDED(CLSIDFromString((LPCOLESTR)idstr, id));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -2804,18 +2891,21 @@ DWORD WINAPI WhichPlatform(void)
|
||||
* Unicode version of SHCreateWorkerWindowA.
|
||||
*/
|
||||
HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
|
||||
DWORD dwStyle, HMENU hMenu, LONG z)
|
||||
DWORD dwStyle, HMENU hMenu, LONG msg_result)
|
||||
{
|
||||
static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
|
||||
static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 };
|
||||
WNDCLASSW wc;
|
||||
HWND hWnd;
|
||||
|
||||
TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
|
||||
wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
|
||||
TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n",
|
||||
wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result);
|
||||
|
||||
/* If our OS is natively ASCII, use the ASCII version */
|
||||
if (!(GetVersion() & 0x80000000)) /* NT */
|
||||
return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
|
||||
/* If our OS is natively ANSI, use the ANSI version */
|
||||
if (GetVersion() & 0x80000000) /* not NT */
|
||||
{
|
||||
TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion());
|
||||
return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result);
|
||||
}
|
||||
|
||||
/* Create Window class */
|
||||
wc.style = 0;
|
||||
@@ -2829,19 +2919,17 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = szClass;
|
||||
|
||||
SHRegisterClassW(&wc); /* Register class */
|
||||
|
||||
/* FIXME: Set extra bits in dwExStyle */
|
||||
SHRegisterClassW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
|
||||
hWndParent, hMenu, shlwapi_hInstance, 0);
|
||||
if (hWnd)
|
||||
{
|
||||
SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
|
||||
SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, msg_result);
|
||||
|
||||
if (wndProc)
|
||||
SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
|
||||
if (wndProc) SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
|
||||
}
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
@@ -2861,7 +2949,8 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle
|
||||
*/
|
||||
HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
|
||||
{
|
||||
return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
|
||||
TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl);
|
||||
return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -3376,12 +3465,12 @@ UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
|
||||
HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
|
||||
{
|
||||
IContextMenu *iContext;
|
||||
HRESULT hRet = E_FAIL;
|
||||
HRESULT hRet;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
|
||||
TRACE("(%p, %p, %p, %d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
|
||||
|
||||
if (!lpFolder)
|
||||
return hRet;
|
||||
return E_FAIL;
|
||||
|
||||
/* Get the context menu from the shell folder */
|
||||
hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
|
||||
@@ -3401,7 +3490,7 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST
|
||||
if (SUCCEEDED(hQuery))
|
||||
{
|
||||
if (bInvokeDefault &&
|
||||
(dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
|
||||
(dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != (UINT)-1)
|
||||
{
|
||||
CMINVOKECOMMANDINFO cmIci;
|
||||
/* Invoke the default item */
|
||||
@@ -3810,7 +3899,7 @@ DWORD WINAPI SHSendMessageBroadcastW(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
*/
|
||||
HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
|
||||
{
|
||||
return CLSIDFromString((LPOLESTR)idstr, id);
|
||||
return CLSIDFromString((LPCOLESTR)idstr, id);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -4171,18 +4260,24 @@ BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
|
||||
*/
|
||||
INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
|
||||
{
|
||||
MENUITEMINFOW mi;
|
||||
INT nCount = GetMenuItemCount(hMenu), nIter = 0;
|
||||
MENUITEMINFOW mi;
|
||||
INT nCount = GetMenuItemCount(hMenu), nIter = 0;
|
||||
|
||||
while (nIter < nCount)
|
||||
{
|
||||
mi.cbSize = sizeof(mi);
|
||||
mi.fMask = MIIM_ID;
|
||||
if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
|
||||
return nIter;
|
||||
nIter++;
|
||||
}
|
||||
return -1;
|
||||
TRACE("%p %u\n", hMenu, wID);
|
||||
|
||||
while (nIter < nCount)
|
||||
{
|
||||
mi.cbSize = sizeof(mi);
|
||||
mi.fMask = MIIM_ID;
|
||||
if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
|
||||
{
|
||||
TRACE("ret %d\n", nIter);
|
||||
return nIter;
|
||||
}
|
||||
nIter++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -4192,6 +4287,7 @@ INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
|
||||
*/
|
||||
DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
|
||||
{
|
||||
TRACE("%p %u\n", hMenu, uID);
|
||||
return GetMenuPosFromID(hMenu, uID);
|
||||
}
|
||||
|
||||
@@ -4270,10 +4366,10 @@ BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
|
||||
/***********************************************************************
|
||||
* SHGetShellKey (SHLWAPI.@)
|
||||
*/
|
||||
DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
|
||||
HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create)
|
||||
{
|
||||
FIXME("(%x, %x, %x): stub\n", a, b, c);
|
||||
return 0x50;
|
||||
FIXME("(0x%08x, %s, %d): stub\n", flags, debugstr_w(sub_key), create);
|
||||
return (HKEY)0x50;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -4422,20 +4518,6 @@ INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText,
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
|
||||
DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
|
||||
{
|
||||
FIXME("%p %s %s %08x %08x %08x %p\n", unk,
|
||||
debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
|
||||
{
|
||||
FIXME("%p %p %p %p\n", unk, x0, x1, x2);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ZoneComputePaneSize [SHLWAPI.382]
|
||||
*/
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long)
|
||||
217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr)
|
||||
218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr long)
|
||||
219 stdcall -noname QISearch(long long long long)
|
||||
219 stdcall QISearch(long long long long)
|
||||
220 stdcall -noname SHSetDefaultDialogFont(ptr long)
|
||||
221 stdcall -noname SHRemoveDefaultDialogFont(ptr)
|
||||
222 stdcall -noname SHGlobalCounterCreate(long)
|
||||
|
||||
@@ -278,7 +278,8 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD EscapeFlags;
|
||||
LPWSTR lpszUrlCpy, wk1, wk2, mp, mp2, root;
|
||||
LPCWSTR wk1, root;
|
||||
LPWSTR lpszUrlCpy, wk2, mp, mp2;
|
||||
INT state;
|
||||
DWORD nByteLen, nLen, nWkLen;
|
||||
WCHAR slash = '/';
|
||||
@@ -322,7 +323,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||
* 6 have location (found /) save root location
|
||||
*/
|
||||
|
||||
wk1 = (LPWSTR)pszUrl;
|
||||
wk1 = pszUrl;
|
||||
wk2 = lpszUrlCpy;
|
||||
state = 0;
|
||||
|
||||
@@ -662,7 +663,7 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative,
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a '#' and the characters immediately preceeding it are
|
||||
/* If there is a '#' and the characters immediately preceding it are
|
||||
* ".htm[l]", then begin looking for the last leaf starting from
|
||||
* the '#'. Otherwise the '#' is not meaningful and just start
|
||||
* looking from the end. */
|
||||
@@ -1718,6 +1719,9 @@ BOOL WINAPI UrlIsA(LPCSTR pszUrl, URLIS Urlis)
|
||||
|
||||
TRACE("(%s %d)\n", debugstr_a(pszUrl), Urlis);
|
||||
|
||||
if(!pszUrl)
|
||||
return FALSE;
|
||||
|
||||
switch (Urlis) {
|
||||
|
||||
case URLIS_OPAQUE:
|
||||
@@ -1768,6 +1772,9 @@ BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
|
||||
|
||||
TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis);
|
||||
|
||||
if(!pszUrl)
|
||||
return FALSE;
|
||||
|
||||
switch (Urlis) {
|
||||
|
||||
case URLIS_OPAQUE:
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -31,6 +30,7 @@
|
||||
#include "objbase.h"
|
||||
#include "initguid.h"
|
||||
#include "sti.h"
|
||||
#include "wia_lh.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
@@ -395,8 +395,11 @@ static struct regsvr_interface const interface_list[] = {
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
extern HRESULT WINAPI STI_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI STI_DllUnregisterServer(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (INETCOMM.@)
|
||||
* DllRegisterServer (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
@@ -404,14 +407,16 @@ HRESULT WINAPI DllRegisterServer(void)
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hr = register_coclasses(coclass_list);
|
||||
hr = STI_DllRegisterServer();
|
||||
if (SUCCEEDED(hr))
|
||||
hr = register_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = register_interfaces(interface_list);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (INETCOMM.@)
|
||||
* DllUnregisterServer (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
@@ -422,5 +427,7 @@ HRESULT WINAPI DllUnregisterServer(void)
|
||||
hr = unregister_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = unregister_interfaces(interface_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = STI_DllUnregisterServer();
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Aric Stewart for CodeWeavers
|
||||
* Copyright (C) 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winerror.h"
|
||||
#include "objbase.h"
|
||||
#include "sti.h"
|
||||
|
||||
#include "sti_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sti);
|
||||
|
||||
static const WCHAR registeredAppsLaunchPath[] = {
|
||||
'S','O','F','T','W','A','R','E','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'S','t','i','l','l','I','m','a','g','e','\\',
|
||||
'R','e','g','i','s','t','e','r','e','d',' ','A','p','p','l','i','c','a','t','i','o','n','s',0
|
||||
};
|
||||
|
||||
static inline stillimage *impl_from_StillImageW(IStillImageW *iface)
|
||||
{
|
||||
return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpVtbl));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_QueryInterface(IStillImageW *iface, REFIID riid, void **ppvObject)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
|
||||
return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject);
|
||||
}
|
||||
|
||||
static ULONG WINAPI stillimagew_AddRef(IStillImageW *iface)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
return IUnknown_AddRef(This->pUnkOuter);
|
||||
}
|
||||
|
||||
static ULONG WINAPI stillimagew_Release(IStillImageW *iface)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
return IUnknown_Release(This->pUnkOuter);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_Initialize(IStillImageW *iface, HINSTANCE hinst, DWORD dwVersion)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
TRACE("(%p, %p, 0x%X)\n", This, hinst, dwVersion);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_GetDeviceList(IStillImageW *iface, DWORD dwType, DWORD dwFlags,
|
||||
DWORD *pdwItemsReturned, LPVOID *ppBuffer)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %u, 0x%X, %p, %p): stub\n", This, dwType, dwFlags, pdwItemsReturned, ppBuffer);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_GetDeviceInfo(IStillImageW *iface, LPWSTR pwszDeviceName,
|
||||
LPVOID *ppBuffer)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), ppBuffer);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_CreateDevice(IStillImageW *iface, LPWSTR pwszDeviceName, DWORD dwMode,
|
||||
PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %u, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), dwMode, pDevice, pUnkOuter);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_GetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
|
||||
LPDWORD pType, LPBYTE pData, LPDWORD cbData)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %s, %p, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
|
||||
pType, pData, cbData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_SetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
|
||||
DWORD type, LPBYTE pData, DWORD cbData)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %s, %u, %p, %u): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
|
||||
type, pData, cbData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_GetSTILaunchInformation(IStillImageW *iface, LPWSTR pwszDeviceName,
|
||||
DWORD *pdwEventCode, LPWSTR pwszEventName)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %p, %p, %p): stub\n", This, pwszDeviceName,
|
||||
pdwEventCode, pwszEventName);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_RegisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName,
|
||||
LPWSTR pwszCommandLine)
|
||||
{
|
||||
static const WCHAR format[] = {'%','s',' ','%','s',0};
|
||||
static const WCHAR commandLineSuffix[] = {
|
||||
'/','S','t','i','D','e','v','i','c','e',':','%','1',' ',
|
||||
'/','S','t','i','E','v','e','n','t',':','%','2',0};
|
||||
HKEY registeredAppsKey = NULL;
|
||||
DWORD ret;
|
||||
HRESULT hr = S_OK;
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
|
||||
TRACE("(%p, %s, %s)\n", This, debugstr_w(pwszAppName), debugstr_w(pwszCommandLine));
|
||||
|
||||
ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, ®isteredAppsKey);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
WCHAR *value = HeapAlloc(GetProcessHeap(), 0,
|
||||
(lstrlenW(pwszCommandLine) + 1 + lstrlenW(commandLineSuffix) + 1) * sizeof(WCHAR));
|
||||
if (value)
|
||||
{
|
||||
sprintfW(value, format, pwszCommandLine, commandLineSuffix);
|
||||
ret = RegSetValueExW(registeredAppsKey, pwszAppName, 0,
|
||||
REG_SZ, (BYTE*)value, (lstrlenW(value)+1)*sizeof(WCHAR));
|
||||
if (ret != ERROR_SUCCESS)
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
HeapFree(GetProcessHeap(), 0, value);
|
||||
}
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
RegCloseKey(registeredAppsKey);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_UnregisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
HKEY registeredAppsKey = NULL;
|
||||
DWORD ret;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%p, %s)\n", This, debugstr_w(pwszAppName));
|
||||
|
||||
ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, ®isteredAppsKey);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
ret = RegDeleteValueW(registeredAppsKey, pwszAppName);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
RegCloseKey(registeredAppsKey);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_EnableHwNotifications(IStillImageW *iface, LPCWSTR pwszDeviceName,
|
||||
BOOL bNewState)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %u): stub\n", This, debugstr_w(pwszDeviceName), bNewState);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_GetHwNotificationState(IStillImageW *iface, LPCWSTR pwszDeviceName,
|
||||
BOOL *pbCurrentState)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), pbCurrentState);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_RefreshDeviceBus(IStillImageW *iface, LPCWSTR pwszDeviceName)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s): stub\n", This, debugstr_w(pwszDeviceName));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_LaunchApplicationForDevice(IStillImageW *iface, LPWSTR pwszDeviceName,
|
||||
LPWSTR pwszAppName, LPSTINOTIFY pStiNotify)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %s, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pwszAppName),
|
||||
pStiNotify);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_SetupDeviceParameters(IStillImageW *iface, PSTI_DEVICE_INFORMATIONW pDevInfo)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %p): stub\n", This, pDevInfo);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI stillimagew_WriteToErrorLog(IStillImageW *iface, DWORD dwMessageType, LPCWSTR pszMessage)
|
||||
{
|
||||
stillimage *This = impl_from_StillImageW(iface);
|
||||
FIXME("(%p, %u, %s): stub\n", This, dwMessageType, debugstr_w(pszMessage));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const struct IStillImageWVtbl stillimagew_vtbl =
|
||||
{
|
||||
stillimagew_QueryInterface,
|
||||
stillimagew_AddRef,
|
||||
stillimagew_Release,
|
||||
stillimagew_Initialize,
|
||||
stillimagew_GetDeviceList,
|
||||
stillimagew_GetDeviceInfo,
|
||||
stillimagew_CreateDevice,
|
||||
stillimagew_GetDeviceValue,
|
||||
stillimagew_SetDeviceValue,
|
||||
stillimagew_GetSTILaunchInformation,
|
||||
stillimagew_RegisterLaunchApplication,
|
||||
stillimagew_UnregisterLaunchApplication,
|
||||
stillimagew_EnableHwNotifications,
|
||||
stillimagew_GetHwNotificationState,
|
||||
stillimagew_RefreshDeviceBus,
|
||||
stillimagew_LaunchApplicationForDevice,
|
||||
stillimagew_SetupDeviceParameters,
|
||||
stillimagew_WriteToErrorLog
|
||||
};
|
||||
|
||||
static inline stillimage *impl_from_InternalUnknown(IUnknown *iface)
|
||||
{
|
||||
return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpInternalUnkVtbl));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Internal_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
|
||||
{
|
||||
stillimage *This = impl_from_InternalUnknown(iface);
|
||||
|
||||
TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown))
|
||||
*ppvObject = iface;
|
||||
else if (IsEqualGUID(riid, &IID_IStillImageW))
|
||||
*ppvObject = &This->lpVtbl;
|
||||
else
|
||||
{
|
||||
if (IsEqualGUID(riid, &IID_IStillImageA))
|
||||
FIXME("interface IStillImageA is unsupported on Windows Vista too, please report if it's needed\n");
|
||||
else
|
||||
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*) *ppvObject);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Internal_AddRef(IUnknown *iface)
|
||||
{
|
||||
stillimage *This = impl_from_InternalUnknown(iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI Internal_Release(IUnknown *iface)
|
||||
{
|
||||
ULONG ref;
|
||||
stillimage *This = impl_from_InternalUnknown(iface);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static const struct IUnknownVtbl internal_unk_vtbl =
|
||||
{
|
||||
Internal_QueryInterface,
|
||||
Internal_AddRef,
|
||||
Internal_Release
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* StiCreateInstanceA (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
FIXME("(%p, %u, %p, %p): stub, unimplemented on Windows Vista too, please report if it's needed\n", hinst, dwVer, ppSti, pUnkOuter);
|
||||
return STG_E_UNIMPLEMENTEDFUNCTION;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* StiCreateInstanceW (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
stillimage *This;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p, %u, %p, %p)\n", hinst, dwVer, ppSti, pUnkOuter);
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(stillimage));
|
||||
if (This)
|
||||
{
|
||||
This->lpVtbl = &stillimagew_vtbl;
|
||||
This->lpInternalUnkVtbl = &internal_unk_vtbl;
|
||||
if (pUnkOuter)
|
||||
This->pUnkOuter = pUnkOuter;
|
||||
else
|
||||
This->pUnkOuter = (IUnknown*) &This->lpInternalUnkVtbl;
|
||||
This->ref = 1;
|
||||
|
||||
hr = IStillImage_Initialize((IStillImageW*) &This->lpVtbl, hinst, dwVer);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (pUnkOuter)
|
||||
*ppSti = (IStillImageW*) &This->lpInternalUnkVtbl;
|
||||
else
|
||||
*ppSti = (IStillImageW*) &This->lpVtbl;
|
||||
}
|
||||
}
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
return hr;
|
||||
}
|
||||
@@ -8,11 +8,29 @@
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<redefine name="_WIN32_WINNT">0x600</redefine>
|
||||
<define name="__WINESRC__" />
|
||||
<define name="ENTRY_PREFIX">STI_</define>
|
||||
<define name="PROXY_DELEGATION" />
|
||||
<define name="REGISTER_PROXY_DLL" />
|
||||
|
||||
<file>regsvr.c</file>
|
||||
<file>sti.c</file>
|
||||
<file>sti_main.c</file>
|
||||
<file>sti_wia.idl</file>
|
||||
<library>wine</library>
|
||||
<library>advapi32</library>
|
||||
<library>sti_proxy</library>
|
||||
<library>ole32</library>
|
||||
<library>oleaut32</library>
|
||||
<library>rpcrt4</library>
|
||||
<library>advapi32</library>
|
||||
<library>pseh</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
</module>
|
||||
<module name="sti_proxy" type="rpcproxy" allowwarnings="true">
|
||||
<define name="__WINESRC__" />
|
||||
<define name="ENTRY_PREFIX">STI_</define>
|
||||
<define name="REGISTER_PROXY_DLL"/>
|
||||
<define name="PROXY_DELEGATION" />
|
||||
<file>sti_wia.idl</file>
|
||||
</module>
|
||||
</group>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ stub DllCanUnloadNow
|
||||
@ stub DllGetClassObject
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
||||
@ stdcall StiCreateInstance(ptr long ptr ptr)
|
||||
@ stdcall StiCreateInstance(ptr long ptr ptr) StiCreateInstanceW
|
||||
@ stdcall StiCreateInstanceA(ptr long ptr ptr)
|
||||
@ stdcall StiCreateInstanceW(ptr long ptr ptr)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Aric Stewart for CodeWeavers
|
||||
* Copyright (C) 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,31 +19,148 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winerror.h"
|
||||
#include "objbase.h"
|
||||
#include "sti.h"
|
||||
|
||||
/******************************************************************************
|
||||
* StiCreateInstance (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI StiCreateInstance( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sti);
|
||||
|
||||
extern HRESULT WINAPI STI_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
|
||||
extern BOOL WINAPI STI_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef HRESULT (*fnCreateInstance)(REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
return STG_E_UNIMPLEMENTEDFUNCTION;
|
||||
const struct IClassFactoryVtbl *vtbl;
|
||||
fnCreateInstance pfnCreateInstance;
|
||||
} sti_cf;
|
||||
|
||||
static inline sti_cf *impl_from_IClassFactory( IClassFactory *iface )
|
||||
{
|
||||
return (sti_cf *)((char *)iface - FIELD_OFFSET( sti_cf, vtbl ));
|
||||
}
|
||||
|
||||
static HRESULT sti_create( REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj )
|
||||
{
|
||||
if (pUnkOuter != NULL && !IsEqualIID(riid, &IID_IUnknown))
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown))
|
||||
return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, pUnkOuter);
|
||||
else if (IsEqualGUID(riid, &IID_IStillImageW))
|
||||
return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, NULL);
|
||||
else if (IsEqualGUID(riid, &IID_IStillImageA))
|
||||
return StiCreateInstanceA(GetCurrentProcess(), STI_VERSION_REAL, (PSTIA*) ppObj, NULL);
|
||||
else
|
||||
{
|
||||
FIXME("no interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sti_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj )
|
||||
{
|
||||
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IClassFactory))
|
||||
{
|
||||
IClassFactory_AddRef( iface );
|
||||
*ppobj = iface;
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sti_cf_AddRef( IClassFactory *iface )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI sti_cf_Release( IClassFactory *iface )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sti_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter,
|
||||
REFIID riid, LPVOID *ppobj )
|
||||
{
|
||||
sti_cf *This = impl_from_IClassFactory( iface );
|
||||
HRESULT r;
|
||||
IUnknown *punk;
|
||||
|
||||
TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj);
|
||||
|
||||
*ppobj = NULL;
|
||||
|
||||
r = This->pfnCreateInstance( riid, pOuter, (LPVOID *)&punk );
|
||||
if (FAILED(r))
|
||||
return r;
|
||||
|
||||
r = IUnknown_QueryInterface( punk, riid, ppobj );
|
||||
if (FAILED(r))
|
||||
return r;
|
||||
|
||||
IUnknown_Release( punk );
|
||||
return r;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sti_cf_LockServer( IClassFactory *iface, BOOL dolock )
|
||||
{
|
||||
FIXME("(%p)->(%d)\n", iface, dolock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const struct IClassFactoryVtbl sti_cf_vtbl =
|
||||
{
|
||||
sti_cf_QueryInterface,
|
||||
sti_cf_AddRef,
|
||||
sti_cf_Release,
|
||||
sti_cf_CreateInstance,
|
||||
sti_cf_LockServer
|
||||
};
|
||||
|
||||
static sti_cf the_sti_cf = { &sti_cf_vtbl, sti_create };
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved);
|
||||
|
||||
if (fdwReason == DLL_WINE_PREATTACH)
|
||||
return FALSE;
|
||||
return STI_DllMain(hInstDLL, fdwReason, lpvReserved);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* StiCreateInstanceA (STI.@)
|
||||
* DllGetClassObject (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI StiCreateInstanceA( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
|
||||
HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
|
||||
{
|
||||
return STG_E_UNIMPLEMENTEDFUNCTION;
|
||||
IClassFactory *cf = NULL;
|
||||
|
||||
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
|
||||
|
||||
if (IsEqualGUID( rclsid, &CLSID_Sti ))
|
||||
{
|
||||
cf = (IClassFactory *)&the_sti_cf.vtbl;
|
||||
}
|
||||
|
||||
if (cf)
|
||||
return IClassFactory_QueryInterface( cf, iid, ppv );
|
||||
return STI_DllGetClassObject( rclsid, iid, ppv );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* StiCreateInstanceW (STI.@)
|
||||
* DllCanUnloadNow (STI.@)
|
||||
*/
|
||||
HRESULT WINAPI StiCreateInstanceW( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
|
||||
HRESULT WINAPI DllCanUnloadNow( void )
|
||||
{
|
||||
return STG_E_UNIMPLEMENTEDFUNCTION;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* STI private definitions
|
||||
*
|
||||
* Copyright 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __STI_PRIVATE__
|
||||
#define __STI_PRIVATE__
|
||||
|
||||
typedef struct _stillimage
|
||||
{
|
||||
const struct IStillImageWVtbl *lpVtbl;
|
||||
const struct IUnknownVtbl *lpInternalUnkVtbl;
|
||||
IUnknown *pUnkOuter;
|
||||
LONG ref;
|
||||
} stillimage;
|
||||
|
||||
#endif /* __STI_PRIVATE__ */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wia_lh.idl"
|
||||
@@ -155,7 +155,7 @@ HWND get_notif_hwnd(void)
|
||||
NULL
|
||||
};
|
||||
|
||||
wndclass.hInstance = URLMON_hInstance;
|
||||
wndclass.hInstance = hProxyDll;
|
||||
|
||||
wnd_class = RegisterClassExW(&wndclass);
|
||||
if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS)
|
||||
@@ -164,7 +164,7 @@ HWND get_notif_hwnd(void)
|
||||
|
||||
tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow,
|
||||
wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE,
|
||||
NULL, URLMON_hInstance, NULL);
|
||||
NULL, hProxyDll, NULL);
|
||||
if(tls_data->notif_hwnd)
|
||||
tls_data->notif_hwnd_cnt++;
|
||||
|
||||
|
||||
@@ -560,7 +560,7 @@ static HRESULT register_inf(BOOL doregister)
|
||||
hAdvpack = LoadLibraryW(wszAdvpack);
|
||||
pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
|
||||
|
||||
hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
|
||||
hres = pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
|
||||
|
||||
for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
|
||||
heap_free(pse[i].pszValue);
|
||||
|
||||
@@ -34,7 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
LONG URLMON_refCount = 0;
|
||||
|
||||
HINSTANCE URLMON_hInstance = 0;
|
||||
static HMODULE hCabinet = NULL;
|
||||
static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
|
||||
|
||||
@@ -144,9 +143,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
|
||||
URLMON_DllMain( hinstDLL, fdwReason, fImpLoad );
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
URLMON_hInstance = hinstDLL;
|
||||
init_session(TRUE);
|
||||
break;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
extern HINSTANCE URLMON_hInstance;
|
||||
extern HINSTANCE hProxyDll DECLSPEC_HIDDEN;
|
||||
extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
@@ -48,6 +48,7 @@ extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
|
||||
extern BOOL WINAPI URLMON_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI URLMON_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI URLMON_DllUnregisterServer(void) DECLSPEC_HIDDEN;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009 Piotr Caban for Codeweavers
|
||||
* Copyright 2009 Piotr Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009 Piotr Caban for Codeweavers
|
||||
* Copyright 2009 Piotr Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -0,0 +1,893 @@
|
||||
/*
|
||||
* Uniscribe BiDirectional handling
|
||||
*
|
||||
* Copyright 2003 Shachar Shemesh
|
||||
* Copyright 2007 Maarten Lankhorst
|
||||
* Copyright 2010 CodeWeavers, Aric Stewart
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* Code derived from the modified reference implementation
|
||||
* that was found in revision 17 of http://unicode.org/reports/tr9/
|
||||
* "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
|
||||
*
|
||||
* -- Copyright (C) 1999-2005, ASMUS, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of the Unicode data files and any associated documentation (the
|
||||
* "Data Files") or Unicode software and any associated documentation (the
|
||||
* "Software") to deal in the Data Files or Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, and/or sell copies of the Data Files or Software,
|
||||
* and to permit persons to whom the Data Files or Software are furnished
|
||||
* to do so, provided that (a) the above copyright notice(s) and this
|
||||
* permission notice appear with all copies of the Data Files or Software,
|
||||
* (b) both the above copyright notice(s) and this permission notice appear
|
||||
* in associated documentation, and (c) there is clear notice in each
|
||||
* modified Data File or in the Software as well as in the documentation
|
||||
* associated with the Data File(s) or Software that the data or software
|
||||
* has been modified.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winnls.h"
|
||||
#include "usp10.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "usp10_internal.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(bidi);
|
||||
|
||||
#define ASSERT(x) do { if (!(x)) FIXME("assert failed: %s\n", #x); } while(0)
|
||||
#define MAX_LEVEL 61
|
||||
|
||||
/* HELPER FUNCTIONS AND DECLARATIONS */
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Bidirectional Character Types
|
||||
|
||||
as defined by the Unicode Bidirectional Algorithm Table 3-7.
|
||||
|
||||
Note:
|
||||
|
||||
The list of bidirectional character types here is not grouped the
|
||||
same way as the table 3-7, since the numberic values for the types
|
||||
are chosen to keep the state and action tables compact.
|
||||
------------------------------------------------------------------------*/
|
||||
enum directions
|
||||
{
|
||||
/* input types */
|
||||
/* ON MUST be zero, code relies on ON = N = 0 */
|
||||
ON = 0, /* Other Neutral */
|
||||
L, /* Left Letter */
|
||||
R, /* Right Letter */
|
||||
AN, /* Arabic Number */
|
||||
EN, /* European Number */
|
||||
AL, /* Arabic Letter (Right-to-left) */
|
||||
NSM, /* Non-spacing Mark */
|
||||
CS, /* Common Separator */
|
||||
ES, /* European Separator */
|
||||
ET, /* European Terminator (post/prefix e.g. $ and %) */
|
||||
|
||||
/* resolved types */
|
||||
BN, /* Boundary neutral (type of RLE etc after explicit levels) */
|
||||
|
||||
/* input types, */
|
||||
S, /* Segment Separator (TAB) // used only in L1 */
|
||||
WS, /* White space // used only in L1 */
|
||||
B, /* Paragraph Separator (aka as PS) */
|
||||
|
||||
/* types for explicit controls */
|
||||
RLO, /* these are used only in X1-X9 */
|
||||
RLE,
|
||||
LRO,
|
||||
LRE,
|
||||
PDF,
|
||||
|
||||
/* resolved types, also resolved directions */
|
||||
N = ON, /* alias, where ON, WS and S are treated the same */
|
||||
};
|
||||
|
||||
/* HELPER FUNCTIONS */
|
||||
/* the character type contains the C1_* flags in the low 12 bits */
|
||||
/* and the C2_* type in the high 4 bits */
|
||||
static __inline unsigned short get_char_typeW( WCHAR ch )
|
||||
{
|
||||
WORD CharType;
|
||||
GetStringTypeW(CT_CTYPE1, &ch, 1, &CharType);
|
||||
return CharType;
|
||||
}
|
||||
|
||||
/* Convert the libwine information to the direction enum */
|
||||
static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount, const SCRIPT_CONTROL *c)
|
||||
{
|
||||
static const enum directions dir_map[16] =
|
||||
{
|
||||
L, /* unassigned defaults to L */
|
||||
L,
|
||||
R,
|
||||
EN,
|
||||
ES,
|
||||
ET,
|
||||
AN,
|
||||
CS,
|
||||
B,
|
||||
S,
|
||||
WS,
|
||||
ON,
|
||||
AL,
|
||||
NSM,
|
||||
BN,
|
||||
PDF /* also LRE, LRO, RLE, RLO */
|
||||
};
|
||||
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < uCount; ++i)
|
||||
{
|
||||
chartype[i] = dir_map[get_char_typeW(lpString[i]) >> 12];
|
||||
switch (chartype[i])
|
||||
{
|
||||
case ES:
|
||||
if (!c->fLegacyBidiClass) break;
|
||||
switch (lpString[i])
|
||||
{
|
||||
case '-':
|
||||
case '+': chartype[i] = N; break;
|
||||
case '/': chartype[i] = CS; break;
|
||||
}
|
||||
break;
|
||||
case PDF:
|
||||
switch (lpString[i])
|
||||
{
|
||||
case 0x202A: chartype[i] = LRE; break;
|
||||
case 0x202B: chartype[i] = RLE; break;
|
||||
case 0x202C: chartype[i] = PDF; break;
|
||||
case 0x202D: chartype[i] = LRO; break;
|
||||
case 0x202E: chartype[i] = RLO; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set a run of cval values at locations all prior to, but not including */
|
||||
/* iStart, to the new value nval. */
|
||||
static void SetDeferredRun(WORD *pval, int cval, int iStart, int nval)
|
||||
{
|
||||
int i = iStart - 1;
|
||||
for (; i >= iStart - cval; i--)
|
||||
{
|
||||
pval[i] = nval;
|
||||
}
|
||||
}
|
||||
|
||||
/* RESOLVE EXPLICIT */
|
||||
|
||||
static WORD GreaterEven(int i)
|
||||
{
|
||||
return odd(i) ? i + 1 : i + 2;
|
||||
}
|
||||
|
||||
static WORD GreaterOdd(int i)
|
||||
{
|
||||
return odd(i) ? i + 2 : i + 1;
|
||||
}
|
||||
|
||||
static WORD EmbeddingDirection(int level)
|
||||
{
|
||||
return odd(level) ? R : L;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Function: resolveExplicit
|
||||
|
||||
Recursively resolves explicit embedding levels and overrides.
|
||||
Implements rules X1-X9, of the Unicode Bidirectional Algorithm.
|
||||
|
||||
Input: Base embedding level and direction
|
||||
Character count
|
||||
|
||||
Output: Array of embedding levels
|
||||
|
||||
In/Out: Array of direction classes
|
||||
|
||||
|
||||
Note: The function uses two simple counters to keep track of
|
||||
matching explicit codes and PDF. Use the default argument for
|
||||
the outermost call. The nesting counter counts the recursion
|
||||
depth and not the embedding level.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
static int resolveExplicit(int level, int dir, WORD *pcls, WORD *plevel, int cch, int nNest)
|
||||
{
|
||||
/* always called with a valid nesting level
|
||||
nesting levels are != embedding levels */
|
||||
int nLastValid = nNest;
|
||||
int ich = 0;
|
||||
|
||||
/* check input values */
|
||||
ASSERT(nNest >= 0 && level >= 0 && level <= MAX_LEVEL);
|
||||
|
||||
/* process the text */
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
WORD cls = pcls[ich];
|
||||
switch (cls)
|
||||
{
|
||||
case LRO:
|
||||
case LRE:
|
||||
nNest++;
|
||||
if (GreaterEven(level) <= MAX_LEVEL - (cls == LRO ? 2 : 0))
|
||||
{
|
||||
plevel[ich] = GreaterEven(level);
|
||||
pcls[ich] = BN;
|
||||
ich += resolveExplicit(plevel[ich], (cls == LRE ? N : L),
|
||||
&pcls[ich+1], &plevel[ich+1],
|
||||
cch - (ich+1), nNest);
|
||||
nNest--;
|
||||
continue;
|
||||
}
|
||||
cls = pcls[ich] = BN;
|
||||
break;
|
||||
|
||||
case RLO:
|
||||
case RLE:
|
||||
nNest++;
|
||||
if (GreaterOdd(level) <= MAX_LEVEL - (cls == RLO ? 2 : 0))
|
||||
{
|
||||
plevel[ich] = GreaterOdd(level);
|
||||
pcls[ich] = BN;
|
||||
ich += resolveExplicit(plevel[ich], (cls == RLE ? N : R),
|
||||
&pcls[ich+1], &plevel[ich+1],
|
||||
cch - (ich+1), nNest);
|
||||
nNest--;
|
||||
continue;
|
||||
}
|
||||
cls = pcls[ich] = BN;
|
||||
break;
|
||||
|
||||
case PDF:
|
||||
cls = pcls[ich] = BN;
|
||||
if (nNest)
|
||||
{
|
||||
if (nLastValid < nNest)
|
||||
{
|
||||
nNest--;
|
||||
}
|
||||
else
|
||||
{
|
||||
cch = ich; /* break the loop, but complete body */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply the override */
|
||||
if (dir != N)
|
||||
{
|
||||
cls = dir;
|
||||
}
|
||||
plevel[ich] = level;
|
||||
if (pcls[ich] != BN)
|
||||
pcls[ich] = cls;
|
||||
}
|
||||
|
||||
return ich;
|
||||
}
|
||||
|
||||
/* RESOLVE WEAK TYPES */
|
||||
|
||||
enum states /* possible states */
|
||||
{
|
||||
xa, /* arabic letter */
|
||||
xr, /* right letter */
|
||||
xl, /* left letter */
|
||||
|
||||
ao, /* arabic lett. foll by ON */
|
||||
ro, /* right lett. foll by ON */
|
||||
lo, /* left lett. foll by ON */
|
||||
|
||||
rt, /* ET following R */
|
||||
lt, /* ET following L */
|
||||
|
||||
cn, /* EN, AN following AL */
|
||||
ra, /* arabic number foll R */
|
||||
re, /* european number foll R */
|
||||
la, /* arabic number foll L */
|
||||
le, /* european number foll L */
|
||||
|
||||
ac, /* CS following cn */
|
||||
rc, /* CS following ra */
|
||||
rs, /* CS,ES following re */
|
||||
lc, /* CS following la */
|
||||
ls, /* CS,ES following le */
|
||||
|
||||
ret, /* ET following re */
|
||||
let, /* ET following le */
|
||||
} ;
|
||||
|
||||
static const int stateWeak[][10] =
|
||||
{
|
||||
/* N, L, R, AN, EN, AL,NSM, CS, ES, ET */
|
||||
/*xa*/ { ao, xl, xr, cn, cn, xa, xa, ao, ao, ao }, /* arabic letter */
|
||||
/*xr*/ { ro, xl, xr, ra, re, xa, xr, ro, ro, rt }, /* right letter */
|
||||
/*xl*/ { lo, xl, xr, la, le, xa, xl, lo, lo, lt }, /* left letter */
|
||||
|
||||
/*ao*/ { ao, xl, xr, cn, cn, xa, ao, ao, ao, ao }, /* arabic lett. foll by ON*/
|
||||
/*ro*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* right lett. foll by ON */
|
||||
/*lo*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* left lett. foll by ON */
|
||||
|
||||
/*rt*/ { ro, xl, xr, ra, re, xa, rt, ro, ro, rt }, /* ET following R */
|
||||
/*lt*/ { lo, xl, xr, la, le, xa, lt, lo, lo, lt }, /* ET following L */
|
||||
|
||||
/*cn*/ { ao, xl, xr, cn, cn, xa, cn, ac, ao, ao }, /* EN, AN following AL */
|
||||
/*ra*/ { ro, xl, xr, ra, re, xa, ra, rc, ro, rt }, /* arabic number foll R */
|
||||
/*re*/ { ro, xl, xr, ra, re, xa, re, rs, rs,ret }, /* european number foll R */
|
||||
/*la*/ { lo, xl, xr, la, le, xa, la, lc, lo, lt }, /* arabic number foll L */
|
||||
/*le*/ { lo, xl, xr, la, le, xa, le, ls, ls,let }, /* european number foll L */
|
||||
|
||||
/*ac*/ { ao, xl, xr, cn, cn, xa, ao, ao, ao, ao }, /* CS following cn */
|
||||
/*rc*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* CS following ra */
|
||||
/*rs*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* CS,ES following re */
|
||||
/*lc*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* CS following la */
|
||||
/*ls*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* CS,ES following le */
|
||||
|
||||
/*ret*/{ ro, xl, xr, ra, re, xa,ret, ro, ro,ret }, /* ET following re */
|
||||
/*let*/{ lo, xl, xr, la, le, xa,let, lo, lo,let }, /* ET following le */
|
||||
};
|
||||
|
||||
enum actions /* possible actions */
|
||||
{
|
||||
/* primitives */
|
||||
IX = 0x100, /* increment */
|
||||
XX = 0xF, /* no-op */
|
||||
|
||||
/* actions */
|
||||
xxx = (XX << 4) + XX, /* no-op */
|
||||
xIx = IX + xxx, /* increment run */
|
||||
xxN = (XX << 4) + ON, /* set current to N */
|
||||
xxE = (XX << 4) + EN, /* set current to EN */
|
||||
xxA = (XX << 4) + AN, /* set current to AN */
|
||||
xxR = (XX << 4) + R, /* set current to R */
|
||||
xxL = (XX << 4) + L, /* set current to L */
|
||||
Nxx = (ON << 4) + 0xF, /* set run to neutral */
|
||||
Axx = (AN << 4) + 0xF, /* set run to AN */
|
||||
ExE = (EN << 4) + EN, /* set run to EN, set current to EN */
|
||||
NIx = (ON << 4) + 0xF + IX, /* set run to N, increment */
|
||||
NxN = (ON << 4) + ON, /* set run to N, set current to N */
|
||||
NxR = (ON << 4) + R, /* set run to N, set current to R */
|
||||
NxE = (ON << 4) + EN, /* set run to N, set current to EN */
|
||||
|
||||
AxA = (AN << 4) + AN, /* set run to AN, set current to AN */
|
||||
NxL = (ON << 4) + L, /* set run to N, set current to L */
|
||||
LxL = (L << 4) + L, /* set run to L, set current to L */
|
||||
} ;
|
||||
|
||||
static const int actionWeak[][10] =
|
||||
{
|
||||
/* N, L, R, AN, EN, AL, NSM, CS, ES, ET */
|
||||
/*xa*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxR, xxN, xxN, xxN }, /* arabic letter */
|
||||
/*xr*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxR, xxN, xxN, xIx }, /* right letter */
|
||||
/*xl*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xIx }, /* left letter */
|
||||
|
||||
/*ao*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxN, xxN, xxN, xxN }, /* arabic lett. foll by ON */
|
||||
/*ro*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxN, xxN, xxN, xIx }, /* right lett. foll by ON */
|
||||
/*lo*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxN, xxN, xxN, xIx }, /* left lett. foll by ON */
|
||||
|
||||
/*rt*/ { Nxx, Nxx, Nxx, Nxx, ExE, NxR, xIx, NxN, NxN, xIx }, /* ET following R */
|
||||
/*lt*/ { Nxx, Nxx, Nxx, Nxx, LxL, NxR, xIx, NxN, NxN, xIx }, /* ET following L */
|
||||
|
||||
/*cn*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxA, xIx, xxN, xxN }, /* EN, AN following AL */
|
||||
/*ra*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxA, xIx, xxN, xIx }, /* arabic number foll R */
|
||||
/*re*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxE, xIx, xIx, xxE }, /* european number foll R */
|
||||
/*la*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxA, xIx, xxN, xIx }, /* arabic number foll L */
|
||||
/*le*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxL, xIx, xIx, xxL }, /* european number foll L */
|
||||
|
||||
/*ac*/ { Nxx, Nxx, Nxx, Axx, AxA, NxR, NxN, NxN, NxN, NxN }, /* CS following cn */
|
||||
/*rc*/ { Nxx, Nxx, Nxx, Axx, NxE, NxR, NxN, NxN, NxN, NIx }, /* CS following ra */
|
||||
/*rs*/ { Nxx, Nxx, Nxx, Nxx, ExE, NxR, NxN, NxN, NxN, NIx }, /* CS,ES following re */
|
||||
/*lc*/ { Nxx, Nxx, Nxx, Axx, NxL, NxR, NxN, NxN, NxN, NIx }, /* CS following la */
|
||||
/*ls*/ { Nxx, Nxx, Nxx, Nxx, LxL, NxR, NxN, NxN, NxN, NIx }, /* CS,ES following le */
|
||||
|
||||
/*ret*/{ xxx, xxx, xxx, xxx, xxE, xxR, xxE, xxN, xxN, xxE }, /* ET following re */
|
||||
/*let*/{ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xxL }, /* ET following le */
|
||||
};
|
||||
|
||||
static int GetDeferredType(int action)
|
||||
{
|
||||
return (action >> 4) & 0xF;
|
||||
}
|
||||
|
||||
static int GetResolvedType(int action)
|
||||
{
|
||||
return action & 0xF;
|
||||
}
|
||||
|
||||
/* Note on action table:
|
||||
|
||||
States can be of two kinds:
|
||||
- Immediate Resolution State, where each input token
|
||||
is resolved as soon as it is seen. These states have
|
||||
only single action codes (xxN) or the no-op (xxx)
|
||||
for static input tokens.
|
||||
- Deferred Resolution State, where input tokens either
|
||||
either extend the run (xIx) or resolve its Type (e.g. Nxx).
|
||||
|
||||
Input classes are of three kinds
|
||||
- Static Input Token, where the class of the token remains
|
||||
unchanged on output (AN, L, N, R)
|
||||
- Replaced Input Token, where the class of the token is
|
||||
always replaced on output (AL, BN, NSM, CS, ES, ET)
|
||||
- Conditional Input Token, where the class of the token is
|
||||
changed on output in some, but not all, cases (EN)
|
||||
|
||||
Where tokens are subject to change, a double action
|
||||
(e.g. NxA, or NxN) is _required_ after deferred states,
|
||||
resolving both the deferred state and changing the current token.
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Function: resolveWeak
|
||||
|
||||
Resolves the directionality of numeric and other weak character types
|
||||
|
||||
Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.
|
||||
|
||||
Input: Array of embedding levels
|
||||
Character count
|
||||
|
||||
In/Out: Array of directional classes
|
||||
|
||||
Note: On input only these directional classes are expected
|
||||
AL, HL, R, L, ON, BN, NSM, AN, EN, ES, ET, CS,
|
||||
------------------------------------------------------------------------*/
|
||||
static void resolveWeak(int baselevel, WORD *pcls, WORD *plevel, int cch)
|
||||
{
|
||||
int state = odd(baselevel) ? xr : xl;
|
||||
int cls;
|
||||
|
||||
int level = baselevel;
|
||||
int action, clsRun, clsNew;
|
||||
int cchRun = 0;
|
||||
int ich = 0;
|
||||
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
/* ignore boundary neutrals */
|
||||
if (pcls[ich] == BN)
|
||||
{
|
||||
/* must flatten levels unless at a level change; */
|
||||
plevel[ich] = level;
|
||||
|
||||
/* lookahead for level changes */
|
||||
if (ich + 1 == cch && level != baselevel)
|
||||
{
|
||||
/* have to fixup last BN before end of the loop, since
|
||||
* its fix-upped value will be needed below the assert */
|
||||
pcls[ich] = EmbeddingDirection(level);
|
||||
}
|
||||
else if (ich + 1 < cch && level != plevel[ich+1] && pcls[ich+1] != BN)
|
||||
{
|
||||
/* fixup LAST BN in front / after a level run to make
|
||||
* it act like the SOR/EOR in rule X10 */
|
||||
int newlevel = plevel[ich+1];
|
||||
if (level > newlevel) {
|
||||
newlevel = level;
|
||||
}
|
||||
plevel[ich] = newlevel;
|
||||
|
||||
/* must match assigned level */
|
||||
pcls[ich] = EmbeddingDirection(newlevel);
|
||||
level = plevel[ich+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* don't interrupt runs */
|
||||
if (cchRun)
|
||||
{
|
||||
cchRun++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(pcls[ich] <= BN);
|
||||
cls = pcls[ich];
|
||||
|
||||
action = actionWeak[state][cls];
|
||||
|
||||
/* resolve the directionality for deferred runs */
|
||||
clsRun = GetDeferredType(action);
|
||||
if (clsRun != XX)
|
||||
{
|
||||
SetDeferredRun(pcls, cchRun, ich, clsRun);
|
||||
cchRun = 0;
|
||||
}
|
||||
|
||||
/* resolve the directionality class at the current location */
|
||||
clsNew = GetResolvedType(action);
|
||||
if (clsNew != XX)
|
||||
pcls[ich] = clsNew;
|
||||
|
||||
/* increment a deferred run */
|
||||
if (IX & action)
|
||||
cchRun++;
|
||||
|
||||
state = stateWeak[state][cls];
|
||||
}
|
||||
|
||||
/* resolve any deferred runs
|
||||
* use the direction of the current level to emulate PDF */
|
||||
cls = EmbeddingDirection(level);
|
||||
|
||||
/* resolve the directionality for deferred runs */
|
||||
clsRun = GetDeferredType(actionWeak[state][cls]);
|
||||
if (clsRun != XX)
|
||||
SetDeferredRun(pcls, cchRun, ich, clsRun);
|
||||
}
|
||||
|
||||
/* RESOLVE NEUTRAL TYPES */
|
||||
|
||||
/* action values */
|
||||
enum neutralactions
|
||||
{
|
||||
/* action to resolve previous input */
|
||||
nL = L, /* resolve EN to L */
|
||||
En = 3 << 4, /* resolve neutrals run to embedding level direction */
|
||||
Rn = R << 4, /* resolve neutrals run to strong right */
|
||||
Ln = L << 4, /* resolved neutrals run to strong left */
|
||||
In = (1<<8), /* increment count of deferred neutrals */
|
||||
LnL = (1<<4)+L, /* set run and EN to L */
|
||||
};
|
||||
|
||||
static int GetDeferredNeutrals(int action, int level)
|
||||
{
|
||||
action = (action >> 4) & 0xF;
|
||||
if (action == (En >> 4))
|
||||
return EmbeddingDirection(level);
|
||||
else
|
||||
return action;
|
||||
}
|
||||
|
||||
static int GetResolvedNeutrals(int action)
|
||||
{
|
||||
action = action & 0xF;
|
||||
if (action == In)
|
||||
return 0;
|
||||
else
|
||||
return action;
|
||||
}
|
||||
|
||||
/* state values */
|
||||
enum resolvestates
|
||||
{
|
||||
/* new temporary class */
|
||||
r, /* R and characters resolved to R */
|
||||
l, /* L and characters resolved to L */
|
||||
rn, /* N preceded by right */
|
||||
ln, /* N preceded by left */
|
||||
a, /* AN preceded by left (the abbreviation 'la' is used up above) */
|
||||
na, /* N preceded by a */
|
||||
} ;
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Notes:
|
||||
|
||||
By rule W7, whenever a EN is 'dominated' by an L (including start of
|
||||
run with embedding direction = L) it is resolved to, and further treated
|
||||
as L.
|
||||
|
||||
This leads to the need for 'a' and 'na' states.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
static const int actionNeutrals[][5] =
|
||||
{
|
||||
/* N, L, R, AN, EN = cls */
|
||||
{ In, 0, 0, 0, 0 }, /* r right */
|
||||
{ In, 0, 0, 0, L }, /* l left */
|
||||
|
||||
{ In, En, Rn, Rn, Rn }, /* rn N preceded by right */
|
||||
{ In, Ln, En, En, LnL}, /* ln N preceded by left */
|
||||
|
||||
{ In, 0, 0, 0, L }, /* a AN preceded by left */
|
||||
{ In, En, Rn, Rn, En }, /* na N preceded by a */
|
||||
} ;
|
||||
|
||||
static const int stateNeutrals[][5] =
|
||||
{
|
||||
/* N, L, R, AN, EN */
|
||||
{ rn, l, r, r, r }, /* r right */
|
||||
{ ln, l, r, a, l }, /* l left */
|
||||
|
||||
{ rn, l, r, r, r }, /* rn N preceded by right */
|
||||
{ ln, l, r, a, l }, /* ln N preceded by left */
|
||||
|
||||
{ na, l, r, a, l }, /* a AN preceded by left */
|
||||
{ na, l, r, a, l }, /* na N preceded by la */
|
||||
} ;
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Function: resolveNeutrals
|
||||
|
||||
Resolves the directionality of neutral character types.
|
||||
|
||||
Implements rules W7, N1 and N2 of the Unicode Bidi Algorithm.
|
||||
|
||||
Input: Array of embedding levels
|
||||
Character count
|
||||
Baselevel
|
||||
|
||||
In/Out: Array of directional classes
|
||||
|
||||
Note: On input only these directional classes are expected
|
||||
R, L, N, AN, EN and BN
|
||||
|
||||
W8 resolves a number of ENs to L
|
||||
------------------------------------------------------------------------*/
|
||||
static void resolveNeutrals(int baselevel, WORD *pcls, const WORD *plevel, int cch)
|
||||
{
|
||||
/* the state at the start of text depends on the base level */
|
||||
int state = odd(baselevel) ? r : l;
|
||||
int cls;
|
||||
|
||||
int cchRun = 0;
|
||||
int level = baselevel;
|
||||
|
||||
int action, clsRun, clsNew;
|
||||
int ich = 0;
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
/* ignore boundary neutrals */
|
||||
if (pcls[ich] == BN)
|
||||
{
|
||||
/* include in the count for a deferred run */
|
||||
if (cchRun)
|
||||
cchRun++;
|
||||
|
||||
/* skip any further processing */
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT(pcls[ich] < 5); /* "Only N, L, R, AN, EN are allowed" */
|
||||
cls = pcls[ich];
|
||||
|
||||
action = actionNeutrals[state][cls];
|
||||
|
||||
/* resolve the directionality for deferred runs */
|
||||
clsRun = GetDeferredNeutrals(action, level);
|
||||
if (clsRun != N)
|
||||
{
|
||||
SetDeferredRun(pcls, cchRun, ich, clsRun);
|
||||
cchRun = 0;
|
||||
}
|
||||
|
||||
/* resolve the directionality class at the current location */
|
||||
clsNew = GetResolvedNeutrals(action);
|
||||
if (clsNew != N)
|
||||
pcls[ich] = clsNew;
|
||||
|
||||
if (In & action)
|
||||
cchRun++;
|
||||
|
||||
state = stateNeutrals[state][cls];
|
||||
level = plevel[ich];
|
||||
}
|
||||
|
||||
/* resolve any deferred runs */
|
||||
cls = EmbeddingDirection(level); /* eor has type of current level */
|
||||
|
||||
/* resolve the directionality for deferred runs */
|
||||
clsRun = GetDeferredNeutrals(actionNeutrals[state][cls], level);
|
||||
if (clsRun != N)
|
||||
SetDeferredRun(pcls, cchRun, ich, clsRun);
|
||||
}
|
||||
|
||||
/* RESOLVE IMPLICIT */
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Function: resolveImplicit
|
||||
|
||||
Recursively resolves implicit embedding levels.
|
||||
Implements rules I1 and I2 of the Unicode Bidirectional Algorithm.
|
||||
|
||||
Input: Array of direction classes
|
||||
Character count
|
||||
Base level
|
||||
|
||||
In/Out: Array of embedding levels
|
||||
|
||||
Note: levels may exceed 15 on output.
|
||||
Accepted subset of direction classes
|
||||
R, L, AN, EN
|
||||
------------------------------------------------------------------------*/
|
||||
static const WORD addLevel[][4] =
|
||||
{
|
||||
/* L, R, AN, EN */
|
||||
/* even */ { 0, 1, 2, 2, },
|
||||
/* odd */ { 1, 0, 1, 1, }
|
||||
|
||||
};
|
||||
|
||||
static void resolveImplicit(const WORD * pcls, WORD *plevel, int cch)
|
||||
{
|
||||
int ich = 0;
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
/* cannot resolve bn here, since some bn were resolved to strong
|
||||
* types in resolveWeak. To remove these we need the original
|
||||
* types, which are available again in resolveWhiteSpace */
|
||||
if (pcls[ich] == BN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ASSERT(pcls[ich] > 0); /* "No Neutrals allowed to survive here." */
|
||||
ASSERT(pcls[ich] < 5); /* "Out of range." */
|
||||
plevel[ich] += addLevel[odd(plevel[ich])][pcls[ich] - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* BIDI_DeterminLevels
|
||||
*/
|
||||
BOOL BIDI_DetermineLevels(
|
||||
LPCWSTR lpString, /* [in] The string for which information is to be returned */
|
||||
INT uCount, /* [in] Number of WCHARs in string. */
|
||||
const SCRIPT_STATE *s,
|
||||
const SCRIPT_CONTROL *c,
|
||||
WORD *lpOutLevels /* [out] final string levels */
|
||||
)
|
||||
{
|
||||
WORD *chartype;
|
||||
unsigned baselevel = 0,j;
|
||||
TRACE("%s, %d", debugstr_wn(lpString, uCount), uCount);
|
||||
|
||||
chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD));
|
||||
if (!chartype)
|
||||
{
|
||||
WARN("Out of memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
baselevel = s->uBidiLevel;
|
||||
|
||||
classify(lpString, chartype, uCount, c);
|
||||
|
||||
for (j = 0; j < uCount; ++j)
|
||||
switch(chartype[j])
|
||||
{
|
||||
case B:
|
||||
case S:
|
||||
case WS:
|
||||
case ON: chartype[j] = N;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
/* resolve explicit */
|
||||
resolveExplicit(baselevel, N, chartype, lpOutLevels, uCount, 0);
|
||||
|
||||
/* resolve weak */
|
||||
resolveWeak(baselevel, chartype, lpOutLevels, uCount);
|
||||
|
||||
/* resolve neutrals */
|
||||
resolveNeutrals(baselevel, chartype, lpOutLevels, uCount);
|
||||
|
||||
/* resolveImplicit */
|
||||
resolveImplicit(chartype, lpOutLevels, uCount);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, chartype);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* reverse cch indexes */
|
||||
static void reverse(int *pidx, int cch)
|
||||
{
|
||||
int temp;
|
||||
int ich = 0;
|
||||
for (; ich < --cch; ich++)
|
||||
{
|
||||
temp = pidx[ich];
|
||||
pidx[ich] = pidx[cch];
|
||||
pidx[cch] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Functions: reorder/reorderLevel
|
||||
|
||||
Recursively reorders the display string
|
||||
"From the highest level down, reverse all characters at that level and
|
||||
higher, down to the lowest odd level"
|
||||
|
||||
Implements rule L2 of the Unicode bidi Algorithm.
|
||||
|
||||
Input: Array of embedding levels
|
||||
Character count
|
||||
Flag enabling reversal (set to false by initial caller)
|
||||
|
||||
In/Out: Text to reorder
|
||||
|
||||
Note: levels may exceed 15 resp. 61 on input.
|
||||
|
||||
Rule L3 - reorder combining marks is not implemented here
|
||||
Rule L4 - glyph mirroring is implemented as a display option below
|
||||
|
||||
Note: this should be applied a line at a time
|
||||
-------------------------------------------------------------------------*/
|
||||
int BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse)
|
||||
{
|
||||
int ich = 0;
|
||||
|
||||
/* true as soon as first odd level encountered */
|
||||
fReverse = fReverse || odd(level);
|
||||
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
if (plevel[ich] < level)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (plevel[ich] > level)
|
||||
{
|
||||
ich += BIDI_ReorderV2lLevel(level + 1, pIndexs + ich, plevel + ich,
|
||||
cch - ich, fReverse) - 1;
|
||||
}
|
||||
}
|
||||
if (fReverse)
|
||||
{
|
||||
reverse(pIndexs, ich);
|
||||
}
|
||||
return ich;
|
||||
}
|
||||
|
||||
/* Applies the reorder in reverse. Taking an already reordered string and returing the original */
|
||||
int BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse)
|
||||
{
|
||||
int ich = 0;
|
||||
int newlevel = -1;
|
||||
|
||||
/* true as soon as first odd level encountered */
|
||||
fReverse = fReverse || odd(level);
|
||||
|
||||
for (; ich < cch; ich++)
|
||||
{
|
||||
if (plevel[ich] < level)
|
||||
break;
|
||||
else if (plevel[ich] > level)
|
||||
newlevel = ich;
|
||||
}
|
||||
if (fReverse)
|
||||
{
|
||||
reverse(pIndexs, ich);
|
||||
}
|
||||
|
||||
if (newlevel > 1)
|
||||
{
|
||||
ich = 0;
|
||||
for (; ich < cch; ich++)
|
||||
if (plevel[ich] > level)
|
||||
ich += BIDI_ReorderL2vLevel(level + 1, pIndexs + ich, plevel + ich,
|
||||
cch - ich, fReverse) - 1;
|
||||
}
|
||||
|
||||
return ich;
|
||||
}
|
||||
+102
-34
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright 2005 Steven Edwards for CodeWeavers
|
||||
* Copyright 2006 Hans Leidekker
|
||||
* Copyright 2010 CodeWeavers, Aric Stewart
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -32,6 +33,8 @@
|
||||
#include "winnls.h"
|
||||
#include "usp10.h"
|
||||
|
||||
#include "usp10_internal.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
@@ -524,6 +527,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
|
||||
int cnt = 0, index = 0;
|
||||
int New_Script = SCRIPT_UNDEFINED;
|
||||
WORD *levels = NULL;
|
||||
|
||||
TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems,
|
||||
psControl, psState, pItems, pcItems);
|
||||
@@ -531,6 +535,24 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (psState && psControl)
|
||||
{
|
||||
int i;
|
||||
levels = heap_alloc_zero(cInChars * sizeof(WORD));
|
||||
if (!levels)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels);
|
||||
for (i = 0; i < cInChars; i++)
|
||||
if (levels[i]!=levels[0])
|
||||
break;
|
||||
if (i >= cInChars)
|
||||
{
|
||||
heap_free(levels);
|
||||
levels = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pItems[index].iCharPos = 0;
|
||||
memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
|
||||
|
||||
@@ -549,15 +571,29 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
if (pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop)
|
||||
pItems[index].a.eScript = Script_Latin;
|
||||
|
||||
if (pItems[index].a.eScript == Script_Arabic)
|
||||
if (levels)
|
||||
{
|
||||
pItems[index].a.fRTL = odd(levels[cnt]);
|
||||
pItems[index].a.fLayoutRTL = odd(levels[cnt]);
|
||||
pItems[index].a.s.uBidiLevel = levels[cnt];
|
||||
}
|
||||
else if (pItems[index].a.eScript == Script_Arabic)
|
||||
{
|
||||
pItems[index].a.s.uBidiLevel = 1;
|
||||
pItems[index].a.fRTL = 1;
|
||||
pItems[index].a.fLayoutRTL = 1;
|
||||
}
|
||||
|
||||
TRACE("New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
|
||||
New_Script, pItems[index].a.eScript, index, cnt,
|
||||
|
||||
TRACE("New_Level=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
|
||||
levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript, index, cnt,
|
||||
pItems[index].iCharPos);
|
||||
|
||||
for (cnt=1; cnt < cInChars; cnt++)
|
||||
{
|
||||
if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel))
|
||||
continue;
|
||||
|
||||
if (pwcInChars[cnt] == '\r')
|
||||
New_Script = Script_CR;
|
||||
else
|
||||
@@ -578,9 +614,9 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
else
|
||||
New_Script = SCRIPT_UNDEFINED;
|
||||
|
||||
if (New_Script != pItems[index].a.eScript)
|
||||
if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) || New_Script != pItems[index].a.eScript)
|
||||
{
|
||||
TRACE("New_Script=%d, eScript=%d ", New_Script, pItems[index].a.eScript);
|
||||
TRACE("New_Level = %i, New_Script=%d, eScript=%d ", levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript);
|
||||
index++;
|
||||
if (index+1 > cMaxItems)
|
||||
return E_OUTOFMEMORY;
|
||||
@@ -588,9 +624,18 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
pItems[index].iCharPos = cnt;
|
||||
memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
|
||||
|
||||
if (New_Script == Script_Arabic)
|
||||
if (levels)
|
||||
{
|
||||
pItems[index].a.fRTL = odd(levels[cnt]);
|
||||
pItems[index].a.fLayoutRTL = odd(levels[cnt]);
|
||||
pItems[index].a.s.uBidiLevel = levels[cnt];
|
||||
}
|
||||
else if (New_Script == Script_Arabic)
|
||||
{
|
||||
pItems[index].a.s.uBidiLevel = 1;
|
||||
|
||||
pItems[index].a.fRTL = 1;
|
||||
pItems[index].a.fLayoutRTL = 1;
|
||||
}
|
||||
pItems[index].a.eScript = New_Script;
|
||||
|
||||
TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
|
||||
@@ -610,6 +655,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
||||
/* Set SCRIPT_ITEM */
|
||||
pItems[index+1].iCharPos = cnt; /* the last + 1 item
|
||||
contains the ptr to the lastchar */
|
||||
heap_free(levels);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -686,7 +732,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
|
||||
int numGlyphsReturned;
|
||||
|
||||
/* FIXME: non unicode strings */
|
||||
WCHAR* pStr = (WCHAR*)pString;
|
||||
const WCHAR* pStr = (const WCHAR*)pString;
|
||||
hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
|
||||
cChar, numGlyphs, &analysis->pItem[i].a,
|
||||
glyphs, pwLogClust, psva, &numGlyphsReturned);
|
||||
@@ -1286,6 +1332,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
|
||||
{
|
||||
HRESULT hr;
|
||||
unsigned int i;
|
||||
BOOL rtl;
|
||||
|
||||
TRACE("(%p, %p, %s, %d, %d, %p, %p, %p, %p, %p)\n", hdc, psc, debugstr_wn(pwcChars, cChars),
|
||||
cChars, cMaxGlyphs, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs);
|
||||
@@ -1295,6 +1342,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
|
||||
|
||||
if (!psva || !pcGlyphs) return E_INVALIDARG;
|
||||
if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
|
||||
rtl = (!psa->fLogicalOrder && psa->fRTL);
|
||||
|
||||
*pcGlyphs = cChars;
|
||||
if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
|
||||
@@ -1304,33 +1352,42 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
|
||||
{
|
||||
for (i = 0; i < cChars; i++)
|
||||
{
|
||||
if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[i])))
|
||||
int idx = i;
|
||||
if (rtl) idx = cChars - 1 - i;
|
||||
if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[idx])))
|
||||
{
|
||||
WORD glyph;
|
||||
if (!hdc) return E_PENDING;
|
||||
if (GetGlyphIndicesW(hdc, &pwcChars[i], 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
|
||||
pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[i], glyph);
|
||||
if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
|
||||
pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("no glyph translation\n");
|
||||
for (i = 0; i < cChars; i++) pwOutGlyphs[i] = pwcChars[i];
|
||||
for (i = 0; i < cChars; i++)
|
||||
{
|
||||
int idx = i;
|
||||
if (rtl) idx = cChars - 1 - i;
|
||||
pwOutGlyphs[i] = pwcChars[idx];
|
||||
}
|
||||
}
|
||||
|
||||
/* set up a valid SCRIPT_VISATTR and LogClust for each char in this run */
|
||||
for (i = 0; i < cChars; i++)
|
||||
{
|
||||
int idx = i;
|
||||
if (rtl) idx = cChars - 1 - i;
|
||||
/* FIXME: set to better values */
|
||||
psva[i].uJustification = (pwcChars[i] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
|
||||
psva[i].uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
|
||||
psva[i].fClusterStart = 1;
|
||||
psva[i].fDiacritic = 0;
|
||||
psva[i].fZeroWidth = 0;
|
||||
psva[i].fReserved = 0;
|
||||
psva[i].fShapeReserved = 0;
|
||||
|
||||
pwLogClust[i] = i;
|
||||
pwLogClust[i] = idx;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1573,28 +1630,45 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB
|
||||
*/
|
||||
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
|
||||
{
|
||||
int i, j = runs - 1, k = 0;
|
||||
int* indexs;
|
||||
int ich;
|
||||
|
||||
TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
|
||||
|
||||
if (!level || (!vistolog && !logtovis))
|
||||
return E_INVALIDARG;
|
||||
|
||||
for (i = 0; i < runs; i++)
|
||||
indexs = heap_alloc(sizeof(int) * runs);
|
||||
if (!indexs)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
||||
if (vistolog)
|
||||
{
|
||||
if (level[i] % 2)
|
||||
{
|
||||
if (vistolog) *vistolog++ = j;
|
||||
if (logtovis) *logtovis++ = j;
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vistolog) *vistolog++ = k;
|
||||
if (logtovis) *logtovis++ = k;
|
||||
k++;
|
||||
}
|
||||
for( ich = 0; ich < runs; ich++)
|
||||
indexs[ich] = ich;
|
||||
|
||||
ich = 0;
|
||||
while (ich < runs)
|
||||
ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
|
||||
for (ich = 0; ich < runs; ich++)
|
||||
vistolog[ich] = indexs[ich];
|
||||
}
|
||||
|
||||
|
||||
if (logtovis)
|
||||
{
|
||||
for( ich = 0; ich < runs; ich++)
|
||||
indexs[ich] = ich;
|
||||
|
||||
ich = 0;
|
||||
while (ich < runs)
|
||||
ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
|
||||
for (ich = 0; ich < runs; ich++)
|
||||
logtovis[ich] = indexs[ich];
|
||||
}
|
||||
heap_free(indexs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1839,9 +1913,3 @@ HRESULT WINAPI ScriptJustify(const SCRIPT_VISATTR *sva, const int *advance,
|
||||
for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL gbLpkPresent = FALSE;
|
||||
VOID WINAPI LpkPresent()
|
||||
{
|
||||
gbLpkPresent = TRUE; /* Turn it on this way! Wine is out of control! */
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<include base="usp10">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__WINESRC__" />
|
||||
<file>bidi.c</file>
|
||||
<file>usp10.c</file>
|
||||
<library>wine</library>
|
||||
<library>gdi32</library>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@ stdcall LpkPresent()
|
||||
@ stub LpkPresent
|
||||
@ stdcall ScriptApplyDigitSubstitution(ptr ptr ptr)
|
||||
@ stdcall ScriptApplyLogicalWidth(ptr long long ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall ScriptBreak(ptr long ptr ptr)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Implementation of Uniscribe Script Processor (usp10.dll)
|
||||
*
|
||||
* Copyright 2010 CodeWeavers, Aric Stewart
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define odd(x) ((x) & 1)
|
||||
|
||||
BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
|
||||
const SCRIPT_CONTROL *c, WORD *lpOutLevels );
|
||||
|
||||
INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
|
||||
INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
|
||||
@@ -199,7 +199,11 @@ static BOOL find_ne_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
|
||||
*/
|
||||
static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
|
||||
{
|
||||
IMAGE_NT_HEADERS pehd;
|
||||
union
|
||||
{
|
||||
IMAGE_NT_HEADERS32 nt32;
|
||||
IMAGE_NT_HEADERS64 nt64;
|
||||
} pehd;
|
||||
DWORD pehdoffset;
|
||||
PIMAGE_DATA_DIRECTORY resDataDir;
|
||||
PIMAGE_SECTION_HEADER sections;
|
||||
@@ -208,14 +212,27 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
|
||||
const void *resDir;
|
||||
const IMAGE_RESOURCE_DIRECTORY *resPtr;
|
||||
const IMAGE_RESOURCE_DATA_ENTRY *resData;
|
||||
int i, nSections;
|
||||
int i, len, nSections;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
/* Read in PE header */
|
||||
pehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
|
||||
if ( sizeof(pehd) != LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ) ) return 0;
|
||||
len = LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) );
|
||||
if (len < sizeof(pehd.nt32.FileHeader)) return 0;
|
||||
if (len < sizeof(pehd)) memset( (char *)&pehd + len, 0, sizeof(pehd) - len );
|
||||
|
||||
switch (pehd.nt32.OptionalHeader.Magic)
|
||||
{
|
||||
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
|
||||
resDataDir = pehd.nt32.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
|
||||
break;
|
||||
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
||||
resDataDir = pehd.nt64.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
resDataDir = pehd.OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
|
||||
if ( !resDataDir->Size )
|
||||
{
|
||||
TRACE("No resources in PE dll\n" );
|
||||
@@ -223,15 +240,13 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
|
||||
}
|
||||
|
||||
/* Read in section table */
|
||||
nSections = pehd.FileHeader.NumberOfSections;
|
||||
nSections = pehd.nt32.FileHeader.NumberOfSections;
|
||||
sections = HeapAlloc( GetProcessHeap(), 0,
|
||||
nSections * sizeof(IMAGE_SECTION_HEADER) );
|
||||
if ( !sections ) return FALSE;
|
||||
|
||||
LZSeek( lzfd, pehdoffset +
|
||||
sizeof(DWORD) + /* Signature */
|
||||
sizeof(IMAGE_FILE_HEADER) +
|
||||
pehd.FileHeader.SizeOfOptionalHeader, SEEK_SET );
|
||||
len = FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + pehd.nt32.FileHeader.SizeOfOptionalHeader;
|
||||
LZSeek( lzfd, pehdoffset + len, SEEK_SET );
|
||||
|
||||
if ( nSections * sizeof(IMAGE_SECTION_HEADER) !=
|
||||
LZRead( lzfd, (LPSTR)sections, nSections * sizeof(IMAGE_SECTION_HEADER) ) )
|
||||
|
||||
@@ -58,12 +58,14 @@ typedef struct {
|
||||
DWORD bc2AppData;
|
||||
} BITMAPCOREHEADER2;
|
||||
|
||||
struct BmpFrameDecode;
|
||||
typedef HRESULT (*ReadDataFunc)(struct BmpFrameDecode* This);
|
||||
struct BmpDecoder;
|
||||
typedef HRESULT (*ReadDataFunc)(struct BmpDecoder* This);
|
||||
|
||||
typedef struct BmpFrameDecode {
|
||||
const IWICBitmapFrameDecodeVtbl *lpVtbl;
|
||||
typedef struct BmpDecoder {
|
||||
const IWICBitmapDecoderVtbl *lpVtbl;
|
||||
const IWICBitmapFrameDecodeVtbl *lpFrameVtbl;
|
||||
LONG ref;
|
||||
BOOL initialized;
|
||||
IStream *stream;
|
||||
BITMAPFILEHEADER bfh;
|
||||
BITMAPV5HEADER bih;
|
||||
@@ -73,12 +75,17 @@ typedef struct BmpFrameDecode {
|
||||
INT stride;
|
||||
BYTE *imagedata;
|
||||
BYTE *imagedatastart;
|
||||
} BmpFrameDecode;
|
||||
CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */
|
||||
} BmpDecoder;
|
||||
|
||||
static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BmpDecoder, lpFrameVtbl);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
@@ -87,7 +94,7 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
|
||||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
|
||||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
|
||||
{
|
||||
*ppv = This;
|
||||
*ppv = iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,35 +108,22 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
|
||||
|
||||
static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
return ref;
|
||||
return IUnknown_AddRef((IUnknown*)This);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
IStream_Release(This->stream);
|
||||
HeapFree(GetProcessHeap(), 0, This->imagedata);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
return IUnknown_Release((IUnknown*)This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
|
||||
UINT *puiWidth, UINT *puiHeight)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
|
||||
|
||||
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
|
||||
@@ -149,7 +143,7 @@ static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
|
||||
static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
|
||||
WICPixelFormatGUID *pPixelFormat)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
TRACE("(%p,%p)\n", iface, pPixelFormat);
|
||||
|
||||
memcpy(pPixelFormat, This->pixelformat, sizeof(GUID));
|
||||
@@ -180,7 +174,7 @@ static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, doubl
|
||||
static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
|
||||
double *pDpiX, double *pDpiY)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
|
||||
|
||||
return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY);
|
||||
@@ -190,13 +184,15 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
{
|
||||
HRESULT hr;
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
int count;
|
||||
WICColor *wiccolors=NULL;
|
||||
RGBTRIPLE *bgrcolors=NULL;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, pIPalette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
|
||||
@@ -238,7 +234,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
}
|
||||
else
|
||||
{
|
||||
return WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -256,7 +253,11 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
|
||||
tablesize = sizeof(WICColor) * count;
|
||||
wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
|
||||
if (!wiccolors) return E_OUTOFMEMORY;
|
||||
if (!wiccolors)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
|
||||
hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
|
||||
@@ -275,13 +276,18 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
}
|
||||
else
|
||||
{
|
||||
return WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
|
||||
|
||||
end:
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, wiccolors);
|
||||
HeapFree(GetProcessHeap(), 0, bgrcolors);
|
||||
return hr;
|
||||
@@ -290,16 +296,18 @@ end:
|
||||
static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
|
||||
{
|
||||
BmpFrameDecode *This = (BmpFrameDecode*)iface;
|
||||
HRESULT hr;
|
||||
BmpDecoder *This = impl_from_frame(iface);
|
||||
HRESULT hr=S_OK;
|
||||
UINT width, height;
|
||||
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
if (!This->imagedata)
|
||||
{
|
||||
hr = This->read_data_func(This);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
LeaveCriticalSection(&This->lock);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = BmpFrameDecode_GetSize(iface, &width, &height);
|
||||
if (FAILED(hr)) return hr;
|
||||
@@ -330,7 +338,7 @@ static HRESULT WINAPI BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
|
||||
return WINCODEC_ERR_CODECNOTHUMBNAIL;
|
||||
}
|
||||
|
||||
static HRESULT BmpFrameDecode_ReadUncompressed(BmpFrameDecode* This)
|
||||
static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This)
|
||||
{
|
||||
UINT bytesperrow;
|
||||
UINT width, height;
|
||||
@@ -387,7 +395,7 @@ fail:
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT BmpFrameDecode_ReadRLE8(BmpFrameDecode* This)
|
||||
static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This)
|
||||
{
|
||||
UINT bytesperrow;
|
||||
UINT width, height;
|
||||
@@ -493,7 +501,7 @@ fail:
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT BmpFrameDecode_ReadRLE4(BmpFrameDecode* This)
|
||||
static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This)
|
||||
{
|
||||
UINT bytesperrow;
|
||||
UINT width, height;
|
||||
@@ -614,7 +622,7 @@ fail:
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT BmpFrameDecode_ReadUnsupported(BmpFrameDecode* This)
|
||||
static HRESULT BmpFrameDecode_ReadUnsupported(BmpDecoder* This)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
@@ -637,7 +645,7 @@ static const struct bitfields_format bitfields_formats[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
|
||||
static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl = {
|
||||
BmpFrameDecode_QueryInterface,
|
||||
BmpFrameDecode_AddRef,
|
||||
BmpFrameDecode_Release,
|
||||
@@ -651,19 +659,6 @@ static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
|
||||
BmpFrameDecode_GetThumbnail
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const IWICBitmapDecoderVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
BOOL initialized;
|
||||
IStream *stream;
|
||||
BITMAPFILEHEADER bfh;
|
||||
BITMAPV5HEADER bih;
|
||||
BmpFrameDecode *framedecode;
|
||||
const WICPixelFormatGUID *pixelformat;
|
||||
int bitsperpixel;
|
||||
ReadDataFunc read_data_func;
|
||||
} BmpDecoder;
|
||||
|
||||
static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
|
||||
{
|
||||
HRESULT hr;
|
||||
@@ -873,7 +868,9 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
|
||||
if (ref == 0)
|
||||
{
|
||||
if (This->stream) IStream_Release(This->stream);
|
||||
if (This->framedecode) IUnknown_Release((IUnknown*)This->framedecode);
|
||||
HeapFree(GetProcessHeap(), 0, This->imagedata);
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
@@ -886,7 +883,9 @@ static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre
|
||||
HRESULT hr;
|
||||
BmpDecoder *This = (BmpDecoder*)iface;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
hr = BmpDecoder_ReadHeaders(This, pIStream);
|
||||
LeaveCriticalSection(&This->lock);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (This->read_data_func == BmpFrameDecode_ReadUnsupported)
|
||||
@@ -903,6 +902,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
HRESULT hr;
|
||||
BmpDecoder *This = (BmpDecoder*)iface;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
hr = BmpDecoder_ReadHeaders(This, pIStream);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
@@ -910,6 +910,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
This->stream = pIStream;
|
||||
IStream_AddRef(pIStream);
|
||||
}
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
@@ -992,25 +993,8 @@ static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface,
|
||||
|
||||
if (!This->stream) return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
if (!This->framedecode)
|
||||
{
|
||||
This->framedecode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameDecode));
|
||||
if (!This->framedecode) return E_OUTOFMEMORY;
|
||||
|
||||
This->framedecode->lpVtbl = &BmpFrameDecode_Vtbl;
|
||||
This->framedecode->ref = 1;
|
||||
This->framedecode->stream = This->stream;
|
||||
IStream_AddRef(This->stream);
|
||||
This->framedecode->bfh = This->bfh;
|
||||
This->framedecode->bih = This->bih;
|
||||
This->framedecode->pixelformat = This->pixelformat;
|
||||
This->framedecode->bitsperpixel = This->bitsperpixel;
|
||||
This->framedecode->read_data_func = This->read_data_func;
|
||||
This->framedecode->imagedata = NULL;
|
||||
}
|
||||
|
||||
*ppIBitmapFrame = (IWICBitmapFrameDecode*)This->framedecode;
|
||||
IWICBitmapFrameDecode_AddRef((IWICBitmapFrameDecode*)This->framedecode);
|
||||
*ppIBitmapFrame = (IWICBitmapFrameDecode*)&This->lpFrameVtbl;
|
||||
IWICBitmapDecoder_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1047,10 +1031,13 @@ HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &BmpDecoder_Vtbl;
|
||||
This->lpFrameVtbl = &BmpDecoder_FrameVtbl;
|
||||
This->ref = 1;
|
||||
This->initialized = FALSE;
|
||||
This->stream = NULL;
|
||||
This->framedecode = NULL;
|
||||
This->imagedata = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -50,6 +50,7 @@ static classinfo wic_classes[] = {
|
||||
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
|
||||
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
|
||||
{&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
|
||||
{&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance},
|
||||
{&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance},
|
||||
{0}};
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ typedef struct FormatConverter {
|
||||
WICBitmapDitherType dither;
|
||||
double alpha_threshold;
|
||||
WICBitmapPaletteType palette_type;
|
||||
CRITICAL_SECTION lock; /* must be held when initialized */
|
||||
} FormatConverter;
|
||||
|
||||
static void make_grayscale_palette(WICColor *colors, UINT num_colors)
|
||||
@@ -765,6 +766,8 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->source) IWICBitmapSource_Release(This->source);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
@@ -841,38 +844,56 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||
const struct pixelformatinfo *srcinfo, *dstinfo;
|
||||
static INT fixme=0;
|
||||
GUID srcFormat;
|
||||
HRESULT res;
|
||||
HRESULT res=S_OK;
|
||||
|
||||
TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
||||
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
||||
|
||||
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
||||
|
||||
if (This->source) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->source)
|
||||
{
|
||||
res = WINCODEC_ERR_WRONGSTATE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
|
||||
if (FAILED(res)) return res;
|
||||
if (FAILED(res)) goto end;
|
||||
|
||||
srcinfo = get_formatinfo(&srcFormat);
|
||||
if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
if (!srcinfo)
|
||||
{
|
||||
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
dstinfo = get_formatinfo(dstFormat);
|
||||
if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
if (!dstinfo)
|
||||
{
|
||||
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dstinfo->copy_function)
|
||||
{
|
||||
IWICBitmapSource_AddRef(pISource);
|
||||
This->source = pISource;
|
||||
This->src_format = srcinfo;
|
||||
This->dst_format = dstinfo;
|
||||
This->dither = dither;
|
||||
This->alpha_threshold = alphaThresholdPercent;
|
||||
This->palette_type = paletteTranslate;
|
||||
This->source = pISource;
|
||||
}
|
||||
else
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
res = WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
|
||||
return S_OK;
|
||||
end:
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
|
||||
@@ -930,6 +951,8 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
|
||||
This->lpVtbl = &FormatConverter_Vtbl;
|
||||
This->ref = 1;
|
||||
This->source = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct {
|
||||
LONG ref;
|
||||
BOOL initialized;
|
||||
GifFileType *gif;
|
||||
CRITICAL_SECTION lock;
|
||||
} GifDecoder;
|
||||
|
||||
typedef struct {
|
||||
@@ -302,6 +303,8 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
DGifCloseFile(This->gif);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
@@ -341,9 +344,12 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
|
||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->initialized || This->gif)
|
||||
{
|
||||
WARN("already initialized\n");
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
@@ -353,16 +359,26 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
|
||||
/* read all data from the stream */
|
||||
This->gif = DGifOpen((void*)pIStream, _gif_inputfunc);
|
||||
if (!This->gif) return E_FAIL;
|
||||
if (!This->gif)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ret = DGifSlurp(This->gif);
|
||||
if (ret == GIF_ERROR) return E_FAIL;
|
||||
if (ret == GIF_ERROR)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* make sure we don't use the stream after this method returns */
|
||||
This->gif->UserData = NULL;
|
||||
|
||||
This->initialized = TRUE;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -502,6 +518,8 @@ HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
This->ref = 1;
|
||||
This->initialized = FALSE;
|
||||
This->gif = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef struct {
|
||||
BOOL initialized;
|
||||
IStream *stream;
|
||||
ICONHEADER header;
|
||||
CRITICAL_SECTION lock; /* must be held when accessing stream */
|
||||
} IcoDecoder;
|
||||
|
||||
typedef struct {
|
||||
@@ -512,15 +513,17 @@ static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
|
||||
{
|
||||
IcoFrameDecode *This = (IcoFrameDecode*)iface;
|
||||
HRESULT hr;
|
||||
HRESULT hr=S_OK;
|
||||
UINT width, height, stride;
|
||||
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
|
||||
EnterCriticalSection(&This->parent->lock);
|
||||
if (!This->bits)
|
||||
{
|
||||
hr = IcoFrameDecode_ReadPixels(This);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
LeaveCriticalSection(&This->parent->lock);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
width = This->entry.bWidth ? This->entry.bWidth : 256;
|
||||
height = This->entry.bHeight ? This->entry.bHeight : 256;
|
||||
@@ -606,6 +609,8 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->stream) IStream_Release(This->stream);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
@@ -629,23 +634,37 @@ static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
ULONG bytesread;
|
||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||
|
||||
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->initialized)
|
||||
{
|
||||
hr = WINCODEC_ERR_WRONGSTATE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
seek.QuadPart = 0;
|
||||
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (FAILED(hr)) goto end;
|
||||
|
||||
hr = IStream_Read(pIStream, &This->header, sizeof(ICONHEADER), &bytesread);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (FAILED(hr)) goto end;
|
||||
if (bytesread != sizeof(ICONHEADER) ||
|
||||
This->header.idReserved != 0 ||
|
||||
This->header.idType != 1) return E_FAIL;
|
||||
This->header.idType != 1)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
This->initialized = TRUE;
|
||||
This->stream = pIStream;
|
||||
IStream_AddRef(pIStream);
|
||||
|
||||
return S_OK;
|
||||
end:
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
|
||||
@@ -715,18 +734,32 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
|
||||
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
|
||||
{
|
||||
IcoDecoder *This = (IcoDecoder*)iface;
|
||||
IcoFrameDecode *result;
|
||||
IcoFrameDecode *result=NULL;
|
||||
LARGE_INTEGER seek;
|
||||
HRESULT hr;
|
||||
ULONG bytesread;
|
||||
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
|
||||
|
||||
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->header.idCount < index) return E_INVALIDARG;
|
||||
if (!This->initialized)
|
||||
{
|
||||
hr = WINCODEC_ERR_NOTINITIALIZED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (This->header.idCount < index)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode));
|
||||
if (!result) return E_OUTOFMEMORY;
|
||||
if (!result)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result->lpVtbl = &IcoFrameDecode_Vtbl;
|
||||
result->ref = 1;
|
||||
@@ -745,9 +778,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
|
||||
|
||||
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
|
||||
fail:
|
||||
LeaveCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, result);
|
||||
if (SUCCEEDED(hr)) hr = E_FAIL;
|
||||
TRACE("<-- %x\n", hr);
|
||||
@@ -789,6 +825,8 @@ HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
This->ref = 1;
|
||||
This->stream = NULL;
|
||||
This->initialized = FALSE;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -103,6 +103,7 @@ typedef struct {
|
||||
struct jpeg_source_mgr source_mgr;
|
||||
BYTE source_buffer[1024];
|
||||
BYTE *image_data;
|
||||
CRITICAL_SECTION lock;
|
||||
} JpegDecoder;
|
||||
|
||||
static inline JpegDecoder *decoder_from_decompress(j_decompress_ptr decompress)
|
||||
@@ -156,6 +157,8 @@ static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo);
|
||||
if (This->stream) IStream_Release(This->stream);
|
||||
HeapFree(GetProcessHeap(), 0, This->image_data);
|
||||
@@ -225,7 +228,13 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
||||
int ret;
|
||||
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
|
||||
|
||||
if (This->cinfo_initialized) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->cinfo_initialized)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->cinfo.err = pjpeg_std_error(&This->jerr);
|
||||
|
||||
@@ -249,6 +258,7 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
||||
|
||||
if (ret != JPEG_HEADER_OK) {
|
||||
WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret);
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -260,11 +270,14 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
||||
if (!pjpeg_start_decompress(&This->cinfo))
|
||||
{
|
||||
ERR("jpeg_start_decompress failed\n");
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
This->initialized = TRUE;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -448,10 +461,16 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
max_row_needed = prc->Y + prc->Height;
|
||||
if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->image_data)
|
||||
{
|
||||
This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size);
|
||||
if (!This->image_data) return E_OUTOFMEMORY;
|
||||
if (!This->image_data)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
while (max_row_needed > This->cinfo.output_scanline)
|
||||
@@ -471,6 +490,7 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
if (ret == 0)
|
||||
{
|
||||
ERR("read_scanlines failed\n");
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -492,6 +512,8 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return copy_pixels(bpp, This->image_data,
|
||||
This->cinfo.output_width, This->cinfo.output_height, stride,
|
||||
prc, cbStride, cbBufferSize, pbBuffer);
|
||||
@@ -559,6 +581,8 @@ HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
This->cinfo_initialized = FALSE;
|
||||
This->stream = NULL;
|
||||
This->image_data = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegDecoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct {
|
||||
UINT count;
|
||||
WICColor *colors;
|
||||
WICBitmapPaletteType type;
|
||||
CRITICAL_SECTION lock; /* must be held when count, colors, or type is accessed */
|
||||
} PaletteImpl;
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid,
|
||||
@@ -83,6 +84,8 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This->colors);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
@@ -117,10 +120,12 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
|
||||
memcpy(new_colors, pColors, sizeof(WICColor) * colorCount);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This->colors);
|
||||
This->colors = new_colors;
|
||||
This->count = colorCount;
|
||||
This->type = WICBitmapPaletteTypeCustom;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -148,7 +153,9 @@ static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface,
|
||||
|
||||
if (!pePaletteType) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
*pePaletteType = This->type;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -161,7 +168,9 @@ static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCoun
|
||||
|
||||
if (!pcCount) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
*pcCount = This->count;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -175,12 +184,16 @@ static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount,
|
||||
|
||||
if (!pColors || !pcActualColors) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->count < colorCount) colorCount = This->count;
|
||||
|
||||
memcpy(pColors, This->colors, sizeof(WICColor) * colorCount);
|
||||
|
||||
*pcActualColors = colorCount;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -192,10 +205,12 @@ static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBla
|
||||
|
||||
if (!pfIsBlackWhite) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
if (This->type == WICBitmapPaletteTypeFixedBW)
|
||||
*pfIsBlackWhite = TRUE;
|
||||
else
|
||||
*pfIsBlackWhite = FALSE;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -208,6 +223,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray
|
||||
|
||||
if (!pfIsGrayscale) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
switch(This->type)
|
||||
{
|
||||
case WICBitmapPaletteTypeFixedBW:
|
||||
@@ -219,6 +235,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray
|
||||
default:
|
||||
*pfIsGrayscale = FALSE;
|
||||
}
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -234,12 +251,14 @@ static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha)
|
||||
|
||||
*pfHasAlpha = FALSE;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
for (i=0; i<This->count; i++)
|
||||
if ((This->colors[i]&0xff000000) != 0xff000000)
|
||||
{
|
||||
*pfHasAlpha = TRUE;
|
||||
break;
|
||||
}
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -272,6 +291,8 @@ HRESULT PaletteImpl_Create(IWICPalette **palette)
|
||||
This->count = 0;
|
||||
This->colors = NULL;
|
||||
This->type = WICBitmapPaletteTypeCustom;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock");
|
||||
|
||||
*palette = (IWICPalette*)This;
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ typedef struct {
|
||||
UINT stride;
|
||||
const WICPixelFormatGUID *format;
|
||||
BYTE *image_bits;
|
||||
CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */
|
||||
} PngDecoder;
|
||||
|
||||
static inline PngDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
|
||||
@@ -214,6 +215,8 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
|
||||
{
|
||||
if (This->png_ptr)
|
||||
ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This->image_bits);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
@@ -246,7 +249,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
{
|
||||
PngDecoder *This = (PngDecoder*)iface;
|
||||
LARGE_INTEGER seek;
|
||||
HRESULT hr;
|
||||
HRESULT hr=S_OK;
|
||||
png_bytep *row_pointers=NULL;
|
||||
UINT image_size;
|
||||
UINT i;
|
||||
@@ -259,16 +262,23 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
|
||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
/* initialize libpng */
|
||||
This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!This->png_ptr) return E_FAIL;
|
||||
if (!This->png_ptr)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
This->info_ptr = ppng_create_info_struct(This->png_ptr);
|
||||
if (!This->info_ptr)
|
||||
{
|
||||
ppng_destroy_read_struct(&This->png_ptr, NULL, NULL);
|
||||
This->png_ptr = NULL;
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
This->end_info = ppng_create_info_struct(This->png_ptr);
|
||||
@@ -276,7 +286,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
{
|
||||
ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL);
|
||||
This->png_ptr = NULL;
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set up setjmp/longjmp error handling */
|
||||
@@ -285,14 +296,15 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
|
||||
HeapFree(GetProcessHeap(), 0, row_pointers);
|
||||
This->png_ptr = NULL;
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
|
||||
|
||||
/* seek to the start of the stream */
|
||||
seek.QuadPart = 0;
|
||||
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (FAILED(hr)) goto end;
|
||||
|
||||
/* set up custom i/o handling */
|
||||
ppng_set_read_fn(This->png_ptr, pIStream, user_read_data);
|
||||
@@ -340,7 +352,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
|
||||
default:
|
||||
ERR("invalid grayscale bit depth: %i\n", bit_depth);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
@@ -357,7 +370,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break;
|
||||
default:
|
||||
ERR("invalid RGBA bit depth: %i\n", bit_depth);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
@@ -370,7 +384,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break;
|
||||
default:
|
||||
ERR("invalid indexed color bit depth: %i\n", bit_depth);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
@@ -384,12 +399,14 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
case 16: This->format = &GUID_WICPixelFormat48bppRGB; break;
|
||||
default:
|
||||
ERR("invalid RGB color bit depth: %i\n", bit_depth);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("invalid color type %i\n", color_type);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* read the image data */
|
||||
@@ -399,10 +416,18 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
image_size = This->stride * This->height;
|
||||
|
||||
This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size);
|
||||
if (!This->image_bits) return E_OUTOFMEMORY;
|
||||
if (!This->image_bits)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height);
|
||||
if (!row_pointers) return E_OUTOFMEMORY;
|
||||
if (!row_pointers)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i=0; i<This->height; i++)
|
||||
row_pointers[i] = This->image_bits + i * This->stride;
|
||||
@@ -416,7 +441,11 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
||||
|
||||
This->initialized = TRUE;
|
||||
|
||||
return S_OK;
|
||||
end:
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
|
||||
@@ -570,6 +599,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac
|
||||
png_uint_32 ret, xres, yres;
|
||||
int unit_type;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type);
|
||||
|
||||
if (ret && unit_type == PNG_RESOLUTION_METER)
|
||||
@@ -583,6 +614,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac
|
||||
*pDpiX = *pDpiY = 96.0;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY);
|
||||
|
||||
return S_OK;
|
||||
@@ -600,16 +633,24 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
int num_trans;
|
||||
png_color_16p trans_values;
|
||||
int i;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, pIPalette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
|
||||
if (!ret) return WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
if (!ret)
|
||||
{
|
||||
hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (num_palette > 256)
|
||||
{
|
||||
ERR("palette has %i colors?!\n", num_palette);
|
||||
return E_FAIL;
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i=0; i<num_palette; i++)
|
||||
@@ -629,7 +670,14 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
}
|
||||
}
|
||||
|
||||
return IWICPalette_InitializeCustom(pIPalette, palette, num_palette);
|
||||
end:
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
@@ -706,6 +754,8 @@ HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
This->end_info = NULL;
|
||||
This->initialized = FALSE;
|
||||
This->image_bits = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
@@ -752,6 +802,7 @@ typedef struct PngEncoder {
|
||||
UINT lines_written;
|
||||
BOOL frame_committed;
|
||||
BOOL committed;
|
||||
CRITICAL_SECTION lock;
|
||||
} PngEncoder;
|
||||
|
||||
static inline PngEncoder *encoder_from_frame(IWICBitmapFrameEncode *iface)
|
||||
@@ -800,10 +851,18 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
|
||||
PngEncoder *This = encoder_from_frame(iface);
|
||||
TRACE("(%p,%p)\n", iface, pIEncoderOptions);
|
||||
|
||||
if (This->frame_initialized) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->frame_initialized)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->frame_initialized = TRUE;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -813,11 +872,19 @@ static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
|
||||
PngEncoder *This = encoder_from_frame(iface);
|
||||
TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
|
||||
|
||||
if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->frame_initialized || This->info_written)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->width = uiWidth;
|
||||
This->height = uiHeight;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -827,11 +894,19 @@ static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
|
||||
PngEncoder *This = encoder_from_frame(iface);
|
||||
TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
|
||||
|
||||
if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->frame_initialized || This->info_written)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->xres = dpiX;
|
||||
This->yres = dpiY;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -842,7 +917,13 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
|
||||
int i;
|
||||
TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
|
||||
|
||||
if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->frame_initialized || This->info_written)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
for (i=0; formats[i].guid; i++)
|
||||
{
|
||||
@@ -855,6 +936,8 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
|
||||
This->format = &formats[i];
|
||||
memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -888,15 +971,24 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
||||
jmp_buf jmpbuf;
|
||||
TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->frame_initialized || !This->width || !This->height || !This->format)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
if (lineCount == 0 || lineCount + This->lines_written > This->height)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* set up setjmp/longjmp error handling */
|
||||
if (setjmp(jmpbuf))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, row_pointers);
|
||||
return E_FAIL;
|
||||
}
|
||||
@@ -927,7 +1019,10 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
||||
|
||||
row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
|
||||
if (!row_pointers)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
for (i=0; i<lineCount; i++)
|
||||
row_pointers[i] = pbPixels + cbStride * i;
|
||||
@@ -935,6 +1030,8 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
||||
ppng_write_rows(This->png_ptr, row_pointers, lineCount);
|
||||
This->lines_written += lineCount;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, row_pointers);
|
||||
|
||||
return S_OK;
|
||||
@@ -1019,12 +1116,18 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
||||
jmp_buf jmpbuf;
|
||||
TRACE("(%p)\n", iface);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->info_written || This->lines_written != This->height || This->frame_committed)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
/* set up setjmp/longjmp error handling */
|
||||
if (setjmp(jmpbuf))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
|
||||
@@ -1033,6 +1136,8 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
||||
|
||||
This->frame_committed = TRUE;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1102,6 +1207,8 @@ static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface)
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->png_ptr)
|
||||
ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
|
||||
if (This->stream)
|
||||
@@ -1137,19 +1244,28 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
|
||||
|
||||
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->png_ptr)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
/* initialize libpng */
|
||||
This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!This->png_ptr)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
This->info_ptr = ppng_create_info_struct(This->png_ptr);
|
||||
if (!This->info_ptr)
|
||||
{
|
||||
ppng_destroy_write_struct(&This->png_ptr, NULL);
|
||||
This->png_ptr = NULL;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -1163,6 +1279,7 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
|
||||
This->png_ptr = NULL;
|
||||
IStream_Release(This->stream);
|
||||
This->stream = NULL;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return E_FAIL;
|
||||
}
|
||||
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
|
||||
@@ -1170,6 +1287,8 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
|
||||
/* set up custom i/o handling */
|
||||
ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1219,17 +1338,31 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
||||
HRESULT hr;
|
||||
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->frame_count != 0)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
if (!This->stream)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
hr = CreatePropertyBag2(ppIEncoderOptions);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->frame_count = 1;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
IWICBitmapEncoder_AddRef(iface);
|
||||
*ppIFrameEncode = (IWICBitmapFrameEncode*)&This->lpFrameVtbl;
|
||||
|
||||
@@ -1241,11 +1374,18 @@ static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface)
|
||||
PngEncoder *This = (PngEncoder*)iface;
|
||||
TRACE("(%p)\n", iface);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (!This->frame_committed || This->committed)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->committed = TRUE;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1309,6 +1449,8 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
This->lines_written = 0;
|
||||
This->frame_committed = FALSE;
|
||||
This->committed = FALSE;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
@@ -727,25 +727,25 @@ static struct regsvr_coclass const coclass_list[] = {
|
||||
"WIC Imaging Factory",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICBmpDecoder,
|
||||
"WIC BMP Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICPngDecoder,
|
||||
"WIC PNG Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICPngEncoder,
|
||||
"WIC PNG Encoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICBmpEncoder,
|
||||
"WIC BMP Encoder",
|
||||
@@ -757,25 +757,31 @@ static struct regsvr_coclass const coclass_list[] = {
|
||||
"WIC GIF Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICIcoDecoder,
|
||||
"WIC ICO Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICJpegDecoder,
|
||||
"WIC JPEG Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICTiffDecoder,
|
||||
"WIC TIFF Decoder",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_WICDefaultFormatConverter,
|
||||
"WIC Default Format Converter",
|
||||
NULL,
|
||||
"windowscodecs.dll",
|
||||
"Apartment"
|
||||
"Both"
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
@@ -868,6 +874,27 @@ static struct decoder_pattern const png_patterns[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
|
||||
static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
|
||||
|
||||
static GUID const * const tiff_formats[] = {
|
||||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat4bppGray,
|
||||
&GUID_WICPixelFormat8bppGray,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
&GUID_WICPixelFormat32bppBGR,
|
||||
&GUID_WICPixelFormat32bppBGRA,
|
||||
&GUID_WICPixelFormat32bppPBGRA,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct decoder_pattern const tiff_patterns[] = {
|
||||
{4,0,tiff_magic_le,mask_all,0},
|
||||
{4,0,tiff_magic_be,mask_all,0},
|
||||
{0}
|
||||
};
|
||||
|
||||
static struct regsvr_decoder const decoder_list[] = {
|
||||
{ &CLSID_WICBmpDecoder,
|
||||
"The Wine Project",
|
||||
@@ -919,6 +946,16 @@ static struct regsvr_decoder const decoder_list[] = {
|
||||
png_formats,
|
||||
png_patterns
|
||||
},
|
||||
{ &CLSID_WICTiffDecoder,
|
||||
"The Wine Project",
|
||||
"TIFF Decoder",
|
||||
"1.0.0.0",
|
||||
&GUID_VendorMicrosoft,
|
||||
"image/tiff",
|
||||
".tif;.tiff",
|
||||
tiff_formats,
|
||||
tiff_patterns
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ typedef struct StreamOnMemory {
|
||||
BYTE *pbMemory;
|
||||
DWORD dwMemsize;
|
||||
DWORD dwCurPos;
|
||||
|
||||
CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */
|
||||
} StreamOnMemory;
|
||||
|
||||
static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
|
||||
@@ -82,6 +84,8 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
@@ -96,9 +100,12 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
|
||||
|
||||
if (!pv) return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
|
||||
memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
|
||||
This->dwCurPos += uBytesRead;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (pcbRead) *pcbRead = uBytesRead;
|
||||
|
||||
return S_OK;
|
||||
@@ -108,18 +115,24 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
|
||||
void const *pv, ULONG cb, ULONG *pcbWritten)
|
||||
{
|
||||
StreamOnMemory *This = (StreamOnMemory*)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (!pv) return E_INVALIDARG;
|
||||
|
||||
if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL;
|
||||
if (cb) {
|
||||
EnterCriticalSection(&This->lock);
|
||||
if (cb > This->dwMemsize - This->dwCurPos) {
|
||||
hr = STG_E_MEDIUMFULL;
|
||||
}
|
||||
else {
|
||||
memcpy(This->pbMemory + This->dwCurPos, pv, cb);
|
||||
This->dwCurPos += cb;
|
||||
hr = S_OK;
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
}
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
|
||||
@@ -127,20 +140,29 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
|
||||
{
|
||||
StreamOnMemory *This = (StreamOnMemory*)iface;
|
||||
LARGE_INTEGER NewPosition;
|
||||
HRESULT hr=S_OK;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart;
|
||||
else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart;
|
||||
else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart;
|
||||
else return E_INVALIDARG;
|
||||
else hr = E_INVALIDARG;
|
||||
|
||||
if (NewPosition.u.HighPart) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG;
|
||||
if (NewPosition.QuadPart < 0) return E_INVALIDARG;
|
||||
This->dwCurPos = NewPosition.u.LowPart;
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (NewPosition.u.HighPart) hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
else if (NewPosition.QuadPart > This->dwMemsize) hr = E_INVALIDARG;
|
||||
else if (NewPosition.QuadPart < 0) hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
|
||||
return S_OK;
|
||||
if (SUCCEEDED(hr)) {
|
||||
This->dwCurPos = NewPosition.u.LowPart;
|
||||
|
||||
if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
|
||||
}
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* SetSize isn't implemented in the native windowscodecs DLL either */
|
||||
@@ -450,8 +472,16 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
|
||||
pObject->pbMemory = pbBuffer;
|
||||
pObject->dwMemsize = cbBufferSize;
|
||||
pObject->dwCurPos = 0;
|
||||
InitializeCriticalSection(&pObject->lock);
|
||||
pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock");
|
||||
|
||||
if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL))
|
||||
{
|
||||
/* Some other thread set the stream first. */
|
||||
IStream_Release((IStream*)pObject);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
This->pStream = (IStream*)pObject;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,866 @@
|
||||
/*
|
||||
* Copyright 2010 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_TIFFIO_H
|
||||
#include <tiffio.h>
|
||||
#endif
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
#include "wincodec.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
#ifdef SONAME_LIBTIFF
|
||||
|
||||
static CRITICAL_SECTION init_tiff_cs;
|
||||
static CRITICAL_SECTION_DEBUG init_tiff_cs_debug =
|
||||
{
|
||||
0, 0, &init_tiff_cs,
|
||||
{ &init_tiff_cs_debug.ProcessLocksList,
|
||||
&init_tiff_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": init_tiff_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static void *libtiff_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(TIFFClientOpen);
|
||||
MAKE_FUNCPTR(TIFFClose);
|
||||
MAKE_FUNCPTR(TIFFCurrentDirectory);
|
||||
MAKE_FUNCPTR(TIFFGetField);
|
||||
MAKE_FUNCPTR(TIFFReadDirectory);
|
||||
MAKE_FUNCPTR(TIFFReadEncodedStrip);
|
||||
MAKE_FUNCPTR(TIFFSetDirectory);
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
static void *load_libtiff(void)
|
||||
{
|
||||
void *result;
|
||||
|
||||
EnterCriticalSection(&init_tiff_cs);
|
||||
|
||||
if (!libtiff_handle &&
|
||||
(libtiff_handle = wine_dlopen(SONAME_LIBTIFF, RTLD_NOW, NULL, 0)) != NULL)
|
||||
{
|
||||
|
||||
#define LOAD_FUNCPTR(f) \
|
||||
if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \
|
||||
ERR("failed to load symbol %s\n", #f); \
|
||||
libtiff_handle = NULL; \
|
||||
LeaveCriticalSection(&init_tiff_cs); \
|
||||
return NULL; \
|
||||
}
|
||||
LOAD_FUNCPTR(TIFFClientOpen);
|
||||
LOAD_FUNCPTR(TIFFClose);
|
||||
LOAD_FUNCPTR(TIFFCurrentDirectory);
|
||||
LOAD_FUNCPTR(TIFFGetField);
|
||||
LOAD_FUNCPTR(TIFFReadDirectory);
|
||||
LOAD_FUNCPTR(TIFFReadEncodedStrip);
|
||||
LOAD_FUNCPTR(TIFFSetDirectory);
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
}
|
||||
|
||||
result = libtiff_handle;
|
||||
|
||||
LeaveCriticalSection(&init_tiff_cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
|
||||
{
|
||||
IStream *stream = (IStream*)client_data;
|
||||
ULONG bytes_read;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IStream_Read(stream, data, size, &bytes_read);
|
||||
if (FAILED(hr)) bytes_read = 0;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
|
||||
{
|
||||
IStream *stream = (IStream*)client_data;
|
||||
ULONG bytes_written;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IStream_Write(stream, data, size, &bytes_written);
|
||||
if (FAILED(hr)) bytes_written = 0;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
|
||||
{
|
||||
IStream *stream = (IStream*)client_data;
|
||||
LARGE_INTEGER move;
|
||||
DWORD origin;
|
||||
ULARGE_INTEGER new_position;
|
||||
HRESULT hr;
|
||||
|
||||
move.QuadPart = offset;
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
origin = STREAM_SEEK_SET;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
origin = STREAM_SEEK_CUR;
|
||||
break;
|
||||
case SEEK_END:
|
||||
origin = STREAM_SEEK_END;
|
||||
break;
|
||||
default:
|
||||
ERR("unknown whence value %i\n", whence);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = IStream_Seek(stream, move, origin, &new_position);
|
||||
if (SUCCEEDED(hr)) return new_position.QuadPart;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
static int tiff_stream_close(thandle_t client_data)
|
||||
{
|
||||
/* Caller is responsible for releasing the stream object. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static toff_t tiff_stream_size(thandle_t client_data)
|
||||
{
|
||||
IStream *stream = (IStream*)client_data;
|
||||
STATSTG statstg;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME);
|
||||
|
||||
if (SUCCEEDED(hr)) return statstg.cbSize.QuadPart;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
|
||||
{
|
||||
/* Cannot mmap streams */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
|
||||
{
|
||||
/* No need to ever do this, since we can't map things. */
|
||||
}
|
||||
|
||||
static TIFF* tiff_open_stream(IStream *stream, const char *mode)
|
||||
{
|
||||
return pTIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
|
||||
tiff_stream_write, tiff_stream_seek, tiff_stream_close,
|
||||
tiff_stream_size, tiff_stream_map, tiff_stream_unmap);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const IWICBitmapDecoderVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
IStream *stream;
|
||||
CRITICAL_SECTION lock; /* Must be held when tiff is used or initiailzed is set */
|
||||
TIFF *tiff;
|
||||
BOOL initialized;
|
||||
} TiffDecoder;
|
||||
|
||||
typedef struct {
|
||||
const WICPixelFormatGUID *format;
|
||||
int bpp;
|
||||
int indexed;
|
||||
int reverse_bgr;
|
||||
UINT width, height;
|
||||
UINT tile_width, tile_height;
|
||||
UINT tile_stride;
|
||||
UINT tile_size;
|
||||
} tiff_decode_info;
|
||||
|
||||
typedef struct {
|
||||
const IWICBitmapFrameDecodeVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
TiffDecoder *parent;
|
||||
UINT index;
|
||||
tiff_decode_info decode_info;
|
||||
INT cached_tile_x, cached_tile_y;
|
||||
BYTE *cached_tile;
|
||||
} TiffFrameDecode;
|
||||
|
||||
static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl;
|
||||
|
||||
static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
||||
{
|
||||
uint16 photometric, bps, samples, planar;
|
||||
int ret;
|
||||
|
||||
decode_info->indexed = 0;
|
||||
decode_info->reverse_bgr = 0;
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing PhotometricInterpretation tag\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps);
|
||||
if (!ret) bps = 1;
|
||||
|
||||
switch(photometric)
|
||||
{
|
||||
case 1: /* BlackIsZero */
|
||||
decode_info->bpp = bps;
|
||||
switch (bps)
|
||||
{
|
||||
case 1:
|
||||
decode_info->format = &GUID_WICPixelFormatBlackWhite;
|
||||
break;
|
||||
case 4:
|
||||
decode_info->format = &GUID_WICPixelFormat4bppGray;
|
||||
break;
|
||||
case 8:
|
||||
decode_info->format = &GUID_WICPixelFormat8bppGray;
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled greyscale bit count %u\n", bps);
|
||||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
case 2: /* RGB */
|
||||
if (bps != 8)
|
||||
{
|
||||
FIXME("unhandled RGB bit count %u\n", bps);
|
||||
return E_FAIL;
|
||||
}
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples);
|
||||
if (samples != 3)
|
||||
{
|
||||
FIXME("unhandled RGB sample count %u\n", samples);
|
||||
return E_FAIL;
|
||||
}
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar);
|
||||
if (!ret) planar = 1;
|
||||
if (planar != 1)
|
||||
{
|
||||
FIXME("unhandled planar configuration %u\n", planar);
|
||||
return E_FAIL;
|
||||
}
|
||||
decode_info->bpp = bps * samples;
|
||||
decode_info->reverse_bgr = 1;
|
||||
decode_info->format = &GUID_WICPixelFormat24bppBGR;
|
||||
break;
|
||||
case 3: /* RGB Palette */
|
||||
decode_info->indexed = 1;
|
||||
decode_info->bpp = bps;
|
||||
switch (bps)
|
||||
{
|
||||
case 4:
|
||||
decode_info->format = &GUID_WICPixelFormat4bppIndexed;
|
||||
break;
|
||||
case 8:
|
||||
decode_info->format = &GUID_WICPixelFormat8bppIndexed;
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled indexed bit count %u\n", bps);
|
||||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
case 0: /* WhiteIsZero */
|
||||
case 4: /* Transparency mask */
|
||||
case 5: /* CMYK */
|
||||
case 6: /* YCbCr */
|
||||
case 8: /* CIELab */
|
||||
default:
|
||||
FIXME("unhandled PhotometricInterpretation %u\n", photometric);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->width);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing image width\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->height);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing image length\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height);
|
||||
if (ret)
|
||||
{
|
||||
decode_info->tile_width = decode_info->width;
|
||||
decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
|
||||
decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Probably a tiled image */
|
||||
FIXME("missing RowsPerStrip value\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
|
||||
{
|
||||
*ppv = This;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TiffDecoder_AddRef(IWICBitmapDecoder *iface)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
if (This->tiff) pTIFFClose(This->tiff);
|
||||
if (This->stream) IStream_Release(This->stream);
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
|
||||
DWORD *pdwCapability)
|
||||
{
|
||||
FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
|
||||
WICDecodeOptions cacheOptions)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
TIFF *tiff;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
TRACE("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if (This->initialized)
|
||||
{
|
||||
hr = WINCODEC_ERR_WRONGSTATE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tiff = tiff_open_stream(pIStream, "r");
|
||||
|
||||
if (!tiff)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
This->tiff = tiff;
|
||||
This->stream = pIStream;
|
||||
IStream_AddRef(pIStream);
|
||||
This->initialized = TRUE;
|
||||
|
||||
exit:
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
|
||||
GUID *pguidContainerFormat)
|
||||
{
|
||||
memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
|
||||
IWICBitmapDecoderInfo **ppIDecoderInfo)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
||||
IWICPalette *pIPalette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
IWICBitmapSource **ppIBitmapSource)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIBitmapSource);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetColorContexts(IWICBitmapDecoder *iface,
|
||||
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
|
||||
{
|
||||
FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetThumbnail(IWICBitmapDecoder *iface,
|
||||
IWICBitmapSource **ppIThumbnail)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, ppIThumbnail);
|
||||
return WINCODEC_ERR_CODECNOTHUMBNAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetFrameCount(IWICBitmapDecoder *iface,
|
||||
UINT *pCount)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
|
||||
if (!This->tiff)
|
||||
{
|
||||
WARN("(%p) <-- WINCODEC_ERR_WRONGSTATE\n", iface);
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
while (pTIFFReadDirectory(This->tiff)) { }
|
||||
*pCount = pTIFFCurrentDirectory(This->tiff)+1;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
TRACE("(%p) <-- %i\n", iface, *pCount);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface,
|
||||
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
|
||||
{
|
||||
TiffDecoder *This = (TiffDecoder*)iface;
|
||||
TiffFrameDecode *result;
|
||||
int res;
|
||||
tiff_decode_info decode_info;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
|
||||
|
||||
if (!This->tiff)
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
res = pTIFFSetDirectory(This->tiff, index);
|
||||
if (!res) hr = E_INVALIDARG;
|
||||
else hr = tiff_get_decode_info(This->tiff, &decode_info);
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
result = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffFrameDecode));
|
||||
|
||||
if (result)
|
||||
{
|
||||
result->lpVtbl = &TiffFrameDecode_Vtbl;
|
||||
result->ref = 1;
|
||||
result->parent = This;
|
||||
result->index = index;
|
||||
result->decode_info = decode_info;
|
||||
result->cached_tile_x = -1;
|
||||
result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size);
|
||||
|
||||
if (result->cached_tile)
|
||||
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
|
||||
else
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
HeapFree(GetProcessHeap(), 0, result);
|
||||
}
|
||||
}
|
||||
else hr = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) *ppIBitmapFrame = NULL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = {
|
||||
TiffDecoder_QueryInterface,
|
||||
TiffDecoder_AddRef,
|
||||
TiffDecoder_Release,
|
||||
TiffDecoder_QueryCapability,
|
||||
TiffDecoder_Initialize,
|
||||
TiffDecoder_GetContainerFormat,
|
||||
TiffDecoder_GetDecoderInfo,
|
||||
TiffDecoder_CopyPalette,
|
||||
TiffDecoder_GetMetadataQueryReader,
|
||||
TiffDecoder_GetPreview,
|
||||
TiffDecoder_GetColorContexts,
|
||||
TiffDecoder_GetThumbnail,
|
||||
TiffDecoder_GetFrameCount,
|
||||
TiffDecoder_GetFrame
|
||||
};
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid) ||
|
||||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
|
||||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
|
||||
{
|
||||
*ppv = This;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TiffFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) refcount=%u\n", iface, ref);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This->cached_tile);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
|
||||
UINT *puiWidth, UINT *puiHeight)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
|
||||
*puiWidth = This->decode_info.width;
|
||||
*puiHeight = This->decode_info.height;
|
||||
|
||||
TRACE("(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
|
||||
WICPixelFormatGUID *pPixelFormat)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
|
||||
memcpy(pPixelFormat, This->decode_info.format, sizeof(GUID));
|
||||
|
||||
TRACE("(%p) <-- %s\n", This, debugstr_guid(This->decode_info.format));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
|
||||
double *pDpiX, double *pDpiY)
|
||||
{
|
||||
FIXME("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
||||
IWICPalette *pIPalette)
|
||||
{
|
||||
FIXME("(%p,%p)\n", iface, pIPalette);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
tsize_t ret;
|
||||
|
||||
ret = pTIFFSetDirectory(This->parent->tiff, This->index);
|
||||
|
||||
if (ret == -1)
|
||||
hr = E_FAIL;
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size);
|
||||
|
||||
if (ret == -1)
|
||||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (hr == S_OK && This->decode_info.reverse_bgr)
|
||||
{
|
||||
if (This->decode_info.format == &GUID_WICPixelFormat24bppBGR)
|
||||
{
|
||||
UINT i, total_pixels;
|
||||
BYTE *pixel, temp;
|
||||
|
||||
total_pixels = This->decode_info.tile_width * This->decode_info.tile_height;
|
||||
pixel = This->cached_tile;
|
||||
for (i=0; i<total_pixels; i++)
|
||||
{
|
||||
temp = pixel[2];
|
||||
pixel[2] = pixel[0];
|
||||
pixel[0] = temp;
|
||||
pixel += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
This->cached_tile_x = tile_x;
|
||||
This->cached_tile_y = tile_y;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
|
||||
{
|
||||
TiffFrameDecode *This = (TiffFrameDecode*)iface;
|
||||
UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
|
||||
UINT tile_x, tile_y;
|
||||
WICRect rc;
|
||||
HRESULT hr=S_OK;
|
||||
BYTE *dst_tilepos;
|
||||
UINT bytesperrow;
|
||||
|
||||
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
|
||||
if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width ||
|
||||
prc->Y+prc->Height > This->decode_info.height)
|
||||
return E_INVALIDARG;
|
||||
|
||||
bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8;
|
||||
|
||||
if (cbStride < bytesperrow)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((cbStride * prc->Height) > cbBufferSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
min_tile_x = prc->X / This->decode_info.tile_width;
|
||||
min_tile_y = prc->Y / This->decode_info.tile_height;
|
||||
max_tile_x = (prc->X+prc->Width-1) / This->decode_info.tile_width;
|
||||
max_tile_y = (prc->Y+prc->Height-1) / This->decode_info.tile_height;
|
||||
|
||||
EnterCriticalSection(&This->parent->lock);
|
||||
|
||||
for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
|
||||
{
|
||||
for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
|
||||
{
|
||||
if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
|
||||
{
|
||||
hr = TiffFrameDecode_ReadTile(This, tile_x, tile_y);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (prc->X < tile_x * This->decode_info.tile_width)
|
||||
rc.X = 0;
|
||||
else
|
||||
rc.X = prc->X - tile_x * This->decode_info.tile_width;
|
||||
|
||||
if (prc->Y < tile_y * This->decode_info.tile_height)
|
||||
rc.Y = 0;
|
||||
else
|
||||
rc.Y = prc->Y - tile_y * This->decode_info.tile_height;
|
||||
|
||||
if (prc->X+prc->Width > (tile_x+1) * This->decode_info.tile_width)
|
||||
rc.Width = This->decode_info.tile_width - rc.X;
|
||||
else
|
||||
rc.Width = prc->Width + rc.X - prc->X;
|
||||
|
||||
if (prc->Y+prc->Height > (tile_y+1) * This->decode_info.tile_height)
|
||||
rc.Height = This->decode_info.tile_height - rc.Y;
|
||||
else
|
||||
rc.Height = prc->Height + rc.Y - prc->Y;
|
||||
|
||||
dst_tilepos = pbBuffer + (cbStride * (rc.Y - prc->Y)) +
|
||||
((This->decode_info.bpp * (rc.X - prc->X) + 7) / 8);
|
||||
|
||||
hr = copy_pixels(This->decode_info.bpp, This->cached_tile,
|
||||
This->decode_info.tile_width, This->decode_info.tile_height, This->decode_info.tile_stride,
|
||||
&rc, cbStride, cbBufferSize, dst_tilepos);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LeaveCriticalSection(&This->parent->lock);
|
||||
TRACE("<-- 0x%x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->parent->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface,
|
||||
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
|
||||
{
|
||||
FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
|
||||
IWICBitmapSource **ppIThumbnail)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = {
|
||||
TiffFrameDecode_QueryInterface,
|
||||
TiffFrameDecode_AddRef,
|
||||
TiffFrameDecode_Release,
|
||||
TiffFrameDecode_GetSize,
|
||||
TiffFrameDecode_GetPixelFormat,
|
||||
TiffFrameDecode_GetResolution,
|
||||
TiffFrameDecode_CopyPalette,
|
||||
TiffFrameDecode_CopyPixels,
|
||||
TiffFrameDecode_GetMetadataQueryReader,
|
||||
TiffFrameDecode_GetColorContexts,
|
||||
TiffFrameDecode_GetThumbnail
|
||||
};
|
||||
|
||||
HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
{
|
||||
HRESULT ret;
|
||||
TiffDecoder *This;
|
||||
|
||||
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
|
||||
|
||||
if (!load_libtiff())
|
||||
{
|
||||
ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffDecoder));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &TiffDecoder_Vtbl;
|
||||
This->ref = 1;
|
||||
This->stream = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock");
|
||||
This->tiff = NULL;
|
||||
This->initialized = FALSE;
|
||||
|
||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||
IUnknown_Release((IUnknown*)This);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* !SONAME_LIBTIFF */
|
||||
|
||||
HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
{
|
||||
ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@ extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void**
|
||||
extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
|
||||
extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
|
||||
extern HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
|
||||
extern HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
|
||||
|
||||
extern HRESULT PaletteImpl_Create(IWICPalette **palette);
|
||||
extern HRESULT StreamImpl_Create(IWICStream **stream);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<file>propertybag.c</file>
|
||||
<file>regsvr.c</file>
|
||||
<file>stream.c</file>
|
||||
<file>tiffformat.c</file>
|
||||
<file>ungif.c</file>
|
||||
|
||||
<file>version.rc</file>
|
||||
|
||||
@@ -102,8 +102,8 @@ static CRITICAL_SECTION_DEBUG WININET_cs_debug =
|
||||
static CRITICAL_SECTION WININET_cs = { &WININET_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static object_header_t **WININET_Handles;
|
||||
static UINT WININET_dwNextHandle;
|
||||
static UINT WININET_dwMaxHandles;
|
||||
static UINT_PTR WININET_dwNextHandle;
|
||||
static UINT_PTR WININET_dwMaxHandles;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -122,7 +122,7 @@ static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l','
|
||||
HINTERNET WININET_AllocHandle( object_header_t *info )
|
||||
{
|
||||
object_header_t **p;
|
||||
UINT handle = 0, num;
|
||||
UINT_PTR handle = 0, num;
|
||||
|
||||
list_init( &info->children );
|
||||
|
||||
@@ -173,7 +173,7 @@ object_header_t *WININET_AddRef( object_header_t *info )
|
||||
object_header_t *WININET_GetObject( HINTERNET hinternet )
|
||||
{
|
||||
object_header_t *info = NULL;
|
||||
UINT handle = (UINT) hinternet;
|
||||
UINT_PTR handle = (UINT_PTR) hinternet;
|
||||
|
||||
EnterCriticalSection( &WININET_cs );
|
||||
|
||||
@@ -183,7 +183,7 @@ object_header_t *WININET_GetObject( HINTERNET hinternet )
|
||||
|
||||
LeaveCriticalSection( &WININET_cs );
|
||||
|
||||
TRACE("handle %d -> %p\n", handle, info);
|
||||
TRACE("handle %ld -> %p\n", handle, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ BOOL WININET_Release( object_header_t *info )
|
||||
BOOL WININET_FreeHandle( HINTERNET hinternet )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
UINT handle = (UINT) hinternet;
|
||||
UINT_PTR handle = (UINT_PTR) hinternet;
|
||||
object_header_t *info = NULL, *child, *next;
|
||||
|
||||
EnterCriticalSection( &WININET_cs );
|
||||
@@ -229,7 +229,7 @@ BOOL WININET_FreeHandle( HINTERNET hinternet )
|
||||
if( WININET_Handles[handle] )
|
||||
{
|
||||
info = WININET_Handles[handle];
|
||||
TRACE( "destroying handle %d for object %p\n", handle+1, info);
|
||||
TRACE( "destroying handle %ld for object %p\n", handle+1, info);
|
||||
WININET_Handles[handle] = NULL;
|
||||
ret = TRUE;
|
||||
}
|
||||
@@ -245,8 +245,8 @@ BOOL WININET_FreeHandle( HINTERNET hinternet )
|
||||
/* Free all children as native does */
|
||||
LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry )
|
||||
{
|
||||
TRACE( "freeing child handle %d for parent handle %d\n",
|
||||
(UINT)child->hInternet, handle+1);
|
||||
TRACE( "freeing child handle %ld for parent handle %ld\n",
|
||||
(UINT_PTR)child->hInternet, handle+1);
|
||||
WININET_FreeHandle( child->hInternet );
|
||||
}
|
||||
WININET_Release( info );
|
||||
|
||||
@@ -986,9 +986,9 @@ static DWORD URLCache_CopyEntry(
|
||||
ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4));
|
||||
dwRequiredSize = DWORD_ALIGN(dwRequiredSize);
|
||||
if (bUnicode)
|
||||
lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0);
|
||||
lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0);
|
||||
else
|
||||
lenUrl = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
|
||||
lenUrl = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
|
||||
dwRequiredSize += (lenUrl + 1) * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
||||
|
||||
/* FIXME: is source url optional? */
|
||||
@@ -998,9 +998,9 @@ static DWORD URLCache_CopyEntry(
|
||||
|
||||
lpCacheEntryInfo->lpszSourceUrlName = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenUrlBytes;
|
||||
if (bUnicode)
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1);
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1);
|
||||
else
|
||||
memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes);
|
||||
memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes);
|
||||
}
|
||||
|
||||
if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
|
||||
@@ -1029,7 +1029,7 @@ static DWORD URLCache_CopyEntry(
|
||||
if (*lpdwBufferSize >= dwRequiredSize)
|
||||
{
|
||||
lpCacheEntryInfo->lpHeaderInfo = (LPBYTE)lpCacheEntryInfo + dwRequiredSize - pUrlEntry->dwHeaderInfoSize - 1;
|
||||
memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize);
|
||||
memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize);
|
||||
((LPBYTE)lpCacheEntryInfo)[dwRequiredSize - 1] = '\0';
|
||||
}
|
||||
if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
|
||||
@@ -1041,18 +1041,18 @@ static DWORD URLCache_CopyEntry(
|
||||
int lenExtension;
|
||||
|
||||
if (bUnicode)
|
||||
lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0);
|
||||
lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0);
|
||||
else
|
||||
lenExtension = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1;
|
||||
lenExtension = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1;
|
||||
dwRequiredSize += lenExtension * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
|
||||
|
||||
if (*lpdwBufferSize >= dwRequiredSize)
|
||||
{
|
||||
lpCacheEntryInfo->lpszFileExtension = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenExtension;
|
||||
if (bUnicode)
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension);
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension);
|
||||
else
|
||||
memcpy(lpCacheEntryInfo->lpszFileExtension, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR));
|
||||
memcpy(lpCacheEntryInfo->lpszFileExtension, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR));
|
||||
}
|
||||
|
||||
if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
|
||||
@@ -1175,8 +1175,8 @@ static inline HASH_CACHEFILE_ENTRY * URLCache_HashEntryFromOffset(LPCURLCACHE_HE
|
||||
static inline BOOL URLCache_IsHashEntryValid(LPCURLCACHE_HEADER pHeader, const HASH_CACHEFILE_ENTRY *pHashEntry)
|
||||
{
|
||||
/* check pHashEntry located within acceptable bounds in the URL cache mapping */
|
||||
return ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) &&
|
||||
((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
|
||||
return ((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) >= ENTRY_START_OFFSET) &&
|
||||
((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) < pHeader->dwFileSize);
|
||||
}
|
||||
|
||||
static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry)
|
||||
@@ -1557,15 +1557,15 @@ BOOL WINAPI GetUrlCacheEntryInfoA(
|
||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||
{
|
||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
||||
TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
|
||||
TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
|
||||
if (pUrlEntry->dwOffsetHeaderInfo)
|
||||
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
|
||||
TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
|
||||
|
||||
if (lpdwCacheEntryInfoBufferSize)
|
||||
{
|
||||
@@ -1639,14 +1639,14 @@ BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl,
|
||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||
{
|
||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
||||
TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
|
||||
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
|
||||
TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
|
||||
TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
|
||||
|
||||
if (lpdwCacheEntryInfoBufferSize)
|
||||
{
|
||||
@@ -3265,9 +3265,9 @@ BOOL WINAPI FindNextUrlCacheEntryA(
|
||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||
continue;
|
||||
|
||||
pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
|
||||
TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
|
||||
TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
|
||||
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
||||
TRACE("Found URL: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
|
||||
TRACE("Header info: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
|
||||
|
||||
error = URLCache_CopyEntry(
|
||||
pContainer,
|
||||
@@ -3563,7 +3563,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredA( LPCSTR url, DWORD dwFlags, FILETIME* pftLas
|
||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||
{
|
||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3625,7 +3625,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
|
||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||
{
|
||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1348,7 +1348,7 @@ static BOOL CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType,
|
||||
link->dwLinkChoice = SPC_FILE_LINK_CHOICE;
|
||||
for (i = 0; i < dataLen / sizeof(WCHAR); i++)
|
||||
link->u.pwszFile[i] =
|
||||
hton16(*(WORD *)(ptr + i * sizeof(WCHAR)));
|
||||
hton16(*(const WORD *)(ptr + i * sizeof(WCHAR)));
|
||||
link->u.pwszFile[realDataLen / sizeof(WCHAR)] = '\0';
|
||||
TRACE("returning file %s\n", debugstr_w(link->u.pwszFile));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#ifndef _NTSECPKG_H
|
||||
#define _NTSECPKG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Flags for the MachineState field in SECPKG_PARAMETERS */
|
||||
#define SECPKG_STATE_ENCRYPTION_PERMITTED 0x01
|
||||
#define SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED 0x02
|
||||
@@ -30,6 +34,9 @@
|
||||
#define SECPKG_INTERFACE_VERSION 0x10000
|
||||
#define SECPKG_INTERFACE_VERSION_2 0x20000
|
||||
#define SECPKG_INTERFACE_VERSION_3 0x40000
|
||||
#define SECPKG_INTERFACE_VERSION_4 0x80000
|
||||
#define SECPKG_INTERFACE_VERSION_5 0x100000
|
||||
#define SECPKG_INTERFACE_VERSION_6 0x200000
|
||||
|
||||
/* enum definitions for Secure Service Provider/Authentication Packages */
|
||||
typedef enum _LSA_TOKEN_INFORMATION_TYPE {
|
||||
@@ -140,6 +147,11 @@ typedef struct _SECPKG_EXTENDED_INFORMATION {
|
||||
} Info;
|
||||
} SECPKG_EXTENDED_INFORMATION, *PSECPKG_EXTENDED_INFORMATION;
|
||||
|
||||
typedef struct _SECPKG_TARGETINFO {
|
||||
PSID DomainSid;
|
||||
PCWSTR ComputerName;
|
||||
} SECPKG_TARGETINFO, *PSECPKG_TARGETINFO;
|
||||
|
||||
/* callbacks implemented by SSP/AP dlls and called by the LSA */
|
||||
typedef VOID (NTAPI *PLSA_CALLBACK_FUNCTION)(ULONG_PTR, ULONG_PTR, PSecBuffer,
|
||||
PSecBuffer);
|
||||
@@ -341,6 +353,18 @@ typedef NTSTATUS (NTAPI SpSetContextAttributesFn)(LSA_SEC_HANDLE, ULONG, PVOID,
|
||||
ULONG);
|
||||
typedef NTSTATUS (NTAPI SpSetCredentialsAttributesFn)(LSA_SEC_HANDLE, ULONG,
|
||||
PVOID, ULONG);
|
||||
typedef NTSTATUS (NTAPI SpChangeAccountPasswordFn)(PUNICODE_STRING,
|
||||
PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, BOOLEAN, PSecBufferDesc);
|
||||
typedef NTSTATUS (NTAPI SpQueryMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING,
|
||||
ULONG, PULONG, PUCHAR *, PLSA_SEC_HANDLE);
|
||||
typedef NTSTATUS (NTAPI SpExchangeMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING,
|
||||
ULONG, ULONG, PUCHAR, PLSA_SEC_HANDLE);
|
||||
typedef NTSTATUS (NTAPI SpGetCredUIContextFn)(LSA_SEC_HANDLE, GUID *, PULONG,
|
||||
PUCHAR *);
|
||||
typedef NTSTATUS (NTAPI SpUpdateCredentialsFn)(LSA_SEC_HANDLE, GUID *, ULONG,
|
||||
PUCHAR);
|
||||
typedef NTSTATUS (NTAPI SpValidateTargetInfoFn)(PLSA_CLIENT_REQUEST, PVOID,
|
||||
PVOID, ULONG, PSECPKG_TARGETINFO);
|
||||
|
||||
/* User-mode functions implemented by SSP/AP obtainable by a dispatch table */
|
||||
typedef NTSTATUS (NTAPI SpInstanceInitFn)(ULONG, PSECPKG_DLL_FUNCTIONS,
|
||||
@@ -402,6 +426,15 @@ typedef struct SECPKG_FUNCTION_TABLE {
|
||||
/* Packages with version SECPKG_INTERFACE_VERSION_2 end here */
|
||||
SpSetCredentialsAttributesFn *SetCredentialsAttributes;
|
||||
/* Packages with version SECPKG_INTERFACE_VERSION_3 end here */
|
||||
SpChangeAccountPasswordFn *ChangeAccountPassword;
|
||||
/* Packages with version SECPKG_INTERFACE_VERSION_4 end here */
|
||||
SpQueryMetaDataFn *QueryMetaData;
|
||||
SpExchangeMetaDataFn *ExchangeMetaData;
|
||||
SpGetCredUIContextFn *GetCredUIContext;
|
||||
SpUpdateCredentialsFn *UpdateCredentials;
|
||||
/* Packages with version SECPKG_INTERFACE_VERSION_5 end here */
|
||||
SpValidateTargetInfoFn *ValidateTargetInfo;
|
||||
/* Packages with version SECPKG_INTERFACE_VERSION_6 end here */
|
||||
} SECPKG_FUNCTION_TABLE,
|
||||
*PSECPKG_FUNCTION_TABLE;
|
||||
|
||||
@@ -432,4 +465,7 @@ typedef NTSTATUS (NTAPI *SpLsaModeInitializeFn)(ULONG, PULONG,
|
||||
typedef NTSTATUS (WINAPI *SpUserModeInitializeFn)(ULONG, PULONG,
|
||||
PSECPKG_USER_FUNCTION_TABLE *, PULONG);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _NTSECPKG_H */
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<file>richole.idl</file>
|
||||
<file>sensevts.idl</file>
|
||||
<file>servprov.idl</file>
|
||||
<file>shdeprecated.idl</file>
|
||||
<file>shldisp.idl</file>
|
||||
<file>shobjidl.idl</file>
|
||||
<file>shtypes.idl</file>
|
||||
@@ -68,6 +69,8 @@
|
||||
<file>xmldso.idl</file>
|
||||
<file>xmldom.idl</file>
|
||||
<file>xmllite.idl</file>
|
||||
<file>wia_lh.idl</file>
|
||||
<file>wia_xp.idl</file>
|
||||
</module>
|
||||
<module name="stdole2" type="embeddedtypelib">
|
||||
<file>stdole2.idl</file>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Deprecated shell interfaces
|
||||
*
|
||||
* Copyright (C) 2010 Nikolay Sivov for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
import "objidl.idl";
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(5836fb00-8187-11cf-a12b-00aa004ae837)
|
||||
]
|
||||
interface IShellService : IUnknown
|
||||
{
|
||||
HRESULT SetOwner( [in] IUnknown *pUnk );
|
||||
}
|
||||
@@ -1028,24 +1028,6 @@ typedef struct _DLLVERSIONINFO2 {
|
||||
HRESULT WINAPI DllInstall(BOOL,LPCWSTR) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
#if (_WIN32_IE >= 0x0600)
|
||||
#define SHGVSPB_PERUSER 0x00000001
|
||||
#define SHGVSPB_ALLUSERS 0x00000002
|
||||
#define SHGVSPB_PERFOLDER 0x00000004
|
||||
#define SHGVSPB_ALLFOLDERS 0x00000008
|
||||
#define SHGVSPB_INHERIT 0x00000010
|
||||
#define SHGVSPB_ROAM 0x00000020
|
||||
#define SHGVSPB_NOAUTODEFAULTS 0x80000000
|
||||
|
||||
#define SHGVSPB_FOLDER (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER)
|
||||
#define SHGVSPB_FOLDERNODEFAULTS (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER | SHGVSPB_NOAUTODEFAULTS)
|
||||
#define SHGVSPB_USERDEFAULTS (SHGVSPB_PERUSER | SHGVSPB_ALLFOLDERS)
|
||||
#define SHGVSPB_GLOBALDEAFAULTS (SHGVSPB_ALLUSERS | SHGVSPB_ALLFOLDERS)
|
||||
|
||||
HRESULT WINAPI SHGetViewStatePropertyBag(LPCITEMIDLIST pidl, LPWSTR bag_name, DWORD flags, REFIID riid, void **ppv);
|
||||
#endif /* (_WIN32_IE >= 0x0600) */
|
||||
|
||||
|
||||
/* IsOS definitions */
|
||||
|
||||
#define OS_WIN32SORGREATER 0x00
|
||||
@@ -1103,6 +1085,15 @@ BOOL WINAPI IsOS(DWORD);
|
||||
#define FDTF_RTLDATE 0x00000200
|
||||
#define FDTF_NOAUTOREADINGORDER 0x00000400
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IID *piid;
|
||||
int dwOffset;
|
||||
} QITAB, *LPQITAB;
|
||||
|
||||
HRESULT WINAPI QISearch(void* base, const QITAB *pqit, REFIID riid, void **ppv);
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -31,6 +31,147 @@ extern "C" {
|
||||
|
||||
DEFINE_GUID(CLSID_Sti, 0xB323F8E0L, 0x2E68, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
|
||||
|
||||
DEFINE_GUID(IID_IStillImageW, 0x641BD880, 0x2DC8, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
|
||||
|
||||
DEFINE_GUID(IID_IStillImageA, 0xA7B1F740, 0x1D7F, 0x11D1, 0xAC, 0xA9, 0x00, 0xA0, 0x24, 0x38, 0xAD, 0x48);
|
||||
|
||||
#define STI_VERSION_REAL 0x00000002
|
||||
#define STI_VERSION_FLAG_UNICODE 0x01000000
|
||||
|
||||
#ifndef WINE_NO_UNICODE_MACROS
|
||||
# ifdef UNICODE
|
||||
# define STI_VERSION (STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE)
|
||||
# else
|
||||
# define STI_VERSION (STI_VERSION_REAL)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct IStillImageA *PSTIA;
|
||||
typedef struct IStillImageW *PSTIW;
|
||||
DECL_WINELIB_TYPE_AW(PSTI)
|
||||
typedef struct IStillImageA *LPSTILLIMAGEA;
|
||||
typedef struct IStillImageW *LPSTILLIMAGEW;
|
||||
DECL_WINELIB_TYPE_AW(LPSTILLIMAGE)
|
||||
typedef struct IStiDeviceA *PSTIDEVICEA;
|
||||
typedef struct IStiDeviceW *PSTIDEVICEW;
|
||||
DECL_WINELIB_TYPE_AW(PSTIDEVICE)
|
||||
|
||||
HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter);
|
||||
HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter);
|
||||
#define StiCreateInstance WINELIB_NAME_AW(StiCreateInstance)
|
||||
|
||||
typedef DWORD STI_DEVICE_TYPE;
|
||||
typedef enum _STI_DEVICE_MJ_TYPE
|
||||
{
|
||||
StiDeviceTypeDefault = 0,
|
||||
StiDeviceTypeScanner = 1,
|
||||
StiDeviceTypeDigitalCamera = 2,
|
||||
StiDeviceTypeStreamingVideo = 3
|
||||
} STI_DEVICE_MJ_TYPE;
|
||||
|
||||
#define GET_STIDEVICE_TYPE(dwDevType) HIWORD(dwDevType)
|
||||
#define GET_STIDEVICE_SUBTYPE(dwDevType) LOWORD(dwDevType)
|
||||
|
||||
typedef struct _STI_DEV_CAPS {
|
||||
DWORD dwGeneric;
|
||||
} STI_DEV_CAPS, *PSTI_DEV_CAPS;
|
||||
|
||||
#define STI_MAX_INTERNAL_NAME_LENGTH 128
|
||||
|
||||
typedef struct _STI_DEVICE_INFORMATIONW {
|
||||
DWORD dwSize;
|
||||
STI_DEVICE_TYPE DeviceType;
|
||||
WCHAR szDeviceInternalName[STI_MAX_INTERNAL_NAME_LENGTH];
|
||||
STI_DEV_CAPS DeviceCapabilities;
|
||||
DWORD dwHardwareConfiguration;
|
||||
LPWSTR pszVendorDescription;
|
||||
LPWSTR pszDeviceDescription;
|
||||
LPWSTR pszPortName;
|
||||
LPWSTR pszPropProvider;
|
||||
LPWSTR pszLocalName;
|
||||
} STI_DEVICE_INFORMATIONW, *PSTI_DEVICE_INFORMATIONW;
|
||||
|
||||
typedef STI_DEVICE_INFORMATIONW STI_DEVICE_INFORMATION;
|
||||
typedef PSTI_DEVICE_INFORMATIONW PSTI_DEVICE_INFORMATION;
|
||||
|
||||
#define MAX_NOTIFICATION_DATA 64
|
||||
|
||||
typedef struct _STINOTIFY {
|
||||
DWORD dwSize;
|
||||
GUID guidNotificationCode;
|
||||
BYTE abNotificationData[MAX_NOTIFICATION_DATA];
|
||||
} STINOTIFY,*LPSTINOTIFY;
|
||||
|
||||
#define INTERFACE IStillImageW
|
||||
DECLARE_INTERFACE_(IStillImageW, IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IStillImageW methods ***/
|
||||
STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
|
||||
STDMETHOD(GetDeviceList)(THIS_ DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer) PURE;
|
||||
STDMETHOD(GetDeviceInfo)(THIS_ LPWSTR pwszDeviceName, LPVOID *ppBuffer) PURE;
|
||||
STDMETHOD(CreateDevice)(THIS_ LPWSTR pwszDeviceName, DWORD dwMode, PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter) PURE;
|
||||
STDMETHOD(GetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, LPDWORD cbData) PURE;
|
||||
STDMETHOD(SetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, DWORD type, LPBYTE pData, DWORD cbData) PURE;
|
||||
STDMETHOD(GetSTILaunchInformation)(THIS_ LPWSTR pwszDeviceName, DWORD *pdwEventCode, LPWSTR pwszEventName) PURE;
|
||||
STDMETHOD(RegisterLaunchApplication)(THIS_ LPWSTR pwszAppName, LPWSTR pwszCommandLine) PURE;
|
||||
STDMETHOD(UnregisterLaunchApplication)(THIS_ LPWSTR pwszAppName) PURE;
|
||||
STDMETHOD(EnableHwNotifications)(THIS_ LPCWSTR pwszDeviceName, BOOL bNewState) PURE;
|
||||
STDMETHOD(GetHwNotificationState)(THIS_ LPCWSTR pwszDeviceName, BOOL *pbCurrentState) PURE;
|
||||
STDMETHOD(RefreshDeviceBus)(THIS_ LPCWSTR pwszDeviceName) PURE;
|
||||
STDMETHOD(LaunchApplicationForDevice)(THIS_ LPWSTR pwszDeviceName, LPWSTR pwszAppName, LPSTINOTIFY pStiNotify);
|
||||
STDMETHOD(SetupDeviceParameters)(THIS_ PSTI_DEVICE_INFORMATIONW pDevInfo);
|
||||
STDMETHOD(WriteToErrorLog)(THIS_ DWORD dwMessageType, LPCWSTR pszMessage) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
/*** IUnknown methods ***/
|
||||
#define IStillImage_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IStillImage_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IStillImage_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IStillImage methods ***/
|
||||
#define IStillImage_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
|
||||
#define IStillImage_GetDeviceList(p,a,b,c,d) (p)->lpVtbl->GetDeviceList(p,a,b,c,d)
|
||||
#define IStillImage_GetDeviceInfo(p,a,b) (p)->lpVtbl->GetDeviceInfo(p,a,b)
|
||||
#define IStillImage_CreateDevice(p,a,b,c,d) (p)->lpVtbl->CreateDevice(p,a,b,c,d)
|
||||
#define IStillImage_GetDeviceValue(p,a,b,c,d,e) (p)->lpVtbl->GetDeviceValue(p,a,b,c,d,e)
|
||||
#define IStillImage_SetDeviceValue(p,a,b,c,d,e) (p)->lpVtbl->SetDeviceValue(p,a,b,c,d,e)
|
||||
#define IStillImage_GetSTILaunchInformation(p,a,b,c) (p)->lpVtbl->GetSTILaunchInformation(p,a,b,c)
|
||||
#define IStillImage_RegisterLaunchApplication(p,a,b) (p)->lpVtbl->RegisterLaunchApplication(p,a,b)
|
||||
#define IStillImage_UnregisterLaunchApplication(p,a) (p)->lpVtbl->UnregisterLaunchApplication(p,a)
|
||||
#define IStillImage_EnableHwNotifications(p,a,b) (p)->lpVtbl->EnableHwNotifications(p,a,b)
|
||||
#define IStillImage_GetHwNotificationState(p,a,b) (p)->lpVtbl->GetHwNotificationState(p,a,b)
|
||||
#define IStillImage_RefreshDeviceBus(p,a) (p)->lpVtbl->RefreshDeviceBus(p,a)
|
||||
#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->lpVtbl->LaunchApplicationForDevice(p,a,b,c)
|
||||
#define IStillImage_SetupDeviceParameters(p,a) (p)->lpVtbl->SetupDeviceParameters(p,a)
|
||||
#define IStillImage_WriteToErrorLog(p,a,b) (p)->lpVtbl->WriteToErrorLog(p,a,b)
|
||||
#else
|
||||
/*** IUnknown methods ***/
|
||||
#define IStillImage_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
|
||||
#define IStillImage_AddRef(p) (p)->AddRef()
|
||||
#define IStillImage_Release(p) (p)->Release()
|
||||
/*** IStillImage methods ***/
|
||||
#define IStillImage_Initialize(p,a,b) (p)->Initialize(a,b)
|
||||
#define IStillImage_GetDeviceList(p,a,b,c,d) (p)->GetDeviceList(a,b,c,d)
|
||||
#define IStillImage_GetDeviceInfo(p,a,b) (p)->GetDeviceInfo(a,b)
|
||||
#define IStillImage_CreateDevice(p,a,b,c,d) (p)->CreateDevice(a,b,c,d)
|
||||
#define IStillImage_GetDeviceValue(p,a,b,c,d,e) (p)->GetDeviceValue(a,b,c,d,e)
|
||||
#define IStillImage_SetDeviceValue(p,a,b,c,d,e) (p)->SetDeviceValue(a,b,c,d,e)
|
||||
#define IStillImage_GetSTILaunchInformation(p,a,b,c) (p)->GetSTILaunchInformation(a,b,c)
|
||||
#define IStillImage_RegisterLaunchApplication(p,a,b) (p)->RegisterLaunchApplication(a,b)
|
||||
#define IStillImage_UnregisterLaunchApplication(p,a) (p)->UnregisterLaunchApplication(a)
|
||||
#define IStillImage_EnableHwNotifications(p,a,b) (p)->EnableHwNotifications(a,b)
|
||||
#define IStillImage_GetHwNotificationState(p,a,b) (p)->GetHwNotificationState(a,b)
|
||||
#define IStillImage_RefreshDeviceBus(p,a) (p)->RefreshDeviceBus(a)
|
||||
#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->LaunchApplicationForDevice(a,b,c)
|
||||
#define IStillImage_SetupDeviceParameters(p,a) (p)->SetupDeviceParameters(a)
|
||||
#define IStillImage_WriteToErrorLog(p,a,b) (p)->WriteToErrorLog(a,b)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __WINESRC__
|
||||
#error Specify wia_lh.h or wia_xp.h explicitly in Wine
|
||||
#endif
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0600)
|
||||
#include <wia_lh.h>
|
||||
#elif (_WIN32_WINNT >= 0x0501)
|
||||
#include <wia_xp.h>
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
import "wtypes.idl";
|
||||
import "objidl.idl";
|
||||
|
||||
interface IEnumWIA_DEV_INFO;
|
||||
interface IWiaItem;
|
||||
interface IWiaEventCallback;
|
||||
|
||||
cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);")
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811)
|
||||
]
|
||||
interface IWiaDevMgr : IUnknown
|
||||
{
|
||||
HRESULT EnumDeviceInfo(
|
||||
[in] LONG lFlag,
|
||||
[retval, out] IEnumWIA_DEV_INFO **ppIEnum);
|
||||
|
||||
HRESULT CreateDevice(
|
||||
[in] BSTR bstrDeviceID,
|
||||
[out] IWiaItem **ppWiaItemRoot);
|
||||
|
||||
HRESULT SelectDeviceDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[in, out] BSTR *pbstrDeviceID,
|
||||
[retval, out] IWiaItem **ppItemRoot);
|
||||
|
||||
HRESULT SelectDeviceDlgID(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[retval, out] BSTR *pbstrDeviceID);
|
||||
|
||||
HRESULT GetImageDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[in] LONG lIntent,
|
||||
[in] IWiaItem *pItemRoot,
|
||||
[in] BSTR bstrFilename,
|
||||
[in, out] GUID *pguidFormat);
|
||||
|
||||
HRESULT RegisterEventCallbackProgram(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[in] BSTR bstrCommandline,
|
||||
[in] BSTR bstrName,
|
||||
[in] BSTR bstrDescription,
|
||||
[in] BSTR bstrIcon);
|
||||
|
||||
HRESULT RegisterEventCallbackInterface(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[unique, in] IWiaEventCallback *pIWiaEventCallback,
|
||||
[out] IUnknown **pEventObject);
|
||||
|
||||
HRESULT RegisterEventCallbackCLSID(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[unique, in] const GUID *pClsID,
|
||||
[in] BSTR bstrName,
|
||||
[in] BSTR bstrDescription,
|
||||
[in] BSTR bstrIcon);
|
||||
|
||||
HRESULT AddDeviceDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lFlags);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811)
|
||||
]
|
||||
interface IEnumWIA_DEV_INFO : IUnknown
|
||||
{
|
||||
/* fill in */
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(4db1ad10-3391-11d2-9a33-00c04fa36145)
|
||||
]
|
||||
interface IWiaItem : IUnknown
|
||||
{
|
||||
/* FIXME: fill in */
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e)
|
||||
]
|
||||
interface IWiaEventCallback : IUnknown
|
||||
{
|
||||
HRESULT ImageEventCallback(
|
||||
[in] const GUID *pEventGUID,
|
||||
[in] BSTR bstrEventDescription,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] BSTR bstrDeviceDescription,
|
||||
[in] DWORD dwDeviceType,
|
||||
[in] BSTR bstrFullItemName,
|
||||
[in,out] ULONG *pulEventType,
|
||||
[in] ULONG ulReserved);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2009 Damjan Jovanovic
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
import "wtypes.idl";
|
||||
import "objidl.idl";
|
||||
|
||||
interface IEnumWIA_DEV_INFO;
|
||||
interface IWiaItem;
|
||||
interface IWiaEventCallback;
|
||||
|
||||
cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);")
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811)
|
||||
]
|
||||
interface IWiaDevMgr : IUnknown
|
||||
{
|
||||
HRESULT EnumDeviceInfo(
|
||||
[in] LONG lFlag,
|
||||
[retval, out] IEnumWIA_DEV_INFO **ppIEnum);
|
||||
|
||||
HRESULT CreateDevice(
|
||||
[in] BSTR bstrDeviceID,
|
||||
[out] IWiaItem **ppWiaItemRoot);
|
||||
|
||||
HRESULT SelectDeviceDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[in, out] BSTR *pbstrDeviceID,
|
||||
[retval, out] IWiaItem **ppItemRoot);
|
||||
|
||||
HRESULT SelectDeviceDlgID(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[retval, out] BSTR *pbstrDeviceID);
|
||||
|
||||
HRESULT GetImageDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lDeviceType,
|
||||
[in] LONG lFlags,
|
||||
[in] LONG lIntent,
|
||||
[in] IWiaItem *pItemRoot,
|
||||
[in] BSTR bstrFilename,
|
||||
[in, out] GUID *pguidFormat);
|
||||
|
||||
HRESULT RegisterEventCallbackProgram(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[in] BSTR bstrCommandline,
|
||||
[in] BSTR bstrName,
|
||||
[in] BSTR bstrDescription,
|
||||
[in] BSTR bstrIcon);
|
||||
|
||||
HRESULT RegisterEventCallbackInterface(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[unique, in] IWiaEventCallback *pIWiaEventCallback,
|
||||
[out] IUnknown **pEventObject);
|
||||
|
||||
HRESULT RegisterEventCallbackCLSID(
|
||||
[in] LONG lFlags,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] const GUID *pEventGUID,
|
||||
[unique, in] const GUID *pClsID,
|
||||
[in] BSTR bstrName,
|
||||
[in] BSTR bstrDescription,
|
||||
[in] BSTR bstrIcon);
|
||||
|
||||
HRESULT AddDeviceDlg(
|
||||
[in] HWND hwndParent,
|
||||
[in] LONG lFlags);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811)
|
||||
]
|
||||
interface IEnumWIA_DEV_INFO : IUnknown
|
||||
{
|
||||
/* fill in */
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(4db1ad10-3391-11d2-9a33-00c04fa36145)
|
||||
]
|
||||
interface IWiaItem : IUnknown
|
||||
{
|
||||
/* FIXME: fill in */
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e)
|
||||
]
|
||||
interface IWiaEventCallback : IUnknown
|
||||
{
|
||||
HRESULT ImageEventCallback(
|
||||
[in] const GUID *pEventGUID,
|
||||
[in] BSTR bstrEventDescription,
|
||||
[in] BSTR bstrDeviceID,
|
||||
[in] BSTR bstrDeviceDescription,
|
||||
[in] DWORD dwDeviceType,
|
||||
[in] BSTR bstrFullItemName,
|
||||
[in,out] ULONG *pulEventType,
|
||||
[in] ULONG ulReserved);
|
||||
}
|
||||
@@ -52,13 +52,13 @@ reactos/dll/win32/comctl32 # Autosync ??
|
||||
reactos/dll/win32/comdlg32 # Autosync
|
||||
reactos/dll/win32/compstui # Autosync
|
||||
reactos/dll/win32/credui # Autosync
|
||||
reactos/dll/win32/crypt32 # Synced to Wine-1_1_40
|
||||
reactos/dll/win32/crypt32 # Synced to Wine-1_1_43
|
||||
reactos/dll/win32/cryptdlg # Autosync
|
||||
reactos/dll/win32/cryptdll # Autosync
|
||||
reactos/dll/win32/cryptnet # Autosync
|
||||
reactos/dll/win32/cryptui # Autosync
|
||||
reactos/dll/win32/dbghelp # Synced to Wine-20080802
|
||||
reactos/dll/win32/dciman32 # Synced to Wine-1_0-rc2
|
||||
reactos/dll/win32/dciman32 # Synced to Wine-1_1_43
|
||||
reactos/dll/win32/dwmapi # Autosync
|
||||
reactos/dll/win32/fusion # Autosync
|
||||
reactos/dll/win32/gdiplus # Autosync
|
||||
@@ -113,7 +113,7 @@ reactos/dll/win32/mstask # Autosync
|
||||
reactos/dll/win32/msvcrt20 # Autosync
|
||||
reactos/dll/win32/msvfw32 # Autosync
|
||||
reactos/dll/win32/msvidc32 # Autosync
|
||||
reactos/dll/win32/msxml3 # Synced to Wine-1_1_40
|
||||
reactos/dll/win32/msxml3 # Synced to Wine-1_1_43
|
||||
reactos/dll/win32/nddeapi # Autosync
|
||||
reactos/dll/win32/netapi32 # Autosync
|
||||
reactos/dll/win32/ntdsapi # Autosync
|
||||
@@ -144,6 +144,8 @@ reactos/dll/win32/rsabase # Autosync
|
||||
reactos/dll/win32/rsaenh # Autosync
|
||||
reactos/dll/win32/sccbase # Autosync
|
||||
reactos/dll/win32/schannel # Autosync ??
|
||||
reactos/dll/win32/secur32 # Forked
|
||||
reactos/dll/win32/security # Forked (different .spec)
|
||||
reactos/dll/win32/sensapi # Autosync
|
||||
reactos/dll/win32/setupapi # Forked at Wine-20050524
|
||||
reactos/dll/win32/shell32 # Forked at Wine-20071011
|
||||
@@ -154,7 +156,7 @@ reactos/dll/win32/slbcsp # Autosync
|
||||
reactos/dll/win32/softpub # Autosync
|
||||
reactos/dll/win32/spoolss # Autosync
|
||||
reactos/dll/win32/stdole2.tlb # Autosync
|
||||
reactos/dll/win32/sti # Autosync ??
|
||||
reactos/dll/win32/sti # Autosync
|
||||
reactos/dll/win32/sxs # Autosync
|
||||
reactos/dll/win32/tapi32 # Autosync
|
||||
reactos/dll/win32/traffic # Autosync
|
||||
@@ -203,7 +205,7 @@ In addition the following libs, dlls and source files are mostly based on code p
|
||||
from Winehq CVS. If you are looking to update something in these files
|
||||
check Wine current souces first as it may already be fixed.
|
||||
|
||||
reactos/lib/uuid # Synced to Wine-20080114
|
||||
reactos/lib/sdk/uuid # Synced to Wine-1.1.42
|
||||
|
||||
advapi32 -
|
||||
reactos/dll/win32/advapi32/crypt/*.c # ekohl says we're not sharing this
|
||||
|
||||
Reference in New Issue
Block a user