- Update README.WINE.
svn path=/trunk/; revision=46967
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDll);
/* Tell usp10 it is activated usp10 */
- LpkPresent();
+ //LpkPresent();
break;
default:
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;
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;
/*** 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);
}
/* 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) {
}
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;
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 */
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++) {
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
- *buffer = (char)0;
+ *buffer = 0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
/*** 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);
}
/* 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) {
}
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;
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: */
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++) {
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
- *buffer = (char)0;
+ *buffer = 0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
/*** 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);
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: */
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++) {
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
- *buffer = (char)0;
+ *buffer = 0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
NULL, /* SetExtendedInformation */
NULL, /* SetContextAttributes */
NULL, /* SetCredentialsAttributes */
+ NULL, /* ChangeAccountPassword */
+ NULL, /* QueryMetaData */
+ NULL, /* ExchangeMetaData */
+ NULL, /* GetCredUIContext */
+ NULL, /* UpdateCredentials */
+ NULL, /* ValidateTargetInfo */
}, {
NULL, /* InitializePackage */
NULL, /* LsaLogonUser */
NULL, /* SetExtendedInformation */
NULL, /* SetContextAttributes */
NULL, /* SetCredentialsAttributes */
+ NULL, /* ChangeAccountPassword */
+ NULL, /* QueryMetaData */
+ NULL, /* ExchangeMetaData */
+ NULL, /* GetCredUIContext */
+ NULL, /* UpdateCredentials */
+ NULL, /* ValidateTargetInfo */
}
};
{
TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables);
- *PackageVersion = SECPKG_INTERFACE_VERSION_3;
+ *PackageVersion = SECPKG_INTERFACE_VERSION_6;
*pcTables = 2;
*ppTables = secPkgFunctionTable;
#include "mmsystem.h"
#include "objbase.h"
#include "exdisp.h"
+#include "shdeprecated.h"
#include "shlobj.h"
#include "shlwapi.h"
#include "shellapi.h"
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)
{
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)
/* 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)
{
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;
}
}
+ RegCloseKey(hDocs);
+
/* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
format->cfFormat = 0;
format->ptd = NULL;
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;
}
}
/* 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;
}
/*************************************************************************
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);
/*************************************************************************
* @ [SHLWAPI.169]
*
- * Release an interface.
+ * Release an interface and zero a supplied pointer.
*
* PARAMS
* lpUnknown [I] Object to release
* 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;
}
/*************************************************************************
*/
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;
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;
}
/*************************************************************************
/*************************************************************************
* @ [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;
}
/*************************************************************************
if (!lpUnknown)
return E_FAIL;
- /* Get an IServiceProvider interface from the object */
hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
(LPVOID*)&pService);
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]
*
{
HMENU hMenu;
+ TRACE("%p %s\n", hInst, debugstr_w(szName));
+
if ((hMenu = LoadMenuW(hInst, szName)))
{
if (GetSubMenu(hMenu, 0))
DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
{
int iItemCount = GetMenuItemCount(hMenu) - 1;
+
+ TRACE("%p\n", hMenu);
+
while (iItemCount >= 0)
{
HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
*/
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);
}
*/
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);
}
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;
IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
- if (*pdwEffect)
+ if (*pdwEffect != DROPEFFECT_NONE)
return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
IDropTarget_DragLeave(pDrop);
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,
{
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;
}
return TRUE;
}
-
-typedef struct {
- REFIID refid;
- DWORD indx;
-} IFACE_INDEX_TBL;
-
/*************************************************************************
* @ [SHLWAPI.219]
*
* 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);
}
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);
* 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);
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;
}
*/
BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
{
- return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id));
+ return SUCCEEDED(CLSIDFromString((LPCOLESTR)idstr, id));
}
/*************************************************************************
* 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;
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;
}
*/
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);
}
/*************************************************************************
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,
if (SUCCEEDED(hQuery))
{
if (bInvokeDefault &&
- (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
+ (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != (UINT)-1)
{
CMINVOKECOMMANDINFO cmIci;
/* Invoke the default item */
*/
HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
{
- return CLSIDFromString((LPOLESTR)idstr, id);
+ return CLSIDFromString((LPCOLESTR)idstr, id);
}
/*************************************************************************
*/
INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
{
- MENUITEMINFOW mi;
- INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+ MENUITEMINFOW mi;
+ INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+
+ 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)
- return nIter;
- nIter++;
- }
- return -1;
+ 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;
}
/*************************************************************************
*/
DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
{
+ TRACE("%p %u\n", hMenu, uID);
return GetMenuPosFromID(hMenu, uID);
}
/***********************************************************************
* 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;
}
/***********************************************************************
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 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)
{
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 = '/';
* 6 have location (found /) save root location
*/
- wk1 = (LPWSTR)pszUrl;
+ wk1 = pszUrl;
wk2 = lpszUrlCpy;
state = 0;
}
}
- /* 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. */
TRACE("(%s %d)\n", debugstr_a(pszUrl), Urlis);
+ if(!pszUrl)
+ return FALSE;
+
switch (Urlis) {
case URLIS_OPAQUE:
TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis);
+ if(!pszUrl)
+ return FALSE;
+
switch (Urlis) {
case URLIS_OPAQUE:
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-
#include <stdarg.h>
#include <string.h>
#include "objbase.h"
#include "initguid.h"
#include "sti.h"
+#include "wia_lh.h"
#include "wine/debug.h"
#include "wine/unicode.h"
{ 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)
{
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)
{
hr = unregister_coclasses(coclass_list);
if (SUCCEEDED(hr))
hr = unregister_interfaces(interface_list);
+ if (SUCCEEDED(hr))
+ hr = STI_DllUnregisterServer();
return hr;
}
--- /dev/null
+/*
+ * 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;
+}
<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>
-@ 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)
/*
* 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
#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
+{
+ 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 STG_E_UNIMPLEMENTEDFUNCTION;
+ 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;
}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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"
NULL
};
- wndclass.hInstance = URLMON_hInstance;
+ wndclass.hInstance = hProxyDll;
wnd_class = RegisterClassExW(&wndclass);
if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS)
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++;
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);
LONG URLMON_refCount = 0;
-HINSTANCE URLMON_hInstance = 0;
static HMODULE hCabinet = NULL;
static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
{
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;
#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);
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;
/*
- * 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
/*
- * 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
--- /dev/null
+/*
+ * 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;
+}
*
* 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
#include "winnls.h"
#include "usp10.h"
+#include "usp10_internal.h"
+
#include "wine/debug.h"
#include "wine/unicode.h"
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);
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));
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
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;
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);
/* Set SCRIPT_ITEM */
pItems[index+1].iCharPos = cnt; /* the last + 1 item
contains the ptr to the lastchar */
+ heap_free(levels);
return S_OK;
}
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);
{
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);
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;
{
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;
}
*/
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;
}
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! */
-}
<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>
-@ 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)
--- /dev/null
+/*
+ * 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);
*/
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;
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" );
}
/* 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) ) )
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;
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;
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
- *ppv = This;
+ *ppv = iface;
}
else
{
static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
- BmpFrameDecode *This = (BmpFrameDecode*)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
+ BmpDecoder *This = impl_from_frame(iface);
- return ref;
+ return IUnknown_AddRef((IUnknown*)This);
}
static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
- BmpFrameDecode *This = (BmpFrameDecode*)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- if (ref == 0)
- {
- IStream_Release(This->stream);
- HeapFree(GetProcessHeap(), 0, This->imagedata);
- HeapFree(GetProcessHeap(), 0, This);
- }
+ BmpDecoder *This = impl_from_frame(iface);
- 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))
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));
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);
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;
}
else
{
- return WINCODEC_ERR_PALETTEUNAVAILABLE;
+ hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+ goto end;
}
}
else
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);
}
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;
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;
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
-static HRESULT BmpFrameDecode_ReadUncompressed(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This)
{
UINT bytesperrow;
UINT width, height;
return hr;
}
-static HRESULT BmpFrameDecode_ReadRLE8(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This)
{
UINT bytesperrow;
UINT width, height;
return hr;
}
-static HRESULT BmpFrameDecode_ReadRLE4(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This)
{
UINT bytesperrow;
UINT width, height;
return hr;
}
-static HRESULT BmpFrameDecode_ReadUnsupported(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadUnsupported(BmpDecoder* This)
{
return E_FAIL;
}
{0}
};
-static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
+static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl = {
BmpFrameDecode_QueryInterface,
BmpFrameDecode_AddRef,
BmpFrameDecode_Release,
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;
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);
}
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)
HRESULT hr;
BmpDecoder *This = (BmpDecoder*)iface;
+ EnterCriticalSection(&This->lock);
hr = BmpDecoder_ReadHeaders(This, pIStream);
if (SUCCEEDED(hr))
This->stream = pIStream;
IStream_AddRef(pIStream);
}
+ LeaveCriticalSection(&This->lock);
return hr;
}
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;
}
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);
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
{&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
+ {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance},
{&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance},
{0}};
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)
if (ref == 0)
{
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
if (This->source) IWICBitmapSource_Release(This->source);
HeapFree(GetProcessHeap(), 0, This);
}
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,
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);
LONG ref;
BOOL initialized;
GifFileType *gif;
+ CRITICAL_SECTION lock;
} GifDecoder;
typedef struct {
if (ref == 0)
{
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
DGifCloseFile(This->gif);
HeapFree(GetProcessHeap(), 0, This);
}
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;
}
/* 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;
}
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);
BOOL initialized;
IStream *stream;
ICONHEADER header;
+ CRITICAL_SECTION lock; /* must be held when accessing stream */
} IcoDecoder;
typedef struct {
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;
if (ref == 0)
{
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
if (This->stream) IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
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,
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->initialized)
+ {
+ hr = WINCODEC_ERR_NOTINITIALIZED;
+ goto fail;
+ }
- if (This->header.idCount < index) return E_INVALIDARG;
+ 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;
*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);
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);
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)
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);
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);
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;
}
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;
}
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)
if (ret == 0)
{
ERR("read_scanlines failed\n");
+ LeaveCriticalSection(&This->lock);
return E_FAIL;
}
}
}
+ LeaveCriticalSection(&This->lock);
+
return copy_pixels(bpp, This->image_data,
This->cinfo.output_width, This->cinfo.output_height, stride,
prc, cbStride, cbBufferSize, pbBuffer);
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);
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,
if (ref == 0)
{
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This->colors);
HeapFree(GetProcessHeap(), 0, This);
}
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;
}
if (!pePaletteType) return E_INVALIDARG;
+ EnterCriticalSection(&This->lock);
*pePaletteType = This->type;
+ LeaveCriticalSection(&This->lock);
return S_OK;
}
if (!pcCount) return E_INVALIDARG;
+ EnterCriticalSection(&This->lock);
*pcCount = This->count;
+ LeaveCriticalSection(&This->lock);
return S_OK;
}
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;
}
if (!pfIsBlackWhite) return E_INVALIDARG;
+ EnterCriticalSection(&This->lock);
if (This->type == WICBitmapPaletteTypeFixedBW)
*pfIsBlackWhite = TRUE;
else
*pfIsBlackWhite = FALSE;
+ LeaveCriticalSection(&This->lock);
return S_OK;
}
if (!pfIsGrayscale) return E_INVALIDARG;
+ EnterCriticalSection(&This->lock);
switch(This->type)
{
case WICBitmapPaletteTypeFixedBW:
default:
*pfIsGrayscale = FALSE;
}
+ LeaveCriticalSection(&This->lock);
return S_OK;
}
*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;
}
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;
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)
{
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);
}
{
PngDecoder *This = (PngDecoder*)iface;
LARGE_INTEGER seek;
- HRESULT hr;
+ HRESULT hr=S_OK;
png_bytep *row_pointers=NULL;
UINT image_size;
UINT i;
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);
{
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 */
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);
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:
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:
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:
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 */
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;
This->initialized = TRUE;
- return S_OK;
+end:
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
}
static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
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)
*pDpiX = *pDpiY = 96.0;
}
+ LeaveCriticalSection(&This->lock);
+
TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY);
return S_OK;
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++)
}
}
- 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,
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);
UINT lines_written;
BOOL frame_committed;
BOOL committed;
+ CRITICAL_SECTION lock;
} PngEncoder;
static inline PngEncoder *encoder_from_frame(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;
}
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;
}
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;
}
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++)
{
This->format = &formats[i];
memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
+ LeaveCriticalSection(&This->lock);
+
return S_OK;
}
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;
}
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;
ppng_write_rows(This->png_ptr, row_pointers, lineCount);
This->lines_written += lineCount;
+ LeaveCriticalSection(&This->lock);
+
HeapFree(GetProcessHeap(), 0, row_pointers);
return S_OK;
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);
This->frame_committed = TRUE;
+ LeaveCriticalSection(&This->lock);
+
return S_OK;
}
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)
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;
}
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);
/* 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;
}
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;
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;
}
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);
"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",
"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 */
};
{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",
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 */
};
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,
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;
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;
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,
{
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 */
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;
}
--- /dev/null
+/*
+ * 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
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);
<file>propertybag.c</file>
<file>regsvr.c</file>
<file>stream.c</file>
+ <file>tiffformat.c</file>
<file>ungif.c</file>
<file>version.rc</file>
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
{
HINTERNET WININET_AllocHandle( object_header_t *info )
{
object_header_t **p;
- UINT handle = 0, num;
+ UINT_PTR handle = 0, num;
list_init( &info->children );
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 );
LeaveCriticalSection( &WININET_cs );
- TRACE("handle %d -> %p\n", handle, info);
+ TRACE("handle %ld -> %p\n", handle, info);
return 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 );
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;
}
/* 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 );
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? */
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))
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))
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))
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)
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)
{
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)
{
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,
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;
}
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;
}
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));
}
#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
#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 {
} 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);
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,
/* 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;
typedef NTSTATUS (WINAPI *SpUserModeInitializeFn)(ULONG, PULONG,
PSECPKG_USER_FUNCTION_TABLE *, PULONG);
+#ifdef __cplusplus
+}
+#endif
#endif /* _NTSECPKG_H */
<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>
<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>
--- /dev/null
+/*
+ * 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 );
+}
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
#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
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
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
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
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
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
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