diff --git a/reactos/dll/win32/lpk/dllmain.c b/reactos/dll/win32/lpk/dllmain.c index 9b7c8e11d0d..1d5bdc0e781 100644 --- a/reactos/dll/win32/lpk/dllmain.c +++ b/reactos/dll/win32/lpk/dllmain.c @@ -36,7 +36,7 @@ LpkDllInitialize ( case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hDll); /* Tell usp10 it is activated usp10 */ - LpkPresent(); + //LpkPresent(); break; default: diff --git a/reactos/dll/win32/rsaenh/rsaenh.c b/reactos/dll/win32/rsaenh/rsaenh.c index 74ad392f2f2..8a5be9935c3 100644 --- a/reactos/dll/win32/rsaenh/rsaenh.c +++ b/reactos/dll/win32/rsaenh/rsaenh.c @@ -3354,6 +3354,33 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam setup_key(pCryptKey); return TRUE; + case KP_SALT: + switch (pCryptKey->aiAlgid) { + case CALG_RC2: + case CALG_RC4: + if (!pbData) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* MSDN: the base provider always sets eleven bytes of + * salt value. + */ + memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, + pbData, 11); + pCryptKey->dwSaltLen = 11; + setup_key(pCryptKey); + /* Strange but true: salt length reset to 0 after setting + * it via KP_SALT. + */ + pCryptKey->dwSaltLen = 0; + break; + default: + SetLastError(NTE_BAD_KEY); + return FALSE; + } + return TRUE; + case KP_SALT_EX: { CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData; @@ -3486,8 +3513,16 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam pCryptKey->dwBlockLen); case KP_SALT: - return copy_param(pbData, pdwDataLen, - &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen); + switch (pCryptKey->aiAlgid) { + case CALG_RC2: + case CALG_RC4: + return copy_param(pbData, pdwDataLen, + &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], + pCryptKey->dwSaltLen); + default: + SetLastError(NTE_BAD_KEY); + return FALSE; + } case KP_PADDING: dwValue = PKCS5_PADDING; diff --git a/reactos/dll/win32/rsaenh/sha2.c b/reactos/dll/win32/rsaenh/sha2.c index 559323c54e5..ea5bb28b48f 100644 --- a/reactos/dll/win32/rsaenh/sha2.c +++ b/reactos/dll/win32/rsaenh/sha2.c @@ -273,7 +273,7 @@ static const char sha2_hex_digits[] = "0123456789abcdef"; /*** SHA-256: *********************************************************/ void SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { + if (context == NULL) { return; } MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); @@ -465,7 +465,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { } /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + assert(context != NULL && data != NULL); usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { @@ -490,7 +490,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ - SHA256_Transform(context, (sha2_word32*)data); + SHA256_Transform(context, (const sha2_word32*)data); context->bitcount += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; @@ -509,10 +509,10 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { unsigned int usedspace; /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + assert(context != NULL); /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { + if (digest != NULL) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; #ifndef WORDS_BIGENDIAN /* Convert FROM host byte order */ @@ -572,9 +572,9 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) { int i; /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + assert(context != NULL); - if (buffer != (char*)0) { + if (buffer != NULL) { SHA256_Final(digest, context); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { @@ -582,7 +582,7 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) { *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } - *buffer = (char)0; + *buffer = 0; } else { MEMSET_BZERO(context, sizeof(context)); } @@ -601,7 +601,7 @@ char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_S /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { + if (context == NULL) { return; } MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); @@ -787,7 +787,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { } /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + assert(context != NULL && data != NULL); usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { @@ -812,7 +812,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { } while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ - SHA512_Transform(context, (sha2_word64*)data); + SHA512_Transform(context, (const sha2_word64*)data); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; @@ -871,10 +871,10 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + assert(context != NULL); /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { + if (digest != NULL) { SHA512_Last(context); /* Save the hash data for output: */ @@ -901,9 +901,9 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) { int i; /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + assert(context != NULL); - if (buffer != (char*)0) { + if (buffer != NULL) { SHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { @@ -911,7 +911,7 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) { *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } - *buffer = (char)0; + *buffer = 0; } else { MEMSET_BZERO(context, sizeof(context)); } @@ -930,7 +930,7 @@ char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_S /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { + if (context == NULL) { return; } MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); @@ -946,10 +946,10 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + assert(context != NULL); /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { + if (digest != NULL) { SHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ @@ -976,9 +976,9 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) { int i; /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + assert(context != NULL); - if (buffer != (char*)0) { + if (buffer != NULL) { SHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { @@ -986,7 +986,7 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) { *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } - *buffer = (char)0; + *buffer = 0; } else { MEMSET_BZERO(context, sizeof(context)); } diff --git a/reactos/dll/win32/schannel/lsamode.c b/reactos/dll/win32/schannel/lsamode.c index 23d85994cc4..f43150e3d3a 100644 --- a/reactos/dll/win32/schannel/lsamode.c +++ b/reactos/dll/win32/schannel/lsamode.c @@ -109,6 +109,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] = NULL, /* SetExtendedInformation */ NULL, /* SetContextAttributes */ NULL, /* SetCredentialsAttributes */ + NULL, /* ChangeAccountPassword */ + NULL, /* QueryMetaData */ + NULL, /* ExchangeMetaData */ + NULL, /* GetCredUIContext */ + NULL, /* UpdateCredentials */ + NULL, /* ValidateTargetInfo */ }, { NULL, /* InitializePackage */ NULL, /* LsaLogonUser */ @@ -139,6 +145,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] = NULL, /* SetExtendedInformation */ NULL, /* SetContextAttributes */ NULL, /* SetCredentialsAttributes */ + NULL, /* ChangeAccountPassword */ + NULL, /* QueryMetaData */ + NULL, /* ExchangeMetaData */ + NULL, /* GetCredUIContext */ + NULL, /* UpdateCredentials */ + NULL, /* ValidateTargetInfo */ } }; @@ -150,7 +162,7 @@ NTSTATUS WINAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG PackageVersion, { TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables); - *PackageVersion = SECPKG_INTERFACE_VERSION_3; + *PackageVersion = SECPKG_INTERFACE_VERSION_6; *pcTables = 2; *ppTables = secPkgFunctionTable; diff --git a/reactos/dll/win32/shlwapi/ordinal.c b/reactos/dll/win32/shlwapi/ordinal.c index 364bbfe8af8..332bdb67f79 100644 --- a/reactos/dll/win32/shlwapi/ordinal.c +++ b/reactos/dll/win32/shlwapi/ordinal.c @@ -42,6 +42,7 @@ #include "mmsystem.h" #include "objbase.h" #include "exdisp.h" +#include "shdeprecated.h" #include "shlobj.h" #include "shlwapi.h" #include "shellapi.h" @@ -309,24 +310,22 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) BSTR property; IEnumFORMATETC* pIEnumFormatEtc = NULL; VARIANTARG var; - HRESULT hRet; - IWebBrowserApp* pBrowser = NULL; + HRESULT hr; + IWebBrowserApp* pBrowser; TRACE("(%p, %p)\n", lpBC, lpUnknown); - /* Get An IWebBrowserApp interface from lpUnknown */ - hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser); - if (FAILED(hRet) || !pBrowser) - return E_NOINTERFACE; + hr = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (void**)&pBrowser); + if (FAILED(hr)) + return hr; V_VT(&var) = VT_EMPTY; /* The property we get is the browsers clipboard enumerator */ property = SysAllocString(szProperty); - hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var); + hr = IWebBrowserApp_GetProperty(pBrowser, property, &var); SysFreeString(property); - if (FAILED(hRet)) - return hRet; + if (FAILED(hr)) goto exit; if (V_VT(&var) == VT_EMPTY) { @@ -340,7 +339,10 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current" "Version\\Internet Settings\\Accepted Documents", &hDocs)) - return E_FAIL; + { + hr = E_FAIL; + goto exit; + } /* Get count of values in key */ while (!dwRet) @@ -355,7 +357,11 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) /* Note: dwCount = number of items + 1; The extra item is the end node */ format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC)); if (!formatList) - return E_OUTOFMEMORY; + { + RegCloseKey(hDocs); + hr = E_OUTOFMEMORY; + goto exit; + } if (dwNumValues > 1) { @@ -372,7 +378,12 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType, (PBYTE)szValueBuff, &dwValueSize); if (!dwRet) - return E_FAIL; + { + HeapFree(GetProcessHeap(), 0, formatList); + RegCloseKey(hDocs); + hr = E_FAIL; + goto exit; + } format->cfFormat = RegisterClipboardFormatA(szValueBuff); format->ptd = NULL; @@ -385,6 +396,8 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) } } + RegCloseKey(hDocs); + /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */ format->cfFormat = 0; format->ptd = NULL; @@ -393,22 +406,21 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) format->tymed = -1; /* Create a clipboard enumerator */ - hRet = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc); - - if (FAILED(hRet) || !pIEnumFormatEtc) - return hRet; + hr = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc); + HeapFree(GetProcessHeap(), 0, formatList); + if (FAILED(hr)) goto exit; /* Set our enumerator as the browsers property */ V_VT(&var) = VT_UNKNOWN; V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc; property = SysAllocString(szProperty); - hRet = IWebBrowserApp_PutProperty(pBrowser, property, var); + hr = IWebBrowserApp_PutProperty(pBrowser, property, var); SysFreeString(property); - if (FAILED(hRet)) + if (FAILED(hr)) { IEnumFORMATETC_Release(pIEnumFormatEtc); - goto RegisterDefaultAcceptHeaders_Exit; + goto exit; } } @@ -422,28 +434,26 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown) /* Get an IEnumFormatEtc interface from the variants value */ pIEnumFormatEtc = NULL; - hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC, - (PVOID)&pIEnumFormatEtc); - if (hRet == S_OK && pIEnumFormatEtc) + hr = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC, (void**)&pIEnumFormatEtc); + if (hr == S_OK && pIEnumFormatEtc) { /* Clone and register the enumerator */ - hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone); - if (hRet == S_OK && pClone) + hr = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone); + if (hr == S_OK && pClone) { RegisterFormatEnumerator(lpBC, pClone, 0); IEnumFORMATETC_Release(pClone); } - /* Release the IEnumFormatEtc interface */ IEnumFORMATETC_Release(pIUnknown); } IUnknown_Release(V_UNKNOWN(&var)); } -RegisterDefaultAcceptHeaders_Exit: +exit: IWebBrowserApp_Release(pBrowser); - return hRet; + return hr; } /************************************************************************* @@ -500,7 +510,7 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) return S_OK; } - /* Did not find a value in the registry or the user buffer is to small */ + /* Did not find a value in the registry or the user buffer is too small */ mylcid = GetUserDefaultLCID(); retval = LcidToRfc1766W(mylcid, mystr, mystrlen); len = lstrlenW(mystr); @@ -1201,7 +1211,7 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f /************************************************************************* * @ [SHLWAPI.169] * - * Release an interface. + * Release an interface and zero a supplied pointer. * * PARAMS * lpUnknown [I] Object to release @@ -1209,19 +1219,16 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f * RETURNS * Nothing. */ -DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown) +void WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown) { - IUnknown *temp; + TRACE("(%p)\n", lpUnknown); - TRACE("(%p)\n",lpUnknown); - - if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0; - temp = *lpUnknown; - *lpUnknown = NULL; + if(!lpUnknown || !*lpUnknown) return; TRACE("doing Release\n"); - return IUnknown_Release(temp); + IUnknown_Release(*lpUnknown); + *lpUnknown = NULL; } /************************************************************************* @@ -1258,9 +1265,10 @@ LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc) */ BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2) { - LPVOID lpUnknown1, lpUnknown2; + IUnknown *lpUnknown1, *lpUnknown2; + BOOL ret; - TRACE("%p %p\n", lpInt1, lpInt2); + TRACE("(%p %p)\n", lpInt1, lpInt2); if (!lpInt1 || !lpInt2) return FALSE; @@ -1268,16 +1276,21 @@ BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2) if (lpInt1 == lpInt2) return TRUE; - if (FAILED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown, &lpUnknown1))) + if (IUnknown_QueryInterface(lpInt1, &IID_IUnknown, (void**)&lpUnknown1) != S_OK) return FALSE; - if (FAILED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown, &lpUnknown2))) + if (IUnknown_QueryInterface(lpInt2, &IID_IUnknown, (void**)&lpUnknown2) != S_OK) + { + IUnknown_Release(lpUnknown1); return FALSE; + } - if (lpUnknown1 == lpUnknown2) - return TRUE; + ret = lpUnknown1 == lpUnknown2; - return FALSE; + IUnknown_Release(lpUnknown1); + IUnknown_Release(lpUnknown2); + + return ret; } /************************************************************************* @@ -1337,36 +1350,32 @@ HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd) /************************************************************************* * @ [SHLWAPI.173] * - * Call a method on as as yet unidentified object. + * Call a SetOwner method of IShellService from specified object. * * PARAMS - * pUnk [I] Object supporting the unidentified interface, - * arg [I] Argument for the call on the object. + * iface [I] Object that supports IShellService + * pUnk [I] Argument for the SetOwner call * * RETURNS - * S_OK. + * Corresponding return value from last call or E_FAIL for null input */ -HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg) +HRESULT WINAPI IUnknown_SetOwner(IUnknown *iface, IUnknown *pUnk) { - static const GUID guid_173 = { - 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 } - }; - IMalloc *pUnk2; + IShellService *service; + HRESULT hr; - TRACE("(%p,%d)\n", pUnk, arg); + TRACE("(%p, %p)\n", iface, pUnk); - /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc - - * We use this interface as its vtable entry is compatible with the - * object in question. - * FIXME: Find out what this object is and where it should be defined. - */ - if (pUnk && - SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2))) + if (!iface) return E_FAIL; + + hr = IUnknown_QueryInterface(iface, &IID_IShellService, (void**)&service); + if (hr == S_OK) { - IMalloc_Alloc(pUnk2, arg); /* Faked call!! */ - IMalloc_Release(pUnk2); + hr = IShellService_SetOwner(service, pUnk); + IShellService_Release(service); } - return S_OK; + + return hr; } /************************************************************************* @@ -1473,7 +1482,6 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri if (!lpUnknown) return E_FAIL; - /* Get an IServiceProvider interface from the object */ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider, (LPVOID*)&pService); @@ -1486,12 +1494,92 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut); - /* Release the IServiceProvider interface */ IUnknown_Release(pService); } return hRet; } +/************************************************************************* + * @ [SHLWAPI.484] + * + * Calls IOleCommandTarget::Exec() for specified service object. + * + * PARAMS + * lpUnknown [I] Object to get an IServiceProvider interface from + * service [I] Service ID for IServiceProvider_QueryService() call + * group [I] Group ID for IOleCommandTarget::Exec() call + * cmdId [I] Command ID for IOleCommandTarget::Exec() call + * cmdOpt [I] Options flags for command + * pIn [I] Input arguments for command + * pOut [O] Output arguments for command + * + * RETURNS + * Success: S_OK. lppOut contains an object providing the requested service + * Failure: An HRESULT error code + * + * NOTES + * lpUnknown is expected to support the IServiceProvider interface. + */ +HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *lpUnknown, REFIID service, + const GUID *group, DWORD cmdId, DWORD cmdOpt, VARIANT *pIn, VARIANT *pOut) +{ + IOleCommandTarget *target; + HRESULT hr; + + TRACE("%p %s %s %d %08x %p %p\n", lpUnknown, debugstr_guid(service), + debugstr_guid(group), cmdId, cmdOpt, pIn, pOut); + + hr = IUnknown_QueryService(lpUnknown, service, &IID_IOleCommandTarget, (void**)&target); + if (hr == S_OK) + { + hr = IOleCommandTarget_Exec(target, group, cmdId, cmdOpt, pIn, pOut); + IOleCommandTarget_Release(target); + } + + TRACE("<-- hr=0x%08x\n", hr); + + return hr; +} + +/************************************************************************* + * @ [SHLWAPI.514] + * + * Calls IProfferService methods to proffer/revoke specified service. + * + * PARAMS + * lpUnknown [I] Object to get an IServiceProvider interface from + * service [I] Service ID for IProfferService::Proffer/Revoke calls + * pService [I] Service to proffer. If NULL ::Revoke is called + * pCookie [IO] Group ID for IOleCommandTarget::Exec() call + * + * RETURNS + * Success: S_OK. IProffer method returns S_OK + * Failure: An HRESULT error code + * + * NOTES + * lpUnknown is expected to support the IServiceProvider interface. + */ +HRESULT WINAPI IUnknown_ProfferService(IUnknown *lpUnknown, REFGUID service, IServiceProvider *pService, DWORD *pCookie) +{ + IProfferService *proffer; + HRESULT hr; + + TRACE("%p %s %p %p\n", lpUnknown, debugstr_guid(service), pService, pCookie); + + hr = IUnknown_QueryService(lpUnknown, &IID_IProfferService, &IID_IProfferService, (void**)&proffer); + if (hr == S_OK) + { + if (pService) + hr = IProfferService_ProfferService(proffer, service, pService, pCookie); + else + hr = IProfferService_RevokeService(proffer, *pCookie); + + IProfferService_Release(proffer); + } + + return hr; +} + /************************************************************************* * @ [SHLWAPI.479] * @@ -1546,6 +1634,8 @@ BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName) { HMENU hMenu; + TRACE("%p %s\n", hInst, debugstr_w(szName)); + if ((hMenu = LoadMenuW(hInst, szName))) { if (GetSubMenu(hMenu, 0)) @@ -1629,6 +1719,9 @@ void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lP DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu) { int iItemCount = GetMenuItemCount(hMenu) - 1; + + TRACE("%p\n", hMenu); + while (iItemCount >= 0) { HMENU hSubMenu = GetSubMenu(hMenu, iItemCount); @@ -1654,6 +1747,7 @@ DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu) */ UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable) { + TRACE("%p, %u, %d\n", hMenu, wItemID, bEnable); return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED); } @@ -1672,6 +1766,7 @@ UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable) */ DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck) { + TRACE("%p, %u, %d\n", hMenu, uID, bCheck); return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED); } @@ -1703,6 +1798,8 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY; POINTL pt = { 0, 0 }; + TRACE("%p %p 0x%08x %p %p\n", pDrop, pDataObj, grfKeyState, lpPt, pdwEffect); + if (!lpPt) lpPt = &pt; @@ -1711,7 +1808,7 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect); - if (*pdwEffect) + if (*pdwEffect != DROPEFFECT_NONE) return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect); IDropTarget_DragLeave(pDrop); @@ -1803,7 +1900,7 @@ HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus) IOleControlSite* lpCSite = NULL; HRESULT hRet = E_FAIL; - TRACE("(%p,%s)\n", lpUnknown, fGotFocus ? "TRUE" : "FALSE"); + TRACE("(%p, %d)\n", lpUnknown, fGotFocus); if (lpUnknown) { hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite, @@ -2061,12 +2158,10 @@ VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown) { TRACE("(%p,%p)\n", lppDest, lpUnknown); - if (lppDest) - IUnknown_AtomicRelease(lppDest); /* Release existing interface */ + IUnknown_AtomicRelease(lppDest); if (lpUnknown) { - /* Copy */ IUnknown_AddRef(lpUnknown); *lppDest = lpUnknown; } @@ -2256,12 +2351,6 @@ BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where) return TRUE; } - -typedef struct { - REFIID refid; - DWORD indx; -} IFACE_INDEX_TBL; - /************************************************************************* * @ [SHLWAPI.219] * @@ -2272,22 +2361,22 @@ typedef struct { * Failure: E_POINTER or E_NOINTERFACE. */ HRESULT WINAPI QISearch( - LPVOID w, /* [in] Table of interfaces */ - IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */ + void *base, /* [in] Table of interfaces */ + const QITAB *table, /* [in] Array of REFIIDs and indexes into the table */ REFIID riid, /* [in] REFIID to get interface for */ - LPVOID *ppv) /* [out] Destination for interface pointer */ + void **ppv) /* [out] Destination for interface pointer */ { HRESULT ret; IUnknown *a_vtbl; - IFACE_INDEX_TBL *xmove; + const QITAB *xmove; - TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv); + TRACE("(%p %p %s %p)\n", base, table, debugstr_guid(riid), ppv); if (ppv) { - xmove = x; - while (xmove->refid) { - TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid)); - if (IsEqualIID(riid, xmove->refid)) { - a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w); + xmove = table; + while (xmove->piid) { + TRACE("trying (offset %d) %s\n", xmove->dwOffset, debugstr_guid(xmove->piid)); + if (IsEqualIID(riid, xmove->piid)) { + a_vtbl = (IUnknown*)(xmove->dwOffset + (LPBYTE)base); TRACE("matched, returning (%p)\n", a_vtbl); *ppv = a_vtbl; IUnknown_AddRef(a_vtbl); @@ -2297,7 +2386,7 @@ HRESULT WINAPI QISearch( } if (IsEqualIID(riid, &IID_IUnknown)) { - a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w); + a_vtbl = (IUnknown*)(table->dwOffset + (LPBYTE)base); TRACE("returning first for IUnknown (%p)\n", a_vtbl); *ppv = a_vtbl; IUnknown_AddRef(a_vtbl); @@ -2506,27 +2595,27 @@ HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite) * dwExStyle [I] Extra style flags * dwStyle [I] Style flags * hMenu [I] Window menu - * z [I] Unknown + * wnd_extra [I] Window extra bytes value * * RETURNS * Success: The window handle of the newly created window. * Failure: 0. */ HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle, - DWORD dwStyle, HMENU hMenu, LONG z) + DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra) { static const char szClass[] = "WorkerA"; WNDCLASSA wc; HWND hWnd; - TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n", - wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z); + TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n", + wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); /* Create Window class */ wc.style = 0; wc.lpfnWndProc = DefWindowProcA; wc.cbClsExtra = 0; - wc.cbWndExtra = 4; + wc.cbWndExtra = sizeof(LONG_PTR); wc.hInstance = shlwapi_hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW); @@ -2534,19 +2623,17 @@ HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle wc.lpszMenuName = NULL; wc.lpszClassName = szClass; - SHRegisterClassA(&wc); /* Register class */ - - /* FIXME: Set extra bits in dwExStyle */ + SHRegisterClassA(&wc); hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0, hWndParent, hMenu, shlwapi_hInstance, 0); if (hWnd) { - SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z); + SetWindowLongPtrW(hWnd, 0, wnd_extra); - if (wndProc) - SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc); + if (wndProc) SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc); } + return hWnd; } @@ -2729,7 +2816,7 @@ BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id) */ BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id) { - return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id)); + return SUCCEEDED(CLSIDFromString((LPCOLESTR)idstr, id)); } /************************************************************************* @@ -2804,18 +2891,21 @@ DWORD WINAPI WhichPlatform(void) * Unicode version of SHCreateWorkerWindowA. */ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle, - DWORD dwStyle, HMENU hMenu, LONG z) + DWORD dwStyle, HMENU hMenu, LONG msg_result) { - static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' }; + static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 }; WNDCLASSW wc; HWND hWnd; - TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n", - wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z); + TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n", + wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result); - /* If our OS is natively ASCII, use the ASCII version */ - if (!(GetVersion() & 0x80000000)) /* NT */ - return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z); + /* If our OS is natively ANSI, use the ANSI version */ + if (GetVersion() & 0x80000000) /* not NT */ + { + TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion()); + return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result); + } /* Create Window class */ wc.style = 0; @@ -2829,19 +2919,17 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle wc.lpszMenuName = NULL; wc.lpszClassName = szClass; - SHRegisterClassW(&wc); /* Register class */ - - /* FIXME: Set extra bits in dwExStyle */ + SHRegisterClassW(&wc); hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0, hWndParent, hMenu, shlwapi_hInstance, 0); if (hWnd) { - SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z); + SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, msg_result); - if (wndProc) - SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc); + if (wndProc) SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc); } + return hWnd; } @@ -2861,7 +2949,8 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle */ HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl) { - return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE); + TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl); + return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE); } /************************************************************************* @@ -3376,12 +3465,12 @@ UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault) { IContextMenu *iContext; - HRESULT hRet = E_FAIL; + HRESULT hRet; - TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault); + TRACE("(%p, %p, %p, %d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault); if (!lpFolder) - return hRet; + return E_FAIL; /* Get the context menu from the shell folder */ hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl, @@ -3401,7 +3490,7 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST if (SUCCEEDED(hQuery)) { if (bInvokeDefault && - (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF) + (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != (UINT)-1) { CMINVOKECOMMANDINFO cmIci; /* Invoke the default item */ @@ -3810,7 +3899,7 @@ DWORD WINAPI SHSendMessageBroadcastW(UINT uMsg, WPARAM wParam, LPARAM lParam) */ HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id) { - return CLSIDFromString((LPOLESTR)idstr, id); + return CLSIDFromString((LPCOLESTR)idstr, id); } /************************************************************************* @@ -4171,18 +4260,24 @@ BOOL WINAPI SHIsLowMemoryMachine (DWORD x) */ INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID) { - MENUITEMINFOW mi; - INT nCount = GetMenuItemCount(hMenu), nIter = 0; + MENUITEMINFOW mi; + INT nCount = GetMenuItemCount(hMenu), nIter = 0; - while (nIter < nCount) - { - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_ID; - if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID) - return nIter; - nIter++; - } - return -1; + TRACE("%p %u\n", hMenu, wID); + + while (nIter < nCount) + { + mi.cbSize = sizeof(mi); + mi.fMask = MIIM_ID; + if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID) + { + TRACE("ret %d\n", nIter); + return nIter; + } + nIter++; + } + + return -1; } /************************************************************************* @@ -4192,6 +4287,7 @@ INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID) */ DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID) { + TRACE("%p %u\n", hMenu, uID); return GetMenuPosFromID(hMenu, uID); } @@ -4270,10 +4366,10 @@ BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid) /*********************************************************************** * SHGetShellKey (SHLWAPI.@) */ -DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c) +HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create) { - FIXME("(%x, %x, %x): stub\n", a, b, c); - return 0x50; + FIXME("(0x%08x, %s, %d): stub\n", flags, debugstr_w(sub_key), create); + return (HKEY)0x50; } /*********************************************************************** @@ -4422,20 +4518,6 @@ INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText, return ret; } -HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid, - DWORD x1, DWORD x2, DWORD x3, void **ppvOut) -{ - FIXME("%p %s %s %08x %08x %08x %p\n", unk, - debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut); - return E_NOTIMPL; -} - -HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2) -{ - FIXME("%p %p %p %p\n", unk, x0, x1, x2); - return E_NOTIMPL; -} - /*********************************************************************** * ZoneComputePaneSize [SHLWAPI.382] */ diff --git a/reactos/dll/win32/shlwapi/shlwapi.spec b/reactos/dll/win32/shlwapi/shlwapi.spec index d899232f9c5..367046b5ebc 100644 --- a/reactos/dll/win32/shlwapi/shlwapi.spec +++ b/reactos/dll/win32/shlwapi/shlwapi.spec @@ -216,7 +216,7 @@ 216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long) 217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr) 218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr long) -219 stdcall -noname QISearch(long long long long) +219 stdcall QISearch(long long long long) 220 stdcall -noname SHSetDefaultDialogFont(ptr long) 221 stdcall -noname SHRemoveDefaultDialogFont(ptr) 222 stdcall -noname SHGlobalCounterCreate(long) diff --git a/reactos/dll/win32/shlwapi/url.c b/reactos/dll/win32/shlwapi/url.c index 958a8429f53..cd83b457178 100644 --- a/reactos/dll/win32/shlwapi/url.c +++ b/reactos/dll/win32/shlwapi/url.c @@ -278,7 +278,8 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, { HRESULT hr = S_OK; DWORD EscapeFlags; - LPWSTR lpszUrlCpy, wk1, wk2, mp, mp2, root; + LPCWSTR wk1, root; + LPWSTR lpszUrlCpy, wk2, mp, mp2; INT state; DWORD nByteLen, nLen, nWkLen; WCHAR slash = '/'; @@ -322,7 +323,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, * 6 have location (found /) save root location */ - wk1 = (LPWSTR)pszUrl; + wk1 = pszUrl; wk2 = lpszUrlCpy; state = 0; @@ -662,7 +663,7 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative, } } - /* If there is a '#' and the characters immediately preceeding it are + /* If there is a '#' and the characters immediately preceding it are * ".htm[l]", then begin looking for the last leaf starting from * the '#'. Otherwise the '#' is not meaningful and just start * looking from the end. */ @@ -1718,6 +1719,9 @@ BOOL WINAPI UrlIsA(LPCSTR pszUrl, URLIS Urlis) TRACE("(%s %d)\n", debugstr_a(pszUrl), Urlis); + if(!pszUrl) + return FALSE; + switch (Urlis) { case URLIS_OPAQUE: @@ -1768,6 +1772,9 @@ BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis) TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis); + if(!pszUrl) + return FALSE; + switch (Urlis) { case URLIS_OPAQUE: diff --git a/reactos/dll/win32/sti/regsvr.c b/reactos/dll/win32/sti/regsvr.c index 018c1781ef6..3e582ec4964 100644 --- a/reactos/dll/win32/sti/regsvr.c +++ b/reactos/dll/win32/sti/regsvr.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ - #include #include @@ -31,6 +30,7 @@ #include "objbase.h" #include "initguid.h" #include "sti.h" +#include "wia_lh.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -395,8 +395,11 @@ static struct regsvr_interface const interface_list[] = { { NULL } /* list terminator */ }; +extern HRESULT WINAPI STI_DllRegisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI STI_DllUnregisterServer(void) DECLSPEC_HIDDEN; + /*********************************************************************** - * DllRegisterServer (INETCOMM.@) + * DllRegisterServer (STI.@) */ HRESULT WINAPI DllRegisterServer(void) { @@ -404,14 +407,16 @@ HRESULT WINAPI DllRegisterServer(void) TRACE("\n"); - hr = register_coclasses(coclass_list); + hr = STI_DllRegisterServer(); + if (SUCCEEDED(hr)) + hr = register_coclasses(coclass_list); if (SUCCEEDED(hr)) hr = register_interfaces(interface_list); return hr; } /*********************************************************************** - * DllUnregisterServer (INETCOMM.@) + * DllUnregisterServer (STI.@) */ HRESULT WINAPI DllUnregisterServer(void) { @@ -422,5 +427,7 @@ HRESULT WINAPI DllUnregisterServer(void) hr = unregister_coclasses(coclass_list); if (SUCCEEDED(hr)) hr = unregister_interfaces(interface_list); + if (SUCCEEDED(hr)) + hr = STI_DllUnregisterServer(); return hr; } diff --git a/reactos/dll/win32/sti/sti.c b/reactos/dll/win32/sti/sti.c new file mode 100644 index 00000000000..974bd06f693 --- /dev/null +++ b/reactos/dll/win32/sti/sti.c @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2002 Aric Stewart for CodeWeavers + * Copyright (C) 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#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; +} diff --git a/reactos/dll/win32/sti/sti.rbuild b/reactos/dll/win32/sti/sti.rbuild index 592c5f123af..edce67acab8 100644 --- a/reactos/dll/win32/sti/sti.rbuild +++ b/reactos/dll/win32/sti/sti.rbuild @@ -8,11 +8,29 @@ include/reactos/wine 0x600 + STI_ + + + regsvr.c + sti.c sti_main.c + sti_wia.idl wine - advapi32 + sti_proxy ole32 + oleaut32 + rpcrt4 + advapi32 + pseh + uuid ntdll + + + STI_ + + + sti_wia.idl + diff --git a/reactos/dll/win32/sti/sti.spec b/reactos/dll/win32/sti/sti.spec index 186f382f195..300e7fac4b7 100644 --- a/reactos/dll/win32/sti/sti.spec +++ b/reactos/dll/win32/sti/sti.spec @@ -1,7 +1,7 @@ -@ stub DllCanUnloadNow -@ stub DllGetClassObject +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() -@ stdcall StiCreateInstance(ptr long ptr ptr) +@ stdcall StiCreateInstance(ptr long ptr ptr) StiCreateInstanceW @ stdcall StiCreateInstanceA(ptr long ptr ptr) @ stdcall StiCreateInstanceW(ptr long ptr ptr) diff --git a/reactos/dll/win32/sti/sti_main.c b/reactos/dll/win32/sti/sti_main.c index 1d4e6ad0408..711c17f14eb 100644 --- a/reactos/dll/win32/sti/sti_main.c +++ b/reactos/dll/win32/sti/sti_main.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2002 Aric Stewart for CodeWeavers + * Copyright (C) 2009 Damjan Jovanovic * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,31 +19,148 @@ #include +#define COBJMACROS + #include "windef.h" #include "winbase.h" #include "winreg.h" #include "winerror.h" +#include "objbase.h" +#include "sti.h" -/****************************************************************************** - * StiCreateInstance (STI.@) - */ -HRESULT WINAPI StiCreateInstance( HINSTANCE a, DWORD b, LPVOID c, LPVOID d) +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(sti); + +extern HRESULT WINAPI STI_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; +extern BOOL WINAPI STI_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; + +typedef HRESULT (*fnCreateInstance)(REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj); + +typedef struct { - return STG_E_UNIMPLEMENTEDFUNCTION; + const struct IClassFactoryVtbl *vtbl; + fnCreateInstance pfnCreateInstance; +} sti_cf; + +static inline sti_cf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return (sti_cf *)((char *)iface - FIELD_OFFSET( sti_cf, vtbl )); +} + +static HRESULT sti_create( REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + if (pUnkOuter != NULL && !IsEqualIID(riid, &IID_IUnknown)) + return CLASS_E_NOAGGREGATION; + + if (IsEqualGUID(riid, &IID_IUnknown)) + return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, pUnkOuter); + else if (IsEqualGUID(riid, &IID_IStillImageW)) + return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, NULL); + else if (IsEqualGUID(riid, &IID_IStillImageA)) + return StiCreateInstanceA(GetCurrentProcess(), STI_VERSION_REAL, (PSTIA*) ppObj, NULL); + else + { + FIXME("no interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } +} + +static HRESULT WINAPI sti_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI sti_cf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI sti_cf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI sti_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj ) +{ + sti_cf *This = impl_from_IClassFactory( iface ); + HRESULT r; + IUnknown *punk; + + TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + r = This->pfnCreateInstance( riid, pOuter, (LPVOID *)&punk ); + if (FAILED(r)) + return r; + + r = IUnknown_QueryInterface( punk, riid, ppobj ); + if (FAILED(r)) + return r; + + IUnknown_Release( punk ); + return r; +} + +static HRESULT WINAPI sti_cf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + return S_OK; +} + +static const struct IClassFactoryVtbl sti_cf_vtbl = +{ + sti_cf_QueryInterface, + sti_cf_AddRef, + sti_cf_Release, + sti_cf_CreateInstance, + sti_cf_LockServer +}; + +static sti_cf the_sti_cf = { &sti_cf_vtbl, sti_create }; + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved); + + if (fdwReason == DLL_WINE_PREATTACH) + return FALSE; + return STI_DllMain(hInstDLL, fdwReason, lpvReserved); } /****************************************************************************** - * StiCreateInstanceA (STI.@) + * DllGetClassObject (STI.@) */ -HRESULT WINAPI StiCreateInstanceA( HINSTANCE a, DWORD b, LPVOID c, LPVOID d) +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) { - return STG_E_UNIMPLEMENTEDFUNCTION; + IClassFactory *cf = NULL; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID( rclsid, &CLSID_Sti )) + { + cf = (IClassFactory *)&the_sti_cf.vtbl; + } + + if (cf) + return IClassFactory_QueryInterface( cf, iid, ppv ); + return STI_DllGetClassObject( rclsid, iid, ppv ); } /****************************************************************************** - * StiCreateInstanceW (STI.@) + * DllCanUnloadNow (STI.@) */ -HRESULT WINAPI StiCreateInstanceW( HINSTANCE a, DWORD b, LPVOID c, LPVOID d) +HRESULT WINAPI DllCanUnloadNow( void ) { - return STG_E_UNIMPLEMENTEDFUNCTION; + return S_FALSE; } diff --git a/reactos/dll/win32/sti/sti_private.h b/reactos/dll/win32/sti/sti_private.h new file mode 100644 index 00000000000..b5e106b60b6 --- /dev/null +++ b/reactos/dll/win32/sti/sti_private.h @@ -0,0 +1,32 @@ +/* + * STI private definitions + * + * Copyright 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __STI_PRIVATE__ +#define __STI_PRIVATE__ + +typedef struct _stillimage +{ + const struct IStillImageWVtbl *lpVtbl; + const struct IUnknownVtbl *lpInternalUnkVtbl; + IUnknown *pUnkOuter; + LONG ref; +} stillimage; + +#endif /* __STI_PRIVATE__ */ diff --git a/reactos/dll/win32/sti/sti_wia.idl b/reactos/dll/win32/sti/sti_wia.idl new file mode 100644 index 00000000000..aaac943445f --- /dev/null +++ b/reactos/dll/win32/sti/sti_wia.idl @@ -0,0 +1,19 @@ +/* + * Copyright 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wia_lh.idl" diff --git a/reactos/dll/win32/urlmon/bindprot.c b/reactos/dll/win32/urlmon/bindprot.c index 07d6fc2f525..29b8532b13d 100644 --- a/reactos/dll/win32/urlmon/bindprot.c +++ b/reactos/dll/win32/urlmon/bindprot.c @@ -155,7 +155,7 @@ HWND get_notif_hwnd(void) NULL }; - wndclass.hInstance = URLMON_hInstance; + wndclass.hInstance = hProxyDll; wnd_class = RegisterClassExW(&wndclass); if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) @@ -164,7 +164,7 @@ HWND get_notif_hwnd(void) tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, - NULL, URLMON_hInstance, NULL); + NULL, hProxyDll, NULL); if(tls_data->notif_hwnd) tls_data->notif_hwnd_cnt++; diff --git a/reactos/dll/win32/urlmon/regsvr.c b/reactos/dll/win32/urlmon/regsvr.c index 9e278259e37..6e417ac9607 100644 --- a/reactos/dll/win32/urlmon/regsvr.c +++ b/reactos/dll/win32/urlmon/regsvr.c @@ -560,7 +560,7 @@ static HRESULT register_inf(BOOL doregister) hAdvpack = LoadLibraryW(wszAdvpack); pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall"); - hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable); + hres = pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", &strtable); for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++) heap_free(pse[i].pszValue); diff --git a/reactos/dll/win32/urlmon/urlmon_main.c b/reactos/dll/win32/urlmon/urlmon_main.c index 272884eb2a6..edaad42289f 100644 --- a/reactos/dll/win32/urlmon/urlmon_main.c +++ b/reactos/dll/win32/urlmon/urlmon_main.c @@ -34,7 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); LONG URLMON_refCount = 0; -HINSTANCE URLMON_hInstance = 0; static HMODULE hCabinet = NULL; static DWORD urlmon_tls = TLS_OUT_OF_INDEXES; @@ -144,9 +143,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); + URLMON_DllMain( hinstDLL, fdwReason, fImpLoad ); + switch(fdwReason) { case DLL_PROCESS_ATTACH: - URLMON_hInstance = hinstDLL; init_session(TRUE); break; diff --git a/reactos/dll/win32/urlmon/urlmon_main.h b/reactos/dll/win32/urlmon/urlmon_main.h index 8db786b7d80..071af8dd73e 100644 --- a/reactos/dll/win32/urlmon/urlmon_main.h +++ b/reactos/dll/win32/urlmon/urlmon_main.h @@ -36,7 +36,7 @@ #include "wine/unicode.h" #include "wine/list.h" -extern HINSTANCE URLMON_hInstance; +extern HINSTANCE hProxyDll DECLSPEC_HIDDEN; extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); @@ -48,6 +48,7 @@ extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); +extern BOOL WINAPI URLMON_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DECLSPEC_HIDDEN; extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; extern HRESULT WINAPI URLMON_DllRegisterServer(void) DECLSPEC_HIDDEN; extern HRESULT WINAPI URLMON_DllUnregisterServer(void) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/urlmon/urlmon_urlmon.idl b/reactos/dll/win32/urlmon/urlmon_urlmon.idl index 71a0719d7d9..d45ba07e456 100644 --- a/reactos/dll/win32/urlmon/urlmon_urlmon.idl +++ b/reactos/dll/win32/urlmon/urlmon_urlmon.idl @@ -1,5 +1,5 @@ /* - * Copyright 2009 Piotr Caban for Codeweavers + * Copyright 2009 Piotr Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/reactos/dll/win32/urlmon/usrmarshal.c b/reactos/dll/win32/urlmon/usrmarshal.c index b94556362be..6ff8f04ef26 100644 --- a/reactos/dll/win32/urlmon/usrmarshal.c +++ b/reactos/dll/win32/urlmon/usrmarshal.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Piotr Caban for Codeweavers + * Copyright 2009 Piotr Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/reactos/dll/win32/usp10/bidi.c b/reactos/dll/win32/usp10/bidi.c new file mode 100644 index 00000000000..28b5d3e76ce --- /dev/null +++ b/reactos/dll/win32/usp10/bidi.c @@ -0,0 +1,893 @@ +/* + * Uniscribe BiDirectional handling + * + * Copyright 2003 Shachar Shemesh + * Copyright 2007 Maarten Lankhorst + * Copyright 2010 CodeWeavers, Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Code derived from the modified reference implementation + * that was found in revision 17 of http://unicode.org/reports/tr9/ + * "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM" + * + * -- Copyright (C) 1999-2005, ASMUS, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of the Unicode data files and any associated documentation (the + * "Data Files") or Unicode software and any associated documentation (the + * "Software") to deal in the Data Files or Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Data Files or Software, + * and to permit persons to whom the Data Files or Software are furnished + * to do so, provided that (a) the above copyright notice(s) and this + * permission notice appear with all copies of the Data Files or Software, + * (b) both the above copyright notice(s) and this permission notice appear + * in associated documentation, and (c) there is clear notice in each + * modified Data File or in the Software as well as in the documentation + * associated with the Data File(s) or Software that the data or software + * has been modified. + */ + +#include "config.h" + +#include +#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; +} diff --git a/reactos/dll/win32/usp10/usp10.c b/reactos/dll/win32/usp10/usp10.c index cdd6d7b2919..85957143557 100644 --- a/reactos/dll/win32/usp10/usp10.c +++ b/reactos/dll/win32/usp10/usp10.c @@ -3,6 +3,7 @@ * * Copyright 2005 Steven Edwards for CodeWeavers * Copyright 2006 Hans Leidekker + * Copyright 2010 CodeWeavers, Aric Stewart * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,6 +33,8 @@ #include "winnls.h" #include "usp10.h" +#include "usp10_internal.h" + #include "wine/debug.h" #include "wine/unicode.h" @@ -524,6 +527,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem int cnt = 0, index = 0; int New_Script = SCRIPT_UNDEFINED; + WORD *levels = NULL; TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, psControl, psState, pItems, pcItems); @@ -531,6 +535,24 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2) return E_INVALIDARG; + if (psState && psControl) + { + int i; + levels = heap_alloc_zero(cInChars * sizeof(WORD)); + if (!levels) + return E_OUTOFMEMORY; + + BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels); + for (i = 0; i < cInChars; i++) + if (levels[i]!=levels[0]) + break; + if (i >= cInChars) + { + heap_free(levels); + levels = NULL; + } + } + pItems[index].iCharPos = 0; memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS)); @@ -549,15 +571,29 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem if (pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop) pItems[index].a.eScript = Script_Latin; - if (pItems[index].a.eScript == Script_Arabic) + if (levels) + { + pItems[index].a.fRTL = odd(levels[cnt]); + pItems[index].a.fLayoutRTL = odd(levels[cnt]); + pItems[index].a.s.uBidiLevel = levels[cnt]; + } + else if (pItems[index].a.eScript == Script_Arabic) + { pItems[index].a.s.uBidiLevel = 1; + pItems[index].a.fRTL = 1; + pItems[index].a.fLayoutRTL = 1; + } - TRACE("New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n", - New_Script, pItems[index].a.eScript, index, cnt, + + TRACE("New_Level=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n", + levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript, index, cnt, pItems[index].iCharPos); for (cnt=1; cnt < cInChars; cnt++) { + if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel)) + continue; + if (pwcInChars[cnt] == '\r') New_Script = Script_CR; else @@ -578,9 +614,9 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem else New_Script = SCRIPT_UNDEFINED; - if (New_Script != pItems[index].a.eScript) + if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) || New_Script != pItems[index].a.eScript) { - TRACE("New_Script=%d, eScript=%d ", New_Script, pItems[index].a.eScript); + TRACE("New_Level = %i, New_Script=%d, eScript=%d ", levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript); index++; if (index+1 > cMaxItems) return E_OUTOFMEMORY; @@ -588,9 +624,18 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem pItems[index].iCharPos = cnt; memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS)); - if (New_Script == Script_Arabic) + if (levels) + { + pItems[index].a.fRTL = odd(levels[cnt]); + pItems[index].a.fLayoutRTL = odd(levels[cnt]); + pItems[index].a.s.uBidiLevel = levels[cnt]; + } + else if (New_Script == Script_Arabic) + { pItems[index].a.s.uBidiLevel = 1; - + pItems[index].a.fRTL = 1; + pItems[index].a.fLayoutRTL = 1; + } pItems[index].a.eScript = New_Script; TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos); @@ -610,6 +655,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem /* Set SCRIPT_ITEM */ pItems[index+1].iCharPos = cnt; /* the last + 1 item contains the ptr to the lastchar */ + heap_free(levels); return S_OK; } @@ -686,7 +732,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, int numGlyphsReturned; /* FIXME: non unicode strings */ - WCHAR* pStr = (WCHAR*)pString; + const WCHAR* pStr = (const WCHAR*)pString; hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs, &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned); @@ -1286,6 +1332,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, { HRESULT hr; unsigned int i; + BOOL rtl; TRACE("(%p, %p, %s, %d, %d, %p, %p, %p, %p, %p)\n", hdc, psc, debugstr_wn(pwcChars, cChars), cChars, cMaxGlyphs, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs); @@ -1295,6 +1342,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, if (!psva || !pcGlyphs) return E_INVALIDARG; if (cChars > cMaxGlyphs) return E_OUTOFMEMORY; + rtl = (!psa->fLogicalOrder && psa->fRTL); *pcGlyphs = cChars; if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr; @@ -1304,33 +1352,42 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, { for (i = 0; i < cChars; i++) { - if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[i]))) + int idx = i; + if (rtl) idx = cChars - 1 - i; + if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[idx]))) { WORD glyph; if (!hdc) return E_PENDING; - if (GetGlyphIndicesW(hdc, &pwcChars[i], 1, &glyph, 0) == GDI_ERROR) return S_FALSE; - pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[i], glyph); + if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE; + pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph); } } } else { TRACE("no glyph translation\n"); - for (i = 0; i < cChars; i++) pwOutGlyphs[i] = pwcChars[i]; + for (i = 0; i < cChars; i++) + { + int idx = i; + if (rtl) idx = cChars - 1 - i; + pwOutGlyphs[i] = pwcChars[idx]; + } } /* set up a valid SCRIPT_VISATTR and LogClust for each char in this run */ for (i = 0; i < cChars; i++) { + int idx = i; + if (rtl) idx = cChars - 1 - i; /* FIXME: set to better values */ - psva[i].uJustification = (pwcChars[i] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER; + psva[i].uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER; psva[i].fClusterStart = 1; psva[i].fDiacritic = 0; psva[i].fZeroWidth = 0; psva[i].fReserved = 0; psva[i].fShapeReserved = 0; - pwLogClust[i] = i; + pwLogClust[i] = idx; } return S_OK; } @@ -1573,28 +1630,45 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB */ HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis) { - int i, j = runs - 1, k = 0; + int* indexs; + int ich; TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis); if (!level || (!vistolog && !logtovis)) return E_INVALIDARG; - for (i = 0; i < runs; i++) + indexs = heap_alloc(sizeof(int) * runs); + if (!indexs) + return E_OUTOFMEMORY; + + + if (vistolog) { - if (level[i] % 2) - { - if (vistolog) *vistolog++ = j; - if (logtovis) *logtovis++ = j; - j--; - } - else - { - if (vistolog) *vistolog++ = k; - if (logtovis) *logtovis++ = k; - k++; - } + for( ich = 0; ich < runs; ich++) + indexs[ich] = ich; + + ich = 0; + while (ich < runs) + ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE); + for (ich = 0; ich < runs; ich++) + vistolog[ich] = indexs[ich]; } + + + if (logtovis) + { + for( ich = 0; ich < runs; ich++) + indexs[ich] = ich; + + ich = 0; + while (ich < runs) + ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE); + for (ich = 0; ich < runs; ich++) + logtovis[ich] = indexs[ich]; + } + heap_free(indexs); + return S_OK; } @@ -1839,9 +1913,3 @@ HRESULT WINAPI ScriptJustify(const SCRIPT_VISATTR *sva, const int *advance, for (i = 0; i < num_glyphs; i++) justify[i] = advance[i]; return S_OK; } - -BOOL gbLpkPresent = FALSE; -VOID WINAPI LpkPresent() -{ - gbLpkPresent = TRUE; /* Turn it on this way! Wine is out of control! */ -} diff --git a/reactos/dll/win32/usp10/usp10.rbuild b/reactos/dll/win32/usp10/usp10.rbuild index ad071018a46..527578c6edd 100644 --- a/reactos/dll/win32/usp10/usp10.rbuild +++ b/reactos/dll/win32/usp10/usp10.rbuild @@ -6,6 +6,7 @@ . include/reactos/wine + bidi.c usp10.c wine gdi32 diff --git a/reactos/dll/win32/usp10/usp10.spec b/reactos/dll/win32/usp10/usp10.spec index 0f7b0aa87c5..5e358707c41 100644 --- a/reactos/dll/win32/usp10/usp10.spec +++ b/reactos/dll/win32/usp10/usp10.spec @@ -1,4 +1,4 @@ -@ stdcall LpkPresent() +@ stub LpkPresent @ stdcall ScriptApplyDigitSubstitution(ptr ptr ptr) @ stdcall ScriptApplyLogicalWidth(ptr long long ptr ptr ptr ptr ptr ptr) @ stdcall ScriptBreak(ptr long ptr ptr) diff --git a/reactos/dll/win32/usp10/usp10_internal.h b/reactos/dll/win32/usp10/usp10_internal.h new file mode 100644 index 00000000000..60e4eff14ab --- /dev/null +++ b/reactos/dll/win32/usp10/usp10_internal.h @@ -0,0 +1,28 @@ +/* + * Implementation of Uniscribe Script Processor (usp10.dll) + * + * Copyright 2010 CodeWeavers, Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define odd(x) ((x) & 1) + +BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s, + const SCRIPT_CONTROL *c, WORD *lpOutLevels ); + +INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse); +INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse); diff --git a/reactos/dll/win32/version/resource.c b/reactos/dll/win32/version/resource.c index e7d34e08a88..16d9eacf83e 100644 --- a/reactos/dll/win32/version/resource.c +++ b/reactos/dll/win32/version/resource.c @@ -199,7 +199,11 @@ static BOOL find_ne_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) */ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) { - IMAGE_NT_HEADERS pehd; + union + { + IMAGE_NT_HEADERS32 nt32; + IMAGE_NT_HEADERS64 nt64; + } pehd; DWORD pehdoffset; PIMAGE_DATA_DIRECTORY resDataDir; PIMAGE_SECTION_HEADER sections; @@ -208,14 +212,27 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) const void *resDir; const IMAGE_RESOURCE_DIRECTORY *resPtr; const IMAGE_RESOURCE_DATA_ENTRY *resData; - int i, nSections; + int i, len, nSections; BOOL ret = FALSE; /* Read in PE header */ pehdoffset = LZSeek( lzfd, 0, SEEK_CUR ); - if ( sizeof(pehd) != LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ) ) return 0; + len = LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ); + if (len < sizeof(pehd.nt32.FileHeader)) return 0; + if (len < sizeof(pehd)) memset( (char *)&pehd + len, 0, sizeof(pehd) - len ); + + switch (pehd.nt32.OptionalHeader.Magic) + { + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + resDataDir = pehd.nt32.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE; + break; + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + resDataDir = pehd.nt64.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE; + break; + default: + return 0; + } - resDataDir = pehd.OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; if ( !resDataDir->Size ) { TRACE("No resources in PE dll\n" ); @@ -223,15 +240,13 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) } /* Read in section table */ - nSections = pehd.FileHeader.NumberOfSections; + nSections = pehd.nt32.FileHeader.NumberOfSections; sections = HeapAlloc( GetProcessHeap(), 0, nSections * sizeof(IMAGE_SECTION_HEADER) ); if ( !sections ) return FALSE; - LZSeek( lzfd, pehdoffset + - sizeof(DWORD) + /* Signature */ - sizeof(IMAGE_FILE_HEADER) + - pehd.FileHeader.SizeOfOptionalHeader, SEEK_SET ); + len = FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + pehd.nt32.FileHeader.SizeOfOptionalHeader; + LZSeek( lzfd, pehdoffset + len, SEEK_SET ); if ( nSections * sizeof(IMAGE_SECTION_HEADER) != LZRead( lzfd, (LPSTR)sections, nSections * sizeof(IMAGE_SECTION_HEADER) ) ) diff --git a/reactos/dll/win32/windowscodecs/bmpdecode.c b/reactos/dll/win32/windowscodecs/bmpdecode.c index 5c805c8c098..854b3374b02 100644 --- a/reactos/dll/win32/windowscodecs/bmpdecode.c +++ b/reactos/dll/win32/windowscodecs/bmpdecode.c @@ -58,12 +58,14 @@ typedef struct { DWORD bc2AppData; } BITMAPCOREHEADER2; -struct BmpFrameDecode; -typedef HRESULT (*ReadDataFunc)(struct BmpFrameDecode* This); +struct BmpDecoder; +typedef HRESULT (*ReadDataFunc)(struct BmpDecoder* This); -typedef struct BmpFrameDecode { - const IWICBitmapFrameDecodeVtbl *lpVtbl; +typedef struct BmpDecoder { + const IWICBitmapDecoderVtbl *lpVtbl; + const IWICBitmapFrameDecodeVtbl *lpFrameVtbl; LONG ref; + BOOL initialized; IStream *stream; BITMAPFILEHEADER bfh; BITMAPV5HEADER bih; @@ -73,12 +75,17 @@ typedef struct BmpFrameDecode { INT stride; BYTE *imagedata; BYTE *imagedatastart; -} BmpFrameDecode; + CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */ +} BmpDecoder; + +static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, BmpDecoder, lpFrameVtbl); +} static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); if (!ppv) return E_INVALIDARG; @@ -87,7 +94,7 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface IsEqualIID(&IID_IWICBitmapSource, iid) || IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) { - *ppv = This; + *ppv = iface; } else { @@ -101,35 +108,22 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; - ULONG ref = InterlockedIncrement(&This->ref); + BmpDecoder *This = impl_from_frame(iface); - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; + return IUnknown_AddRef((IUnknown*)This); } static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; - ULONG ref = InterlockedDecrement(&This->ref); + BmpDecoder *This = impl_from_frame(iface); - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->imagedata); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; + return IUnknown_Release((IUnknown*)This); } static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; + BmpDecoder *This = impl_from_frame(iface); TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight); if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) @@ -149,7 +143,7 @@ static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface, static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; + BmpDecoder *This = impl_from_frame(iface); TRACE("(%p,%p)\n", iface, pPixelFormat); memcpy(pPixelFormat, This->pixelformat, sizeof(GUID)); @@ -180,7 +174,7 @@ static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, doubl static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; + BmpDecoder *This = impl_from_frame(iface); TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY); return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY); @@ -190,13 +184,15 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { HRESULT hr; - BmpFrameDecode *This = (BmpFrameDecode*)iface; + BmpDecoder *This = impl_from_frame(iface); int count; WICColor *wiccolors=NULL; RGBTRIPLE *bgrcolors=NULL; TRACE("(%p,%p)\n", iface, pIPalette); + EnterCriticalSection(&This->lock); + if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; @@ -238,7 +234,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, } else { - return WINCODEC_ERR_PALETTEUNAVAILABLE; + hr = WINCODEC_ERR_PALETTEUNAVAILABLE; + goto end; } } else @@ -256,7 +253,11 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, tablesize = sizeof(WICColor) * count; wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); - if (!wiccolors) return E_OUTOFMEMORY; + if (!wiccolors) + { + hr = E_OUTOFMEMORY; + goto end; + } offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size; hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); @@ -275,13 +276,18 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, } else { - return WINCODEC_ERR_PALETTEUNAVAILABLE; + hr = WINCODEC_ERR_PALETTEUNAVAILABLE; + goto end; } } - hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); - end: + + LeaveCriticalSection(&This->lock); + + if (SUCCEEDED(hr)) + hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); + HeapFree(GetProcessHeap(), 0, wiccolors); HeapFree(GetProcessHeap(), 0, bgrcolors); return hr; @@ -290,16 +296,18 @@ end: static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { - BmpFrameDecode *This = (BmpFrameDecode*)iface; - HRESULT hr; + BmpDecoder *This = impl_from_frame(iface); + HRESULT hr=S_OK; UINT width, height; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); + EnterCriticalSection(&This->lock); if (!This->imagedata) { hr = This->read_data_func(This); - if (FAILED(hr)) return hr; } + LeaveCriticalSection(&This->lock); + if (FAILED(hr)) return hr; hr = BmpFrameDecode_GetSize(iface, &width, &height); if (FAILED(hr)) return hr; @@ -330,7 +338,7 @@ static HRESULT WINAPI BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, return WINCODEC_ERR_CODECNOTHUMBNAIL; } -static HRESULT BmpFrameDecode_ReadUncompressed(BmpFrameDecode* This) +static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This) { UINT bytesperrow; UINT width, height; @@ -387,7 +395,7 @@ fail: return hr; } -static HRESULT BmpFrameDecode_ReadRLE8(BmpFrameDecode* This) +static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This) { UINT bytesperrow; UINT width, height; @@ -493,7 +501,7 @@ fail: return hr; } -static HRESULT BmpFrameDecode_ReadRLE4(BmpFrameDecode* This) +static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This) { UINT bytesperrow; UINT width, height; @@ -614,7 +622,7 @@ fail: return hr; } -static HRESULT BmpFrameDecode_ReadUnsupported(BmpFrameDecode* This) +static HRESULT BmpFrameDecode_ReadUnsupported(BmpDecoder* This) { return E_FAIL; } @@ -637,7 +645,7 @@ static const struct bitfields_format bitfields_formats[] = { {0} }; -static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = { +static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl = { BmpFrameDecode_QueryInterface, BmpFrameDecode_AddRef, BmpFrameDecode_Release, @@ -651,19 +659,6 @@ static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = { BmpFrameDecode_GetThumbnail }; -typedef struct { - const IWICBitmapDecoderVtbl *lpVtbl; - LONG ref; - BOOL initialized; - IStream *stream; - BITMAPFILEHEADER bfh; - BITMAPV5HEADER bih; - BmpFrameDecode *framedecode; - const WICPixelFormatGUID *pixelformat; - int bitsperpixel; - ReadDataFunc read_data_func; -} BmpDecoder; - static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) { HRESULT hr; @@ -873,7 +868,9 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface) if (ref == 0) { if (This->stream) IStream_Release(This->stream); - if (This->framedecode) IUnknown_Release((IUnknown*)This->framedecode); + HeapFree(GetProcessHeap(), 0, This->imagedata); + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This); } @@ -886,7 +883,9 @@ static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre HRESULT hr; BmpDecoder *This = (BmpDecoder*)iface; + EnterCriticalSection(&This->lock); hr = BmpDecoder_ReadHeaders(This, pIStream); + LeaveCriticalSection(&This->lock); if (FAILED(hr)) return hr; if (This->read_data_func == BmpFrameDecode_ReadUnsupported) @@ -903,6 +902,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p HRESULT hr; BmpDecoder *This = (BmpDecoder*)iface; + EnterCriticalSection(&This->lock); hr = BmpDecoder_ReadHeaders(This, pIStream); if (SUCCEEDED(hr)) @@ -910,6 +910,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p This->stream = pIStream; IStream_AddRef(pIStream); } + LeaveCriticalSection(&This->lock); return hr; } @@ -992,25 +993,8 @@ static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface, if (!This->stream) return WINCODEC_ERR_WRONGSTATE; - if (!This->framedecode) - { - This->framedecode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameDecode)); - if (!This->framedecode) return E_OUTOFMEMORY; - - This->framedecode->lpVtbl = &BmpFrameDecode_Vtbl; - This->framedecode->ref = 1; - This->framedecode->stream = This->stream; - IStream_AddRef(This->stream); - This->framedecode->bfh = This->bfh; - This->framedecode->bih = This->bih; - This->framedecode->pixelformat = This->pixelformat; - This->framedecode->bitsperpixel = This->bitsperpixel; - This->framedecode->read_data_func = This->read_data_func; - This->framedecode->imagedata = NULL; - } - - *ppIBitmapFrame = (IWICBitmapFrameDecode*)This->framedecode; - IWICBitmapFrameDecode_AddRef((IWICBitmapFrameDecode*)This->framedecode); + *ppIBitmapFrame = (IWICBitmapFrameDecode*)&This->lpFrameVtbl; + IWICBitmapDecoder_AddRef(iface); return S_OK; } @@ -1047,10 +1031,13 @@ HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) if (!This) return E_OUTOFMEMORY; This->lpVtbl = &BmpDecoder_Vtbl; + This->lpFrameVtbl = &BmpDecoder_FrameVtbl; This->ref = 1; This->initialized = FALSE; This->stream = NULL; - This->framedecode = NULL; + This->imagedata = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/clsfactory.c b/reactos/dll/win32/windowscodecs/clsfactory.c index d8d21052d5e..68e0530fbdc 100644 --- a/reactos/dll/win32/windowscodecs/clsfactory.c +++ b/reactos/dll/win32/windowscodecs/clsfactory.c @@ -50,6 +50,7 @@ static classinfo wic_classes[] = { {&CLSID_WICGifDecoder, GifDecoder_CreateInstance}, {&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance}, {&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance}, + {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance}, {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, {0}}; diff --git a/reactos/dll/win32/windowscodecs/converter.c b/reactos/dll/win32/windowscodecs/converter.c index 15c7b0f380a..b1c0952b9a2 100644 --- a/reactos/dll/win32/windowscodecs/converter.c +++ b/reactos/dll/win32/windowscodecs/converter.c @@ -71,6 +71,7 @@ typedef struct FormatConverter { WICBitmapDitherType dither; double alpha_threshold; WICBitmapPaletteType palette_type; + CRITICAL_SECTION lock; /* must be held when initialized */ } FormatConverter; static void make_grayscale_palette(WICColor *colors, UINT num_colors) @@ -765,6 +766,8 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); HeapFree(GetProcessHeap(), 0, This); } @@ -841,38 +844,56 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, const struct pixelformatinfo *srcinfo, *dstinfo; static INT fixme=0; GUID srcFormat; - HRESULT res; + HRESULT res=S_OK; TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat), dither, pIPalette, alphaThresholdPercent, paletteTranslate); if (pIPalette && !fixme++) FIXME("ignoring palette\n"); - if (This->source) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (This->source) + { + res = WINCODEC_ERR_WRONGSTATE; + goto end; + } res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat); - if (FAILED(res)) return res; + if (FAILED(res)) goto end; srcinfo = get_formatinfo(&srcFormat); - if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + if (!srcinfo) + { + res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + goto end; + } dstinfo = get_formatinfo(dstFormat); - if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + if (!dstinfo) + { + res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + goto end; + } if (dstinfo->copy_function) { IWICBitmapSource_AddRef(pISource); - This->source = pISource; This->src_format = srcinfo; This->dst_format = dstinfo; This->dither = dither; This->alpha_threshold = alphaThresholdPercent; This->palette_type = paletteTranslate; + This->source = pISource; } else - return WINCODEC_ERR_UNSUPPORTEDOPERATION; + res = WINCODEC_ERR_UNSUPPORTEDOPERATION; - return S_OK; +end: + + LeaveCriticalSection(&This->lock); + + return res; } static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface, @@ -930,6 +951,8 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p This->lpVtbl = &FormatConverter_Vtbl; This->ref = 1; This->source = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/gifformat.c b/reactos/dll/win32/windowscodecs/gifformat.c index 0597b1afbe3..3443b2c1ae1 100644 --- a/reactos/dll/win32/windowscodecs/gifformat.c +++ b/reactos/dll/win32/windowscodecs/gifformat.c @@ -40,6 +40,7 @@ typedef struct { LONG ref; BOOL initialized; GifFileType *gif; + CRITICAL_SECTION lock; } GifDecoder; typedef struct { @@ -302,6 +303,8 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); DGifCloseFile(This->gif); HeapFree(GetProcessHeap(), 0, This); } @@ -341,9 +344,12 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + EnterCriticalSection(&This->lock); + if (This->initialized || This->gif) { WARN("already initialized\n"); + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } @@ -353,16 +359,26 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p /* read all data from the stream */ This->gif = DGifOpen((void*)pIStream, _gif_inputfunc); - if (!This->gif) return E_FAIL; + if (!This->gif) + { + LeaveCriticalSection(&This->lock); + return E_FAIL; + } ret = DGifSlurp(This->gif); - if (ret == GIF_ERROR) return E_FAIL; + if (ret == GIF_ERROR) + { + LeaveCriticalSection(&This->lock); + return E_FAIL; + } /* make sure we don't use the stream after this method returns */ This->gif->UserData = NULL; This->initialized = TRUE; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -502,6 +518,8 @@ HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->ref = 1; This->initialized = FALSE; This->gif = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/icoformat.c b/reactos/dll/win32/windowscodecs/icoformat.c index ab30ab0a8af..e1ea7c6c8d6 100644 --- a/reactos/dll/win32/windowscodecs/icoformat.c +++ b/reactos/dll/win32/windowscodecs/icoformat.c @@ -62,6 +62,7 @@ typedef struct { BOOL initialized; IStream *stream; ICONHEADER header; + CRITICAL_SECTION lock; /* must be held when accessing stream */ } IcoDecoder; typedef struct { @@ -512,15 +513,17 @@ static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { IcoFrameDecode *This = (IcoFrameDecode*)iface; - HRESULT hr; + HRESULT hr=S_OK; UINT width, height, stride; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); + EnterCriticalSection(&This->parent->lock); if (!This->bits) { hr = IcoFrameDecode_ReadPixels(This); - if (FAILED(hr)) return hr; } + LeaveCriticalSection(&This->parent->lock); + if (FAILED(hr)) return hr; width = This->entry.bWidth ? This->entry.bWidth : 256; height = This->entry.bHeight ? This->entry.bHeight : 256; @@ -606,6 +609,8 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); if (This->stream) IStream_Release(This->stream); HeapFree(GetProcessHeap(), 0, This); } @@ -629,23 +634,37 @@ static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p ULONG bytesread; TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); - if (This->initialized) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (This->initialized) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } seek.QuadPart = 0; hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) return hr; + if (FAILED(hr)) goto end; hr = IStream_Read(pIStream, &This->header, sizeof(ICONHEADER), &bytesread); - if (FAILED(hr)) return hr; + if (FAILED(hr)) goto end; if (bytesread != sizeof(ICONHEADER) || This->header.idReserved != 0 || - This->header.idType != 1) return E_FAIL; + This->header.idType != 1) + { + hr = E_FAIL; + goto end; + } This->initialized = TRUE; This->stream = pIStream; IStream_AddRef(pIStream); - return S_OK; +end: + + LeaveCriticalSection(&This->lock); + + return hr; } static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface, @@ -715,18 +734,32 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) { IcoDecoder *This = (IcoDecoder*)iface; - IcoFrameDecode *result; + IcoFrameDecode *result=NULL; LARGE_INTEGER seek; HRESULT hr; ULONG bytesread; TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; + EnterCriticalSection(&This->lock); - if (This->header.idCount < index) return E_INVALIDARG; + if (!This->initialized) + { + hr = WINCODEC_ERR_NOTINITIALIZED; + goto fail; + } + + if (This->header.idCount < index) + { + hr = E_INVALIDARG; + goto fail; + } result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode)); - if (!result) return E_OUTOFMEMORY; + if (!result) + { + hr = E_OUTOFMEMORY; + goto fail; + } result->lpVtbl = &IcoFrameDecode_Vtbl; result->ref = 1; @@ -745,9 +778,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, *ppIBitmapFrame = (IWICBitmapFrameDecode*)result; + LeaveCriticalSection(&This->lock); + return S_OK; fail: + LeaveCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, result); if (SUCCEEDED(hr)) hr = E_FAIL; TRACE("<-- %x\n", hr); @@ -789,6 +825,8 @@ HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->ref = 1; This->stream = NULL; This->initialized = FALSE; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/jpegformat.c b/reactos/dll/win32/windowscodecs/jpegformat.c index 017e6045790..b5676eaacc8 100644 --- a/reactos/dll/win32/windowscodecs/jpegformat.c +++ b/reactos/dll/win32/windowscodecs/jpegformat.c @@ -103,6 +103,7 @@ typedef struct { struct jpeg_source_mgr source_mgr; BYTE source_buffer[1024]; BYTE *image_data; + CRITICAL_SECTION lock; } JpegDecoder; static inline JpegDecoder *decoder_from_decompress(j_decompress_ptr decompress) @@ -156,6 +157,8 @@ static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo); if (This->stream) IStream_Release(This->stream); HeapFree(GetProcessHeap(), 0, This->image_data); @@ -225,7 +228,13 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * int ret; TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); - if (This->cinfo_initialized) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (This->cinfo_initialized) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } This->cinfo.err = pjpeg_std_error(&This->jerr); @@ -249,6 +258,7 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * if (ret != JPEG_HEADER_OK) { WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); + LeaveCriticalSection(&This->lock); return E_FAIL; } @@ -260,11 +270,14 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * if (!pjpeg_start_decompress(&This->cinfo)) { ERR("jpeg_start_decompress failed\n"); + LeaveCriticalSection(&This->lock); return E_FAIL; } This->initialized = TRUE; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -448,10 +461,16 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, max_row_needed = prc->Y + prc->Height; if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG; + EnterCriticalSection(&This->lock); + if (!This->image_data) { This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size); - if (!This->image_data) return E_OUTOFMEMORY; + if (!This->image_data) + { + LeaveCriticalSection(&This->lock); + return E_OUTOFMEMORY; + } } while (max_row_needed > This->cinfo.output_scanline) @@ -471,6 +490,7 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, if (ret == 0) { ERR("read_scanlines failed\n"); + LeaveCriticalSection(&This->lock); return E_FAIL; } @@ -492,6 +512,8 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, } } + LeaveCriticalSection(&This->lock); + return copy_pixels(bpp, This->image_data, This->cinfo.output_width, This->cinfo.output_height, stride, prc, cbStride, cbBufferSize, pbBuffer); @@ -559,6 +581,8 @@ HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->cinfo_initialized = FALSE; This->stream = NULL; This->image_data = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegDecoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/palette.c b/reactos/dll/win32/windowscodecs/palette.c index 842d3b51c30..40ab190958e 100644 --- a/reactos/dll/win32/windowscodecs/palette.c +++ b/reactos/dll/win32/windowscodecs/palette.c @@ -40,6 +40,7 @@ typedef struct { UINT count; WICColor *colors; WICBitmapPaletteType type; + CRITICAL_SECTION lock; /* must be held when count, colors, or type is accessed */ } PaletteImpl; static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid, @@ -83,6 +84,8 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This->colors); HeapFree(GetProcessHeap(), 0, This); } @@ -117,10 +120,12 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface, memcpy(new_colors, pColors, sizeof(WICColor) * colorCount); } + EnterCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This->colors); This->colors = new_colors; This->count = colorCount; This->type = WICBitmapPaletteTypeCustom; + LeaveCriticalSection(&This->lock); return S_OK; } @@ -148,7 +153,9 @@ static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface, if (!pePaletteType) return E_INVALIDARG; + EnterCriticalSection(&This->lock); *pePaletteType = This->type; + LeaveCriticalSection(&This->lock); return S_OK; } @@ -161,7 +168,9 @@ static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCoun if (!pcCount) return E_INVALIDARG; + EnterCriticalSection(&This->lock); *pcCount = This->count; + LeaveCriticalSection(&This->lock); return S_OK; } @@ -175,12 +184,16 @@ static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount, if (!pColors || !pcActualColors) return E_INVALIDARG; + EnterCriticalSection(&This->lock); + if (This->count < colorCount) colorCount = This->count; memcpy(pColors, This->colors, sizeof(WICColor) * colorCount); *pcActualColors = colorCount; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -192,10 +205,12 @@ static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBla if (!pfIsBlackWhite) return E_INVALIDARG; + EnterCriticalSection(&This->lock); if (This->type == WICBitmapPaletteTypeFixedBW) *pfIsBlackWhite = TRUE; else *pfIsBlackWhite = FALSE; + LeaveCriticalSection(&This->lock); return S_OK; } @@ -208,6 +223,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray if (!pfIsGrayscale) return E_INVALIDARG; + EnterCriticalSection(&This->lock); switch(This->type) { case WICBitmapPaletteTypeFixedBW: @@ -219,6 +235,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray default: *pfIsGrayscale = FALSE; } + LeaveCriticalSection(&This->lock); return S_OK; } @@ -234,12 +251,14 @@ static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha) *pfHasAlpha = FALSE; + EnterCriticalSection(&This->lock); for (i=0; icount; i++) if ((This->colors[i]&0xff000000) != 0xff000000) { *pfHasAlpha = TRUE; break; } + LeaveCriticalSection(&This->lock); return S_OK; } @@ -272,6 +291,8 @@ HRESULT PaletteImpl_Create(IWICPalette **palette) This->count = 0; This->colors = NULL; This->type = WICBitmapPaletteTypeCustom; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock"); *palette = (IWICPalette*)This; diff --git a/reactos/dll/win32/windowscodecs/pngformat.c b/reactos/dll/win32/windowscodecs/pngformat.c index 5af680e876c..3dcbd9aeb44 100644 --- a/reactos/dll/win32/windowscodecs/pngformat.c +++ b/reactos/dll/win32/windowscodecs/pngformat.c @@ -162,6 +162,7 @@ typedef struct { UINT stride; const WICPixelFormatGUID *format; BYTE *image_bits; + CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */ } PngDecoder; static inline PngDecoder *impl_from_frame(IWICBitmapFrameDecode *iface) @@ -214,6 +215,8 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface) { if (This->png_ptr) ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This->image_bits); HeapFree(GetProcessHeap(), 0, This); } @@ -246,7 +249,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p { PngDecoder *This = (PngDecoder*)iface; LARGE_INTEGER seek; - HRESULT hr; + HRESULT hr=S_OK; png_bytep *row_pointers=NULL; UINT image_size; UINT i; @@ -259,16 +262,23 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + EnterCriticalSection(&This->lock); + /* initialize libpng */ This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!This->png_ptr) return E_FAIL; + if (!This->png_ptr) + { + hr = E_FAIL; + goto end; + } This->info_ptr = ppng_create_info_struct(This->png_ptr); if (!This->info_ptr) { ppng_destroy_read_struct(&This->png_ptr, NULL, NULL); This->png_ptr = NULL; - return E_FAIL; + hr = E_FAIL; + goto end; } This->end_info = ppng_create_info_struct(This->png_ptr); @@ -276,7 +286,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p { ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL); This->png_ptr = NULL; - return E_FAIL; + hr = E_FAIL; + goto end; } /* set up setjmp/longjmp error handling */ @@ -285,14 +296,15 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); HeapFree(GetProcessHeap(), 0, row_pointers); This->png_ptr = NULL; - return E_FAIL; + hr = E_FAIL; + goto end; } ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn); /* seek to the start of the stream */ seek.QuadPart = 0; hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) return hr; + if (FAILED(hr)) goto end; /* set up custom i/o handling */ ppng_set_read_fn(This->png_ptr, pIStream, user_read_data); @@ -340,7 +352,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p case 16: This->format = &GUID_WICPixelFormat16bppGray; break; default: ERR("invalid grayscale bit depth: %i\n", bit_depth); - return E_FAIL; + hr = E_FAIL; + goto end; } break; case PNG_COLOR_TYPE_GRAY_ALPHA: @@ -357,7 +370,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break; default: ERR("invalid RGBA bit depth: %i\n", bit_depth); - return E_FAIL; + hr = E_FAIL; + goto end; } break; case PNG_COLOR_TYPE_PALETTE: @@ -370,7 +384,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break; default: ERR("invalid indexed color bit depth: %i\n", bit_depth); - return E_FAIL; + hr = E_FAIL; + goto end; } break; case PNG_COLOR_TYPE_RGB: @@ -384,12 +399,14 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p case 16: This->format = &GUID_WICPixelFormat48bppRGB; break; default: ERR("invalid RGB color bit depth: %i\n", bit_depth); - return E_FAIL; + hr = E_FAIL; + goto end; } break; default: ERR("invalid color type %i\n", color_type); - return E_FAIL; + hr = E_FAIL; + goto end; } /* read the image data */ @@ -399,10 +416,18 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p image_size = This->stride * This->height; This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size); - if (!This->image_bits) return E_OUTOFMEMORY; + if (!This->image_bits) + { + hr = E_OUTOFMEMORY; + goto end; + } row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height); - if (!row_pointers) return E_OUTOFMEMORY; + if (!row_pointers) + { + hr = E_OUTOFMEMORY; + goto end; + } for (i=0; iheight; i++) row_pointers[i] = This->image_bits + i * This->stride; @@ -416,7 +441,11 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p This->initialized = TRUE; - return S_OK; +end: + + LeaveCriticalSection(&This->lock); + + return hr; } static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface, @@ -570,6 +599,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac png_uint_32 ret, xres, yres; int unit_type; + EnterCriticalSection(&This->lock); + ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type); if (ret && unit_type == PNG_RESOLUTION_METER) @@ -583,6 +614,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac *pDpiX = *pDpiY = 96.0; } + LeaveCriticalSection(&This->lock); + TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); return S_OK; @@ -600,16 +633,24 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, int num_trans; png_color_16p trans_values; int i; + HRESULT hr=S_OK; TRACE("(%p,%p)\n", iface, pIPalette); + EnterCriticalSection(&This->lock); + ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); - if (!ret) return WINCODEC_ERR_PALETTEUNAVAILABLE; + if (!ret) + { + hr = WINCODEC_ERR_PALETTEUNAVAILABLE; + goto end; + } if (num_palette > 256) { ERR("palette has %i colors?!\n", num_palette); - return E_FAIL; + hr = E_FAIL; + goto end; } for (i=0; ilock); + + if (SUCCEEDED(hr)) + hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette); + + return hr; } static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, @@ -706,6 +754,8 @@ HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->end_info = NULL; This->initialized = FALSE; This->image_bits = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); @@ -752,6 +802,7 @@ typedef struct PngEncoder { UINT lines_written; BOOL frame_committed; BOOL committed; + CRITICAL_SECTION lock; } PngEncoder; static inline PngEncoder *encoder_from_frame(IWICBitmapFrameEncode *iface) @@ -800,10 +851,18 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface, PngEncoder *This = encoder_from_frame(iface); TRACE("(%p,%p)\n", iface, pIEncoderOptions); - if (This->frame_initialized) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (This->frame_initialized) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } This->frame_initialized = TRUE; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -813,11 +872,19 @@ static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface, PngEncoder *This = encoder_from_frame(iface); TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (!This->frame_initialized || This->info_written) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } This->width = uiWidth; This->height = uiHeight; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -827,11 +894,19 @@ static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, PngEncoder *This = encoder_from_frame(iface); TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (!This->frame_initialized || This->info_written) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } This->xres = dpiX; This->yres = dpiY; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -842,7 +917,13 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface int i; TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE; + EnterCriticalSection(&This->lock); + + if (!This->frame_initialized || This->info_written) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } for (i=0; formats[i].guid; i++) { @@ -855,6 +936,8 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface This->format = &formats[i]; memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -888,15 +971,24 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, jmp_buf jmpbuf; TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); + EnterCriticalSection(&This->lock); + if (!This->frame_initialized || !This->width || !This->height || !This->format) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; + } if (lineCount == 0 || lineCount + This->lines_written > This->height) + { + LeaveCriticalSection(&This->lock); return E_INVALIDARG; + } /* set up setjmp/longjmp error handling */ if (setjmp(jmpbuf)) { + LeaveCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, row_pointers); return E_FAIL; } @@ -927,7 +1019,10 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*)); if (!row_pointers) + { + LeaveCriticalSection(&This->lock); return E_OUTOFMEMORY; + } for (i=0; ipng_ptr, row_pointers, lineCount); This->lines_written += lineCount; + LeaveCriticalSection(&This->lock); + HeapFree(GetProcessHeap(), 0, row_pointers); return S_OK; @@ -1019,12 +1116,18 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) jmp_buf jmpbuf; TRACE("(%p)\n", iface); + EnterCriticalSection(&This->lock); + if (!This->info_written || This->lines_written != This->height || This->frame_committed) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; + } /* set up setjmp/longjmp error handling */ if (setjmp(jmpbuf)) { + LeaveCriticalSection(&This->lock); return E_FAIL; } ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn); @@ -1033,6 +1136,8 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) This->frame_committed = TRUE; + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -1102,6 +1207,8 @@ static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface) if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); if (This->png_ptr) ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr); if (This->stream) @@ -1137,19 +1244,28 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface, TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); + EnterCriticalSection(&This->lock); + if (This->png_ptr) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; + } /* initialize libpng */ This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!This->png_ptr) + { + LeaveCriticalSection(&This->lock); return E_FAIL; + } This->info_ptr = ppng_create_info_struct(This->png_ptr); if (!This->info_ptr) { ppng_destroy_write_struct(&This->png_ptr, NULL); This->png_ptr = NULL; + LeaveCriticalSection(&This->lock); return E_FAIL; } @@ -1163,6 +1279,7 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface, This->png_ptr = NULL; IStream_Release(This->stream); This->stream = NULL; + LeaveCriticalSection(&This->lock); return E_FAIL; } ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn); @@ -1170,6 +1287,8 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface, /* set up custom i/o handling */ ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush); + LeaveCriticalSection(&This->lock); + return S_OK; } @@ -1219,17 +1338,31 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, HRESULT hr; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); + EnterCriticalSection(&This->lock); + if (This->frame_count != 0) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } if (!This->stream) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_NOTINITIALIZED; + } hr = CreatePropertyBag2(ppIEncoderOptions); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + LeaveCriticalSection(&This->lock); + return hr; + } This->frame_count = 1; + LeaveCriticalSection(&This->lock); + IWICBitmapEncoder_AddRef(iface); *ppIFrameEncode = (IWICBitmapFrameEncode*)&This->lpFrameVtbl; @@ -1241,11 +1374,18 @@ static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface) PngEncoder *This = (PngEncoder*)iface; TRACE("(%p)\n", iface); + EnterCriticalSection(&This->lock); + if (!This->frame_committed || This->committed) + { + LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; + } This->committed = TRUE; + EnterCriticalSection(&This->lock); + return S_OK; } @@ -1309,6 +1449,8 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->lines_written = 0; This->frame_committed = FALSE; This->committed = FALSE; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock"); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/reactos/dll/win32/windowscodecs/regsvr.c b/reactos/dll/win32/windowscodecs/regsvr.c index c87aa4b2458..c5828a6b8b9 100644 --- a/reactos/dll/win32/windowscodecs/regsvr.c +++ b/reactos/dll/win32/windowscodecs/regsvr.c @@ -727,25 +727,25 @@ static struct regsvr_coclass const coclass_list[] = { "WIC Imaging Factory", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICBmpDecoder, "WIC BMP Decoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICPngDecoder, "WIC PNG Decoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICPngEncoder, "WIC PNG Encoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICBmpEncoder, "WIC BMP Encoder", @@ -757,25 +757,31 @@ static struct regsvr_coclass const coclass_list[] = { "WIC GIF Decoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICIcoDecoder, "WIC ICO Decoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { &CLSID_WICJpegDecoder, "WIC JPEG Decoder", NULL, "windowscodecs.dll", - "Apartment" + "Both" + }, + { &CLSID_WICTiffDecoder, + "WIC TIFF Decoder", + NULL, + "windowscodecs.dll", + "Both" }, { &CLSID_WICDefaultFormatConverter, "WIC Default Format Converter", NULL, "windowscodecs.dll", - "Apartment" + "Both" }, { NULL } /* list terminator */ }; @@ -868,6 +874,27 @@ static struct decoder_pattern const png_patterns[] = { {0} }; +static const BYTE tiff_magic_le[] = {0x49,0x49,42,0}; +static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42}; + +static GUID const * const tiff_formats[] = { + &GUID_WICPixelFormatBlackWhite, + &GUID_WICPixelFormat4bppGray, + &GUID_WICPixelFormat8bppGray, + &GUID_WICPixelFormat4bppIndexed, + &GUID_WICPixelFormat8bppIndexed, + &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppPBGRA, + NULL +}; + +static struct decoder_pattern const tiff_patterns[] = { + {4,0,tiff_magic_le,mask_all,0}, + {4,0,tiff_magic_be,mask_all,0}, + {0} +}; + static struct regsvr_decoder const decoder_list[] = { { &CLSID_WICBmpDecoder, "The Wine Project", @@ -919,6 +946,16 @@ static struct regsvr_decoder const decoder_list[] = { png_formats, png_patterns }, + { &CLSID_WICTiffDecoder, + "The Wine Project", + "TIFF Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + "image/tiff", + ".tif;.tiff", + tiff_formats, + tiff_patterns + }, { NULL } /* list terminator */ }; diff --git a/reactos/dll/win32/windowscodecs/stream.c b/reactos/dll/win32/windowscodecs/stream.c index c59a9d27861..bd5592b9f30 100644 --- a/reactos/dll/win32/windowscodecs/stream.c +++ b/reactos/dll/win32/windowscodecs/stream.c @@ -41,6 +41,8 @@ typedef struct StreamOnMemory { BYTE *pbMemory; DWORD dwMemsize; DWORD dwCurPos; + + CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */ } StreamOnMemory; static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface, @@ -82,6 +84,8 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface) TRACE("(%p) refcount=%u\n", iface, ref); if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -96,9 +100,12 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface, if (!pv) return E_INVALIDARG; + EnterCriticalSection(&This->lock); uBytesRead = min(cb, This->dwMemsize - This->dwCurPos); memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead); This->dwCurPos += uBytesRead; + LeaveCriticalSection(&This->lock); + if (pcbRead) *pcbRead = uBytesRead; return S_OK; @@ -108,18 +115,24 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface, void const *pv, ULONG cb, ULONG *pcbWritten) { StreamOnMemory *This = (StreamOnMemory*)iface; + HRESULT hr; TRACE("(%p)\n", This); if (!pv) return E_INVALIDARG; - if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL; - if (cb) { + EnterCriticalSection(&This->lock); + if (cb > This->dwMemsize - This->dwCurPos) { + hr = STG_E_MEDIUMFULL; + } + else { memcpy(This->pbMemory + This->dwCurPos, pv, cb); This->dwCurPos += cb; + hr = S_OK; + if (pcbWritten) *pcbWritten = cb; } - if (pcbWritten) *pcbWritten = cb; + LeaveCriticalSection(&This->lock); - return S_OK; + return hr; } static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface, @@ -127,20 +140,29 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface, { StreamOnMemory *This = (StreamOnMemory*)iface; LARGE_INTEGER NewPosition; + HRESULT hr=S_OK; TRACE("(%p)\n", This); + EnterCriticalSection(&This->lock); if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart; else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart; else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart; - else return E_INVALIDARG; + else hr = E_INVALIDARG; - if (NewPosition.u.HighPart) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); - if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG; - if (NewPosition.QuadPart < 0) return E_INVALIDARG; - This->dwCurPos = NewPosition.u.LowPart; + if (SUCCEEDED(hr)) { + if (NewPosition.u.HighPart) hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + else if (NewPosition.QuadPart > This->dwMemsize) hr = E_INVALIDARG; + else if (NewPosition.QuadPart < 0) hr = E_INVALIDARG; + } - if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos; - return S_OK; + if (SUCCEEDED(hr)) { + This->dwCurPos = NewPosition.u.LowPart; + + if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos; + } + LeaveCriticalSection(&This->lock); + + return hr; } /* SetSize isn't implemented in the native windowscodecs DLL either */ @@ -450,8 +472,16 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, pObject->pbMemory = pbBuffer; pObject->dwMemsize = cbBufferSize; pObject->dwCurPos = 0; + InitializeCriticalSection(&pObject->lock); + pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock"); + + if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) + { + /* Some other thread set the stream first. */ + IStream_Release((IStream*)pObject); + return WINCODEC_ERR_WRONGSTATE; + } - This->pStream = (IStream*)pObject; return S_OK; } diff --git a/reactos/dll/win32/windowscodecs/tiffformat.c b/reactos/dll/win32/windowscodecs/tiffformat.c new file mode 100644 index 00000000000..fe87ddd6ba5 --- /dev/null +++ b/reactos/dll/win32/windowscodecs/tiffformat.c @@ -0,0 +1,866 @@ +/* + * Copyright 2010 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_TIFFIO_H +#include +#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("", 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; icached_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 diff --git a/reactos/dll/win32/windowscodecs/wincodecs_private.h b/reactos/dll/win32/windowscodecs/wincodecs_private.h index 632f82206da..0e72793dafc 100644 --- a/reactos/dll/win32/windowscodecs/wincodecs_private.h +++ b/reactos/dll/win32/windowscodecs/wincodecs_private.h @@ -28,6 +28,7 @@ extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv); extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv); extern HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv); +extern HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv); extern HRESULT PaletteImpl_Create(IWICPalette **palette); extern HRESULT StreamImpl_Create(IWICStream **stream); diff --git a/reactos/dll/win32/windowscodecs/windowscodecs.rbuild b/reactos/dll/win32/windowscodecs/windowscodecs.rbuild index 563a7a99352..da8e3e46618 100644 --- a/reactos/dll/win32/windowscodecs/windowscodecs.rbuild +++ b/reactos/dll/win32/windowscodecs/windowscodecs.rbuild @@ -28,6 +28,7 @@ propertybag.c regsvr.c stream.c + tiffformat.c ungif.c version.rc diff --git a/reactos/dll/win32/wininet/internet.c b/reactos/dll/win32/wininet/internet.c index f4b8a0a3abd..6fc8a212c89 100644 --- a/reactos/dll/win32/wininet/internet.c +++ b/reactos/dll/win32/wininet/internet.c @@ -102,8 +102,8 @@ static CRITICAL_SECTION_DEBUG WININET_cs_debug = static CRITICAL_SECTION WININET_cs = { &WININET_cs_debug, -1, 0, 0, 0, 0 }; static object_header_t **WININET_Handles; -static UINT WININET_dwNextHandle; -static UINT WININET_dwMaxHandles; +static UINT_PTR WININET_dwNextHandle; +static UINT_PTR WININET_dwMaxHandles; typedef struct { @@ -122,7 +122,7 @@ static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l',' HINTERNET WININET_AllocHandle( object_header_t *info ) { object_header_t **p; - UINT handle = 0, num; + UINT_PTR handle = 0, num; list_init( &info->children ); @@ -173,7 +173,7 @@ object_header_t *WININET_AddRef( object_header_t *info ) object_header_t *WININET_GetObject( HINTERNET hinternet ) { object_header_t *info = NULL; - UINT handle = (UINT) hinternet; + UINT_PTR handle = (UINT_PTR) hinternet; EnterCriticalSection( &WININET_cs ); @@ -183,7 +183,7 @@ object_header_t *WININET_GetObject( HINTERNET hinternet ) LeaveCriticalSection( &WININET_cs ); - TRACE("handle %d -> %p\n", handle, info); + TRACE("handle %ld -> %p\n", handle, info); return info; } @@ -218,7 +218,7 @@ BOOL WININET_Release( object_header_t *info ) BOOL WININET_FreeHandle( HINTERNET hinternet ) { BOOL ret = FALSE; - UINT handle = (UINT) hinternet; + UINT_PTR handle = (UINT_PTR) hinternet; object_header_t *info = NULL, *child, *next; EnterCriticalSection( &WININET_cs ); @@ -229,7 +229,7 @@ BOOL WININET_FreeHandle( HINTERNET hinternet ) if( WININET_Handles[handle] ) { info = WININET_Handles[handle]; - TRACE( "destroying handle %d for object %p\n", handle+1, info); + TRACE( "destroying handle %ld for object %p\n", handle+1, info); WININET_Handles[handle] = NULL; ret = TRUE; } @@ -245,8 +245,8 @@ BOOL WININET_FreeHandle( HINTERNET hinternet ) /* Free all children as native does */ LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry ) { - TRACE( "freeing child handle %d for parent handle %d\n", - (UINT)child->hInternet, handle+1); + TRACE( "freeing child handle %ld for parent handle %ld\n", + (UINT_PTR)child->hInternet, handle+1); WININET_FreeHandle( child->hInternet ); } WININET_Release( info ); diff --git a/reactos/dll/win32/wininet/urlcache.c b/reactos/dll/win32/wininet/urlcache.c index 29d26ab0b6b..6a39c691475 100644 --- a/reactos/dll/win32/wininet/urlcache.c +++ b/reactos/dll/win32/wininet/urlcache.c @@ -986,9 +986,9 @@ static DWORD URLCache_CopyEntry( ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4)); dwRequiredSize = DWORD_ALIGN(dwRequiredSize); if (bUnicode) - lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0); + lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0); else - lenUrl = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); + lenUrl = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); dwRequiredSize += (lenUrl + 1) * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); /* FIXME: is source url optional? */ @@ -998,9 +998,9 @@ static DWORD URLCache_CopyEntry( lpCacheEntryInfo->lpszSourceUrlName = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenUrlBytes; if (bUnicode) - MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1); + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1); else - memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes); + memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes); } if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) @@ -1029,7 +1029,7 @@ static DWORD URLCache_CopyEntry( if (*lpdwBufferSize >= dwRequiredSize) { lpCacheEntryInfo->lpHeaderInfo = (LPBYTE)lpCacheEntryInfo + dwRequiredSize - pUrlEntry->dwHeaderInfoSize - 1; - memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize); + memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize); ((LPBYTE)lpCacheEntryInfo)[dwRequiredSize - 1] = '\0'; } if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) @@ -1041,18 +1041,18 @@ static DWORD URLCache_CopyEntry( int lenExtension; if (bUnicode) - lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0); + lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0); else - lenExtension = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1; + lenExtension = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1; dwRequiredSize += lenExtension * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); if (*lpdwBufferSize >= dwRequiredSize) { lpCacheEntryInfo->lpszFileExtension = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenExtension; if (bUnicode) - MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension); + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension); else - memcpy(lpCacheEntryInfo->lpszFileExtension, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR)); + memcpy(lpCacheEntryInfo->lpszFileExtension, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR)); } if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) @@ -1175,8 +1175,8 @@ static inline HASH_CACHEFILE_ENTRY * URLCache_HashEntryFromOffset(LPCURLCACHE_HE static inline BOOL URLCache_IsHashEntryValid(LPCURLCACHE_HEADER pHeader, const HASH_CACHEFILE_ENTRY *pHashEntry) { /* check pHashEntry located within acceptable bounds in the URL cache mapping */ - return ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) && - ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize); + return ((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) >= ENTRY_START_OFFSET) && + ((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) < pHeader->dwFileSize); } static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry) @@ -1557,15 +1557,15 @@ BOOL WINAPI GetUrlCacheEntryInfoA( if (pEntry->dwSignature != URL_SIGNATURE) { URLCacheContainer_UnlockIndex(pContainer, pHeader); - FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD))); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry; - TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl)); + TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl)); if (pUrlEntry->dwOffsetHeaderInfo) - TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); + TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); if (lpdwCacheEntryInfoBufferSize) { @@ -1639,14 +1639,14 @@ BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl, if (pEntry->dwSignature != URL_SIGNATURE) { URLCacheContainer_UnlockIndex(pContainer, pHeader); - FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD))); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry; - TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl)); - TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); + TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl)); + TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); if (lpdwCacheEntryInfoBufferSize) { @@ -3265,9 +3265,9 @@ BOOL WINAPI FindNextUrlCacheEntryA( if (pEntry->dwSignature != URL_SIGNATURE) continue; - pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; - TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); - TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo); + pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry; + TRACE("Found URL: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); + TRACE("Header info: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo); error = URLCache_CopyEntry( pContainer, @@ -3563,7 +3563,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredA( LPCSTR url, DWORD dwFlags, FILETIME* pftLas if (pEntry->dwSignature != URL_SIGNATURE) { URLCacheContainer_UnlockIndex(pContainer, pHeader); - FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD))); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } @@ -3625,7 +3625,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa if (pEntry->dwSignature != URL_SIGNATURE) { URLCacheContainer_UnlockIndex(pContainer, pHeader); - FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD))); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } diff --git a/reactos/dll/win32/wintrust/asn.c b/reactos/dll/win32/wintrust/asn.c index 69c9dd3d604..865926640a3 100644 --- a/reactos/dll/win32/wintrust/asn.c +++ b/reactos/dll/win32/wintrust/asn.c @@ -1348,7 +1348,7 @@ static BOOL CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType, link->dwLinkChoice = SPC_FILE_LINK_CHOICE; for (i = 0; i < dataLen / sizeof(WCHAR); i++) link->u.pwszFile[i] = - hton16(*(WORD *)(ptr + i * sizeof(WCHAR))); + hton16(*(const WORD *)(ptr + i * sizeof(WCHAR))); link->u.pwszFile[realDataLen / sizeof(WCHAR)] = '\0'; TRACE("returning file %s\n", debugstr_w(link->u.pwszFile)); } diff --git a/reactos/include/psdk/ntsecpkg.h b/reactos/include/psdk/ntsecpkg.h index 4de56cc05b0..b83d364544b 100644 --- a/reactos/include/psdk/ntsecpkg.h +++ b/reactos/include/psdk/ntsecpkg.h @@ -19,6 +19,10 @@ #ifndef _NTSECPKG_H #define _NTSECPKG_H +#ifdef __cplusplus +extern "C" { +#endif + /* Flags for the MachineState field in SECPKG_PARAMETERS */ #define SECPKG_STATE_ENCRYPTION_PERMITTED 0x01 #define SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED 0x02 @@ -30,6 +34,9 @@ #define SECPKG_INTERFACE_VERSION 0x10000 #define SECPKG_INTERFACE_VERSION_2 0x20000 #define SECPKG_INTERFACE_VERSION_3 0x40000 +#define SECPKG_INTERFACE_VERSION_4 0x80000 +#define SECPKG_INTERFACE_VERSION_5 0x100000 +#define SECPKG_INTERFACE_VERSION_6 0x200000 /* enum definitions for Secure Service Provider/Authentication Packages */ typedef enum _LSA_TOKEN_INFORMATION_TYPE { @@ -140,6 +147,11 @@ typedef struct _SECPKG_EXTENDED_INFORMATION { } Info; } SECPKG_EXTENDED_INFORMATION, *PSECPKG_EXTENDED_INFORMATION; +typedef struct _SECPKG_TARGETINFO { + PSID DomainSid; + PCWSTR ComputerName; +} SECPKG_TARGETINFO, *PSECPKG_TARGETINFO; + /* callbacks implemented by SSP/AP dlls and called by the LSA */ typedef VOID (NTAPI *PLSA_CALLBACK_FUNCTION)(ULONG_PTR, ULONG_PTR, PSecBuffer, PSecBuffer); @@ -341,6 +353,18 @@ typedef NTSTATUS (NTAPI SpSetContextAttributesFn)(LSA_SEC_HANDLE, ULONG, PVOID, ULONG); typedef NTSTATUS (NTAPI SpSetCredentialsAttributesFn)(LSA_SEC_HANDLE, ULONG, PVOID, ULONG); +typedef NTSTATUS (NTAPI SpChangeAccountPasswordFn)(PUNICODE_STRING, + PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, BOOLEAN, PSecBufferDesc); +typedef NTSTATUS (NTAPI SpQueryMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING, + ULONG, PULONG, PUCHAR *, PLSA_SEC_HANDLE); +typedef NTSTATUS (NTAPI SpExchangeMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING, + ULONG, ULONG, PUCHAR, PLSA_SEC_HANDLE); +typedef NTSTATUS (NTAPI SpGetCredUIContextFn)(LSA_SEC_HANDLE, GUID *, PULONG, + PUCHAR *); +typedef NTSTATUS (NTAPI SpUpdateCredentialsFn)(LSA_SEC_HANDLE, GUID *, ULONG, + PUCHAR); +typedef NTSTATUS (NTAPI SpValidateTargetInfoFn)(PLSA_CLIENT_REQUEST, PVOID, + PVOID, ULONG, PSECPKG_TARGETINFO); /* User-mode functions implemented by SSP/AP obtainable by a dispatch table */ typedef NTSTATUS (NTAPI SpInstanceInitFn)(ULONG, PSECPKG_DLL_FUNCTIONS, @@ -402,6 +426,15 @@ typedef struct SECPKG_FUNCTION_TABLE { /* Packages with version SECPKG_INTERFACE_VERSION_2 end here */ SpSetCredentialsAttributesFn *SetCredentialsAttributes; /* Packages with version SECPKG_INTERFACE_VERSION_3 end here */ + SpChangeAccountPasswordFn *ChangeAccountPassword; + /* Packages with version SECPKG_INTERFACE_VERSION_4 end here */ + SpQueryMetaDataFn *QueryMetaData; + SpExchangeMetaDataFn *ExchangeMetaData; + SpGetCredUIContextFn *GetCredUIContext; + SpUpdateCredentialsFn *UpdateCredentials; + /* Packages with version SECPKG_INTERFACE_VERSION_5 end here */ + SpValidateTargetInfoFn *ValidateTargetInfo; + /* Packages with version SECPKG_INTERFACE_VERSION_6 end here */ } SECPKG_FUNCTION_TABLE, *PSECPKG_FUNCTION_TABLE; @@ -432,4 +465,7 @@ typedef NTSTATUS (NTAPI *SpLsaModeInitializeFn)(ULONG, PULONG, typedef NTSTATUS (WINAPI *SpUserModeInitializeFn)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG); +#ifdef __cplusplus +} +#endif #endif /* _NTSECPKG_H */ diff --git a/reactos/include/psdk/psdk.rbuild b/reactos/include/psdk/psdk.rbuild index 02256ebc338..ebf38da2d59 100644 --- a/reactos/include/psdk/psdk.rbuild +++ b/reactos/include/psdk/psdk.rbuild @@ -47,6 +47,7 @@ richole.idl sensevts.idl servprov.idl + shdeprecated.idl shldisp.idl shobjidl.idl shtypes.idl @@ -68,6 +69,8 @@ xmldso.idl xmldom.idl xmllite.idl + wia_lh.idl + wia_xp.idl stdole2.idl diff --git a/reactos/include/psdk/shdeprecated.idl b/reactos/include/psdk/shdeprecated.idl new file mode 100644 index 00000000000..304b0875224 --- /dev/null +++ b/reactos/include/psdk/shdeprecated.idl @@ -0,0 +1,31 @@ +/* + * Deprecated shell interfaces + * + * Copyright (C) 2010 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "objidl.idl"; + +[ + object, + local, + uuid(5836fb00-8187-11cf-a12b-00aa004ae837) +] +interface IShellService : IUnknown +{ + HRESULT SetOwner( [in] IUnknown *pUnk ); +} diff --git a/reactos/include/psdk/shlwapi.h b/reactos/include/psdk/shlwapi.h index 29e70b76d8c..223bcdd3c05 100644 --- a/reactos/include/psdk/shlwapi.h +++ b/reactos/include/psdk/shlwapi.h @@ -1028,24 +1028,6 @@ typedef struct _DLLVERSIONINFO2 { HRESULT WINAPI DllInstall(BOOL,LPCWSTR) DECLSPEC_HIDDEN; -#if (_WIN32_IE >= 0x0600) -#define SHGVSPB_PERUSER 0x00000001 -#define SHGVSPB_ALLUSERS 0x00000002 -#define SHGVSPB_PERFOLDER 0x00000004 -#define SHGVSPB_ALLFOLDERS 0x00000008 -#define SHGVSPB_INHERIT 0x00000010 -#define SHGVSPB_ROAM 0x00000020 -#define SHGVSPB_NOAUTODEFAULTS 0x80000000 - -#define SHGVSPB_FOLDER (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER) -#define SHGVSPB_FOLDERNODEFAULTS (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER | SHGVSPB_NOAUTODEFAULTS) -#define SHGVSPB_USERDEFAULTS (SHGVSPB_PERUSER | SHGVSPB_ALLFOLDERS) -#define SHGVSPB_GLOBALDEAFAULTS (SHGVSPB_ALLUSERS | SHGVSPB_ALLFOLDERS) - -HRESULT WINAPI SHGetViewStatePropertyBag(LPCITEMIDLIST pidl, LPWSTR bag_name, DWORD flags, REFIID riid, void **ppv); -#endif /* (_WIN32_IE >= 0x0600) */ - - /* IsOS definitions */ #define OS_WIN32SORGREATER 0x00 @@ -1103,6 +1085,15 @@ BOOL WINAPI IsOS(DWORD); #define FDTF_RTLDATE 0x00000200 #define FDTF_NOAUTOREADINGORDER 0x00000400 + +typedef struct +{ + const IID *piid; + int dwOffset; +} QITAB, *LPQITAB; + +HRESULT WINAPI QISearch(void* base, const QITAB *pqit, REFIID riid, void **ppv); + #include #ifdef __cplusplus diff --git a/reactos/include/psdk/sti.h b/reactos/include/psdk/sti.h index 56650f5a011..204492d9a2f 100644 --- a/reactos/include/psdk/sti.h +++ b/reactos/include/psdk/sti.h @@ -31,6 +31,147 @@ extern "C" { DEFINE_GUID(CLSID_Sti, 0xB323F8E0L, 0x2E68, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C); +DEFINE_GUID(IID_IStillImageW, 0x641BD880, 0x2DC8, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C); + +DEFINE_GUID(IID_IStillImageA, 0xA7B1F740, 0x1D7F, 0x11D1, 0xAC, 0xA9, 0x00, 0xA0, 0x24, 0x38, 0xAD, 0x48); + +#define STI_VERSION_REAL 0x00000002 +#define STI_VERSION_FLAG_UNICODE 0x01000000 + +#ifndef WINE_NO_UNICODE_MACROS +# ifdef UNICODE +# define STI_VERSION (STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE) +# else +# define STI_VERSION (STI_VERSION_REAL) +# endif +#endif + +typedef struct IStillImageA *PSTIA; +typedef struct IStillImageW *PSTIW; +DECL_WINELIB_TYPE_AW(PSTI) +typedef struct IStillImageA *LPSTILLIMAGEA; +typedef struct IStillImageW *LPSTILLIMAGEW; +DECL_WINELIB_TYPE_AW(LPSTILLIMAGE) +typedef struct IStiDeviceA *PSTIDEVICEA; +typedef struct IStiDeviceW *PSTIDEVICEW; +DECL_WINELIB_TYPE_AW(PSTIDEVICE) + +HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter); +HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter); +#define StiCreateInstance WINELIB_NAME_AW(StiCreateInstance) + +typedef DWORD STI_DEVICE_TYPE; +typedef enum _STI_DEVICE_MJ_TYPE +{ + StiDeviceTypeDefault = 0, + StiDeviceTypeScanner = 1, + StiDeviceTypeDigitalCamera = 2, + StiDeviceTypeStreamingVideo = 3 +} STI_DEVICE_MJ_TYPE; + +#define GET_STIDEVICE_TYPE(dwDevType) HIWORD(dwDevType) +#define GET_STIDEVICE_SUBTYPE(dwDevType) LOWORD(dwDevType) + +typedef struct _STI_DEV_CAPS { + DWORD dwGeneric; +} STI_DEV_CAPS, *PSTI_DEV_CAPS; + +#define STI_MAX_INTERNAL_NAME_LENGTH 128 + +typedef struct _STI_DEVICE_INFORMATIONW { + DWORD dwSize; + STI_DEVICE_TYPE DeviceType; + WCHAR szDeviceInternalName[STI_MAX_INTERNAL_NAME_LENGTH]; + STI_DEV_CAPS DeviceCapabilities; + DWORD dwHardwareConfiguration; + LPWSTR pszVendorDescription; + LPWSTR pszDeviceDescription; + LPWSTR pszPortName; + LPWSTR pszPropProvider; + LPWSTR pszLocalName; +} STI_DEVICE_INFORMATIONW, *PSTI_DEVICE_INFORMATIONW; + +typedef STI_DEVICE_INFORMATIONW STI_DEVICE_INFORMATION; +typedef PSTI_DEVICE_INFORMATIONW PSTI_DEVICE_INFORMATION; + +#define MAX_NOTIFICATION_DATA 64 + +typedef struct _STINOTIFY { + DWORD dwSize; + GUID guidNotificationCode; + BYTE abNotificationData[MAX_NOTIFICATION_DATA]; +} STINOTIFY,*LPSTINOTIFY; + +#define INTERFACE IStillImageW +DECLARE_INTERFACE_(IStillImageW, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IStillImageW methods ***/ + STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE; + STDMETHOD(GetDeviceList)(THIS_ DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer) PURE; + STDMETHOD(GetDeviceInfo)(THIS_ LPWSTR pwszDeviceName, LPVOID *ppBuffer) PURE; + STDMETHOD(CreateDevice)(THIS_ LPWSTR pwszDeviceName, DWORD dwMode, PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, LPDWORD cbData) PURE; + STDMETHOD(SetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, DWORD type, LPBYTE pData, DWORD cbData) PURE; + STDMETHOD(GetSTILaunchInformation)(THIS_ LPWSTR pwszDeviceName, DWORD *pdwEventCode, LPWSTR pwszEventName) PURE; + STDMETHOD(RegisterLaunchApplication)(THIS_ LPWSTR pwszAppName, LPWSTR pwszCommandLine) PURE; + STDMETHOD(UnregisterLaunchApplication)(THIS_ LPWSTR pwszAppName) PURE; + STDMETHOD(EnableHwNotifications)(THIS_ LPCWSTR pwszDeviceName, BOOL bNewState) PURE; + STDMETHOD(GetHwNotificationState)(THIS_ LPCWSTR pwszDeviceName, BOOL *pbCurrentState) PURE; + STDMETHOD(RefreshDeviceBus)(THIS_ LPCWSTR pwszDeviceName) PURE; + STDMETHOD(LaunchApplicationForDevice)(THIS_ LPWSTR pwszDeviceName, LPWSTR pwszAppName, LPSTINOTIFY pStiNotify); + STDMETHOD(SetupDeviceParameters)(THIS_ PSTI_DEVICE_INFORMATIONW pDevInfo); + STDMETHOD(WriteToErrorLog)(THIS_ DWORD dwMessageType, LPCWSTR pszMessage) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IStillImage_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IStillImage_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IStillImage_Release(p) (p)->lpVtbl->Release(p) +/*** IStillImage methods ***/ +#define IStillImage_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IStillImage_GetDeviceList(p,a,b,c,d) (p)->lpVtbl->GetDeviceList(p,a,b,c,d) +#define IStillImage_GetDeviceInfo(p,a,b) (p)->lpVtbl->GetDeviceInfo(p,a,b) +#define IStillImage_CreateDevice(p,a,b,c,d) (p)->lpVtbl->CreateDevice(p,a,b,c,d) +#define IStillImage_GetDeviceValue(p,a,b,c,d,e) (p)->lpVtbl->GetDeviceValue(p,a,b,c,d,e) +#define IStillImage_SetDeviceValue(p,a,b,c,d,e) (p)->lpVtbl->SetDeviceValue(p,a,b,c,d,e) +#define IStillImage_GetSTILaunchInformation(p,a,b,c) (p)->lpVtbl->GetSTILaunchInformation(p,a,b,c) +#define IStillImage_RegisterLaunchApplication(p,a,b) (p)->lpVtbl->RegisterLaunchApplication(p,a,b) +#define IStillImage_UnregisterLaunchApplication(p,a) (p)->lpVtbl->UnregisterLaunchApplication(p,a) +#define IStillImage_EnableHwNotifications(p,a,b) (p)->lpVtbl->EnableHwNotifications(p,a,b) +#define IStillImage_GetHwNotificationState(p,a,b) (p)->lpVtbl->GetHwNotificationState(p,a,b) +#define IStillImage_RefreshDeviceBus(p,a) (p)->lpVtbl->RefreshDeviceBus(p,a) +#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->lpVtbl->LaunchApplicationForDevice(p,a,b,c) +#define IStillImage_SetupDeviceParameters(p,a) (p)->lpVtbl->SetupDeviceParameters(p,a) +#define IStillImage_WriteToErrorLog(p,a,b) (p)->lpVtbl->WriteToErrorLog(p,a,b) +#else +/*** IUnknown methods ***/ +#define IStillImage_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IStillImage_AddRef(p) (p)->AddRef() +#define IStillImage_Release(p) (p)->Release() +/*** IStillImage methods ***/ +#define IStillImage_Initialize(p,a,b) (p)->Initialize(a,b) +#define IStillImage_GetDeviceList(p,a,b,c,d) (p)->GetDeviceList(a,b,c,d) +#define IStillImage_GetDeviceInfo(p,a,b) (p)->GetDeviceInfo(a,b) +#define IStillImage_CreateDevice(p,a,b,c,d) (p)->CreateDevice(a,b,c,d) +#define IStillImage_GetDeviceValue(p,a,b,c,d,e) (p)->GetDeviceValue(a,b,c,d,e) +#define IStillImage_SetDeviceValue(p,a,b,c,d,e) (p)->SetDeviceValue(a,b,c,d,e) +#define IStillImage_GetSTILaunchInformation(p,a,b,c) (p)->GetSTILaunchInformation(a,b,c) +#define IStillImage_RegisterLaunchApplication(p,a,b) (p)->RegisterLaunchApplication(a,b) +#define IStillImage_UnregisterLaunchApplication(p,a) (p)->UnregisterLaunchApplication(a) +#define IStillImage_EnableHwNotifications(p,a,b) (p)->EnableHwNotifications(a,b) +#define IStillImage_GetHwNotificationState(p,a,b) (p)->GetHwNotificationState(a,b) +#define IStillImage_RefreshDeviceBus(p,a) (p)->RefreshDeviceBus(a) +#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->LaunchApplicationForDevice(a,b,c) +#define IStillImage_SetupDeviceParameters(p,a) (p)->SetupDeviceParameters(a) +#define IStillImage_WriteToErrorLog(p,a,b) (p)->WriteToErrorLog(a,b) +#endif + #ifdef __cplusplus }; #endif diff --git a/reactos/include/psdk/wia.h b/reactos/include/psdk/wia.h new file mode 100644 index 00000000000..3a0497e6d83 --- /dev/null +++ b/reactos/include/psdk/wia.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifdef __WINESRC__ +#error Specify wia_lh.h or wia_xp.h explicitly in Wine +#endif + +#if (_WIN32_WINNT >= 0x0600) +#include +#elif (_WIN32_WINNT >= 0x0501) +#include +#endif diff --git a/reactos/include/psdk/wia_lh.idl b/reactos/include/psdk/wia_lh.idl new file mode 100644 index 00000000000..5024787a6fc --- /dev/null +++ b/reactos/include/psdk/wia_lh.idl @@ -0,0 +1,127 @@ +/* + * Copyright 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "wtypes.idl"; +import "objidl.idl"; + +interface IEnumWIA_DEV_INFO; +interface IWiaItem; +interface IWiaEventCallback; + +cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);") + +[ + object, + uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811) +] +interface IWiaDevMgr : IUnknown +{ + HRESULT EnumDeviceInfo( + [in] LONG lFlag, + [retval, out] IEnumWIA_DEV_INFO **ppIEnum); + + HRESULT CreateDevice( + [in] BSTR bstrDeviceID, + [out] IWiaItem **ppWiaItemRoot); + + HRESULT SelectDeviceDlg( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [in, out] BSTR *pbstrDeviceID, + [retval, out] IWiaItem **ppItemRoot); + + HRESULT SelectDeviceDlgID( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [retval, out] BSTR *pbstrDeviceID); + + HRESULT GetImageDlg( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [in] LONG lIntent, + [in] IWiaItem *pItemRoot, + [in] BSTR bstrFilename, + [in, out] GUID *pguidFormat); + + HRESULT RegisterEventCallbackProgram( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [in] BSTR bstrCommandline, + [in] BSTR bstrName, + [in] BSTR bstrDescription, + [in] BSTR bstrIcon); + + HRESULT RegisterEventCallbackInterface( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [unique, in] IWiaEventCallback *pIWiaEventCallback, + [out] IUnknown **pEventObject); + + HRESULT RegisterEventCallbackCLSID( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [unique, in] const GUID *pClsID, + [in] BSTR bstrName, + [in] BSTR bstrDescription, + [in] BSTR bstrIcon); + + HRESULT AddDeviceDlg( + [in] HWND hwndParent, + [in] LONG lFlags); +} + +[ + object, + uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811) +] +interface IEnumWIA_DEV_INFO : IUnknown +{ + /* fill in */ +} + +[ + object, + uuid(4db1ad10-3391-11d2-9a33-00c04fa36145) +] +interface IWiaItem : IUnknown +{ + /* FIXME: fill in */ +} + +[ + object, + uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e) +] +interface IWiaEventCallback : IUnknown +{ + HRESULT ImageEventCallback( + [in] const GUID *pEventGUID, + [in] BSTR bstrEventDescription, + [in] BSTR bstrDeviceID, + [in] BSTR bstrDeviceDescription, + [in] DWORD dwDeviceType, + [in] BSTR bstrFullItemName, + [in,out] ULONG *pulEventType, + [in] ULONG ulReserved); +} diff --git a/reactos/include/psdk/wia_xp.idl b/reactos/include/psdk/wia_xp.idl new file mode 100644 index 00000000000..5024787a6fc --- /dev/null +++ b/reactos/include/psdk/wia_xp.idl @@ -0,0 +1,127 @@ +/* + * Copyright 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +import "wtypes.idl"; +import "objidl.idl"; + +interface IEnumWIA_DEV_INFO; +interface IWiaItem; +interface IWiaEventCallback; + +cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);") + +[ + object, + uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811) +] +interface IWiaDevMgr : IUnknown +{ + HRESULT EnumDeviceInfo( + [in] LONG lFlag, + [retval, out] IEnumWIA_DEV_INFO **ppIEnum); + + HRESULT CreateDevice( + [in] BSTR bstrDeviceID, + [out] IWiaItem **ppWiaItemRoot); + + HRESULT SelectDeviceDlg( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [in, out] BSTR *pbstrDeviceID, + [retval, out] IWiaItem **ppItemRoot); + + HRESULT SelectDeviceDlgID( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [retval, out] BSTR *pbstrDeviceID); + + HRESULT GetImageDlg( + [in] HWND hwndParent, + [in] LONG lDeviceType, + [in] LONG lFlags, + [in] LONG lIntent, + [in] IWiaItem *pItemRoot, + [in] BSTR bstrFilename, + [in, out] GUID *pguidFormat); + + HRESULT RegisterEventCallbackProgram( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [in] BSTR bstrCommandline, + [in] BSTR bstrName, + [in] BSTR bstrDescription, + [in] BSTR bstrIcon); + + HRESULT RegisterEventCallbackInterface( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [unique, in] IWiaEventCallback *pIWiaEventCallback, + [out] IUnknown **pEventObject); + + HRESULT RegisterEventCallbackCLSID( + [in] LONG lFlags, + [in] BSTR bstrDeviceID, + [in] const GUID *pEventGUID, + [unique, in] const GUID *pClsID, + [in] BSTR bstrName, + [in] BSTR bstrDescription, + [in] BSTR bstrIcon); + + HRESULT AddDeviceDlg( + [in] HWND hwndParent, + [in] LONG lFlags); +} + +[ + object, + uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811) +] +interface IEnumWIA_DEV_INFO : IUnknown +{ + /* fill in */ +} + +[ + object, + uuid(4db1ad10-3391-11d2-9a33-00c04fa36145) +] +interface IWiaItem : IUnknown +{ + /* FIXME: fill in */ +} + +[ + object, + uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e) +] +interface IWiaEventCallback : IUnknown +{ + HRESULT ImageEventCallback( + [in] const GUID *pEventGUID, + [in] BSTR bstrEventDescription, + [in] BSTR bstrDeviceID, + [in] BSTR bstrDeviceDescription, + [in] DWORD dwDeviceType, + [in] BSTR bstrFullItemName, + [in,out] ULONG *pulEventType, + [in] ULONG ulReserved); +} diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 828e413dbc1..a1fbc15d694 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -52,13 +52,13 @@ reactos/dll/win32/comctl32 # Autosync ?? reactos/dll/win32/comdlg32 # Autosync reactos/dll/win32/compstui # Autosync reactos/dll/win32/credui # Autosync -reactos/dll/win32/crypt32 # Synced to Wine-1_1_40 +reactos/dll/win32/crypt32 # Synced to Wine-1_1_43 reactos/dll/win32/cryptdlg # Autosync reactos/dll/win32/cryptdll # Autosync reactos/dll/win32/cryptnet # Autosync reactos/dll/win32/cryptui # Autosync reactos/dll/win32/dbghelp # Synced to Wine-20080802 -reactos/dll/win32/dciman32 # Synced to Wine-1_0-rc2 +reactos/dll/win32/dciman32 # Synced to Wine-1_1_43 reactos/dll/win32/dwmapi # Autosync reactos/dll/win32/fusion # Autosync reactos/dll/win32/gdiplus # Autosync @@ -113,7 +113,7 @@ reactos/dll/win32/mstask # Autosync reactos/dll/win32/msvcrt20 # Autosync reactos/dll/win32/msvfw32 # Autosync reactos/dll/win32/msvidc32 # Autosync -reactos/dll/win32/msxml3 # Synced to Wine-1_1_40 +reactos/dll/win32/msxml3 # Synced to Wine-1_1_43 reactos/dll/win32/nddeapi # Autosync reactos/dll/win32/netapi32 # Autosync reactos/dll/win32/ntdsapi # Autosync @@ -144,6 +144,8 @@ reactos/dll/win32/rsabase # Autosync reactos/dll/win32/rsaenh # Autosync reactos/dll/win32/sccbase # Autosync reactos/dll/win32/schannel # Autosync ?? +reactos/dll/win32/secur32 # Forked +reactos/dll/win32/security # Forked (different .spec) reactos/dll/win32/sensapi # Autosync reactos/dll/win32/setupapi # Forked at Wine-20050524 reactos/dll/win32/shell32 # Forked at Wine-20071011 @@ -154,7 +156,7 @@ reactos/dll/win32/slbcsp # Autosync reactos/dll/win32/softpub # Autosync reactos/dll/win32/spoolss # Autosync reactos/dll/win32/stdole2.tlb # Autosync -reactos/dll/win32/sti # Autosync ?? +reactos/dll/win32/sti # Autosync reactos/dll/win32/sxs # Autosync reactos/dll/win32/tapi32 # Autosync reactos/dll/win32/traffic # Autosync @@ -203,7 +205,7 @@ In addition the following libs, dlls and source files are mostly based on code p from Winehq CVS. If you are looking to update something in these files check Wine current souces first as it may already be fixed. -reactos/lib/uuid # Synced to Wine-20080114 +reactos/lib/sdk/uuid # Synced to Wine-1.1.42 advapi32 - reactos/dll/win32/advapi32/crypt/*.c # ekohl says we're not sharing this