-/*\r
- * SHLWAPI ordinal functions\r
- *\r
- * Copyright 1997 Marcus Meissner\r
- * 1998 Jürgen Schmied\r
- * 2001-2003 Jon Griffiths\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-#define COM_NO_WINDOWS_H\r
-#include "config.h"\r
-#include "wine/port.h"\r
-\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#define COBJMACROS\r
-#define NONAMELESSUNION\r
-#define NONAMELESSSTRUCT\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "objbase.h"\r
-#include "docobj.h"\r
-#include "exdisp.h"\r
-#include "shlguid.h"\r
-#include "wingdi.h"\r
-#include "shlobj.h"\r
-#include "shellapi.h"\r
-#include "commdlg.h"\r
-#include "wine/unicode.h"\r
-#include "winreg.h"\r
-#include "wine/debug.h"\r
-#include "shlwapi.h"\r
-\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(shell);\r
-\r
-/* Get a function pointer from a DLL handle */\r
-#define GET_FUNC(func, module, name, fail) \\r
- do { \\r
- if (!func) { \\r
- if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \\r
- func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \\r
- if (!func) return fail; \\r
- } \\r
- } while (0)\r
-\r
-/* DLL handles for late bound calls */\r
-extern HINSTANCE shlwapi_hInstance;\r
-extern HMODULE SHLWAPI_hshell32;\r
-extern HMODULE SHLWAPI_hwinmm;\r
-extern HMODULE SHLWAPI_hcomdlg32;\r
-extern HMODULE SHLWAPI_hcomctl32;\r
-extern HMODULE SHLWAPI_hmpr;\r
-extern HMODULE SHLWAPI_hurlmon;\r
-extern HMODULE SHLWAPI_hversion;\r
-\r
-extern DWORD SHLWAPI_ThreadRef_index;\r
-\r
-/* following is GUID for IObjectWithSite::SetSite -- see _174 */\r
-static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};\r
-/* following is GUID for IPersistMoniker::GetClassID -- see _174 */\r
-static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};\r
-\r
-/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */\r
-typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);\r
-static fnpSHBrowseForFolderW pSHBrowseForFolderW;\r
-typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);\r
-static fnpPlaySoundW pPlaySoundW;\r
-typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);\r
-static fnpSHGetFileInfoW pSHGetFileInfoW;\r
-typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);\r
-static fnpDragQueryFileW pDragQueryFileW;\r
-typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);\r
-static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;\r
-typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);\r
-static fnpShellExecuteExW pShellExecuteExW;\r
-typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);\r
-static fnpSHFileOperationW pSHFileOperationW;\r
-typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);\r
-static fnpExtractIconExW pExtractIconExW;\r
-typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);\r
-static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;\r
-typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);\r
-static fnpSHDefExtractIconW pSHDefExtractIconW;\r
-typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);\r
-static fnpExtractIconW pExtractIconW;\r
-typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);\r
-static fnpGetSaveFileNameW pGetSaveFileNameW;\r
-typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);\r
-static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;\r
-typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);\r
-static fnpWNetGetLastErrorW pWNetGetLastErrorW;\r
-typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);\r
-static fnpPageSetupDlgW pPageSetupDlgW;\r
-typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);\r
-static fnpPrintDlgW pPrintDlgW;\r
-typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);\r
-static fnpGetOpenFileNameW pGetOpenFileNameW;\r
-typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);\r
-static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;\r
-typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);\r
-static fnpGetFileVersionInfoW pGetFileVersionInfoW;\r
-typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);\r
-static fnpVerQueryValueW pVerQueryValueW;\r
-typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);\r
-static fnpCOMCTL32_417 pCOMCTL32_417;\r
-typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);\r
-static fnpDllGetVersion pDllGetVersion;\r
-typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);\r
-static fnpCreateFormatEnumerator pCreateFormatEnumerator;\r
-typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);\r
-static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;\r
-\r
-HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);\r
-HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);\r
-HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);\r
-BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);\r
-\r
-/*\r
- NOTES: Most functions exported by ordinal seem to be superflous.\r
- The reason for these functions to be there is to provide a wrapper\r
- for unicode functions to provide these functions on systems without\r
- unicode functions eg. win95/win98. Since we have such functions we just\r
- call these. If running Wine with native DLL's, some late bound calls may\r
- fail. However, it is better to implement the functions in the forward DLL\r
- and recommend the builtin rather than reimplementing the calls here!\r
-*/\r
-\r
-/*************************************************************************\r
- * SHLWAPI_DupSharedHandle\r
- *\r
- * Internal implemetation of SHLWAPI_11.\r
- */\r
-static\r
-HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,\r
- DWORD dwSrcProcId, DWORD dwAccess,\r
- DWORD dwOptions)\r
-{\r
- HANDLE hDst, hSrc;\r
- DWORD dwMyProcId = GetCurrentProcessId();\r
- HANDLE hRet = NULL;\r
-\r
- TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,\r
- dwAccess, dwOptions);\r
-\r
- /* Get dest process handle */\r
- if (dwDstProcId == dwMyProcId)\r
- hDst = GetCurrentProcess();\r
- else\r
- hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);\r
-\r
- if (hDst)\r
- {\r
- /* Get src process handle */\r
- if (dwSrcProcId == dwMyProcId)\r
- hSrc = GetCurrentProcess();\r
- else\r
- hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);\r
-\r
- if (hSrc)\r
- {\r
- /* Make handle available to dest process */\r
- if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,\r
- dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))\r
- hRet = NULL;\r
-\r
- if (dwSrcProcId != dwMyProcId)\r
- CloseHandle(hSrc);\r
- }\r
-\r
- if (dwDstProcId != dwMyProcId)\r
- CloseHandle(hDst);\r
- }\r
-\r
- TRACE("Returning handle %p\n", hRet);\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.7]\r
- *\r
- * Create a block of sharable memory and initialise it with data.\r
- *\r
- * PARAMS\r
- * lpvData [I] Pointer to data to write\r
- * dwSize [I] Size of data\r
- * dwProcId [I] ID of process owning data\r
- *\r
- * RETURNS\r
- * Success: A shared memory handle\r
- * Failure: NULL\r
- *\r
- * NOTES\r
- * Ordinals 7-11 provide a set of calls to create shared memory between a\r
- * group of processes. The shared memory is treated opaquely in that its size\r
- * is not exposed to clients who map it. This is accomplished by storing\r
- * the size of the map as the first DWORD of mapped data, and then offsetting\r
- * the view pointer returned by this size.\r
- *\r
- */\r
-HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)\r
-{\r
- HANDLE hMap;\r
- LPVOID pMapped;\r
- HANDLE hRet = NULL;\r
-\r
- TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);\r
-\r
- /* Create file mapping of the correct length */\r
- hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,\r
- dwSize + sizeof(dwSize), NULL);\r
- if (!hMap)\r
- return hRet;\r
-\r
- /* Get a view in our process address space */\r
- pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);\r
-\r
- if (pMapped)\r
- {\r
- /* Write size of data, followed by the data, to the view */\r
- *((DWORD*)pMapped) = dwSize;\r
- if (lpvData)\r
- memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);\r
-\r
- /* Release view. All further views mapped will be opaque */\r
- UnmapViewOfFile(pMapped);\r
- hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,\r
- GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,\r
- DUPLICATE_SAME_ACCESS);\r
- }\r
-\r
- CloseHandle(hMap);\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.8]\r
- *\r
- * Get a pointer to a block of shared memory from a shared memory handle.\r
- *\r
- * PARAMS\r
- * hShared [I] Shared memory handle\r
- * dwProcId [I] ID of process owning hShared\r
- *\r
- * RETURNS\r
- * Success: A pointer to the shared memory\r
- * Failure: NULL\r
- *\r
- */\r
-PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)\r
-{\r
- HANDLE hDup;\r
- LPVOID pMapped;\r
-\r
- TRACE("(%p %ld)\n", hShared, dwProcId);\r
-\r
- /* Get handle to shared memory for current process */\r
- hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),\r
- FILE_MAP_ALL_ACCESS, 0);\r
- /* Get View */\r
- pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);\r
- CloseHandle(hDup);\r
-\r
- if (pMapped)\r
- return (char *) pMapped + sizeof(DWORD); /* Hide size */\r
- return NULL;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.9]\r
- *\r
- * Release a pointer to a block of shared memory.\r
- *\r
- * PARAMS\r
- * lpView [I] Shared memory pointer\r
- *\r
- * RETURNS\r
- * Success: TRUE\r
- * Failure: FALSE\r
- *\r
- */\r
-BOOL WINAPI SHUnlockShared(LPVOID lpView)\r
-{\r
- TRACE("(%p)\n", lpView);\r
- return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.10]\r
- *\r
- * Destroy a block of sharable memory.\r
- *\r
- * PARAMS\r
- * hShared [I] Shared memory handle\r
- * dwProcId [I] ID of process owning hShared\r
- *\r
- * RETURNS\r
- * Success: TRUE\r
- * Failure: FALSE\r
- *\r
- */\r
-BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)\r
-{\r
- HANDLE hClose;\r
-\r
- TRACE("(%p %ld)\n", hShared, dwProcId);\r
-\r
- /* Get a copy of the handle for our process, closing the source handle */\r
- hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),\r
- FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);\r
- /* Close local copy */\r
- return CloseHandle(hClose);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.11]\r
- *\r
- * Copy a sharable memory handle from one process to another.\r
- *\r
- * PARAMS\r
- * hShared [I] Shared memory handle to duplicate\r
- * dwDstProcId [I] ID of the process wanting the duplicated handle\r
- * dwSrcProcId [I] ID of the process owning hShared\r
- * dwAccess [I] Desired DuplicateHandle() access\r
- * dwOptions [I] Desired DuplicateHandle() options\r
- *\r
- * RETURNS\r
- * Success: A handle suitable for use by the dwDstProcId process.\r
- * Failure: A NULL handle.\r
- *\r
- */\r
-HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,\r
- DWORD dwAccess, DWORD dwOptions)\r
-{\r
- HANDLE hRet;\r
-\r
- hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,\r
- dwAccess, dwOptions);\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.13]\r
- *\r
- * Create and register a clipboard enumerator for a web browser.\r
- *\r
- * PARAMS\r
- * lpBC [I] Binding context\r
- * lpUnknown [I] An object exposing the IWebBrowserApp interface\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code.\r
- *\r
- * NOTES\r
- * The enumerator is stored as a property of the web browser. If it does not\r
- * yet exist, it is created and set before being registered.\r
- */\r
-HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)\r
-{\r
- static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',\r
- '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',\r
- '0','A','A','0','0','4','A','E','8','3','7','}','\0' };\r
- IEnumFORMATETC* pIEnumFormatEtc = NULL;\r
- VARIANTARG var;\r
- HRESULT hRet;\r
- IWebBrowserApp* pBrowser = NULL;\r
-\r
- TRACE("(%p, %p)\n", lpBC, lpUnknown);\r
-\r
- /* Get An IWebBrowserApp interface from lpUnknown */\r
- hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);\r
- if (FAILED(hRet) || !pBrowser)\r
- return E_NOINTERFACE;\r
-\r
- V_VT(&var) = VT_EMPTY;\r
-\r
- /* The property we get is the browsers clipboard enumerator */\r
- hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);\r
- if (FAILED(hRet))\r
- return hRet;\r
-\r
- if (V_VT(&var) == VT_EMPTY)\r
- {\r
- /* Iterate through accepted documents and RegisterClipBoardFormatA() them */\r
- char szKeyBuff[128], szValueBuff[128];\r
- DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;\r
- FORMATETC* formatList, *format;\r
- HKEY hDocs;\r
-\r
- TRACE("Registering formats and creating IEnumFORMATETC instance\n");\r
-\r
- if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"\r
- "Version\\Internet Settings\\Accepted Documents", &hDocs))\r
- return E_FAIL;\r
-\r
- /* Get count of values in key */\r
- while (!dwRet)\r
- {\r
- dwKeySize = sizeof(szKeyBuff);\r
- dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);\r
- dwCount++;\r
- }\r
-\r
- dwNumValues = dwCount;\r
-\r
- /* Note: dwCount = number of items + 1; The extra item is the end node */\r
- format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));\r
- if (!formatList)\r
- return E_OUTOFMEMORY;\r
-\r
- if (dwNumValues > 1)\r
- {\r
- dwRet = 0;\r
- dwCount = 0;\r
-\r
- dwNumValues--;\r
-\r
- /* Register clipboard formats for the values and populate format list */\r
- while(!dwRet && dwCount < dwNumValues)\r
- {\r
- dwKeySize = sizeof(szKeyBuff);\r
- dwValueSize = sizeof(szValueBuff);\r
- dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,\r
- (PBYTE)szValueBuff, &dwValueSize);\r
- if (!dwRet)\r
- return E_FAIL;\r
-\r
- format->cfFormat = RegisterClipboardFormatA(szValueBuff);\r
- format->ptd = NULL;\r
- format->dwAspect = 1;\r
- format->lindex = 4;\r
- format->tymed = -1;\r
-\r
- format++;\r
- dwCount++;\r
- }\r
- }\r
-\r
- /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */\r
- format->cfFormat = 0;\r
- format->ptd = NULL;\r
- format->dwAspect = 1;\r
- format->lindex = 4;\r
- format->tymed = -1;\r
-\r
- /* Create a clipboard enumerator */\r
- GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);\r
- hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);\r
-\r
- if (FAILED(hRet) || !pIEnumFormatEtc)\r
- return hRet;\r
-\r
- /* Set our enumerator as the browsers property */\r
- V_VT(&var) = VT_UNKNOWN;\r
- V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;\r
-\r
- hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);\r
- if (FAILED(hRet))\r
- {\r
- IEnumFORMATETC_Release(pIEnumFormatEtc);\r
- goto RegisterDefaultAcceptHeaders_Exit;\r
- }\r
- }\r
-\r
- if (V_VT(&var) == VT_UNKNOWN)\r
- {\r
- /* Our variant is holding the clipboard enumerator */\r
- IUnknown* pIUnknown = V_UNKNOWN(&var);\r
- IEnumFORMATETC* pClone = NULL;\r
-\r
- TRACE("Retrieved IEnumFORMATETC property\n");\r
-\r
- /* Get an IEnumFormatEtc interface from the variants value */\r
- pIEnumFormatEtc = NULL;\r
- hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,\r
- (PVOID)&pIEnumFormatEtc);\r
- if (!hRet && pIEnumFormatEtc)\r
- {\r
- /* Clone and register the enumerator */\r
- hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);\r
- if (!hRet && pClone)\r
- {\r
- GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);\r
- pRegisterFormatEnumerator(lpBC, pClone, 0);\r
-\r
- IEnumFORMATETC_Release(pClone);\r
- }\r
-\r
- /* Release the IEnumFormatEtc interface */\r
- IEnumFORMATETC_Release(pIUnknown);\r
- }\r
- IUnknown_Release(V_UNKNOWN(&var));\r
- }\r
-\r
-RegisterDefaultAcceptHeaders_Exit:\r
- IWebBrowserApp_Release(pBrowser);\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.15]\r
- *\r
- * Get Explorers "AcceptLanguage" setting.\r
- *\r
- * PARAMS\r
- * langbuf [O] Destination for language string\r
- * buflen [I] Length of langbuf\r
- * [0] Success: used length of langbuf\r
- *\r
- * RETURNS\r
- * Success: S_OK. langbuf is set to the language string found.\r
- * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer\r
- * does not contain the setting.\r
- * E_INVALIDARG, If the buffer is not big enough\r
- */\r
-HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)\r
-{\r
- static const WCHAR szkeyW[] = {\r
- 'S','o','f','t','w','a','r','e','\\',\r
- 'M','i','c','r','o','s','o','f','t','\\',\r
- 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',\r
- 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};\r
- static const WCHAR valueW[] = {\r
- 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};\r
- static const WCHAR enusW[] = {'e','n','-','u','s',0};\r
- DWORD mystrlen, mytype;\r
- HKEY mykey;\r
- HRESULT retval;\r
- LCID mylcid;\r
- WCHAR *mystr;\r
-\r
- if(!langbuf || !buflen || !*buflen)\r
- return E_FAIL;\r
-\r
- mystrlen = (*buflen > 20) ? *buflen : 20 ;\r
- mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);\r
- RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);\r
- if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {\r
- /* Did not find value */\r
- mylcid = GetUserDefaultLCID();\r
- /* somehow the mylcid translates into "en-us"\r
- * this is similar to "LOCALE_SABBREVLANGNAME"\r
- * which could be gotten via GetLocaleInfo.\r
- * The only problem is LOCALE_SABBREVLANGUAGE" is\r
- * a 3 char string (first 2 are country code and third is\r
- * letter for "sublanguage", which does not come close to\r
- * "en-us"\r
- */\r
- lstrcpyW(mystr, enusW);\r
- mystrlen = lstrlenW(mystr);\r
- } else {\r
- /* handle returned string */\r
- FIXME("missing code\n");\r
- }\r
- memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );\r
-\r
- if(*buflen > strlenW(mystr)) {\r
- *buflen = strlenW(mystr);\r
- retval = S_OK;\r
- } else {\r
- *buflen = 0;\r
- retval = E_INVALIDARG;\r
- SetLastError(ERROR_INSUFFICIENT_BUFFER);\r
- }\r
- RegCloseKey(mykey);\r
- HeapFree(GetProcessHeap(), 0, mystr);\r
- return retval;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.14]\r
- *\r
- * Ascii version of GetAcceptLanguagesW.\r
- */\r
-HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)\r
-{\r
- WCHAR *langbufW;\r
- DWORD buflenW, convlen;\r
- HRESULT retval;\r
-\r
- if(!langbuf || !buflen || !*buflen) return E_FAIL;\r
-\r
- buflenW = *buflen;\r
- langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);\r
- retval = GetAcceptLanguagesW(langbufW, &buflenW);\r
-\r
- /* FIXME: this is wrong, the string may not be null-terminated */\r
- convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,\r
- *buflen, NULL, NULL);\r
- *buflen = buflenW ? convlen : 0;\r
-\r
- HeapFree(GetProcessHeap(), 0, langbufW);\r
- return retval;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.23]\r
- *\r
- * Convert a GUID to a string.\r
- *\r
- * PARAMS\r
- * guid [I] GUID to convert\r
- * lpszDest [O] Destination for string\r
- * cchMax [I] Length of output buffer\r
- *\r
- * RETURNS\r
- * The length of the string created.\r
- */\r
-INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)\r
-{\r
- char xguid[40];\r
- INT iLen;\r
-\r
- TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);\r
-\r
- sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",\r
- guid->Data1, guid->Data2, guid->Data3,\r
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],\r
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);\r
-\r
- iLen = strlen(xguid) + 1;\r
-\r
- if (iLen > cchMax)\r
- return 0;\r
- memcpy(lpszDest, xguid, iLen);\r
- return iLen;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.24]\r
- *\r
- * Convert a GUID to a string.\r
- *\r
- * PARAMS\r
- * guid [I] GUID to convert\r
- * str [O] Destination for string\r
- * cmax [I] Length of output buffer\r
- *\r
- * RETURNS\r
- * The length of the string created.\r
- */\r
-INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)\r
-{\r
- WCHAR xguid[40];\r
- INT iLen;\r
- static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',\r
- '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',\r
- 'X','%','0','2','X','%','0','2','X','}',0};\r
-\r
- TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);\r
-\r
- sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,\r
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],\r
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);\r
-\r
- iLen = strlenW(xguid) + 1;\r
-\r
- if (iLen > cchMax)\r
- return 0;\r
- memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));\r
- return iLen;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.29]\r
- *\r
- * Determine if a Unicode character is a space.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is a space,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI IsCharSpaceW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.30]\r
- *\r
- * Determine if a Unicode character is a blank.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is a blank,\r
- * FALSE otherwise.\r
- *\r
- */\r
-BOOL WINAPI IsCharBlankW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.31]\r
- *\r
- * Determine if a Unicode character is punctuation.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is punctuation,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI IsCharPunctW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.32]\r
- *\r
- * Determine if a Unicode character is a control character.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is a control character,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI IsCharCntrlW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.33]\r
- *\r
- * Determine if a Unicode character is a digit.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is a digit,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI IsCharDigitW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.34]\r
- *\r
- * Determine if a Unicode character is a hex digit.\r
- *\r
- * PARAMS\r
- * wc [I] Character to check.\r
- *\r
- * RETURNS\r
- * TRUE, if wc is a hex digit,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI IsCharXDigitW(WCHAR wc)\r
-{\r
- WORD CharType;\r
-\r
- return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.35]\r
- *\r
- */\r
-BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)\r
-{\r
- FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.36]\r
- *\r
- * Insert a bitmap menu item at the bottom of a menu.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu to insert into\r
- * flags [I] Flags for insertion\r
- * id [I] Menu ID of the item\r
- * str [I] Menu text for the item\r
- *\r
- * RETURNS\r
- * Success: TRUE, the item is inserted into the menu\r
- * Failure: FALSE, if any parameter is invalid\r
- */\r
-BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)\r
-{\r
- TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));\r
- return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.74]\r
- *\r
- * Get the text from a given dialog item.\r
- *\r
- * PARAMS\r
- * hWnd [I] Handle of dialog\r
- * nItem [I] Index of item\r
- * lpsDest [O] Buffer for receiving window text\r
- * nDestLen [I] Length of buffer.\r
- *\r
- * RETURNS\r
- * Success: The length of the returned text.\r
- * Failure: 0.\r
- */\r
-INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)\r
-{\r
- HWND hItem = GetDlgItem(hWnd, nItem);\r
-\r
- if (hItem)\r
- return GetWindowTextW(hItem, lpsDest, nDestLen);\r
- if (nDestLen)\r
- *lpsDest = (WCHAR)'\0';\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.138]\r
- *\r
- * Set the text of a given dialog item.\r
- *\r
- * PARAMS\r
- * hWnd [I] Handle of dialog\r
- * iItem [I] Index of item\r
- * lpszText [O] Text to set\r
- *\r
- * RETURNS\r
- * Success: TRUE. The text of the dialog is set to lpszText.\r
- * Failure: FALSE, Otherwise.\r
- */\r
-BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)\r
-{\r
- HWND hWndItem = GetDlgItem(hWnd, iItem);\r
- if (hWndItem)\r
- return SetWindowTextW(hWndItem, lpszText);\r
- return FALSE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.151]\r
- *\r
- * Compare two Ascii strings up to a given length.\r
- *\r
- * PARAMS\r
- * lpszSrc [I] Source string\r
- * lpszCmp [I] String to compare to lpszSrc\r
- * len [I] Maximum length\r
- *\r
- * RETURNS\r
- * A number greater than, less than or equal to 0 depending on whether\r
- * lpszSrc is greater than, less than or equal to lpszCmp.\r
- */\r
-DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)\r
-{\r
- return strncmp(lpszSrc, lpszCmp, len);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.152]\r
- *\r
- * Unicode version of StrCmpNCA.\r
- */\r
-DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)\r
-{\r
- return strncmpW(lpszSrc, lpszCmp, len);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.153]\r
- *\r
- * Compare two Ascii strings up to a given length, ignoring case.\r
- *\r
- * PARAMS\r
- * lpszSrc [I] Source string\r
- * lpszCmp [I] String to compare to lpszSrc\r
- * len [I] Maximum length\r
- *\r
- * RETURNS\r
- * A number greater than, less than or equal to 0 depending on whether\r
- * lpszSrc is greater than, less than or equal to lpszCmp.\r
- */\r
-DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)\r
-{\r
- return strncasecmp(lpszSrc, lpszCmp, len);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.154]\r
- *\r
- * Unicode version of StrCmpNICA.\r
- */\r
-DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)\r
-{\r
- return strncmpiW(lpszSrc, lpszCmp, len);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.155]\r
- *\r
- * Compare two Ascii strings.\r
- *\r
- * PARAMS\r
- * lpszSrc [I] Source string\r
- * lpszCmp [I] String to compare to lpszSrc\r
- *\r
- * RETURNS\r
- * A number greater than, less than or equal to 0 depending on whether\r
- * lpszSrc is greater than, less than or equal to lpszCmp.\r
- */\r
-DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)\r
-{\r
- return strcmp(lpszSrc, lpszCmp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.156]\r
- *\r
- * Unicode version of StrCmpCA.\r
- */\r
-DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)\r
-{\r
- return strcmpW(lpszSrc, lpszCmp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.157]\r
- *\r
- * Compare two Ascii strings, ignoring case.\r
- *\r
- * PARAMS\r
- * lpszSrc [I] Source string\r
- * lpszCmp [I] String to compare to lpszSrc\r
- *\r
- * RETURNS\r
- * A number greater than, less than or equal to 0 depending on whether\r
- * lpszSrc is greater than, less than or equal to lpszCmp.\r
- */\r
-DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)\r
-{\r
- return strcasecmp(lpszSrc, lpszCmp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.158]\r
- *\r
- * Unicode version of StrCmpICA.\r
- */\r
-DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)\r
-{\r
- return strcmpiW(lpszSrc, lpszCmp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.160]\r
- *\r
- * Get an identification string for the OS and explorer.\r
- *\r
- * PARAMS\r
- * lpszDest [O] Destination for Id string\r
- * dwDestLen [I] Length of lpszDest\r
- *\r
- * RETURNS\r
- * TRUE, If the string was created successfully\r
- * FALSE, Otherwise\r
- */\r
-BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)\r
-{\r
- WCHAR buff[2084];\r
-\r
- TRACE("(%p,%ld)\n", lpszDest, dwDestLen);\r
-\r
- if (lpszDest && SHAboutInfoW(buff, dwDestLen))\r
- {\r
- WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.161]\r
- *\r
- * Unicode version of SHAboutInfoA.\r
- */\r
-BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)\r
-{\r
- static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',\r
- 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',\r
- ' ','E','x','p','l','o','r','e','r','\0' };\r
- static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',\r
- 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',\r
- 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };\r
- static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',\r
- 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',\r
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };\r
- static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',\r
- 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',\r
- ' ','E','x','p','l','o','r','e','r','\\',\r
- 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };\r
- static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };\r
- static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',\r
- 'V','e','r','s','i','o','n','\0' };\r
- static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',\r
- 'O','w','n','e','r','\0' };\r
- static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',\r
- 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };\r
- static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };\r
- static const WCHAR szUpdate[] = { 'I','E','A','K',\r
- 'U','p','d','a','t','e','U','r','l','\0' };\r
- static const WCHAR szHelp[] = { 'I','E','A','K',\r
- 'H','e','l','p','S','t','r','i','n','g','\0' };\r
- WCHAR buff[2084];\r
- HKEY hReg;\r
- DWORD dwType, dwLen;\r
-\r
- TRACE("(%p,%ld)\n", lpszDest, dwDestLen);\r
-\r
- if (!lpszDest)\r
- return FALSE;\r
-\r
- *lpszDest = '\0';\r
-\r
- /* Try the NT key first, followed by 95/98 key */\r
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&\r
- RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))\r
- return FALSE;\r
-\r
- /* OS Version */\r
- buff[0] = '\0';\r
- dwLen = 30;\r
- if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))\r
- {\r
- DWORD dwStrLen = strlenW(buff);\r
- dwLen = 30 - dwStrLen;\r
- SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,\r
- szCustomized, &dwType, buff+dwStrLen, &dwLen);\r
- }\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* ~Registered Owner */\r
- buff[0] = '~';\r
- dwLen = 256;\r
- if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))\r
- buff[1] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* ~Registered Organization */\r
- dwLen = 256;\r
- if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))\r
- buff[1] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* FIXME: Not sure where this number comes from */\r
- buff[0] = '~';\r
- buff[1] = '0';\r
- buff[2] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* ~Product Id */\r
- dwLen = 256;\r
- if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))\r
- buff[1] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* ~IE Update Url */\r
- dwLen = 2048;\r
- if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))\r
- buff[1] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- /* ~IE Help String */\r
- dwLen = 256;\r
- if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))\r
- buff[1] = '\0';\r
- StrCatBuffW(lpszDest, buff, dwDestLen);\r
-\r
- RegCloseKey(hReg);\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.163]\r
- *\r
- * Call IOleCommandTarget_QueryStatus() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IOleCommandTarget interface\r
- * pguidCmdGroup [I] GUID for the command group\r
- * cCmds [I]\r
- * prgCmds [O] Commands\r
- * pCmdText [O] Command text\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_FAIL, if lpUnknown is NULL.\r
- * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.\r
- * Otherwise, an error code from IOleCommandTarget_QueryStatus().\r
- */\r
-HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,\r
- ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)\r
-{\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);\r
-\r
- if (lpUnknown)\r
- {\r
- IOleCommandTarget* lpOle;\r
-\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,\r
- (void**)&lpOle);\r
-\r
- if (SUCCEEDED(hRet) && lpOle)\r
- {\r
- hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,\r
- prgCmds, pCmdText);\r
- IOleCommandTarget_Release(lpOle);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.164]\r
- *\r
- * Call IOleCommandTarget_Exec() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IOleCommandTarget interface\r
- * pguidCmdGroup [I] GUID for the command group\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_FAIL, if lpUnknown is NULL.\r
- * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.\r
- * Otherwise, an error code from IOleCommandTarget_Exec().\r
- */\r
-HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,\r
- DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,\r
- VARIANT* pvaOut)\r
-{\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,\r
- nCmdexecopt, pvaIn, pvaOut);\r
-\r
- if (lpUnknown)\r
- {\r
- IOleCommandTarget* lpOle;\r
-\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,\r
- (void**)&lpOle);\r
- if (SUCCEEDED(hRet) && lpOle)\r
- {\r
- hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,\r
- nCmdexecopt, pvaIn, pvaOut);\r
- IOleCommandTarget_Release(lpOle);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.165]\r
- *\r
- * Retrieve, modify, and re-set a value from a window.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window to get value from\r
- * offset [I] Offset of value\r
- * wMask [I] Mask for uiFlags\r
- * wFlags [I] Bits to set in window value\r
- *\r
- * RETURNS\r
- * The new value as it was set, or 0 if any parameter is invalid.\r
- *\r
- * NOTES\r
- * Any bits set in uiMask are cleared from the value, then any bits set in\r
- * uiFlags are set in the value.\r
- */\r
-LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)\r
-{\r
- LONG ret = GetWindowLongA(hwnd, offset);\r
- LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);\r
-\r
- if (newFlags != ret)\r
- ret = SetWindowLongA(hwnd, offset, newFlags);\r
- return ret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.167]\r
- *\r
- * Change a window's parent.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window to change parent of\r
- * hWndParent [I] New parent window\r
- *\r
- * RETURNS\r
- * The old parent of hWnd.\r
- *\r
- * NOTES\r
- * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.\r
- * If hWndParent is NOT NULL then we set the WS_CHILD style.\r
- */\r
-HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)\r
-{\r
- TRACE("%p, %p\n", hWnd, hWndParent);\r
-\r
- if(GetParent(hWnd) == hWndParent)\r
- return 0;\r
-\r
- if(hWndParent)\r
- SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);\r
- else\r
- SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);\r
-\r
- return SetParent(hWnd, hWndParent);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.168]\r
- *\r
- * Locate and advise a connection point in an IConnectionPointContainer object.\r
- *\r
- * PARAMS\r
- * lpUnkSink [I] Sink for the connection point advise call\r
- * riid [I] REFIID of connection point to advise\r
- * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first\r
- * lpUnknown [I] Object supporting the IConnectionPointContainer interface\r
- * lpCookie [O] Pointer to connection point cookie\r
- * lppCP [O] Destination for the IConnectionPoint found\r
- *\r
- * RETURNS\r
- * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint\r
- * that was advised. The caller is responsable for releasing it.\r
- * Failure: E_FAIL, if any arguments are invalid.\r
- * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,\r
- * Or an HRESULT error code if any call fails.\r
- */\r
-HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,\r
- IUnknown* lpUnknown, LPDWORD lpCookie,\r
- IConnectionPoint **lppCP)\r
-{\r
- HRESULT hRet;\r
- IConnectionPointContainer* lpContainer;\r
- IConnectionPoint *lpCP;\r
-\r
- if(!lpUnknown || (bAdviseOnly && !lpUnkSink))\r
- return E_FAIL;\r
-\r
- if(lppCP)\r
- *lppCP = NULL;\r
-\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,\r
- (void**)&lpContainer);\r
- if (SUCCEEDED(hRet))\r
- {\r
- hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);\r
-\r
- if (SUCCEEDED(hRet))\r
- {\r
- if(!bAdviseOnly)\r
- hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);\r
- hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);\r
-\r
- if (FAILED(hRet))\r
- *lpCookie = 0;\r
-\r
- if (lppCP && SUCCEEDED(hRet))\r
- *lppCP = lpCP; /* Caller keeps the interface */\r
- else\r
- IConnectionPoint_Release(lpCP); /* Release it */\r
- }\r
-\r
- IUnknown_Release(lpContainer);\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.169]\r
- *\r
- * Release an interface.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object to release\r
- *\r
- * RETURNS\r
- * Nothing.\r
- */\r
-DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)\r
-{\r
- IUnknown *temp;\r
-\r
- TRACE("(%p)\n",lpUnknown);\r
-\r
- if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;\r
- temp = *lpUnknown;\r
- *lpUnknown = NULL;\r
-\r
- TRACE("doing Release\n");\r
-\r
- return IUnknown_Release(temp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.170]\r
- *\r
- * Skip '//' if present in a string.\r
- *\r
- * PARAMS\r
- * lpszSrc [I] String to check for '//'\r
- *\r
- * RETURNS\r
- * Success: The next character after the '//' or the string if not present\r
- * Failure: NULL, if lpszStr is NULL.\r
- */\r
-LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)\r
-{\r
- if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')\r
- lpszSrc += 2;\r
- return lpszSrc;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.171]\r
- *\r
- * Check if two interfaces come from the same object.\r
- *\r
- * PARAMS\r
- * lpInt1 [I] Interface to check against lpInt2.\r
- * lpInt2 [I] Interface to check against lpInt1.\r
- *\r
- * RETURNS\r
- * TRUE, If the interfaces come from the same object.\r
- * FALSE Otherwise.\r
- */\r
-BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)\r
-{\r
- LPVOID lpUnknown1, lpUnknown2;\r
-\r
- TRACE("%p %p\n", lpInt1, lpInt2);\r
-\r
- if (!lpInt1 || !lpInt2)\r
- return FALSE;\r
-\r
- if (lpInt1 == lpInt2)\r
- return TRUE;\r
-\r
- if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,\r
- (LPVOID *)&lpUnknown1)))\r
- return FALSE;\r
-\r
- if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,\r
- (LPVOID *)&lpUnknown2)))\r
- return FALSE;\r
-\r
- if (lpUnknown1 == lpUnknown2)\r
- return TRUE;\r
-\r
- return FALSE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.172]\r
- *\r
- * Get the window handle of an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object to get the window handle of\r
- * lphWnd [O] Destination for window handle\r
- *\r
- * RETURNS\r
- * Success: S_OK. lphWnd contains the objects window handle.\r
- * Failure: An HRESULT error code.\r
- *\r
- * NOTES\r
- * lpUnknown is expected to support one of the following interfaces:\r
- * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().\r
- */\r
-HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)\r
-{\r
- /* FIXME: Wine has no header for this object */\r
- static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,\r
- 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};\r
- IUnknown *lpOle;\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p)\n", lpUnknown, lphWnd);\r
-\r
- if (!lpUnknown)\r
- return hRet;\r
-\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);\r
-\r
- if (FAILED(hRet))\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);\r
-\r
- if (FAILED(hRet))\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,\r
- (void**)&lpOle);\r
- }\r
- }\r
-\r
- if (SUCCEEDED(hRet))\r
- {\r
- /* Lazyness here - Since GetWindow() is the first method for the above 3\r
- * interfaces, we use the same call for them all.\r
- */\r
- hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);\r
- IUnknown_Release(lpOle);\r
- if (lphWnd)\r
- TRACE("Returning HWND=%p\n", *lphWnd);\r
- }\r
-\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.173]\r
- *\r
- * Call a method on as as yet unidentified object.\r
- *\r
- * PARAMS\r
- * pUnk [I] Object supporting the unidentified interface,\r
- * arg [I] Argument for the call on the object.\r
- *\r
- * RETURNS\r
- * S_OK.\r
- */\r
-HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)\r
-{\r
- static const GUID guid_173 = {\r
- 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }\r
- };\r
- IMalloc *pUnk2;\r
-\r
- TRACE("(%p,%ld)\n", pUnk, arg);\r
-\r
- /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -\r
- * We use this interface as its vtable entry is compatible with the\r
- * object in question.\r
- * FIXME: Find out what this object is and where it should be defined.\r
- */\r
- if (pUnk &&\r
- SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))\r
- {\r
- IMalloc_Alloc(pUnk2, arg); /* Faked call!! */\r
- IMalloc_Release(pUnk2);\r
- }\r
- return S_OK;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.174]\r
- *\r
- * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on\r
- * an interface.\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_FAIL, if p1 is NULL.\r
- * E_NOINTERFACE If p1 does not support the IPersist interface,\r
- * Or an HRESULT error code.\r
- */\r
-DWORD WINAPI IUnknown_SetSite(\r
- IUnknown *p1, /* [in] OLE object */\r
- LPVOID *p2) /* [out] ptr for call results */\r
-{\r
- DWORD ret, aa;\r
- IUnknown *iobjectwithsite;\r
-\r
- if (!p1) return E_FAIL;\r
-\r
- /* see if SetSite interface exists for IObjectWithSite object */\r
- ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&iobjectwithsite);\r
- TRACE("first IU_QI ret=%08lx, iobjectwithsite=%p\n", ret, iobjectwithsite);\r
- if (ret) {\r
-\r
- /* see if GetClassId interface exists for IPersistMoniker object */\r
- ret = IUnknown_QueryInterface(p1, (REFIID)id2, (LPVOID *)&aa);\r
- TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);\r
- if (ret) return ret;\r
-\r
- /* fake a GetClassId call */\r
- ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);\r
- TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,\r
- *(LPDWORD)p2);\r
- IUnknown_Release((IUnknown *)aa);\r
- }\r
- else {\r
- /* fake a SetSite call */\r
- ret = IOleWindow_GetWindow((IOleWindow *)iobjectwithsite, (HWND*)p2);\r
- TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,\r
- *(LPDWORD)p2);\r
- IUnknown_Release((IUnknown *)iobjectwithsite);\r
- }\r
- return ret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.175]\r
- *\r
- * Call IPersist_GetClassID() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IPersist interface\r
- * lpClassId [O] Destination for Class Id\r
- *\r
- * RETURNS\r
- * Success: S_OK. lpClassId contains the Class Id requested.\r
- * Failure: E_FAIL, If lpUnknown is NULL,\r
- * E_NOINTERFACE If lpUnknown does not support IPersist,\r
- * Or an HRESULT error code.\r
- */\r
-HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)\r
-{\r
- IPersist* lpPersist;\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));\r
-\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);\r
- if (SUCCEEDED(hRet))\r
- {\r
- IPersist_GetClassID(lpPersist, lpClassId);\r
- IPersist_Release(lpPersist);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.176]\r
- *\r
- * Retrieve a Service Interface from an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object to get an IServiceProvider interface from\r
- * sid [I] Service ID for IServiceProvider_QueryService() call\r
- * riid [I] Function requested for QueryService call\r
- * lppOut [O] Destination for the service interface pointer\r
- *\r
- * RETURNS\r
- * Success: S_OK. lppOut contains an object providing the requested service\r
- * Failure: An HRESULT error code\r
- *\r
- * NOTES\r
- * lpUnknown is expected to support the IServiceProvider interface.\r
- */\r
-HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,\r
- LPVOID *lppOut)\r
-{\r
- IServiceProvider* pService = NULL;\r
- HRESULT hRet;\r
-\r
- if (!lppOut)\r
- return E_FAIL;\r
-\r
- *lppOut = NULL;\r
-\r
- if (!lpUnknown)\r
- return E_FAIL;\r
-\r
- /* Get an IServiceProvider interface from the object */\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,\r
- (LPVOID*)&pService);\r
-\r
- if (!hRet && pService)\r
- {\r
- TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);\r
-\r
- /* Get a Service interface from the object */\r
- hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);\r
-\r
- TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);\r
-\r
- /* Release the IServiceProvider interface */\r
- IUnknown_Release(pService);\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.177]\r
- *\r
- * Loads a popup menu.\r
- *\r
- * PARAMS\r
- * hInst [I] Instance handle\r
- * szName [I] Menu name\r
- *\r
- * RETURNS\r
- * Success: TRUE.\r
- * Failure: FALSE.\r
- */\r
-BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)\r
-{\r
- HMENU hMenu, hSubMenu;\r
-\r
- if ((hMenu = LoadMenuW(hInst, szName)))\r
- {\r
- if ((hSubMenu = GetSubMenu(hMenu, 0)))\r
- RemoveMenu(hMenu, 0, MF_BYPOSITION);\r
-\r
- DestroyMenu(hMenu);\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-typedef struct _enumWndData\r
-{\r
- UINT uiMsgId;\r
- WPARAM wParam;\r
- LPARAM lParam;\r
- LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);\r
-} enumWndData;\r
-\r
-/* Callback for SHLWAPI_178 */\r
-static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)\r
-{\r
- enumWndData *data = (enumWndData *)lParam;\r
-\r
- TRACE("(%p,%p)\n", hWnd, data);\r
- data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.178]\r
- *\r
- * Send or post a message to every child of a window.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window whose children will get the messages\r
- * uiMsgId [I] Message Id\r
- * wParam [I] WPARAM of message\r
- * lParam [I] LPARAM of message\r
- * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()\r
- *\r
- * RETURNS\r
- * Nothing.\r
- *\r
- * NOTES\r
- * The appropriate ASCII or Unicode function is called for the window.\r
- */\r
-void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)\r
-{\r
- enumWndData data;\r
-\r
- TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);\r
-\r
- if(hWnd)\r
- {\r
- data.uiMsgId = uiMsgId;\r
- data.wParam = wParam;\r
- data.lParam = lParam;\r
-\r
- if (bSend)\r
- data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;\r
- else\r
- data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;\r
-\r
- EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.180]\r
- *\r
- * Remove all sub-menus from a menu.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu to remove sub-menus from\r
- *\r
- * RETURNS\r
- * Success: 0. All sub-menus under hMenu are removed\r
- * Failure: -1, if any parameter is invalid\r
- */\r
-DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)\r
-{\r
- int iItemCount = GetMenuItemCount(hMenu) - 1;\r
- while (iItemCount >= 0)\r
- {\r
- HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);\r
- if (hSubMenu)\r
- RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);\r
- iItemCount--;\r
- }\r
- return iItemCount;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.181]\r
- *\r
- * Enable or disable a menu item.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu holding menu item\r
- * uID [I] ID of menu item to enable/disable\r
- * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.\r
- *\r
- * RETURNS\r
- * The return code from EnableMenuItem.\r
- */\r
-UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)\r
-{\r
- return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.182]\r
- *\r
- * Check or uncheck a menu item.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu holding menu item\r
- * uID [I] ID of menu item to check/uncheck\r
- * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.\r
- *\r
- * RETURNS\r
- * The return code from CheckMenuItem.\r
- */\r
-DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)\r
-{\r
- return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.183]\r
- *\r
- * Register a window class if it isn't already.\r
- *\r
- * PARAMS\r
- * lpWndClass [I] Window class to register\r
- *\r
- * RETURNS\r
- * The result of the RegisterClassA call.\r
- */\r
-DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)\r
-{\r
- WNDCLASSA wca;\r
- if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))\r
- return TRUE;\r
- return (DWORD)RegisterClassA(wndclass);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.186]\r
- */\r
-BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,\r
- DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)\r
-{\r
- DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;\r
- POINTL pt = { 0, 0 };\r
-\r
- if (!lpPt)\r
- lpPt = &pt;\r
-\r
- if (!pdwEffect)\r
- pdwEffect = &dwEffect;\r
-\r
- IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);\r
-\r
- if (*pdwEffect)\r
- return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);\r
-\r
- IDropTarget_DragLeave(pDrop);\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.187]\r
- *\r
- * Call IPersistPropertyBag_Load() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IPersistPropertyBag interface\r
- * lpPropBag [O] Destination for loaded IPropertyBag\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.\r
- */\r
-DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)\r
-{\r
- IPersistPropertyBag* lpPPBag;\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p)\n", lpUnknown, lpPropBag);\r
-\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,\r
- (void**)&lpPPBag);\r
- if (SUCCEEDED(hRet) && lpPPBag)\r
- {\r
- hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);\r
- IPersistPropertyBag_Release(lpPPBag);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.188]\r
- *\r
- * Call IOleControlSite_TranslateAccelerator() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IOleControlSite interface.\r
- * lpMsg [I] Key message to be processed.\r
- * dwModifiers [I] Flags containing the state of the modifier keys.\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.\r
- */\r
-HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)\r
-{\r
- IOleControlSite* lpCSite = NULL;\r
- HRESULT hRet = E_INVALIDARG;\r
-\r
- TRACE("(%p,%p,0x%08lx)\n", lpUnknown, lpMsg, dwModifiers);\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,\r
- (void**)&lpCSite);\r
- if (SUCCEEDED(hRet) && lpCSite)\r
- {\r
- hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);\r
- IOleControlSite_Release(lpCSite);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.189]\r
- *\r
- * Call IOleControlSite_GetExtendedControl() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IOleControlSite interface.\r
- * lppDisp [O] Destination for resulting IDispatch.\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.\r
- */\r
-DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)\r
-{\r
- IOleControlSite* lpCSite = NULL;\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p)\n", lpUnknown, lppDisp);\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,\r
- (void**)&lpCSite);\r
- if (SUCCEEDED(hRet) && lpCSite)\r
- {\r
- hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);\r
- IOleControlSite_Release(lpCSite);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.190]\r
- */\r
-HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,\r
- PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)\r
-{\r
- /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */\r
- static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };\r
- /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */\r
- static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };\r
- HRESULT hRet = E_INVALIDARG;\r
- LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */\r
-\r
- TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);\r
-\r
- if (lpUnknown && lpArg4)\r
- {\r
- hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,\r
- (REFGUID)function_id, (void**)&lpUnkInner);\r
-\r
- if (SUCCEEDED(hRet) && lpUnkInner)\r
- {\r
- /* FIXME: The type of service object requested is unknown, however\r
- * testing shows that its first method is called with 4 parameters.\r
- * Fake this by using IParseDisplayName_ParseDisplayName since the\r
- * signature and position in the vtable matches our unknown object type.\r
- */\r
- hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,\r
- lpArg1, lpArg2, lpArg3, lpArg4);\r
- IUnknown_Release(lpUnkInner);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.192]\r
- *\r
- * Get a sub-menu from a menu item.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu to get sub-menu from\r
- * uID [I] ID of menu item containing sub-menu\r
- *\r
- * RETURNS\r
- * The sub-menu of the item, or a NULL handle if any parameters are invalid.\r
- */\r
-HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)\r
-{\r
- MENUITEMINFOA mi;\r
-\r
- TRACE("(%p,%uld)\n", hMenu, uID);\r
-\r
- mi.cbSize = sizeof(MENUITEMINFOA);\r
- mi.fMask = MIIM_SUBMENU;\r
-\r
- if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))\r
- return NULL;\r
-\r
- return mi.hSubMenu;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.193]\r
- *\r
- * Get the color depth of the primary display.\r
- *\r
- * PARAMS\r
- * None.\r
- *\r
- * RETURNS\r
- * The color depth of the primary display.\r
- */\r
-DWORD WINAPI SHGetCurColorRes()\r
-{\r
- HDC hdc;\r
- DWORD ret;\r
-\r
- TRACE("()\n");\r
-\r
- hdc = GetDC(0);\r
- ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);\r
- ReleaseDC(0, hdc);\r
- return ret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.194]\r
- *\r
- * Wait for a message to arrive, with a timeout.\r
- *\r
- * PARAMS\r
- * hand [I] Handle to query\r
- * dwTimeout [I] Timeout in ticks or INFINITE to never timeout\r
- *\r
- * RETURNS\r
- * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.\r
- * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a\r
- * message is available.\r
- */\r
-DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)\r
-{\r
- DWORD dwEndTicks = GetTickCount() + dwTimeout;\r
- DWORD dwRet;\r
-\r
- while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)\r
- {\r
- MSG msg;\r
-\r
- PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);\r
-\r
- if (dwTimeout != INFINITE)\r
- {\r
- if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)\r
- return WAIT_TIMEOUT;\r
- }\r
- }\r
-\r
- return dwRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.195]\r
- *\r
- * Determine if a shell folder can be expanded.\r
- *\r
- * PARAMS\r
- * lpFolder [I] Parent folder containing the object to test.\r
- * pidl [I] Id of the object to test.\r
- *\r
- * RETURNS\r
- * Success: S_OK, if the object is expandable, S_FALSE otherwise.\r
- * Failure: E_INVALIDARG, if any argument is invalid.\r
- *\r
- * NOTES\r
- * If the object to be tested does not expose the IQueryInfo() interface it\r
- * will not be identified as an expandable folder.\r
- */\r
-HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)\r
-{\r
- HRESULT hRet = E_INVALIDARG;\r
- IQueryInfo *lpInfo;\r
-\r
- if (lpFolder && pidl)\r
- {\r
- hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,\r
- NULL, (void**)&lpInfo);\r
- if (FAILED(hRet))\r
- hRet = S_FALSE; /* Doesn't expose IQueryInfo */\r
- else\r
- {\r
- DWORD dwFlags = 0;\r
-\r
- /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not\r
- * currently used". Really? You wouldn't be holding out on me would you?\r
- */\r
- hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);\r
-\r
- if (SUCCEEDED(hRet))\r
- {\r
- /* 0x2 is an undocumented flag apparently indicating expandability */\r
- hRet = dwFlags & 0x2 ? S_OK : S_FALSE;\r
- }\r
-\r
- IQueryInfo_Release(lpInfo);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.197]\r
- *\r
- * Blank out a region of text by drawing the background only.\r
- *\r
- * PARAMS\r
- * hDC [I] Device context to draw in\r
- * pRect [I] Area to draw in\r
- * cRef [I] Color to draw in\r
- *\r
- * RETURNS\r
- * Nothing.\r
- */\r
-DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)\r
-{\r
- COLORREF cOldColor = SetBkColor(hDC, cRef);\r
- ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);\r
- SetBkColor(hDC, cOldColor);\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.198]\r
- *\r
- * Return the value asociated with a key in a map.\r
- *\r
- * PARAMS\r
- * lpKeys [I] A list of keys of length iLen\r
- * lpValues [I] A list of values associated with lpKeys, of length iLen\r
- * iLen [I] Length of both lpKeys and lpValues\r
- * iKey [I] The key value to look up in lpKeys\r
- *\r
- * RETURNS\r
- * The value in lpValues associated with iKey, or -1 if iKey is not\r
- * found in lpKeys.\r
- *\r
- * NOTES\r
- * - If two elements in the map share the same key, this function returns\r
- * the value closest to the start of the map\r
- * - The native version of this function crashes if lpKeys or lpValues is NULL.\r
- */\r
-int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)\r
-{\r
- if (lpKeys && lpValues)\r
- {\r
- int i = 0;\r
-\r
- while (i < iLen)\r
- {\r
- if (lpKeys[i] == iKey)\r
- return lpValues[i]; /* Found */\r
- i++;\r
- }\r
- }\r
- return -1; /* Not found */\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.199]\r
- *\r
- * Copy an interface pointer\r
- *\r
- * PARAMS\r
- * lppDest [O] Destination for copy\r
- * lpUnknown [I] Source for copy\r
- *\r
- * RETURNS\r
- * Nothing.\r
- */\r
-VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)\r
-{\r
- TRACE("(%p,%p)\n", lppDest, lpUnknown);\r
-\r
- if (lppDest)\r
- IUnknown_AtomicRelease(lppDest); /* Release existing interface */\r
-\r
- if (lpUnknown)\r
- {\r
- /* Copy */\r
- IUnknown_AddRef(lpUnknown);\r
- *lppDest = lpUnknown;\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.200]\r
- *\r
- */\r
-HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,\r
- REFGUID riidCmdGrp, ULONG cCmds,\r
- OLECMD *prgCmds, OLECMDTEXT* pCmdText)\r
-{\r
- FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",\r
- lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);\r
-\r
- /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */\r
- return DRAGDROP_E_NOTREGISTERED;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.201]\r
- *\r
- */\r
-HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,\r
- DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,\r
- VARIANT* pvaOut)\r
-{\r
- FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,\r
- nCmdID, nCmdexecopt, pvaIn, pvaOut);\r
- return DRAGDROP_E_NOTREGISTERED;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.202]\r
- *\r
- */\r
-HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)\r
-{\r
- FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);\r
- return DRAGDROP_E_NOTREGISTERED;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.204]\r
- *\r
- * Determine if a window is not a child of another window.\r
- *\r
- * PARAMS\r
- * hParent [I] Suspected parent window\r
- * hChild [I] Suspected child window\r
- *\r
- * RETURNS\r
- * TRUE: If hChild is a child window of hParent\r
- * FALSE: If hChild is not a child window of hParent, or they are equal\r
- */\r
-BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)\r
-{\r
- TRACE("(%p,%p)\n", hParent, hChild);\r
-\r
- if (!hParent || !hChild)\r
- return TRUE;\r
- else if(hParent == hChild)\r
- return FALSE;\r
- return !IsChild(hParent, hChild);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.208]\r
- *\r
- * Some sort of memory management process.\r
- */\r
-DWORD WINAPI FDSA_Initialize(\r
- DWORD a,\r
- DWORD b,\r
- LPVOID c,\r
- LPVOID d,\r
- DWORD e)\r
-{\r
- FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",\r
- a, b, c, d, e);\r
- return 1;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.209]\r
- *\r
- * Some sort of memory management process.\r
- */\r
-DWORD WINAPI FDSA_Destroy(\r
- LPVOID a)\r
-{\r
- FIXME("(%p) stub\n",\r
- a);\r
- return 1;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.210]\r
- *\r
- * Some sort of memory management process.\r
- */\r
-DWORD WINAPI FDSA_InsertItem(\r
- LPVOID a,\r
- DWORD b,\r
- LPVOID c)\r
-{\r
- FIXME("(%p 0x%08lx %p) stub\n",\r
- a, b, c);\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.211]\r
- */\r
-DWORD WINAPI FDSA_DeleteItem(\r
- LPVOID a,\r
- DWORD b)\r
-{\r
- FIXME("(%p 0x%08lx) stub\n",\r
- a, b);\r
- return 1;\r
-}\r
-\r
-typedef struct {\r
- REFIID refid;\r
- DWORD indx;\r
-} IFACE_INDEX_TBL;\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.219]\r
- *\r
- * Call IUnknown_QueryInterface() on a table of objects.\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_POINTER or E_NOINTERFACE.\r
- */\r
-HRESULT WINAPI QISearch(\r
- LPVOID w, /* [in] Table of interfaces */\r
- IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */\r
- REFIID riid, /* [in] REFIID to get interface for */\r
- LPVOID *ppv) /* [out] Destination for interface pointer */\r
-{\r
- HRESULT ret;\r
- IUnknown *a_vtbl;\r
- IFACE_INDEX_TBL *xmove;\r
-\r
- TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);\r
- if (ppv) {\r
- xmove = x;\r
- while (xmove->refid) {\r
- TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));\r
- if (IsEqualIID(riid, xmove->refid)) {\r
- a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);\r
- TRACE("matched, returning (%p)\n", a_vtbl);\r
- *ppv = (LPVOID)a_vtbl;\r
- IUnknown_AddRef(a_vtbl);\r
- return S_OK;\r
- }\r
- xmove++;\r
- }\r
-\r
- if (IsEqualIID(riid, &IID_IUnknown)) {\r
- a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);\r
- TRACE("returning first for IUnknown (%p)\n", a_vtbl);\r
- *ppv = (LPVOID)a_vtbl;\r
- IUnknown_AddRef(a_vtbl);\r
- return S_OK;\r
- }\r
- *ppv = 0;\r
- ret = E_NOINTERFACE;\r
- } else\r
- ret = E_POINTER;\r
-\r
- TRACE("-- 0x%08lx\n", ret);\r
- return ret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.221]\r
- *\r
- * Remove the "PropDlgFont" property from a window.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window to remove the property from\r
- *\r
- * RETURNS\r
- * A handle to the removed property, or NULL if it did not exist.\r
- */\r
-HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)\r
-{\r
- HANDLE hProp;\r
-\r
- TRACE("(%p)\n", hWnd);\r
-\r
- hProp = GetPropA(hWnd, "PropDlgFont");\r
-\r
- if(hProp)\r
- {\r
- DeleteObject(hProp);\r
- hProp = RemovePropA(hWnd, "PropDlgFont");\r
- }\r
- return hProp;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.236]\r
- *\r
- * Load the in-process server of a given GUID.\r
- *\r
- * PARAMS\r
- * refiid [I] GUID of the server to load.\r
- *\r
- * RETURNS\r
- * Success: A handle to the loaded server dll.\r
- * Failure: A NULL handle.\r
- */\r
-HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)\r
-{\r
- HKEY newkey;\r
- DWORD type, count;\r
- CHAR value[MAX_PATH], string[MAX_PATH];\r
-\r
- strcpy(string, "CLSID\\");\r
- SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);\r
- strcat(string, "\\InProcServer32");\r
-\r
- count = MAX_PATH;\r
- RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);\r
- RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);\r
- RegCloseKey(newkey);\r
- return LoadLibraryExA(value, 0, 0);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.237]\r
- *\r
- * Unicode version of SHLWAPI_183.\r
- */\r
-DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)\r
-{\r
- WNDCLASSW WndClass;\r
-\r
- TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));\r
-\r
- if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))\r
- return TRUE;\r
- return RegisterClassW(lpWndClass);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.238]\r
- *\r
- * Unregister a list of classes.\r
- *\r
- * PARAMS\r
- * hInst [I] Application instance that registered the classes\r
- * lppClasses [I] List of class names\r
- * iCount [I] Number of names in lppClasses\r
- *\r
- * RETURNS\r
- * Nothing.\r
- */\r
-void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)\r
-{\r
- WNDCLASSA WndClass;\r
-\r
- TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);\r
-\r
- while (iCount > 0)\r
- {\r
- if (GetClassInfoA(hInst, *lppClasses, &WndClass))\r
- UnregisterClassA(*lppClasses, hInst);\r
- lppClasses++;\r
- iCount--;\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.239]\r
- *\r
- * Unicode version of SHUnregisterClassesA.\r
- */\r
-void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)\r
-{\r
- WNDCLASSW WndClass;\r
-\r
- TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);\r
-\r
- while (iCount > 0)\r
- {\r
- if (GetClassInfoW(hInst, *lppClasses, &WndClass))\r
- UnregisterClassW(*lppClasses, hInst);\r
- lppClasses++;\r
- iCount--;\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.240]\r
- *\r
- * Call The correct (Ascii/Unicode) default window procedure for a window.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window to call the default procedure for\r
- * uMessage [I] Message ID\r
- * wParam [I] WPARAM of message\r
- * lParam [I] LPARAM of message\r
- *\r
- * RETURNS\r
- * The result of calling DefWindowProcA() or DefWindowProcW().\r
- */\r
-LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)\r
-{\r
- if (IsWindowUnicode(hWnd))\r
- return DefWindowProcW(hWnd, uMessage, wParam, lParam);\r
- return DefWindowProcA(hWnd, uMessage, wParam, lParam);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.256]\r
- */\r
-HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)\r
-{\r
- HRESULT hRet = E_INVALIDARG;\r
- LPOBJECTWITHSITE lpSite = NULL;\r
-\r
- TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);\r
-\r
- if (lpUnknown && iid && lppSite)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,\r
- (void**)&lpSite);\r
- if (SUCCEEDED(hRet) && lpSite)\r
- {\r
- hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);\r
- IObjectWithSite_Release(lpSite);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.257]\r
- *\r
- * Create a worker window using CreateWindowExA().\r
- *\r
- * PARAMS\r
- * wndProc [I] Window procedure\r
- * hWndParent [I] Parent window\r
- * dwExStyle [I] Extra style flags\r
- * dwStyle [I] Style flags\r
- * hMenu [I] Window menu\r
- * z [I] Unknown\r
- *\r
- * RETURNS\r
- * Success: The window handle of the newly created window.\r
- * Failure: 0.\r
- */\r
-HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,\r
- DWORD dwStyle, HMENU hMenu, LONG z)\r
-{\r
- static const char* szClass = "WorkerA";\r
- WNDCLASSA wc;\r
- HWND hWnd;\r
-\r
- TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",\r
- wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);\r
-\r
- /* Create Window class */\r
- wc.style = 0;\r
- wc.lpfnWndProc = DefWindowProcA;\r
- wc.cbClsExtra = 0;\r
- wc.cbWndExtra = 4;\r
- wc.hInstance = shlwapi_hInstance;\r
- wc.hIcon = NULL;\r
- wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);\r
- wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;\r
- wc.lpszMenuName = NULL;\r
- wc.lpszClassName = szClass;\r
-\r
- SHRegisterClassA(&wc); /* Register class */\r
-\r
- /* FIXME: Set extra bits in dwExStyle */\r
-\r
- hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,\r
- hWndParent, hMenu, shlwapi_hInstance, 0);\r
- if (hWnd)\r
- {\r
- SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);\r
-\r
- if (wndProc)\r
- SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);\r
- }\r
- return hWnd;\r
-}\r
-\r
-typedef struct tagPOLICYDATA\r
-{\r
- DWORD policy; /* flags value passed to SHRestricted */\r
- LPCWSTR appstr; /* application str such as "Explorer" */\r
- LPCWSTR keystr; /* name of the actual registry key / policy */\r
-} POLICYDATA, *LPPOLICYDATA;\r
-\r
-#define SHELL_NO_POLICY 0xffffffff\r
-\r
-/* default shell policy registry key */\r
-static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',\r
- 's','o','f','t','\\','W','i','n','d','o','w','s','\\',\r
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',\r
- '\\','P','o','l','i','c','i','e','s',0};\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.271]\r
- *\r
- * Retrieve a policy value from the registry.\r
- *\r
- * PARAMS\r
- * lpSubKey [I] registry key name\r
- * lpSubName [I] subname of registry key\r
- * lpValue [I] value name of registry value\r
- *\r
- * RETURNS\r
- * the value associated with the registry key or 0 if not found\r
- */\r
-DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)\r
-{\r
- DWORD retval, datsize = sizeof(retval);\r
- HKEY hKey;\r
-\r
- if (!lpSubKey)\r
- lpSubKey = strRegistryPolicyW;\r
-\r
- retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);\r
- if (retval != ERROR_SUCCESS)\r
- retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);\r
- if (retval != ERROR_SUCCESS)\r
- return 0;\r
-\r
- SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);\r
- RegCloseKey(hKey);\r
- return retval;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.266]\r
- *\r
- * Helper function to retrieve the possibly cached value for a specific policy\r
- *\r
- * PARAMS\r
- * policy [I] The policy to look for\r
- * initial [I] Main registry key to open, if NULL use default\r
- * polTable [I] Table of known policies, 0 terminated\r
- * polArr [I] Cache array of policy values\r
- *\r
- * RETURNS\r
- * The retrieved policy value or 0 if not successful\r
- *\r
- * NOTES\r
- * This function is used by the native SHRestricted function to search for the\r
- * policy and cache it once retrieved. The current Wine implementation uses a\r
- * different POLICYDATA structure and implements a similar algorithme adapted to\r
- * that structure.\r
- */\r
-DWORD WINAPI SHRestrictionLookup(\r
- DWORD policy,\r
- LPCWSTR initial,\r
- LPPOLICYDATA polTable,\r
- LPDWORD polArr)\r
-{\r
- TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);\r
-\r
- if (!polTable || !polArr)\r
- return 0;\r
-\r
- for (;polTable->policy; polTable++, polArr++)\r
- {\r
- if (policy == polTable->policy)\r
- {\r
- /* we have a known policy */\r
-\r
- /* check if this policy has been cached */\r
- if (*polArr == SHELL_NO_POLICY)\r
- *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);\r
- return *polArr;\r
- }\r
- }\r
- /* we don't know this policy, return 0 */\r
- TRACE("unknown policy: (%08lx)\n", policy);\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.267]\r
- *\r
- * Get an interface from an object.\r
- *\r
- * RETURNS\r
- * Success: S_OK. ppv contains the requested interface.\r
- * Failure: An HRESULT error code.\r
- *\r
- * NOTES\r
- * This QueryInterface asks the inner object for an interface. In case\r
- * of aggregation this request would be forwarded by the inner to the\r
- * outer object. This function asks the inner object directly for the\r
- * interface circumventing the forwarding to the outer object.\r
- */\r
-HRESULT WINAPI SHWeakQueryInterface(\r
- IUnknown * pUnk, /* [in] Outer object */\r
- IUnknown * pInner, /* [in] Inner object */\r
- IID * riid, /* [in] Interface GUID to query for */\r
- LPVOID* ppv) /* [out] Destination for queried interface */\r
-{\r
- HRESULT hret = E_NOINTERFACE;\r
- TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);\r
-\r
- *ppv = NULL;\r
- if(pUnk && pInner) {\r
- hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);\r
- if (SUCCEEDED(hret)) IUnknown_Release(pUnk);\r
- }\r
- TRACE("-- 0x%08lx\n", hret);\r
- return hret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.268]\r
- *\r
- * Move a reference from one interface to another.\r
- *\r
- * PARAMS\r
- * lpDest [O] Destination to receive the reference\r
- * lppUnknown [O] Source to give up the reference to lpDest\r
- *\r
- * RETURNS\r
- * Nothing.\r
- */\r
-VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)\r
-{\r
- TRACE("(%p,%p)\n", lpDest, lppUnknown);\r
-\r
- if (*lppUnknown)\r
- {\r
- /* Copy Reference*/\r
- IUnknown_AddRef(lpDest);\r
- IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.269]\r
- *\r
- * Convert an ASCII string of a CLSID into a CLSID.\r
- *\r
- * PARAMS\r
- * idstr [I] String representing a CLSID in registry format\r
- * id [O] Destination for the converted CLSID\r
- *\r
- * RETURNS\r
- * Success: TRUE. id contains the converted CLSID.\r
- * Failure: FALSE.\r
- */\r
-BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)\r
-{\r
- WCHAR wClsid[40];\r
- MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));\r
- return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.270]\r
- *\r
- * Unicode version of GUIDFromStringA.\r
- */\r
-BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)\r
-{\r
- return SUCCEEDED(CLSIDFromStringWrap(idstr, id));\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.276]\r
- *\r
- * Determine if the browser is integrated into the shell, and set a registry\r
- * key accordingly.\r
- *\r
- * PARAMS\r
- * None.\r
- *\r
- * RETURNS\r
- * 1, If the browser is not integrated.\r
- * 2, If the browser is integrated.\r
- *\r
- * NOTES\r
- * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is\r
- * either set to TRUE, or removed depending on whether the browser is deemed\r
- * to be integrated.\r
- */\r
-DWORD WINAPI WhichPlatform()\r
-{\r
- static LPCSTR szIntegratedBrowser = "IntegratedBrowser";\r
- static DWORD dwState = 0;\r
- HKEY hKey;\r
- DWORD dwRet, dwData, dwSize;\r
-\r
- if (dwState)\r
- return dwState;\r
-\r
- /* If shell32 exports DllGetVersion(), the browser is integrated */\r
- GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);\r
- dwState = pDllGetVersion ? 2 : 1;\r
-\r
- /* Set or delete the key accordingly */\r
- dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,\r
- "Software\\Microsoft\\Internet Explorer", 0,\r
- KEY_ALL_ACCESS, &hKey);\r
- if (!dwRet)\r
- {\r
- dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,\r
- (LPBYTE)&dwData, &dwSize);\r
-\r
- if (!dwRet && dwState == 1)\r
- {\r
- /* Value exists but browser is not integrated */\r
- RegDeleteValueA(hKey, szIntegratedBrowser);\r
- }\r
- else if (dwRet && dwState == 2)\r
- {\r
- /* Browser is integrated but value does not exist */\r
- dwData = TRUE;\r
- RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,\r
- (LPBYTE)&dwData, sizeof(dwData));\r
- }\r
- RegCloseKey(hKey);\r
- }\r
- return dwState;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.278]\r
- *\r
- * Unicode version of SHCreateWorkerWindowA.\r
- */\r
-HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,\r
- DWORD dwStyle, HMENU hMenu, LONG z)\r
-{\r
- static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };\r
- WNDCLASSW wc;\r
- HWND hWnd;\r
-\r
- TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",\r
- wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);\r
-\r
- /* If our OS is natively ASCII, use the ASCII version */\r
- if (!(GetVersion() & 0x80000000)) /* NT */\r
- return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);\r
-\r
- /* Create Window class */\r
- wc.style = 0;\r
- wc.lpfnWndProc = DefWindowProcW;\r
- wc.cbClsExtra = 0;\r
- wc.cbWndExtra = 4;\r
- wc.hInstance = shlwapi_hInstance;\r
- wc.hIcon = NULL;\r
- wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);\r
- wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;\r
- wc.lpszMenuName = NULL;\r
- wc.lpszClassName = szClass;\r
-\r
- SHRegisterClassW(&wc); /* Register class */\r
-\r
- /* FIXME: Set extra bits in dwExStyle */\r
-\r
- hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,\r
- hWndParent, hMenu, shlwapi_hInstance, 0);\r
- if (hWnd)\r
- {\r
- SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);\r
-\r
- if (wndProc)\r
- SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);\r
- }\r
- return hWnd;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.279]\r
- *\r
- * Get and show a context menu from a shell folder.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window displaying the shell folder\r
- * lpFolder [I] IShellFolder interface\r
- * lpApidl [I] Id for the particular folder desired\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code indicating the error.\r
- */\r
-HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)\r
-{\r
- return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.281]\r
- *\r
- * _SHPackDispParamsV\r
- */\r
-HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)\r
-{\r
- FIXME("%p %p %p %p\n",w,x,y,z);\r
- return E_FAIL;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.282]\r
- *\r
- * This function seems to be a forward to SHPackDispParamsV (whatever THAT\r
- * function does...).\r
- */\r
-HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)\r
-{\r
- FIXME("%p %p %p %p\n", w, x, y, z);\r
- return E_FAIL;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.284]\r
- *\r
- * _IConnectionPoint_SimpleInvoke\r
- */\r
-DWORD WINAPI IConnectionPoint_SimpleInvoke(\r
- LPVOID x,\r
- LPVOID y,\r
- LPVOID z)\r
-{\r
- FIXME("(%p %p %p) stub\n",x,y,z);\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.285]\r
- *\r
- * Notify an IConnectionPoint object of changes.\r
- *\r
- * PARAMS\r
- * lpCP [I] Object to notify\r
- * dispID [I]\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the\r
- * IConnectionPoint interface.\r
- */\r
-HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)\r
-{\r
- IEnumConnections *lpEnum;\r
- HRESULT hRet = E_NOINTERFACE;\r
-\r
- TRACE("(%p,0x%8lX)\n", lpCP, dispID);\r
-\r
- /* Get an enumerator for the connections */\r
- if (lpCP)\r
- hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);\r
-\r
- if (SUCCEEDED(hRet))\r
- {\r
- IPropertyNotifySink *lpSink;\r
- CONNECTDATA connData;\r
- ULONG ulFetched;\r
-\r
- /* Call OnChanged() for every notify sink in the connection point */\r
- while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)\r
- {\r
- if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&\r
- lpSink)\r
- {\r
- IPropertyNotifySink_OnChanged(lpSink, dispID);\r
- IPropertyNotifySink_Release(lpSink);\r
- }\r
- IUnknown_Release(connData.pUnk);\r
- }\r
-\r
- IEnumConnections_Release(lpEnum);\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.287]\r
- *\r
- * Notify an IConnectionPointContainer object of changes.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object to notify\r
- * dispID [I]\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the\r
- * IConnectionPointContainer interface.\r
- */\r
-HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)\r
-{\r
- IConnectionPointContainer* lpCPC = NULL;\r
- HRESULT hRet = E_NOINTERFACE;\r
-\r
- TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);\r
-\r
- if (lpUnknown)\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);\r
-\r
- if (SUCCEEDED(hRet))\r
- {\r
- IConnectionPoint* lpCP;\r
-\r
- hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);\r
- IConnectionPointContainer_Release(lpCPC);\r
-\r
- hRet = IConnectionPoint_OnChanged(lpCP, dispID);\r
- IConnectionPoint_Release(lpCP);\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.289]\r
- *\r
- * See PlaySoundW.\r
- */\r
-BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)\r
-{\r
- GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);\r
- return pPlaySoundW(pszSound, hmod, fdwSound);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.294]\r
- */\r
-BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)\r
-{\r
- /*\r
- * str1: "I" "I" pushl esp+0x20\r
- * str2: "U" "I" pushl 0x77c93810\r
- * (is "I" and "U" "integer" and "unsigned" ??)\r
- *\r
- * pStr: "" "" pushl eax\r
- * some_len: 0x824 0x104 pushl 0x824\r
- * lpStr2: "%l" "%l" pushl esp+0xc\r
- *\r
- * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);\r
- * LocalAlloc(0x00, some_len) -> irrelevant_var\r
- * LocalAlloc(0x40, irrelevant_len) -> pStr\r
- * shlwapi.294(str1, str2, pStr, some_len, lpStr2);\r
- * shlwapi.PathRemoveBlanksW(pStr);\r
- */\r
- FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.295]\r
- *\r
- * Called by ICQ2000b install via SHDOCVW:\r
- * str1: "InternetShortcut"\r
- * x: some unknown pointer\r
- * str2: "http://free.aol.com/tryaolfree/index.adp?139269"\r
- * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"\r
- *\r
- * In short: this one maybe creates a desktop link :-)\r
- */\r
-BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)\r
-{\r
- FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.299]\r
- *\r
- * See COMCTL32_417.\r
- */\r
-BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,\r
- LPCWSTR str, UINT count, const INT *lpDx)\r
-{\r
- GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);\r
- return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.313]\r
- *\r
- * See SHGetFileInfoW.\r
- */\r
-DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,\r
- SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)\r
-{\r
- GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);\r
- return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.318]\r
- *\r
- * See DragQueryFileW.\r
- */\r
-UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)\r
-{\r
- GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);\r
- return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.333]\r
- *\r
- * See SHBrowseForFolderW.\r
- */\r
-LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)\r
-{\r
- GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);\r
- return pSHBrowseForFolderW(lpBi);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.334]\r
- *\r
- * See SHGetPathFromIDListW.\r
- */\r
-BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)\r
-{\r
- GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);\r
- return pSHGetPathFromIDListW(pidl, pszPath);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.335]\r
- *\r
- * See ShellExecuteExW.\r
- */\r
-BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)\r
-{\r
- GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);\r
- return pShellExecuteExW(lpExecInfo);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.336]\r
- *\r
- * See SHFileOperationW.\r
- */\r
-HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)\r
-{\r
- GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);\r
- return pSHFileOperationW(lpFileOp);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.337]\r
- *\r
- * See ExtractIconExW.\r
- */\r
-UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,\r
- HICON *phiconSmall, UINT nIcons)\r
-{\r
- GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);\r
- return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.342]\r
- *\r
- */\r
-LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)\r
-{\r
- return InterlockedCompareExchange(dest, xchg, compare);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.350]\r
- *\r
- * See GetFileVersionInfoSizeW.\r
- */\r
-DWORD WINAPI GetFileVersionInfoSizeWrapW(\r
- LPWSTR x,\r
- LPVOID y)\r
-{\r
- DWORD ret;\r
-\r
- GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);\r
- ret = pGetFileVersionInfoSizeW(x, y);\r
- return 0x208 + ret;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.351]\r
- *\r
- * See GetFileVersionInfoW.\r
- */\r
-BOOL WINAPI GetFileVersionInfoWrapW(\r
- LPWSTR w, /* [in] path to dll */\r
- DWORD x, /* [in] parm 2 to GetFileVersionInfoA */\r
- DWORD y, /* [in] return value from SHLWAPI_350() - assume length */\r
- LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */\r
-{\r
- GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);\r
- return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.352]\r
- *\r
- * See VerQueryValueW.\r
- */\r
-WORD WINAPI VerQueryValueWrapW(\r
- LPVOID w, /* [in] Buffer from SHLWAPI_351() */\r
- LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */\r
- LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */\r
- UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */\r
-{\r
- GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);\r
- return pVerQueryValueW((char*)w+0x208, x, y, z);\r
-}\r
-\r
-#define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))\r
-#define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB\r
-#define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.355]\r
- *\r
- * Change the modality of a shell object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object to make modeless\r
- * bModeless [I] TRUE=Make modeless, FALSE=Make modal\r
- *\r
- * RETURNS\r
- * Success: S_OK. The modality lpUnknown is changed.\r
- * Failure: An HRESULT error code indicating the error.\r
- *\r
- * NOTES\r
- * lpUnknown must support the IOleInPlaceFrame interface, the\r
- * IInternetSecurityMgrSite interface, the IShellBrowser interface\r
- * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,\r
- * or this call will fail.\r
- */\r
-HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)\r
-{\r
- IUnknown *lpObj;\r
- HRESULT hRet;\r
-\r
- TRACE("(%p,%d)\n", lpUnknown, bModeless);\r
-\r
- if (!lpUnknown)\r
- return E_FAIL;\r
-\r
- if (IsIface(IOleInPlaceActiveObject))\r
- EnableModeless(IOleInPlaceActiveObject);\r
- else if (IsIface(IOleInPlaceFrame))\r
- EnableModeless(IOleInPlaceFrame);\r
- else if (IsIface(IShellBrowser))\r
- EnableModeless(IShellBrowser);\r
-#if 0\r
- /* FIXME: Wine has no headers for these objects yet */\r
- else if (IsIface(IInternetSecurityMgrSite))\r
- EnableModeless(IInternetSecurityMgrSite);\r
- else if (IsIface(IDocHostUIHandler))\r
- EnableModeless(IDocHostUIHandler);\r
-#endif\r
- else\r
- return hRet;\r
-\r
- IUnknown_Release(lpObj);\r
- return S_OK;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.357]\r
- *\r
- * See SHGetNewLinkInfoW.\r
- */\r
-BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,\r
- BOOL *pfMustCopy, UINT uFlags)\r
-{\r
- GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);\r
- return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.358]\r
- *\r
- * See SHDefExtractIconW.\r
- */\r
-UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,\r
- HICON* phiconSmall, UINT nIconSize)\r
-{\r
- GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);\r
- return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.363]\r
- *\r
- * Get and show a context menu from a shell folder.\r
- *\r
- * PARAMS\r
- * hWnd [I] Window displaying the shell folder\r
- * lpFolder [I] IShellFolder interface\r
- * lpApidl [I] Id for the particular folder desired\r
- * bInvokeDefault [I] Whether to invoke the default menu item\r
- *\r
- * RETURNS\r
- * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was\r
- * executed.\r
- * Failure: An HRESULT error code indicating the error.\r
- */\r
-HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)\r
-{\r
- IContextMenu *iContext;\r
- HRESULT hRet = E_FAIL;\r
-\r
- TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);\r
-\r
- if (!lpFolder)\r
- return hRet;\r
-\r
- /* Get the context menu from the shell folder */\r
- hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,\r
- &IID_IContextMenu, 0, (void**)&iContext);\r
- if (SUCCEEDED(hRet))\r
- {\r
- HMENU hMenu;\r
- if ((hMenu = CreatePopupMenu()))\r
- {\r
- HRESULT hQuery;\r
- DWORD dwDefaultId = 0;\r
-\r
- /* Add the context menu entries to the popup */\r
- hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,\r
- bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);\r
-\r
- if (SUCCEEDED(hQuery))\r
- {\r
- if (bInvokeDefault &&\r
- (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)\r
- {\r
- CMINVOKECOMMANDINFO cmIci;\r
- /* Invoke the default item */\r
- memset(&cmIci,0,sizeof(cmIci));\r
- cmIci.cbSize = sizeof(cmIci);\r
- cmIci.fMask = CMIC_MASK_ASYNCOK;\r
- cmIci.hwnd = hWnd;\r
- cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);\r
- cmIci.nShow = SW_SCROLLCHILDREN;\r
-\r
- hRet = IContextMenu_InvokeCommand(iContext, &cmIci);\r
- }\r
- }\r
- DestroyMenu(hMenu);\r
- }\r
- IContextMenu_Release(iContext);\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.370]\r
- *\r
- * See ExtractIconW.\r
- */\r
-HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,\r
- UINT nIconIndex)\r
-{\r
- GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);\r
- return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.376]\r
- */\r
-LANGID WINAPI MLGetUILanguage()\r
-{\r
- FIXME("() stub\n");\r
- /* FIXME: This should be a forward in the .spec file to the win2k function\r
- * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.\r
- */\r
- return GetUserDefaultLangID();\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.377]\r
- *\r
- * Load a library from the directory of a particular process.\r
- *\r
- * PARAMS\r
- * new_mod [I] Library name\r
- * inst_hwnd [I] Module whose directory is to be used\r
- * dwFlags [I] Flags controlling the load\r
- *\r
- * RETURNS\r
- * Success: A handle to the loaded module\r
- * Failure: A NULL handle.\r
- */\r
-HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)\r
-{\r
- /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for\r
- * each call here.\r
- * FIXME: Native shows calls to:\r
- * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"\r
- * CheckVersion\r
- * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"\r
- * RegQueryValueExA for "LPKInstalled"\r
- * RegCloseKey\r
- * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"\r
- * RegQueryValueExA for "ResourceLocale"\r
- * RegCloseKey\r
- * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"\r
- * RegQueryValueExA for "Locale"\r
- * RegCloseKey\r
- * and then tests the Locale ("en" for me).\r
- * code below\r
- * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.\r
- */\r
- CHAR mod_path[2*MAX_PATH];\r
- LPSTR ptr;\r
- DWORD len;\r
-\r
- FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);\r
- len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));\r
- if (!len || len >= sizeof(mod_path)) return NULL;\r
-\r
- ptr = strrchr(mod_path, '\\');\r
- if (ptr) {\r
- strcpy(ptr+1, new_mod);\r
- TRACE("loading %s\n", debugstr_a(mod_path));\r
- return LoadLibraryA(mod_path);\r
- }\r
- return NULL;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.378]\r
- *\r
- * Unicode version of MLLoadLibraryA.\r
- */\r
-HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)\r
-{\r
- WCHAR mod_path[2*MAX_PATH];\r
- LPWSTR ptr;\r
- DWORD len;\r
-\r
- FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);\r
- len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));\r
- if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;\r
-\r
- ptr = strrchrW(mod_path, '\\');\r
- if (ptr) {\r
- strcpyW(ptr+1, new_mod);\r
- TRACE("loading %s\n", debugstr_w(mod_path));\r
- return LoadLibraryW(mod_path);\r
- }\r
- return NULL;\r
-}\r
-\r
-/*************************************************************************\r
- * ColorAdjustLuma [SHLWAPI.@]\r
- *\r
- * Adjust the luminosity of a color\r
- *\r
- * PARAMS\r
- * cRGB [I] RGB value to convert\r
- * dwLuma [I] Luma adjustment\r
- * bUnknown [I] Unknown\r
- *\r
- * RETURNS\r
- * The adjusted RGB color.\r
- */\r
-COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)\r
-{\r
- TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);\r
-\r
- if (dwLuma)\r
- {\r
- WORD wH, wL, wS;\r
-\r
- ColorRGBToHLS(cRGB, &wH, &wL, &wS);\r
-\r
- FIXME("Ignoring luma adjustment\n");\r
-\r
- /* FIXME: The ajdustment is not linear */\r
-\r
- cRGB = ColorHLSToRGB(wH, wL, wS);\r
- }\r
- return cRGB;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.389]\r
- *\r
- * See GetSaveFileNameW.\r
- */\r
-BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)\r
-{\r
- GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);\r
- return pGetSaveFileNameW(ofn);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.390]\r
- *\r
- * See WNetRestoreConnectionW.\r
- */\r
-DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)\r
-{\r
- GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);\r
- return pWNetRestoreConnectionW(hwndOwner, lpszDevice);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.391]\r
- *\r
- * See WNetGetLastErrorW.\r
- */\r
-DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,\r
- LPWSTR lpNameBuf, DWORD nNameBufSize)\r
-{\r
- GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);\r
- return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.401]\r
- *\r
- * See PageSetupDlgW.\r
- */\r
-BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)\r
-{\r
- GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);\r
- return pPageSetupDlgW(pagedlg);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.402]\r
- *\r
- * See PrintDlgW.\r
- */\r
-BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)\r
-{\r
- GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);\r
- return pPrintDlgW(printdlg);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.403]\r
- *\r
- * See GetOpenFileNameW.\r
- */\r
-BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)\r
-{\r
- GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);\r
- return pGetOpenFileNameW(ofn);\r
-}\r
-\r
-/* INTERNAL: Map from HLS color space to RGB */\r
-static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)\r
-{\r
- wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;\r
-\r
- if (wHue > 160)\r
- return wMid1;\r
- else if (wHue > 120)\r
- wHue = 160 - wHue;\r
- else if (wHue > 40)\r
- return wMid2;\r
-\r
- return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;\r
-}\r
-\r
-/* Convert to RGB and scale into RGB range (0..255) */\r
-#define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240\r
-\r
-/*************************************************************************\r
- * ColorHLSToRGB [SHLWAPI.@]\r
- *\r
- * Convert from hls color space into an rgb COLORREF.\r
- *\r
- * PARAMS\r
- * wHue [I] Hue amount\r
- * wLuminosity [I] Luminosity amount\r
- * wSaturation [I] Saturation amount\r
- *\r
- * RETURNS\r
- * A COLORREF representing the converted color.\r
- *\r
- * NOTES\r
- * Input hls values are constrained to the range (0..240).\r
- */\r
-COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)\r
-{\r
- WORD wRed;\r
-\r
- if (wSaturation)\r
- {\r
- WORD wGreen, wBlue, wMid1, wMid2;\r
-\r
- if (wLuminosity > 120)\r
- wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;\r
- else\r
- wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;\r
-\r
- wMid1 = wLuminosity * 2 - wMid2;\r
-\r
- wRed = GET_RGB(wHue + 80);\r
- wGreen = GET_RGB(wHue);\r
- wBlue = GET_RGB(wHue - 80);\r
-\r
- return RGB(wRed, wGreen, wBlue);\r
- }\r
-\r
- wRed = wLuminosity * 255 / 240;\r
- return RGB(wRed, wRed, wRed);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.413]\r
- *\r
- * Get the current docking status of the system.\r
- *\r
- * PARAMS\r
- * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused\r
- *\r
- * RETURNS\r
- * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not\r
- * a notebook.\r
- */\r
-DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)\r
-{\r
- HW_PROFILE_INFOA hwInfo;\r
-\r
- TRACE("(0x%08lx)\n", dwFlags);\r
-\r
- GetCurrentHwProfileA(&hwInfo);\r
- switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))\r
- {\r
- case DOCKINFO_DOCKED:\r
- case DOCKINFO_UNDOCKED:\r
- return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);\r
- default:\r
- return 0;\r
- }\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.418]\r
- *\r
- * Function seems to do FreeLibrary plus other things.\r
- *\r
- * FIXME native shows the following calls:\r
- * RtlEnterCriticalSection\r
- * LocalFree\r
- * GetProcAddress(Comctl32??, 150L)\r
- * DPA_DeletePtr\r
- * RtlLeaveCriticalSection\r
- * followed by the FreeLibrary.\r
- * The above code may be related to .377 above.\r
- */\r
-BOOL WINAPI MLFreeLibrary(HMODULE hModule)\r
-{\r
- FIXME("(%p) semi-stub\n", hModule);\r
- return FreeLibrary(hModule);\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.419]\r
- */\r
-BOOL WINAPI SHFlushSFCacheWrap(void) {\r
- FIXME(": stub\n");\r
- return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.429]\r
- * FIXME I have no idea what this function does or what its arguments are.\r
- */\r
-BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)\r
-{\r
- FIXME("(%p) stub\n", hInst);\r
- return FALSE;\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.430]\r
- */\r
-DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)\r
-{\r
- FIXME("(%p,%p) stub\n", hInst, hHeap);\r
- return E_FAIL; /* This is what is used if shlwapi not loaded */\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.431]\r
- */\r
-DWORD WINAPI MLClearMLHInstance(DWORD x)\r
-{\r
- FIXME("(0x%08lx)stub\n", x);\r
- return 0xabba1247;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.436]\r
- *\r
- * Convert an Unicode string CLSID into a CLSID.\r
- *\r
- * PARAMS\r
- * idstr [I] string containing a CLSID in text form\r
- * id [O] CLSID extracted from the string\r
- *\r
- * RETURNS\r
- * S_OK on success or E_INVALIDARG on failure\r
- *\r
- * NOTES\r
- * This is really CLSIDFromString() which is exported by ole32.dll,\r
- * however the native shlwapi.dll does *not* import ole32. Nor does\r
- * ole32.dll import this ordinal from shlwapi. Therefore we must conclude\r
- * that MS duplicated the code for CLSIDFromString(), and yes they did, only\r
- * it returns an E_INVALIDARG error code on failure.\r
- * This is a duplicate (with changes for Unicode) of CLSIDFromString16()\r
- * in "dlls/ole32/compobj.c".\r
- */\r
-HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)\r
-{\r
- LPCWSTR s = idstr;\r
- BYTE *p;\r
- INT i;\r
- WCHAR table[256];\r
-\r
- if (!s) {\r
- memset(id, 0, sizeof(CLSID));\r
- return S_OK;\r
- }\r
- else { /* validate the CLSID string */\r
-\r
- if (strlenW(s) != 38)\r
- return E_INVALIDARG;\r
-\r
- if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))\r
- return E_INVALIDARG;\r
-\r
- for (i=1; i<37; i++)\r
- {\r
- if ((i == 9)||(i == 14)||(i == 19)||(i == 24))\r
- continue;\r
- if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||\r
- ((s[i] >= L'a') && (s[i] <= L'f')) ||\r
- ((s[i] >= L'A') && (s[i] <= L'F')))\r
- )\r
- return E_INVALIDARG;\r
- }\r
- }\r
-\r
- TRACE("%s -> %p\n", debugstr_w(s), id);\r
-\r
- /* quick lookup table */\r
- memset(table, 0, 256*sizeof(WCHAR));\r
-\r
- for (i = 0; i < 10; i++) {\r
- table['0' + i] = i;\r
- }\r
- for (i = 0; i < 6; i++) {\r
- table['A' + i] = i+10;\r
- table['a' + i] = i+10;\r
- }\r
-\r
- /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */\r
-\r
- p = (BYTE *) id;\r
-\r
- s++; /* skip leading brace */\r
- for (i = 0; i < 4; i++) {\r
- p[3 - i] = table[*s]<<4 | table[*(s+1)];\r
- s += 2;\r
- }\r
- p += 4;\r
- s++; /* skip - */\r
-\r
- for (i = 0; i < 2; i++) {\r
- p[1-i] = table[*s]<<4 | table[*(s+1)];\r
- s += 2;\r
- }\r
- p += 2;\r
- s++; /* skip - */\r
-\r
- for (i = 0; i < 2; i++) {\r
- p[1-i] = table[*s]<<4 | table[*(s+1)];\r
- s += 2;\r
- }\r
- p += 2;\r
- s++; /* skip - */\r
-\r
- /* these are just sequential bytes */\r
- for (i = 0; i < 2; i++) {\r
- *p++ = table[*s]<<4 | table[*(s+1)];\r
- s += 2;\r
- }\r
- s++; /* skip - */\r
-\r
- for (i = 0; i < 6; i++) {\r
- *p++ = table[*s]<<4 | table[*(s+1)];\r
- s += 2;\r
- }\r
-\r
- return S_OK;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.437]\r
- *\r
- * Determine if the OS supports a given feature.\r
- *\r
- * PARAMS\r
- * dwFeature [I] Feature requested (undocumented)\r
- *\r
- * RETURNS\r
- * TRUE If the feature is available.\r
- * FALSE If the feature is not available.\r
- */\r
-BOOL WINAPI IsOS(DWORD feature)\r
-{\r
- OSVERSIONINFOA osvi;\r
- DWORD platform, majorv, minorv;\r
-\r
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);\r
- if(!GetVersionExA(&osvi)) {\r
- ERR("GetVersionEx failed");\r
- return FALSE;\r
- }\r
-\r
- majorv = osvi.dwMajorVersion;\r
- minorv = osvi.dwMinorVersion;\r
- platform = osvi.dwPlatformId;\r
-\r
-#define ISOS_RETURN(x) \\r
- TRACE("(0x%lx) ret=%d\n",feature,(x)); \\r
- return (x);\r
-\r
- switch(feature) {\r
- case OS_WIN32SORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32s\r
- || platform == VER_PLATFORM_WIN32_WINDOWS)\r
- case OS_NT:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_WIN95ORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)\r
- case OS_NT4ORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)\r
- case OS_WIN2000ORGREATER_ALT:\r
- case OS_WIN2000ORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)\r
- case OS_WIN98ORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)\r
- case OS_WIN98_GOLD:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)\r
- case OS_WIN2000PRO:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)\r
- case OS_WIN2000SERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))\r
- case OS_WIN2000ADVSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))\r
- case OS_WIN2000DATACENTER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))\r
- case OS_WIN2000TERMINAL:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))\r
- case OS_EMBEDDED:\r
- FIXME("(OS_EMBEDDED) What should we return here?\n");\r
- return FALSE;\r
- case OS_TERMINALCLIENT:\r
- FIXME("(OS_TERMINALCLIENT) What should we return here?\n");\r
- return FALSE;\r
- case OS_TERMINALREMOTEADMIN:\r
- FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");\r
- return FALSE;\r
- case OS_WIN95_GOLD:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)\r
- case OS_MEORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)\r
- case OS_XPORGREATER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)\r
- case OS_HOME:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)\r
- case OS_PROFESSIONAL:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_DATACENTER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_ADVSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)\r
- case OS_SERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_TERMINALSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_PERSONALTERMINALSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)\r
- case OS_FASTUSERSWITCHING:\r
- FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");\r
- return TRUE;\r
- case OS_WELCOMELOGONUI:\r
- FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");\r
- return FALSE;\r
- case OS_DOMAINMEMBER:\r
- FIXME("(OS_DOMAINMEMBER) What should we return here?\n");\r
- return TRUE;\r
- case OS_ANYSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_WOW6432:\r
- FIXME("(OS_WOW6432) Should we check this?\n");\r
- return FALSE;\r
- case OS_WEBSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_SMALLBUSINESSSERVER:\r
- ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)\r
- case OS_TABLETPC:\r
- FIXME("(OS_TABLEPC) What should we return here?\n");\r
- return FALSE;\r
- case OS_SERVERADMINUI:\r
- FIXME("(OS_SERVERADMINUI) What should we return here?\n");\r
- return FALSE;\r
- case OS_MEDIACENTER:\r
- FIXME("(OS_MEDIACENTER) What should we return here?\n");\r
- return FALSE;\r
- case OS_APPLIANCE:\r
- FIXME("(OS_APPLIANCE) What should we return here?\n");\r
- return FALSE;\r
- }\r
-\r
-#undef ISOS_RETURN\r
-\r
- WARN("(0x%lx) unknown parameter\n",feature);\r
-\r
- return FALSE;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.478]\r
- *\r
- * Call IInputObject_TranslateAcceleratorIO() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IInputObject interface.\r
- * lpMsg [I] Key message to be processed.\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.\r
- */\r
-HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)\r
-{\r
- IInputObject* lpInput = NULL;\r
- HRESULT hRet = E_INVALIDARG;\r
-\r
- TRACE("(%p,%p)\n", lpUnknown, lpMsg);\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,\r
- (void**)&lpInput);\r
- if (SUCCEEDED(hRet) && lpInput)\r
- {\r
- hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);\r
- IInputObject_Release(lpInput);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.481]\r
- *\r
- * Call IInputObject_HasFocusIO() on an object.\r
- *\r
- * PARAMS\r
- * lpUnknown [I] Object supporting the IInputObject interface.\r
- *\r
- * RETURNS\r
- * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,\r
- * or S_FALSE otherwise.\r
- * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.\r
- */\r
-HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)\r
-{\r
- IInputObject* lpInput = NULL;\r
- HRESULT hRet = E_INVALIDARG;\r
-\r
- TRACE("(%p)\n", lpUnknown);\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,\r
- (void**)&lpInput);\r
- if (SUCCEEDED(hRet) && lpInput)\r
- {\r
- hRet = IInputObject_HasFocusIO(lpInput);\r
- IInputObject_Release(lpInput);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/*************************************************************************\r
- * ColorRGBToHLS [SHLWAPI.@]\r
- *\r
- * Convert an rgb COLORREF into the hls color space.\r
- *\r
- * PARAMS\r
- * cRGB [I] Source rgb value\r
- * pwHue [O] Destination for converted hue\r
- * pwLuminance [O] Destination for converted luminance\r
- * pwSaturation [O] Destination for converted saturation\r
- *\r
- * RETURNS\r
- * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted\r
- * values.\r
- *\r
- * NOTES\r
- * Output HLS values are constrained to the range (0..240).\r
- * For Achromatic conversions, Hue is set to 160.\r
- */\r
-VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,\r
- LPWORD pwLuminance, LPWORD pwSaturation)\r
-{\r
- int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;\r
-\r
- TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);\r
-\r
- wR = GetRValue(cRGB);\r
- wG = GetGValue(cRGB);\r
- wB = GetBValue(cRGB);\r
-\r
- wMax = max(wR, max(wG, wB));\r
- wMin = min(wR, min(wG, wB));\r
-\r
- /* Luminosity */\r
- wLuminosity = ((wMax + wMin) * 240 + 255) / 510;\r
-\r
- if (wMax == wMin)\r
- {\r
- /* Achromatic case */\r
- wSaturation = 0;\r
- /* Hue is now unrepresentable, but this is what native returns... */\r
- wHue = 160;\r
- }\r
- else\r
- {\r
- /* Chromatic case */\r
- int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;\r
-\r
- /* Saturation */\r
- if (wLuminosity <= 120)\r
- wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);\r
- else\r
- wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);\r
-\r
- /* Hue */\r
- wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;\r
- wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;\r
- wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;\r
-\r
- if (wR == wMax)\r
- wHue = wBNorm - wGNorm;\r
- else if (wG == wMax)\r
- wHue = 80 + wRNorm - wBNorm;\r
- else\r
- wHue = 160 + wGNorm - wRNorm;\r
- if (wHue < 0)\r
- wHue += 240;\r
- else if (wHue > 240)\r
- wHue -= 240;\r
- }\r
- if (pwHue)\r
- *pwHue = wHue;\r
- if (pwLuminance)\r
- *pwLuminance = wLuminosity;\r
- if (pwSaturation)\r
- *pwSaturation = wSaturation;\r
-}\r
-\r
-/*************************************************************************\r
- * SHCreateShellPalette [SHLWAPI.@]\r
- */\r
-HPALETTE WINAPI SHCreateShellPalette(HDC hdc)\r
-{\r
- FIXME("stub\n");\r
- return CreateHalftonePalette(hdc);\r
-}\r
-\r
-/*************************************************************************\r
- * SHGetInverseCMAP (SHLWAPI.@)\r
- *\r
- * Get an inverse color map table.\r
- *\r
- * PARAMS\r
- * lpCmap [O] Destination for color map\r
- * dwSize [I] Size of memory pointed to by lpCmap\r
- *\r
- * RETURNS\r
- * Success: S_OK.\r
- * Failure: E_POINTER, If lpCmap is invalid.\r
- * E_INVALIDARG, If dwFlags is invalid\r
- * E_OUTOFMEMORY, If there is no memory available\r
- *\r
- * NOTES\r
- * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).\r
- * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's\r
- * internal CMap.\r
- * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from\r
- * this DLL's internal CMap.\r
- */\r
-HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)\r
-{\r
- if (dwSize == 4) {\r
- FIXME(" - returning bogus address for SHGetInverseCMAP\n");\r
- *dest = (DWORD)0xabba1249;\r
- return 0;\r
- }\r
- FIXME("(%p, %#lx) stub\n", dest, dwSize);\r
- return 0;\r
-}\r
-\r
-/*************************************************************************\r
- * SHIsLowMemoryMachine [SHLWAPI.@]\r
- *\r
- * Determine if the current computer has low memory.\r
- *\r
- * PARAMS\r
- * x [I] FIXME\r
- *\r
- * RETURNS\r
- * TRUE if the users machine has 16 Megabytes of memory or less,\r
- * FALSE otherwise.\r
- */\r
-BOOL WINAPI SHIsLowMemoryMachine (DWORD x)\r
-{\r
- FIXME("(0x%08lx) stub\n", x);\r
- return FALSE;\r
-}\r
-\r
-/*************************************************************************\r
- * GetMenuPosFromID [SHLWAPI.@]\r
- *\r
- * Return the position of a menu item from its Id.\r
- *\r
- * PARAMS\r
- * hMenu [I] Menu containing the item\r
- * wID [I] Id of the menu item\r
- *\r
- * RETURNS\r
- * Success: The index of the menu item in hMenu.\r
- * Failure: -1, If the item is not found.\r
- */\r
-INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)\r
-{\r
- MENUITEMINFOA mi;\r
- INT nCount = GetMenuItemCount(hMenu), nIter = 0;\r
-\r
- while (nIter < nCount)\r
- {\r
- mi.wID = 0;\r
- if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)\r
- return nIter;\r
- nIter++;\r
- }\r
- return -1;\r
-}\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.179]\r
- *\r
- * Same as SHLWAPI.GetMenuPosFromID\r
- */\r
-DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)\r
-{\r
- return GetMenuPosFromID(hMenu, uID);\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.448]\r
- */\r
-VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)\r
-{\r
- while (*lpwstr)\r
- {\r
- if (*lpwstr == '/')\r
- *lpwstr = '\\';\r
- lpwstr++;\r
- }\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.461]\r
- */\r
-DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)\r
-{\r
- FIXME("(0x%08lx) stub\n", dwUnknown);\r
- return 0;\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * @ [SHLWAPI.549]\r
- */\r
-HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,\r
- DWORD dwClsContext, REFIID iid, LPVOID *ppv)\r
-{\r
- return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);\r
-}\r
-\r
-/*************************************************************************\r
- * SHSkipJunction [SHLWAPI.@]\r
- *\r
- * Determine if a bind context can be bound to an object\r
- *\r
- * PARAMS\r
- * pbc [I] Bind context to check\r
- * pclsid [I] CLSID of object to be bound to\r
- *\r
- * RETURNS\r
- * TRUE: If it is safe to bind\r
- * FALSE: If pbc is invalid or binding would not be safe\r
- *\r
- */\r
-BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)\r
-{\r
- static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',\r
- 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };\r
- BOOL bRet = FALSE;\r
-\r
- if (pbc)\r
- {\r
- IUnknown* lpUnk;\r
-\r
- if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))\r
- {\r
- CLSID clsid;\r
-\r
- if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&\r
- IsEqualGUID(pclsid, &clsid))\r
- bRet = TRUE;\r
-\r
- IUnknown_Release(lpUnk);\r
- }\r
- }\r
- return bRet;\r
-}\r
-\r
-/***********************************************************************\r
- * SHGetShellKey (SHLWAPI.@)\r
- */\r
-DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)\r
-{\r
- FIXME("(%lx, %lx, %lx): stub\n", a, b, c);\r
- return 0x50;\r
-}\r
-\r
-/***********************************************************************\r
- * SHQueueUserWorkItem (SHLWAPI.@)\r
- */\r
-HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)\r
-{\r
- FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);\r
- return E_FAIL;\r
-}\r
-\r
-/***********************************************************************\r
- * IUnknown_OnFocusChangeIS (SHLWAPI.@)\r
- */\r
-HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)\r
-{\r
- IInputObjectSite *pIOS = NULL;\r
- HRESULT hRet = E_INVALIDARG;\r
-\r
- TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");\r
-\r
- if (lpUnknown)\r
- {\r
- hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,\r
- (void **)&pIOS);\r
- if (SUCCEEDED(hRet) && pIOS)\r
- {\r
- hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);\r
- IInputObjectSite_Release(pIOS);\r
- }\r
- }\r
- return hRet;\r
-}\r
-\r
-/***********************************************************************\r
- * SHGetValueW (SHLWAPI.@)\r
- */\r
-HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)\r
-{\r
- FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);\r
- return E_FAIL;\r
-}\r
-\r
-typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);\r
-\r
-/***********************************************************************\r
- * GetUIVersion (SHLWAPI.452)\r
- */\r
-DWORD WINAPI GetUIVersion(void)\r
-{\r
- static DWORD version;\r
-\r
- if (!version)\r
- {\r
- DllGetVersion_func pDllGetVersion;\r
- HMODULE dll = LoadLibraryA("shell32.dll");\r
- if (!dll) return 0;\r
-\r
- pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");\r
- if (pDllGetVersion)\r
- {\r
- DLLVERSIONINFO dvi;\r
- dvi.cbSize = sizeof(DLLVERSIONINFO);\r
- if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;\r
- }\r
- FreeLibrary( dll );\r
- if (!version) version = 3; /* old shell dlls don't have DllGetVersion */\r
- }\r
- return version;\r
-}\r
+/*
+ * SHLWAPI ordinal functions
+ *
+ * Copyright 1997 Marcus Meissner
+ * 1998 Jürgen Schmied
+ * 2001-2003 Jon Griffiths
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define COM_NO_WINDOWS_H
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "objbase.h"
+#include "docobj.h"
+#include "exdisp.h"
+#include "shlguid.h"
+#include "wingdi.h"
+#include "shlobj.h"
+#include "shellapi.h"
+#include "commdlg.h"
+#include "wine/unicode.h"
+#include "winreg.h"
+#include "wine/debug.h"
+#include "shlwapi.h"
+
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+/* Get a function pointer from a DLL handle */
+#define GET_FUNC(func, module, name, fail) \
+ do { \
+ if (!func) { \
+ if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
+ func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
+ if (!func) return fail; \
+ } \
+ } while (0)
+
+/* DLL handles for late bound calls */
+extern HINSTANCE shlwapi_hInstance;
+extern HMODULE SHLWAPI_hshell32;
+extern HMODULE SHLWAPI_hwinmm;
+extern HMODULE SHLWAPI_hcomdlg32;
+extern HMODULE SHLWAPI_hcomctl32;
+extern HMODULE SHLWAPI_hmpr;
+extern HMODULE SHLWAPI_hurlmon;
+extern HMODULE SHLWAPI_hversion;
+
+extern DWORD SHLWAPI_ThreadRef_index;
+
+/* following is GUID for IObjectWithSite::SetSite -- see _174 */
+static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
+/* following is GUID for IPersistMoniker::GetClassID -- see _174 */
+static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
+
+/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
+typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
+static fnpSHBrowseForFolderW pSHBrowseForFolderW;
+typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
+static fnpPlaySoundW pPlaySoundW;
+typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
+static fnpSHGetFileInfoW pSHGetFileInfoW;
+typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
+static fnpDragQueryFileW pDragQueryFileW;
+typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
+static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
+typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
+static fnpShellExecuteExW pShellExecuteExW;
+typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
+static fnpSHFileOperationW pSHFileOperationW;
+typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
+static fnpExtractIconExW pExtractIconExW;
+typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
+static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
+typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
+static fnpSHDefExtractIconW pSHDefExtractIconW;
+typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
+static fnpExtractIconW pExtractIconW;
+typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
+static fnpGetSaveFileNameW pGetSaveFileNameW;
+typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
+static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
+typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
+static fnpWNetGetLastErrorW pWNetGetLastErrorW;
+typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
+static fnpPageSetupDlgW pPageSetupDlgW;
+typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
+static fnpPrintDlgW pPrintDlgW;
+typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
+static fnpGetOpenFileNameW pGetOpenFileNameW;
+typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
+static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
+typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
+static fnpGetFileVersionInfoW pGetFileVersionInfoW;
+typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
+static fnpVerQueryValueW pVerQueryValueW;
+typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
+static fnpCOMCTL32_417 pCOMCTL32_417;
+typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
+static fnpDllGetVersion pDllGetVersion;
+typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
+static fnpCreateFormatEnumerator pCreateFormatEnumerator;
+typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
+static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
+
+HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
+HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
+HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
+BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
+
+/*
+ NOTES: Most functions exported by ordinal seem to be superflous.
+ The reason for these functions to be there is to provide a wrapper
+ for unicode functions to provide these functions on systems without
+ unicode functions eg. win95/win98. Since we have such functions we just
+ call these. If running Wine with native DLL's, some late bound calls may
+ fail. However, it is better to implement the functions in the forward DLL
+ and recommend the builtin rather than reimplementing the calls here!
+*/
+
+/*************************************************************************
+ * SHLWAPI_DupSharedHandle
+ *
+ * Internal implemetation of SHLWAPI_11.
+ */
+static
+HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
+ DWORD dwSrcProcId, DWORD dwAccess,
+ DWORD dwOptions)
+{
+ HANDLE hDst, hSrc;
+ DWORD dwMyProcId = GetCurrentProcessId();
+ HANDLE hRet = NULL;
+
+ TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
+ dwAccess, dwOptions);
+
+ /* Get dest process handle */
+ if (dwDstProcId == dwMyProcId)
+ hDst = GetCurrentProcess();
+ else
+ hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
+
+ if (hDst)
+ {
+ /* Get src process handle */
+ if (dwSrcProcId == dwMyProcId)
+ hSrc = GetCurrentProcess();
+ else
+ hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
+
+ if (hSrc)
+ {
+ /* Make handle available to dest process */
+ if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
+ dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
+ hRet = NULL;
+
+ if (dwSrcProcId != dwMyProcId)
+ CloseHandle(hSrc);
+ }
+
+ if (dwDstProcId != dwMyProcId)
+ CloseHandle(hDst);
+ }
+
+ TRACE("Returning handle %p\n", hRet);
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.7]
+ *
+ * Create a block of sharable memory and initialise it with data.
+ *
+ * PARAMS
+ * lpvData [I] Pointer to data to write
+ * dwSize [I] Size of data
+ * dwProcId [I] ID of process owning data
+ *
+ * RETURNS
+ * Success: A shared memory handle
+ * Failure: NULL
+ *
+ * NOTES
+ * Ordinals 7-11 provide a set of calls to create shared memory between a
+ * group of processes. The shared memory is treated opaquely in that its size
+ * is not exposed to clients who map it. This is accomplished by storing
+ * the size of the map as the first DWORD of mapped data, and then offsetting
+ * the view pointer returned by this size.
+ *
+ */
+HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
+{
+ HANDLE hMap;
+ LPVOID pMapped;
+ HANDLE hRet = NULL;
+
+ TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
+
+ /* Create file mapping of the correct length */
+ hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
+ dwSize + sizeof(dwSize), NULL);
+ if (!hMap)
+ return hRet;
+
+ /* Get a view in our process address space */
+ pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
+
+ if (pMapped)
+ {
+ /* Write size of data, followed by the data, to the view */
+ *((DWORD*)pMapped) = dwSize;
+ if (lpvData)
+ memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
+
+ /* Release view. All further views mapped will be opaque */
+ UnmapViewOfFile(pMapped);
+ hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
+ GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
+ DUPLICATE_SAME_ACCESS);
+ }
+
+ CloseHandle(hMap);
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.8]
+ *
+ * Get a pointer to a block of shared memory from a shared memory handle.
+ *
+ * PARAMS
+ * hShared [I] Shared memory handle
+ * dwProcId [I] ID of process owning hShared
+ *
+ * RETURNS
+ * Success: A pointer to the shared memory
+ * Failure: NULL
+ *
+ */
+PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
+{
+ HANDLE hDup;
+ LPVOID pMapped;
+
+ TRACE("(%p %ld)\n", hShared, dwProcId);
+
+ /* Get handle to shared memory for current process */
+ hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
+ FILE_MAP_ALL_ACCESS, 0);
+ /* Get View */
+ pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
+ CloseHandle(hDup);
+
+ if (pMapped)
+ return (char *) pMapped + sizeof(DWORD); /* Hide size */
+ return NULL;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.9]
+ *
+ * Release a pointer to a block of shared memory.
+ *
+ * PARAMS
+ * lpView [I] Shared memory pointer
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ */
+BOOL WINAPI SHUnlockShared(LPVOID lpView)
+{
+ TRACE("(%p)\n", lpView);
+ return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.10]
+ *
+ * Destroy a block of sharable memory.
+ *
+ * PARAMS
+ * hShared [I] Shared memory handle
+ * dwProcId [I] ID of process owning hShared
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ */
+BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
+{
+ HANDLE hClose;
+
+ TRACE("(%p %ld)\n", hShared, dwProcId);
+
+ /* Get a copy of the handle for our process, closing the source handle */
+ hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
+ FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
+ /* Close local copy */
+ return CloseHandle(hClose);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.11]
+ *
+ * Copy a sharable memory handle from one process to another.
+ *
+ * PARAMS
+ * hShared [I] Shared memory handle to duplicate
+ * dwDstProcId [I] ID of the process wanting the duplicated handle
+ * dwSrcProcId [I] ID of the process owning hShared
+ * dwAccess [I] Desired DuplicateHandle() access
+ * dwOptions [I] Desired DuplicateHandle() options
+ *
+ * RETURNS
+ * Success: A handle suitable for use by the dwDstProcId process.
+ * Failure: A NULL handle.
+ *
+ */
+HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
+ DWORD dwAccess, DWORD dwOptions)
+{
+ HANDLE hRet;
+
+ hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
+ dwAccess, dwOptions);
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.13]
+ *
+ * Create and register a clipboard enumerator for a web browser.
+ *
+ * PARAMS
+ * lpBC [I] Binding context
+ * lpUnknown [I] An object exposing the IWebBrowserApp interface
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code.
+ *
+ * NOTES
+ * The enumerator is stored as a property of the web browser. If it does not
+ * yet exist, it is created and set before being registered.
+ */
+HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
+{
+ static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
+ '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
+ '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
+ IEnumFORMATETC* pIEnumFormatEtc = NULL;
+ VARIANTARG var;
+ HRESULT hRet;
+ IWebBrowserApp* pBrowser = NULL;
+
+ 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;
+
+ V_VT(&var) = VT_EMPTY;
+
+ /* The property we get is the browsers clipboard enumerator */
+ hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
+ if (FAILED(hRet))
+ return hRet;
+
+ if (V_VT(&var) == VT_EMPTY)
+ {
+ /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
+ char szKeyBuff[128], szValueBuff[128];
+ DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
+ FORMATETC* formatList, *format;
+ HKEY hDocs;
+
+ TRACE("Registering formats and creating IEnumFORMATETC instance\n");
+
+ if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
+ "Version\\Internet Settings\\Accepted Documents", &hDocs))
+ return E_FAIL;
+
+ /* Get count of values in key */
+ while (!dwRet)
+ {
+ dwKeySize = sizeof(szKeyBuff);
+ dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
+ dwCount++;
+ }
+
+ dwNumValues = dwCount;
+
+ /* 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;
+
+ if (dwNumValues > 1)
+ {
+ dwRet = 0;
+ dwCount = 0;
+
+ dwNumValues--;
+
+ /* Register clipboard formats for the values and populate format list */
+ while(!dwRet && dwCount < dwNumValues)
+ {
+ dwKeySize = sizeof(szKeyBuff);
+ dwValueSize = sizeof(szValueBuff);
+ dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
+ (PBYTE)szValueBuff, &dwValueSize);
+ if (!dwRet)
+ return E_FAIL;
+
+ format->cfFormat = RegisterClipboardFormatA(szValueBuff);
+ format->ptd = NULL;
+ format->dwAspect = 1;
+ format->lindex = 4;
+ format->tymed = -1;
+
+ format++;
+ dwCount++;
+ }
+ }
+
+ /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
+ format->cfFormat = 0;
+ format->ptd = NULL;
+ format->dwAspect = 1;
+ format->lindex = 4;
+ format->tymed = -1;
+
+ /* Create a clipboard enumerator */
+ GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
+ hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
+
+ if (FAILED(hRet) || !pIEnumFormatEtc)
+ return hRet;
+
+ /* Set our enumerator as the browsers property */
+ V_VT(&var) = VT_UNKNOWN;
+ V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
+
+ hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
+ if (FAILED(hRet))
+ {
+ IEnumFORMATETC_Release(pIEnumFormatEtc);
+ goto RegisterDefaultAcceptHeaders_Exit;
+ }
+ }
+
+ if (V_VT(&var) == VT_UNKNOWN)
+ {
+ /* Our variant is holding the clipboard enumerator */
+ IUnknown* pIUnknown = V_UNKNOWN(&var);
+ IEnumFORMATETC* pClone = NULL;
+
+ TRACE("Retrieved IEnumFORMATETC property\n");
+
+ /* Get an IEnumFormatEtc interface from the variants value */
+ pIEnumFormatEtc = NULL;
+ hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
+ (PVOID)&pIEnumFormatEtc);
+ if (!hRet && pIEnumFormatEtc)
+ {
+ /* Clone and register the enumerator */
+ hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
+ if (!hRet && pClone)
+ {
+ GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
+ pRegisterFormatEnumerator(lpBC, pClone, 0);
+
+ IEnumFORMATETC_Release(pClone);
+ }
+
+ /* Release the IEnumFormatEtc interface */
+ IEnumFORMATETC_Release(pIUnknown);
+ }
+ IUnknown_Release(V_UNKNOWN(&var));
+ }
+
+RegisterDefaultAcceptHeaders_Exit:
+ IWebBrowserApp_Release(pBrowser);
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.15]
+ *
+ * Get Explorers "AcceptLanguage" setting.
+ *
+ * PARAMS
+ * langbuf [O] Destination for language string
+ * buflen [I] Length of langbuf
+ * [0] Success: used length of langbuf
+ *
+ * RETURNS
+ * Success: S_OK. langbuf is set to the language string found.
+ * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
+ * does not contain the setting.
+ * E_INVALIDARG, If the buffer is not big enough
+ */
+HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
+{
+ static const WCHAR szkeyW[] = {
+ 'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
+ 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
+ static const WCHAR valueW[] = {
+ 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
+ static const WCHAR enusW[] = {'e','n','-','u','s',0};
+ DWORD mystrlen, mytype;
+ HKEY mykey;
+ HRESULT retval;
+ LCID mylcid;
+ WCHAR *mystr;
+
+ if(!langbuf || !buflen || !*buflen)
+ return E_FAIL;
+
+ mystrlen = (*buflen > 20) ? *buflen : 20 ;
+ mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
+ RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
+ if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
+ /* Did not find value */
+ mylcid = GetUserDefaultLCID();
+ /* somehow the mylcid translates into "en-us"
+ * this is similar to "LOCALE_SABBREVLANGNAME"
+ * which could be gotten via GetLocaleInfo.
+ * The only problem is LOCALE_SABBREVLANGUAGE" is
+ * a 3 char string (first 2 are country code and third is
+ * letter for "sublanguage", which does not come close to
+ * "en-us"
+ */
+ lstrcpyW(mystr, enusW);
+ mystrlen = lstrlenW(mystr);
+ } else {
+ /* handle returned string */
+ FIXME("missing code\n");
+ }
+ memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
+
+ if(*buflen > strlenW(mystr)) {
+ *buflen = strlenW(mystr);
+ retval = S_OK;
+ } else {
+ *buflen = 0;
+ retval = E_INVALIDARG;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ }
+ RegCloseKey(mykey);
+ HeapFree(GetProcessHeap(), 0, mystr);
+ return retval;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.14]
+ *
+ * Ascii version of GetAcceptLanguagesW.
+ */
+HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
+{
+ WCHAR *langbufW;
+ DWORD buflenW, convlen;
+ HRESULT retval;
+
+ if(!langbuf || !buflen || !*buflen) return E_FAIL;
+
+ buflenW = *buflen;
+ langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
+ retval = GetAcceptLanguagesW(langbufW, &buflenW);
+
+ /* FIXME: this is wrong, the string may not be null-terminated */
+ convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
+ *buflen, NULL, NULL);
+ *buflen = buflenW ? convlen : 0;
+
+ HeapFree(GetProcessHeap(), 0, langbufW);
+ return retval;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.23]
+ *
+ * Convert a GUID to a string.
+ *
+ * PARAMS
+ * guid [I] GUID to convert
+ * lpszDest [O] Destination for string
+ * cchMax [I] Length of output buffer
+ *
+ * RETURNS
+ * The length of the string created.
+ */
+INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
+{
+ char xguid[40];
+ INT iLen;
+
+ TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
+
+ sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ guid->Data1, guid->Data2, guid->Data3,
+ guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+ guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+
+ iLen = strlen(xguid) + 1;
+
+ if (iLen > cchMax)
+ return 0;
+ memcpy(lpszDest, xguid, iLen);
+ return iLen;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.24]
+ *
+ * Convert a GUID to a string.
+ *
+ * PARAMS
+ * guid [I] GUID to convert
+ * str [O] Destination for string
+ * cmax [I] Length of output buffer
+ *
+ * RETURNS
+ * The length of the string created.
+ */
+INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
+{
+ WCHAR xguid[40];
+ INT iLen;
+ static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
+ '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
+ 'X','%','0','2','X','%','0','2','X','}',0};
+
+ TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
+
+ sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
+ guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+ guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+
+ iLen = strlenW(xguid) + 1;
+
+ if (iLen > cchMax)
+ return 0;
+ memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
+ return iLen;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.29]
+ *
+ * Determine if a Unicode character is a space.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is a space,
+ * FALSE otherwise.
+ */
+BOOL WINAPI IsCharSpaceW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.30]
+ *
+ * Determine if a Unicode character is a blank.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is a blank,
+ * FALSE otherwise.
+ *
+ */
+BOOL WINAPI IsCharBlankW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.31]
+ *
+ * Determine if a Unicode character is punctuation.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is punctuation,
+ * FALSE otherwise.
+ */
+BOOL WINAPI IsCharPunctW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.32]
+ *
+ * Determine if a Unicode character is a control character.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is a control character,
+ * FALSE otherwise.
+ */
+BOOL WINAPI IsCharCntrlW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.33]
+ *
+ * Determine if a Unicode character is a digit.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is a digit,
+ * FALSE otherwise.
+ */
+BOOL WINAPI IsCharDigitW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.34]
+ *
+ * Determine if a Unicode character is a hex digit.
+ *
+ * PARAMS
+ * wc [I] Character to check.
+ *
+ * RETURNS
+ * TRUE, if wc is a hex digit,
+ * FALSE otherwise.
+ */
+BOOL WINAPI IsCharXDigitW(WCHAR wc)
+{
+ WORD CharType;
+
+ return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.35]
+ *
+ */
+BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
+{
+ FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.36]
+ *
+ * Insert a bitmap menu item at the bottom of a menu.
+ *
+ * PARAMS
+ * hMenu [I] Menu to insert into
+ * flags [I] Flags for insertion
+ * id [I] Menu ID of the item
+ * str [I] Menu text for the item
+ *
+ * RETURNS
+ * Success: TRUE, the item is inserted into the menu
+ * Failure: FALSE, if any parameter is invalid
+ */
+BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
+{
+ TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
+ return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.74]
+ *
+ * Get the text from a given dialog item.
+ *
+ * PARAMS
+ * hWnd [I] Handle of dialog
+ * nItem [I] Index of item
+ * lpsDest [O] Buffer for receiving window text
+ * nDestLen [I] Length of buffer.
+ *
+ * RETURNS
+ * Success: The length of the returned text.
+ * Failure: 0.
+ */
+INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
+{
+ HWND hItem = GetDlgItem(hWnd, nItem);
+
+ if (hItem)
+ return GetWindowTextW(hItem, lpsDest, nDestLen);
+ if (nDestLen)
+ *lpsDest = (WCHAR)'\0';
+ return 0;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.138]
+ *
+ * Set the text of a given dialog item.
+ *
+ * PARAMS
+ * hWnd [I] Handle of dialog
+ * iItem [I] Index of item
+ * lpszText [O] Text to set
+ *
+ * RETURNS
+ * Success: TRUE. The text of the dialog is set to lpszText.
+ * Failure: FALSE, Otherwise.
+ */
+BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
+{
+ HWND hWndItem = GetDlgItem(hWnd, iItem);
+ if (hWndItem)
+ return SetWindowTextW(hWndItem, lpszText);
+ return FALSE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.151]
+ *
+ * Compare two Ascii strings up to a given length.
+ *
+ * PARAMS
+ * lpszSrc [I] Source string
+ * lpszCmp [I] String to compare to lpszSrc
+ * len [I] Maximum length
+ *
+ * RETURNS
+ * A number greater than, less than or equal to 0 depending on whether
+ * lpszSrc is greater than, less than or equal to lpszCmp.
+ */
+DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
+{
+ return strncmp(lpszSrc, lpszCmp, len);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.152]
+ *
+ * Unicode version of StrCmpNCA.
+ */
+DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
+{
+ return strncmpW(lpszSrc, lpszCmp, len);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.153]
+ *
+ * Compare two Ascii strings up to a given length, ignoring case.
+ *
+ * PARAMS
+ * lpszSrc [I] Source string
+ * lpszCmp [I] String to compare to lpszSrc
+ * len [I] Maximum length
+ *
+ * RETURNS
+ * A number greater than, less than or equal to 0 depending on whether
+ * lpszSrc is greater than, less than or equal to lpszCmp.
+ */
+DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
+{
+ return strncasecmp(lpszSrc, lpszCmp, len);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.154]
+ *
+ * Unicode version of StrCmpNICA.
+ */
+DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
+{
+ return strncmpiW(lpszSrc, lpszCmp, len);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.155]
+ *
+ * Compare two Ascii strings.
+ *
+ * PARAMS
+ * lpszSrc [I] Source string
+ * lpszCmp [I] String to compare to lpszSrc
+ *
+ * RETURNS
+ * A number greater than, less than or equal to 0 depending on whether
+ * lpszSrc is greater than, less than or equal to lpszCmp.
+ */
+DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
+{
+ return strcmp(lpszSrc, lpszCmp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.156]
+ *
+ * Unicode version of StrCmpCA.
+ */
+DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
+{
+ return strcmpW(lpszSrc, lpszCmp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.157]
+ *
+ * Compare two Ascii strings, ignoring case.
+ *
+ * PARAMS
+ * lpszSrc [I] Source string
+ * lpszCmp [I] String to compare to lpszSrc
+ *
+ * RETURNS
+ * A number greater than, less than or equal to 0 depending on whether
+ * lpszSrc is greater than, less than or equal to lpszCmp.
+ */
+DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
+{
+ return strcasecmp(lpszSrc, lpszCmp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.158]
+ *
+ * Unicode version of StrCmpICA.
+ */
+DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
+{
+ return strcmpiW(lpszSrc, lpszCmp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.160]
+ *
+ * Get an identification string for the OS and explorer.
+ *
+ * PARAMS
+ * lpszDest [O] Destination for Id string
+ * dwDestLen [I] Length of lpszDest
+ *
+ * RETURNS
+ * TRUE, If the string was created successfully
+ * FALSE, Otherwise
+ */
+BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
+{
+ WCHAR buff[2084];
+
+ TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
+
+ if (lpszDest && SHAboutInfoW(buff, dwDestLen))
+ {
+ WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.161]
+ *
+ * Unicode version of SHAboutInfoA.
+ */
+BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
+{
+ static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
+ ' ','E','x','p','l','o','r','e','r','\0' };
+ static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
+ 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
+ static const WCHAR szWinKey[] = { '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','\0' };
+ static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
+ ' ','E','x','p','l','o','r','e','r','\\',
+ 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
+ static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
+ static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
+ 'V','e','r','s','i','o','n','\0' };
+ static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
+ 'O','w','n','e','r','\0' };
+ static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
+ 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
+ static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
+ static const WCHAR szUpdate[] = { 'I','E','A','K',
+ 'U','p','d','a','t','e','U','r','l','\0' };
+ static const WCHAR szHelp[] = { 'I','E','A','K',
+ 'H','e','l','p','S','t','r','i','n','g','\0' };
+ WCHAR buff[2084];
+ HKEY hReg;
+ DWORD dwType, dwLen;
+
+ TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
+
+ if (!lpszDest)
+ return FALSE;
+
+ *lpszDest = '\0';
+
+ /* Try the NT key first, followed by 95/98 key */
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
+ RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
+ return FALSE;
+
+ /* OS Version */
+ buff[0] = '\0';
+ dwLen = 30;
+ if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
+ {
+ DWORD dwStrLen = strlenW(buff);
+ dwLen = 30 - dwStrLen;
+ SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
+ szCustomized, &dwType, buff+dwStrLen, &dwLen);
+ }
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* ~Registered Owner */
+ buff[0] = '~';
+ dwLen = 256;
+ if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
+ buff[1] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* ~Registered Organization */
+ dwLen = 256;
+ if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
+ buff[1] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* FIXME: Not sure where this number comes from */
+ buff[0] = '~';
+ buff[1] = '0';
+ buff[2] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* ~Product Id */
+ dwLen = 256;
+ if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
+ buff[1] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* ~IE Update Url */
+ dwLen = 2048;
+ if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
+ buff[1] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ /* ~IE Help String */
+ dwLen = 256;
+ if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
+ buff[1] = '\0';
+ StrCatBuffW(lpszDest, buff, dwDestLen);
+
+ RegCloseKey(hReg);
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.163]
+ *
+ * Call IOleCommandTarget_QueryStatus() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IOleCommandTarget interface
+ * pguidCmdGroup [I] GUID for the command group
+ * cCmds [I]
+ * prgCmds [O] Commands
+ * pCmdText [O] Command text
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_FAIL, if lpUnknown is NULL.
+ * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
+ * Otherwise, an error code from IOleCommandTarget_QueryStatus().
+ */
+HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
+ ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
+{
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
+
+ if (lpUnknown)
+ {
+ IOleCommandTarget* lpOle;
+
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
+ (void**)&lpOle);
+
+ if (SUCCEEDED(hRet) && lpOle)
+ {
+ hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
+ prgCmds, pCmdText);
+ IOleCommandTarget_Release(lpOle);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.164]
+ *
+ * Call IOleCommandTarget_Exec() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IOleCommandTarget interface
+ * pguidCmdGroup [I] GUID for the command group
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_FAIL, if lpUnknown is NULL.
+ * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
+ * Otherwise, an error code from IOleCommandTarget_Exec().
+ */
+HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
+ DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
+ VARIANT* pvaOut)
+{
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
+ nCmdexecopt, pvaIn, pvaOut);
+
+ if (lpUnknown)
+ {
+ IOleCommandTarget* lpOle;
+
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
+ (void**)&lpOle);
+ if (SUCCEEDED(hRet) && lpOle)
+ {
+ hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
+ nCmdexecopt, pvaIn, pvaOut);
+ IOleCommandTarget_Release(lpOle);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.165]
+ *
+ * Retrieve, modify, and re-set a value from a window.
+ *
+ * PARAMS
+ * hWnd [I] Window to get value from
+ * offset [I] Offset of value
+ * wMask [I] Mask for uiFlags
+ * wFlags [I] Bits to set in window value
+ *
+ * RETURNS
+ * The new value as it was set, or 0 if any parameter is invalid.
+ *
+ * NOTES
+ * Any bits set in uiMask are cleared from the value, then any bits set in
+ * uiFlags are set in the value.
+ */
+LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
+{
+ LONG ret = GetWindowLongA(hwnd, offset);
+ LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
+
+ if (newFlags != ret)
+ ret = SetWindowLongA(hwnd, offset, newFlags);
+ return ret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.167]
+ *
+ * Change a window's parent.
+ *
+ * PARAMS
+ * hWnd [I] Window to change parent of
+ * hWndParent [I] New parent window
+ *
+ * RETURNS
+ * The old parent of hWnd.
+ *
+ * NOTES
+ * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
+ * If hWndParent is NOT NULL then we set the WS_CHILD style.
+ */
+HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
+{
+ TRACE("%p, %p\n", hWnd, hWndParent);
+
+ if(GetParent(hWnd) == hWndParent)
+ return 0;
+
+ if(hWndParent)
+ SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
+ else
+ SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
+
+ return SetParent(hWnd, hWndParent);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.168]
+ *
+ * Locate and advise a connection point in an IConnectionPointContainer object.
+ *
+ * PARAMS
+ * lpUnkSink [I] Sink for the connection point advise call
+ * riid [I] REFIID of connection point to advise
+ * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
+ * lpUnknown [I] Object supporting the IConnectionPointContainer interface
+ * lpCookie [O] Pointer to connection point cookie
+ * lppCP [O] Destination for the IConnectionPoint found
+ *
+ * RETURNS
+ * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
+ * that was advised. The caller is responsable for releasing it.
+ * Failure: E_FAIL, if any arguments are invalid.
+ * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
+ * Or an HRESULT error code if any call fails.
+ */
+HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
+ IUnknown* lpUnknown, LPDWORD lpCookie,
+ IConnectionPoint **lppCP)
+{
+ HRESULT hRet;
+ IConnectionPointContainer* lpContainer;
+ IConnectionPoint *lpCP;
+
+ if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
+ return E_FAIL;
+
+ if(lppCP)
+ *lppCP = NULL;
+
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
+ (void**)&lpContainer);
+ if (SUCCEEDED(hRet))
+ {
+ hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
+
+ if (SUCCEEDED(hRet))
+ {
+ if(!bAdviseOnly)
+ hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
+ hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
+
+ if (FAILED(hRet))
+ *lpCookie = 0;
+
+ if (lppCP && SUCCEEDED(hRet))
+ *lppCP = lpCP; /* Caller keeps the interface */
+ else
+ IConnectionPoint_Release(lpCP); /* Release it */
+ }
+
+ IUnknown_Release(lpContainer);
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.169]
+ *
+ * Release an interface.
+ *
+ * PARAMS
+ * lpUnknown [I] Object to release
+ *
+ * RETURNS
+ * Nothing.
+ */
+DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
+{
+ IUnknown *temp;
+
+ TRACE("(%p)\n",lpUnknown);
+
+ if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
+ temp = *lpUnknown;
+ *lpUnknown = NULL;
+
+ TRACE("doing Release\n");
+
+ return IUnknown_Release(temp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.170]
+ *
+ * Skip '//' if present in a string.
+ *
+ * PARAMS
+ * lpszSrc [I] String to check for '//'
+ *
+ * RETURNS
+ * Success: The next character after the '//' or the string if not present
+ * Failure: NULL, if lpszStr is NULL.
+ */
+LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
+{
+ if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
+ lpszSrc += 2;
+ return lpszSrc;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.171]
+ *
+ * Check if two interfaces come from the same object.
+ *
+ * PARAMS
+ * lpInt1 [I] Interface to check against lpInt2.
+ * lpInt2 [I] Interface to check against lpInt1.
+ *
+ * RETURNS
+ * TRUE, If the interfaces come from the same object.
+ * FALSE Otherwise.
+ */
+BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
+{
+ LPVOID lpUnknown1, lpUnknown2;
+
+ TRACE("%p %p\n", lpInt1, lpInt2);
+
+ if (!lpInt1 || !lpInt2)
+ return FALSE;
+
+ if (lpInt1 == lpInt2)
+ return TRUE;
+
+ if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
+ (LPVOID *)&lpUnknown1)))
+ return FALSE;
+
+ if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
+ (LPVOID *)&lpUnknown2)))
+ return FALSE;
+
+ if (lpUnknown1 == lpUnknown2)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.172]
+ *
+ * Get the window handle of an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object to get the window handle of
+ * lphWnd [O] Destination for window handle
+ *
+ * RETURNS
+ * Success: S_OK. lphWnd contains the objects window handle.
+ * Failure: An HRESULT error code.
+ *
+ * NOTES
+ * lpUnknown is expected to support one of the following interfaces:
+ * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
+ */
+HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
+{
+ /* FIXME: Wine has no header for this object */
+ static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
+ 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
+ IUnknown *lpOle;
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p)\n", lpUnknown, lphWnd);
+
+ if (!lpUnknown)
+ return hRet;
+
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
+
+ if (FAILED(hRet))
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
+
+ if (FAILED(hRet))
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
+ (void**)&lpOle);
+ }
+ }
+
+ if (SUCCEEDED(hRet))
+ {
+ /* Lazyness here - Since GetWindow() is the first method for the above 3
+ * interfaces, we use the same call for them all.
+ */
+ hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
+ IUnknown_Release(lpOle);
+ if (lphWnd)
+ TRACE("Returning HWND=%p\n", *lphWnd);
+ }
+
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.173]
+ *
+ * Call a method on as as yet unidentified object.
+ *
+ * PARAMS
+ * pUnk [I] Object supporting the unidentified interface,
+ * arg [I] Argument for the call on the object.
+ *
+ * RETURNS
+ * S_OK.
+ */
+HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
+{
+ static const GUID guid_173 = {
+ 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
+ };
+ IMalloc *pUnk2;
+
+ TRACE("(%p,%ld)\n", pUnk, arg);
+
+ /* 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)))
+ {
+ IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
+ IMalloc_Release(pUnk2);
+ }
+ return S_OK;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.174]
+ *
+ * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
+ * an interface.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_FAIL, if p1 is NULL.
+ * E_NOINTERFACE If p1 does not support the IPersist interface,
+ * Or an HRESULT error code.
+ */
+DWORD WINAPI IUnknown_SetSite(
+ IUnknown *p1, /* [in] OLE object */
+ LPVOID *p2) /* [out] ptr for call results */
+{
+ DWORD ret, aa;
+ IUnknown *iobjectwithsite;
+
+ if (!p1) return E_FAIL;
+
+ /* see if SetSite interface exists for IObjectWithSite object */
+ ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&iobjectwithsite);
+ TRACE("first IU_QI ret=%08lx, iobjectwithsite=%p\n", ret, iobjectwithsite);
+ if (ret) {
+
+ /* see if GetClassId interface exists for IPersistMoniker object */
+ ret = IUnknown_QueryInterface(p1, (REFIID)id2, (LPVOID *)&aa);
+ TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
+ if (ret) return ret;
+
+ /* fake a GetClassId call */
+ ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
+ TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
+ *(LPDWORD)p2);
+ IUnknown_Release((IUnknown *)aa);
+ }
+ else {
+ /* fake a SetSite call */
+ ret = IOleWindow_GetWindow((IOleWindow *)iobjectwithsite, (HWND*)p2);
+ TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
+ *(LPDWORD)p2);
+ IUnknown_Release((IUnknown *)iobjectwithsite);
+ }
+ return ret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.175]
+ *
+ * Call IPersist_GetClassID() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IPersist interface
+ * lpClassId [O] Destination for Class Id
+ *
+ * RETURNS
+ * Success: S_OK. lpClassId contains the Class Id requested.
+ * Failure: E_FAIL, If lpUnknown is NULL,
+ * E_NOINTERFACE If lpUnknown does not support IPersist,
+ * Or an HRESULT error code.
+ */
+HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
+{
+ IPersist* lpPersist;
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
+
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
+ if (SUCCEEDED(hRet))
+ {
+ IPersist_GetClassID(lpPersist, lpClassId);
+ IPersist_Release(lpPersist);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.176]
+ *
+ * Retrieve a Service Interface from an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object to get an IServiceProvider interface from
+ * sid [I] Service ID for IServiceProvider_QueryService() call
+ * riid [I] Function requested for QueryService call
+ * lppOut [O] Destination for the service interface pointer
+ *
+ * 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_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
+ LPVOID *lppOut)
+{
+ IServiceProvider* pService = NULL;
+ HRESULT hRet;
+
+ if (!lppOut)
+ return E_FAIL;
+
+ *lppOut = NULL;
+
+ if (!lpUnknown)
+ return E_FAIL;
+
+ /* Get an IServiceProvider interface from the object */
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
+ (LPVOID*)&pService);
+
+ if (!hRet && pService)
+ {
+ TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
+
+ /* Get a Service interface from the object */
+ hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
+
+ TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
+
+ /* Release the IServiceProvider interface */
+ IUnknown_Release(pService);
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.177]
+ *
+ * Loads a popup menu.
+ *
+ * PARAMS
+ * hInst [I] Instance handle
+ * szName [I] Menu name
+ *
+ * RETURNS
+ * Success: TRUE.
+ * Failure: FALSE.
+ */
+BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
+{
+ HMENU hMenu, hSubMenu;
+
+ if ((hMenu = LoadMenuW(hInst, szName)))
+ {
+ if ((hSubMenu = GetSubMenu(hMenu, 0)))
+ RemoveMenu(hMenu, 0, MF_BYPOSITION);
+
+ DestroyMenu(hMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+typedef struct _enumWndData
+{
+ UINT uiMsgId;
+ WPARAM wParam;
+ LPARAM lParam;
+ LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
+} enumWndData;
+
+/* Callback for SHLWAPI_178 */
+static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
+{
+ enumWndData *data = (enumWndData *)lParam;
+
+ TRACE("(%p,%p)\n", hWnd, data);
+ data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.178]
+ *
+ * Send or post a message to every child of a window.
+ *
+ * PARAMS
+ * hWnd [I] Window whose children will get the messages
+ * uiMsgId [I] Message Id
+ * wParam [I] WPARAM of message
+ * lParam [I] LPARAM of message
+ * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
+ *
+ * RETURNS
+ * Nothing.
+ *
+ * NOTES
+ * The appropriate ASCII or Unicode function is called for the window.
+ */
+void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
+{
+ enumWndData data;
+
+ TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
+
+ if(hWnd)
+ {
+ data.uiMsgId = uiMsgId;
+ data.wParam = wParam;
+ data.lParam = lParam;
+
+ if (bSend)
+ data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
+ else
+ data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
+
+ EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.180]
+ *
+ * Remove all sub-menus from a menu.
+ *
+ * PARAMS
+ * hMenu [I] Menu to remove sub-menus from
+ *
+ * RETURNS
+ * Success: 0. All sub-menus under hMenu are removed
+ * Failure: -1, if any parameter is invalid
+ */
+DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
+{
+ int iItemCount = GetMenuItemCount(hMenu) - 1;
+ while (iItemCount >= 0)
+ {
+ HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
+ if (hSubMenu)
+ RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
+ iItemCount--;
+ }
+ return iItemCount;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.181]
+ *
+ * Enable or disable a menu item.
+ *
+ * PARAMS
+ * hMenu [I] Menu holding menu item
+ * uID [I] ID of menu item to enable/disable
+ * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
+ *
+ * RETURNS
+ * The return code from EnableMenuItem.
+ */
+UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
+{
+ return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.182]
+ *
+ * Check or uncheck a menu item.
+ *
+ * PARAMS
+ * hMenu [I] Menu holding menu item
+ * uID [I] ID of menu item to check/uncheck
+ * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
+ *
+ * RETURNS
+ * The return code from CheckMenuItem.
+ */
+DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
+{
+ return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.183]
+ *
+ * Register a window class if it isn't already.
+ *
+ * PARAMS
+ * lpWndClass [I] Window class to register
+ *
+ * RETURNS
+ * The result of the RegisterClassA call.
+ */
+DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
+{
+ WNDCLASSA wca;
+ if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
+ return TRUE;
+ return (DWORD)RegisterClassA(wndclass);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.186]
+ */
+BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
+ DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
+{
+ DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
+ POINTL pt = { 0, 0 };
+
+ if (!lpPt)
+ lpPt = &pt;
+
+ if (!pdwEffect)
+ pdwEffect = &dwEffect;
+
+ IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
+
+ if (*pdwEffect)
+ return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
+
+ IDropTarget_DragLeave(pDrop);
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.187]
+ *
+ * Call IPersistPropertyBag_Load() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IPersistPropertyBag interface
+ * lpPropBag [O] Destination for loaded IPropertyBag
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
+ */
+DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
+{
+ IPersistPropertyBag* lpPPBag;
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
+
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
+ (void**)&lpPPBag);
+ if (SUCCEEDED(hRet) && lpPPBag)
+ {
+ hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
+ IPersistPropertyBag_Release(lpPPBag);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.188]
+ *
+ * Call IOleControlSite_TranslateAccelerator() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IOleControlSite interface.
+ * lpMsg [I] Key message to be processed.
+ * dwModifiers [I] Flags containing the state of the modifier keys.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
+ */
+HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
+{
+ IOleControlSite* lpCSite = NULL;
+ HRESULT hRet = E_INVALIDARG;
+
+ TRACE("(%p,%p,0x%08lx)\n", lpUnknown, lpMsg, dwModifiers);
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
+ (void**)&lpCSite);
+ if (SUCCEEDED(hRet) && lpCSite)
+ {
+ hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
+ IOleControlSite_Release(lpCSite);
+ }
+ }
+ return hRet;
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.189]
+ *
+ * Call IOleControlSite_GetExtendedControl() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IOleControlSite interface.
+ * lppDisp [O] Destination for resulting IDispatch.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
+ */
+DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
+{
+ IOleControlSite* lpCSite = NULL;
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p)\n", lpUnknown, lppDisp);
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
+ (void**)&lpCSite);
+ if (SUCCEEDED(hRet) && lpCSite)
+ {
+ hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
+ IOleControlSite_Release(lpCSite);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.190]
+ */
+HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
+ PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
+{
+ /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
+ static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
+ /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
+ static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
+ HRESULT hRet = E_INVALIDARG;
+ LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
+
+ TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
+
+ if (lpUnknown && lpArg4)
+ {
+ hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
+ (REFGUID)function_id, (void**)&lpUnkInner);
+
+ if (SUCCEEDED(hRet) && lpUnkInner)
+ {
+ /* FIXME: The type of service object requested is unknown, however
+ * testing shows that its first method is called with 4 parameters.
+ * Fake this by using IParseDisplayName_ParseDisplayName since the
+ * signature and position in the vtable matches our unknown object type.
+ */
+ hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
+ lpArg1, lpArg2, lpArg3, lpArg4);
+ IUnknown_Release(lpUnkInner);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.192]
+ *
+ * Get a sub-menu from a menu item.
+ *
+ * PARAMS
+ * hMenu [I] Menu to get sub-menu from
+ * uID [I] ID of menu item containing sub-menu
+ *
+ * RETURNS
+ * The sub-menu of the item, or a NULL handle if any parameters are invalid.
+ */
+HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
+{
+ MENUITEMINFOA mi;
+
+ TRACE("(%p,%uld)\n", hMenu, uID);
+
+ mi.cbSize = sizeof(MENUITEMINFOA);
+ mi.fMask = MIIM_SUBMENU;
+
+ if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
+ return NULL;
+
+ return mi.hSubMenu;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.193]
+ *
+ * Get the color depth of the primary display.
+ *
+ * PARAMS
+ * None.
+ *
+ * RETURNS
+ * The color depth of the primary display.
+ */
+DWORD WINAPI SHGetCurColorRes()
+{
+ HDC hdc;
+ DWORD ret;
+
+ TRACE("()\n");
+
+ hdc = GetDC(0);
+ ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
+ ReleaseDC(0, hdc);
+ return ret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.194]
+ *
+ * Wait for a message to arrive, with a timeout.
+ *
+ * PARAMS
+ * hand [I] Handle to query
+ * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
+ *
+ * RETURNS
+ * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
+ * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
+ * message is available.
+ */
+DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
+{
+ DWORD dwEndTicks = GetTickCount() + dwTimeout;
+ DWORD dwRet;
+
+ while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
+ {
+ MSG msg;
+
+ PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
+
+ if (dwTimeout != INFINITE)
+ {
+ if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
+ return WAIT_TIMEOUT;
+ }
+ }
+
+ return dwRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.195]
+ *
+ * Determine if a shell folder can be expanded.
+ *
+ * PARAMS
+ * lpFolder [I] Parent folder containing the object to test.
+ * pidl [I] Id of the object to test.
+ *
+ * RETURNS
+ * Success: S_OK, if the object is expandable, S_FALSE otherwise.
+ * Failure: E_INVALIDARG, if any argument is invalid.
+ *
+ * NOTES
+ * If the object to be tested does not expose the IQueryInfo() interface it
+ * will not be identified as an expandable folder.
+ */
+HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
+{
+ HRESULT hRet = E_INVALIDARG;
+ IQueryInfo *lpInfo;
+
+ if (lpFolder && pidl)
+ {
+ hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
+ NULL, (void**)&lpInfo);
+ if (FAILED(hRet))
+ hRet = S_FALSE; /* Doesn't expose IQueryInfo */
+ else
+ {
+ DWORD dwFlags = 0;
+
+ /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
+ * currently used". Really? You wouldn't be holding out on me would you?
+ */
+ hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
+
+ if (SUCCEEDED(hRet))
+ {
+ /* 0x2 is an undocumented flag apparently indicating expandability */
+ hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
+ }
+
+ IQueryInfo_Release(lpInfo);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.197]
+ *
+ * Blank out a region of text by drawing the background only.
+ *
+ * PARAMS
+ * hDC [I] Device context to draw in
+ * pRect [I] Area to draw in
+ * cRef [I] Color to draw in
+ *
+ * RETURNS
+ * Nothing.
+ */
+DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
+{
+ COLORREF cOldColor = SetBkColor(hDC, cRef);
+ ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
+ SetBkColor(hDC, cOldColor);
+ return 0;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.198]
+ *
+ * Return the value asociated with a key in a map.
+ *
+ * PARAMS
+ * lpKeys [I] A list of keys of length iLen
+ * lpValues [I] A list of values associated with lpKeys, of length iLen
+ * iLen [I] Length of both lpKeys and lpValues
+ * iKey [I] The key value to look up in lpKeys
+ *
+ * RETURNS
+ * The value in lpValues associated with iKey, or -1 if iKey is not
+ * found in lpKeys.
+ *
+ * NOTES
+ * - If two elements in the map share the same key, this function returns
+ * the value closest to the start of the map
+ * - The native version of this function crashes if lpKeys or lpValues is NULL.
+ */
+int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
+{
+ if (lpKeys && lpValues)
+ {
+ int i = 0;
+
+ while (i < iLen)
+ {
+ if (lpKeys[i] == iKey)
+ return lpValues[i]; /* Found */
+ i++;
+ }
+ }
+ return -1; /* Not found */
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.199]
+ *
+ * Copy an interface pointer
+ *
+ * PARAMS
+ * lppDest [O] Destination for copy
+ * lpUnknown [I] Source for copy
+ *
+ * RETURNS
+ * Nothing.
+ */
+VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
+{
+ TRACE("(%p,%p)\n", lppDest, lpUnknown);
+
+ if (lppDest)
+ IUnknown_AtomicRelease(lppDest); /* Release existing interface */
+
+ if (lpUnknown)
+ {
+ /* Copy */
+ IUnknown_AddRef(lpUnknown);
+ *lppDest = lpUnknown;
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.200]
+ *
+ */
+HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
+ REFGUID riidCmdGrp, ULONG cCmds,
+ OLECMD *prgCmds, OLECMDTEXT* pCmdText)
+{
+ FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",
+ lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
+
+ /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
+ return DRAGDROP_E_NOTREGISTERED;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.201]
+ *
+ */
+HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
+ DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
+ VARIANT* pvaOut)
+{
+ FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
+ nCmdID, nCmdexecopt, pvaIn, pvaOut);
+ return DRAGDROP_E_NOTREGISTERED;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.202]
+ *
+ */
+HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
+{
+ FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
+ return DRAGDROP_E_NOTREGISTERED;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.204]
+ *
+ * Determine if a window is not a child of another window.
+ *
+ * PARAMS
+ * hParent [I] Suspected parent window
+ * hChild [I] Suspected child window
+ *
+ * RETURNS
+ * TRUE: If hChild is a child window of hParent
+ * FALSE: If hChild is not a child window of hParent, or they are equal
+ */
+BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
+{
+ TRACE("(%p,%p)\n", hParent, hChild);
+
+ if (!hParent || !hChild)
+ return TRUE;
+ else if(hParent == hChild)
+ return FALSE;
+ return !IsChild(hParent, hChild);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.208]
+ *
+ * Some sort of memory management process.
+ */
+DWORD WINAPI FDSA_Initialize(
+ DWORD a,
+ DWORD b,
+ LPVOID c,
+ LPVOID d,
+ DWORD e)
+{
+ FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
+ a, b, c, d, e);
+ return 1;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.209]
+ *
+ * Some sort of memory management process.
+ */
+DWORD WINAPI FDSA_Destroy(
+ LPVOID a)
+{
+ FIXME("(%p) stub\n",
+ a);
+ return 1;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.210]
+ *
+ * Some sort of memory management process.
+ */
+DWORD WINAPI FDSA_InsertItem(
+ LPVOID a,
+ DWORD b,
+ LPVOID c)
+{
+ FIXME("(%p 0x%08lx %p) stub\n",
+ a, b, c);
+ return 0;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.211]
+ */
+DWORD WINAPI FDSA_DeleteItem(
+ LPVOID a,
+ DWORD b)
+{
+ FIXME("(%p 0x%08lx) stub\n",
+ a, b);
+ return 1;
+}
+
+typedef struct {
+ REFIID refid;
+ DWORD indx;
+} IFACE_INDEX_TBL;
+
+/*************************************************************************
+ * @ [SHLWAPI.219]
+ *
+ * Call IUnknown_QueryInterface() on a table of objects.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * 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 */
+ REFIID riid, /* [in] REFIID to get interface for */
+ LPVOID *ppv) /* [out] Destination for interface pointer */
+{
+ HRESULT ret;
+ IUnknown *a_vtbl;
+ IFACE_INDEX_TBL *xmove;
+
+ TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
+ if (ppv) {
+ xmove = x;
+ while (xmove->refid) {
+ TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
+ if (IsEqualIID(riid, xmove->refid)) {
+ a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
+ TRACE("matched, returning (%p)\n", a_vtbl);
+ *ppv = (LPVOID)a_vtbl;
+ IUnknown_AddRef(a_vtbl);
+ return S_OK;
+ }
+ xmove++;
+ }
+
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
+ TRACE("returning first for IUnknown (%p)\n", a_vtbl);
+ *ppv = (LPVOID)a_vtbl;
+ IUnknown_AddRef(a_vtbl);
+ return S_OK;
+ }
+ *ppv = 0;
+ ret = E_NOINTERFACE;
+ } else
+ ret = E_POINTER;
+
+ TRACE("-- 0x%08lx\n", ret);
+ return ret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.221]
+ *
+ * Remove the "PropDlgFont" property from a window.
+ *
+ * PARAMS
+ * hWnd [I] Window to remove the property from
+ *
+ * RETURNS
+ * A handle to the removed property, or NULL if it did not exist.
+ */
+HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
+{
+ HANDLE hProp;
+
+ TRACE("(%p)\n", hWnd);
+
+ hProp = GetPropA(hWnd, "PropDlgFont");
+
+ if(hProp)
+ {
+ DeleteObject(hProp);
+ hProp = RemovePropA(hWnd, "PropDlgFont");
+ }
+ return hProp;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.236]
+ *
+ * Load the in-process server of a given GUID.
+ *
+ * PARAMS
+ * refiid [I] GUID of the server to load.
+ *
+ * RETURNS
+ * Success: A handle to the loaded server dll.
+ * Failure: A NULL handle.
+ */
+HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
+{
+ HKEY newkey;
+ DWORD type, count;
+ CHAR value[MAX_PATH], string[MAX_PATH];
+
+ strcpy(string, "CLSID\\");
+ SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
+ strcat(string, "\\InProcServer32");
+
+ count = MAX_PATH;
+ RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
+ RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
+ RegCloseKey(newkey);
+ return LoadLibraryExA(value, 0, 0);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.237]
+ *
+ * Unicode version of SHLWAPI_183.
+ */
+DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
+{
+ WNDCLASSW WndClass;
+
+ TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
+
+ if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
+ return TRUE;
+ return RegisterClassW(lpWndClass);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.238]
+ *
+ * Unregister a list of classes.
+ *
+ * PARAMS
+ * hInst [I] Application instance that registered the classes
+ * lppClasses [I] List of class names
+ * iCount [I] Number of names in lppClasses
+ *
+ * RETURNS
+ * Nothing.
+ */
+void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
+{
+ WNDCLASSA WndClass;
+
+ TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
+
+ while (iCount > 0)
+ {
+ if (GetClassInfoA(hInst, *lppClasses, &WndClass))
+ UnregisterClassA(*lppClasses, hInst);
+ lppClasses++;
+ iCount--;
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.239]
+ *
+ * Unicode version of SHUnregisterClassesA.
+ */
+void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
+{
+ WNDCLASSW WndClass;
+
+ TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
+
+ while (iCount > 0)
+ {
+ if (GetClassInfoW(hInst, *lppClasses, &WndClass))
+ UnregisterClassW(*lppClasses, hInst);
+ lppClasses++;
+ iCount--;
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.240]
+ *
+ * Call The correct (Ascii/Unicode) default window procedure for a window.
+ *
+ * PARAMS
+ * hWnd [I] Window to call the default procedure for
+ * uMessage [I] Message ID
+ * wParam [I] WPARAM of message
+ * lParam [I] LPARAM of message
+ *
+ * RETURNS
+ * The result of calling DefWindowProcA() or DefWindowProcW().
+ */
+LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
+{
+ if (IsWindowUnicode(hWnd))
+ return DefWindowProcW(hWnd, uMessage, wParam, lParam);
+ return DefWindowProcA(hWnd, uMessage, wParam, lParam);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.256]
+ */
+HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
+{
+ HRESULT hRet = E_INVALIDARG;
+ LPOBJECTWITHSITE lpSite = NULL;
+
+ TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
+
+ if (lpUnknown && iid && lppSite)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
+ (void**)&lpSite);
+ if (SUCCEEDED(hRet) && lpSite)
+ {
+ hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
+ IObjectWithSite_Release(lpSite);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.257]
+ *
+ * Create a worker window using CreateWindowExA().
+ *
+ * PARAMS
+ * wndProc [I] Window procedure
+ * hWndParent [I] Parent window
+ * dwExStyle [I] Extra style flags
+ * dwStyle [I] Style flags
+ * hMenu [I] Window menu
+ * z [I] Unknown
+ *
+ * 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)
+{
+ static const char* szClass = "WorkerA";
+ WNDCLASSA wc;
+ HWND hWnd;
+
+ TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
+ wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+
+ /* Create Window class */
+ wc.style = 0;
+ wc.lpfnWndProc = DefWindowProcA;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 4;
+ wc.hInstance = shlwapi_hInstance;
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = szClass;
+
+ SHRegisterClassA(&wc); /* Register class */
+
+ /* FIXME: Set extra bits in dwExStyle */
+
+ hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
+ hWndParent, hMenu, shlwapi_hInstance, 0);
+ if (hWnd)
+ {
+ SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
+
+ if (wndProc)
+ SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
+ }
+ return hWnd;
+}
+
+typedef struct tagPOLICYDATA
+{
+ DWORD policy; /* flags value passed to SHRestricted */
+ LPCWSTR appstr; /* application str such as "Explorer" */
+ LPCWSTR keystr; /* name of the actual registry key / policy */
+} POLICYDATA, *LPPOLICYDATA;
+
+#define SHELL_NO_POLICY 0xffffffff
+
+/* default shell policy registry key */
+static const WCHAR strRegistryPolicyW[] = {'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',
+ '\\','P','o','l','i','c','i','e','s',0};
+
+/*************************************************************************
+ * @ [SHLWAPI.271]
+ *
+ * Retrieve a policy value from the registry.
+ *
+ * PARAMS
+ * lpSubKey [I] registry key name
+ * lpSubName [I] subname of registry key
+ * lpValue [I] value name of registry value
+ *
+ * RETURNS
+ * the value associated with the registry key or 0 if not found
+ */
+DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
+{
+ DWORD retval, datsize = sizeof(retval);
+ HKEY hKey;
+
+ if (!lpSubKey)
+ lpSubKey = strRegistryPolicyW;
+
+ retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
+ if (retval != ERROR_SUCCESS)
+ retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
+ if (retval != ERROR_SUCCESS)
+ return 0;
+
+ SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
+ RegCloseKey(hKey);
+ return retval;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.266]
+ *
+ * Helper function to retrieve the possibly cached value for a specific policy
+ *
+ * PARAMS
+ * policy [I] The policy to look for
+ * initial [I] Main registry key to open, if NULL use default
+ * polTable [I] Table of known policies, 0 terminated
+ * polArr [I] Cache array of policy values
+ *
+ * RETURNS
+ * The retrieved policy value or 0 if not successful
+ *
+ * NOTES
+ * This function is used by the native SHRestricted function to search for the
+ * policy and cache it once retrieved. The current Wine implementation uses a
+ * different POLICYDATA structure and implements a similar algorithme adapted to
+ * that structure.
+ */
+DWORD WINAPI SHRestrictionLookup(
+ DWORD policy,
+ LPCWSTR initial,
+ LPPOLICYDATA polTable,
+ LPDWORD polArr)
+{
+ TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
+
+ if (!polTable || !polArr)
+ return 0;
+
+ for (;polTable->policy; polTable++, polArr++)
+ {
+ if (policy == polTable->policy)
+ {
+ /* we have a known policy */
+
+ /* check if this policy has been cached */
+ if (*polArr == SHELL_NO_POLICY)
+ *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
+ return *polArr;
+ }
+ }
+ /* we don't know this policy, return 0 */
+ TRACE("unknown policy: (%08lx)\n", policy);
+ return 0;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.267]
+ *
+ * Get an interface from an object.
+ *
+ * RETURNS
+ * Success: S_OK. ppv contains the requested interface.
+ * Failure: An HRESULT error code.
+ *
+ * NOTES
+ * This QueryInterface asks the inner object for an interface. In case
+ * of aggregation this request would be forwarded by the inner to the
+ * outer object. This function asks the inner object directly for the
+ * interface circumventing the forwarding to the outer object.
+ */
+HRESULT WINAPI SHWeakQueryInterface(
+ IUnknown * pUnk, /* [in] Outer object */
+ IUnknown * pInner, /* [in] Inner object */
+ IID * riid, /* [in] Interface GUID to query for */
+ LPVOID* ppv) /* [out] Destination for queried interface */
+{
+ HRESULT hret = E_NOINTERFACE;
+ TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+ if(pUnk && pInner) {
+ hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
+ if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
+ }
+ TRACE("-- 0x%08lx\n", hret);
+ return hret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.268]
+ *
+ * Move a reference from one interface to another.
+ *
+ * PARAMS
+ * lpDest [O] Destination to receive the reference
+ * lppUnknown [O] Source to give up the reference to lpDest
+ *
+ * RETURNS
+ * Nothing.
+ */
+VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
+{
+ TRACE("(%p,%p)\n", lpDest, lppUnknown);
+
+ if (*lppUnknown)
+ {
+ /* Copy Reference*/
+ IUnknown_AddRef(lpDest);
+ IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.269]
+ *
+ * Convert an ASCII string of a CLSID into a CLSID.
+ *
+ * PARAMS
+ * idstr [I] String representing a CLSID in registry format
+ * id [O] Destination for the converted CLSID
+ *
+ * RETURNS
+ * Success: TRUE. id contains the converted CLSID.
+ * Failure: FALSE.
+ */
+BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
+{
+ WCHAR wClsid[40];
+ MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
+ return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.270]
+ *
+ * Unicode version of GUIDFromStringA.
+ */
+BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
+{
+ return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.276]
+ *
+ * Determine if the browser is integrated into the shell, and set a registry
+ * key accordingly.
+ *
+ * PARAMS
+ * None.
+ *
+ * RETURNS
+ * 1, If the browser is not integrated.
+ * 2, If the browser is integrated.
+ *
+ * NOTES
+ * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
+ * either set to TRUE, or removed depending on whether the browser is deemed
+ * to be integrated.
+ */
+DWORD WINAPI WhichPlatform()
+{
+ static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
+ static DWORD dwState = 0;
+ HKEY hKey;
+ DWORD dwRet, dwData, dwSize;
+
+ if (dwState)
+ return dwState;
+
+ /* If shell32 exports DllGetVersion(), the browser is integrated */
+ GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
+ dwState = pDllGetVersion ? 2 : 1;
+
+ /* Set or delete the key accordingly */
+ dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Internet Explorer", 0,
+ KEY_ALL_ACCESS, &hKey);
+ if (!dwRet)
+ {
+ dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
+ (LPBYTE)&dwData, &dwSize);
+
+ if (!dwRet && dwState == 1)
+ {
+ /* Value exists but browser is not integrated */
+ RegDeleteValueA(hKey, szIntegratedBrowser);
+ }
+ else if (dwRet && dwState == 2)
+ {
+ /* Browser is integrated but value does not exist */
+ dwData = TRUE;
+ RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
+ (LPBYTE)&dwData, sizeof(dwData));
+ }
+ RegCloseKey(hKey);
+ }
+ return dwState;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.278]
+ *
+ * Unicode version of SHCreateWorkerWindowA.
+ */
+HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
+ DWORD dwStyle, HMENU hMenu, LONG z)
+{
+ static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
+ WNDCLASSW wc;
+ HWND hWnd;
+
+ TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
+ wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+
+ /* If our OS is natively ASCII, use the ASCII version */
+ if (!(GetVersion() & 0x80000000)) /* NT */
+ return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+
+ /* Create Window class */
+ wc.style = 0;
+ wc.lpfnWndProc = DefWindowProcW;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 4;
+ wc.hInstance = shlwapi_hInstance;
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = szClass;
+
+ SHRegisterClassW(&wc); /* Register class */
+
+ /* FIXME: Set extra bits in dwExStyle */
+
+ hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
+ hWndParent, hMenu, shlwapi_hInstance, 0);
+ if (hWnd)
+ {
+ SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
+
+ if (wndProc)
+ SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
+ }
+ return hWnd;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.279]
+ *
+ * Get and show a context menu from a shell folder.
+ *
+ * PARAMS
+ * hWnd [I] Window displaying the shell folder
+ * lpFolder [I] IShellFolder interface
+ * lpApidl [I] Id for the particular folder desired
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
+ */
+HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
+{
+ return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.281]
+ *
+ * _SHPackDispParamsV
+ */
+HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
+{
+ FIXME("%p %p %p %p\n",w,x,y,z);
+ return E_FAIL;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.282]
+ *
+ * This function seems to be a forward to SHPackDispParamsV (whatever THAT
+ * function does...).
+ */
+HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
+{
+ FIXME("%p %p %p %p\n", w, x, y, z);
+ return E_FAIL;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.284]
+ *
+ * _IConnectionPoint_SimpleInvoke
+ */
+DWORD WINAPI IConnectionPoint_SimpleInvoke(
+ LPVOID x,
+ LPVOID y,
+ LPVOID z)
+{
+ FIXME("(%p %p %p) stub\n",x,y,z);
+ return 0;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.285]
+ *
+ * Notify an IConnectionPoint object of changes.
+ *
+ * PARAMS
+ * lpCP [I] Object to notify
+ * dispID [I]
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
+ * IConnectionPoint interface.
+ */
+HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
+{
+ IEnumConnections *lpEnum;
+ HRESULT hRet = E_NOINTERFACE;
+
+ TRACE("(%p,0x%8lX)\n", lpCP, dispID);
+
+ /* Get an enumerator for the connections */
+ if (lpCP)
+ hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
+
+ if (SUCCEEDED(hRet))
+ {
+ IPropertyNotifySink *lpSink;
+ CONNECTDATA connData;
+ ULONG ulFetched;
+
+ /* Call OnChanged() for every notify sink in the connection point */
+ while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
+ {
+ if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
+ lpSink)
+ {
+ IPropertyNotifySink_OnChanged(lpSink, dispID);
+ IPropertyNotifySink_Release(lpSink);
+ }
+ IUnknown_Release(connData.pUnk);
+ }
+
+ IEnumConnections_Release(lpEnum);
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.287]
+ *
+ * Notify an IConnectionPointContainer object of changes.
+ *
+ * PARAMS
+ * lpUnknown [I] Object to notify
+ * dispID [I]
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
+ * IConnectionPointContainer interface.
+ */
+HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
+{
+ IConnectionPointContainer* lpCPC = NULL;
+ HRESULT hRet = E_NOINTERFACE;
+
+ TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
+
+ if (lpUnknown)
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
+
+ if (SUCCEEDED(hRet))
+ {
+ IConnectionPoint* lpCP;
+
+ hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
+ IConnectionPointContainer_Release(lpCPC);
+
+ hRet = IConnectionPoint_OnChanged(lpCP, dispID);
+ IConnectionPoint_Release(lpCP);
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.289]
+ *
+ * See PlaySoundW.
+ */
+BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
+{
+ GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
+ return pPlaySoundW(pszSound, hmod, fdwSound);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.294]
+ */
+BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
+{
+ /*
+ * str1: "I" "I" pushl esp+0x20
+ * str2: "U" "I" pushl 0x77c93810
+ * (is "I" and "U" "integer" and "unsigned" ??)
+ *
+ * pStr: "" "" pushl eax
+ * some_len: 0x824 0x104 pushl 0x824
+ * lpStr2: "%l" "%l" pushl esp+0xc
+ *
+ * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
+ * LocalAlloc(0x00, some_len) -> irrelevant_var
+ * LocalAlloc(0x40, irrelevant_len) -> pStr
+ * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
+ * shlwapi.PathRemoveBlanksW(pStr);
+ */
+ FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.295]
+ *
+ * Called by ICQ2000b install via SHDOCVW:
+ * str1: "InternetShortcut"
+ * x: some unknown pointer
+ * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
+ * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
+ *
+ * In short: this one maybe creates a desktop link :-)
+ */
+BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
+{
+ FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.299]
+ *
+ * See COMCTL32_417.
+ */
+BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
+ LPCWSTR str, UINT count, const INT *lpDx)
+{
+ GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
+ return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.313]
+ *
+ * See SHGetFileInfoW.
+ */
+DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
+ SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
+{
+ GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
+ return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.318]
+ *
+ * See DragQueryFileW.
+ */
+UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
+{
+ GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
+ return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.333]
+ *
+ * See SHBrowseForFolderW.
+ */
+LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
+{
+ GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
+ return pSHBrowseForFolderW(lpBi);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.334]
+ *
+ * See SHGetPathFromIDListW.
+ */
+BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
+{
+ GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
+ return pSHGetPathFromIDListW(pidl, pszPath);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.335]
+ *
+ * See ShellExecuteExW.
+ */
+BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
+{
+ GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
+ return pShellExecuteExW(lpExecInfo);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.336]
+ *
+ * See SHFileOperationW.
+ */
+HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
+{
+ GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
+ return pSHFileOperationW(lpFileOp);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.337]
+ *
+ * See ExtractIconExW.
+ */
+UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
+ HICON *phiconSmall, UINT nIcons)
+{
+ GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
+ return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.342]
+ *
+ */
+LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
+{
+ return InterlockedCompareExchange(dest, xchg, compare);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.350]
+ *
+ * See GetFileVersionInfoSizeW.
+ */
+DWORD WINAPI GetFileVersionInfoSizeWrapW(
+ LPWSTR x,
+ LPVOID y)
+{
+ DWORD ret;
+
+ GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
+ ret = pGetFileVersionInfoSizeW(x, y);
+ return 0x208 + ret;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.351]
+ *
+ * See GetFileVersionInfoW.
+ */
+BOOL WINAPI GetFileVersionInfoWrapW(
+ LPWSTR w, /* [in] path to dll */
+ DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
+ DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
+ LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
+{
+ GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
+ return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.352]
+ *
+ * See VerQueryValueW.
+ */
+WORD WINAPI VerQueryValueWrapW(
+ LPVOID w, /* [in] Buffer from SHLWAPI_351() */
+ LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
+ LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
+ UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
+{
+ GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
+ return pVerQueryValueW((char*)w+0x208, x, y, z);
+}
+
+#define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
+#define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
+#define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
+
+/*************************************************************************
+ * @ [SHLWAPI.355]
+ *
+ * Change the modality of a shell object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object to make modeless
+ * bModeless [I] TRUE=Make modeless, FALSE=Make modal
+ *
+ * RETURNS
+ * Success: S_OK. The modality lpUnknown is changed.
+ * Failure: An HRESULT error code indicating the error.
+ *
+ * NOTES
+ * lpUnknown must support the IOleInPlaceFrame interface, the
+ * IInternetSecurityMgrSite interface, the IShellBrowser interface
+ * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
+ * or this call will fail.
+ */
+HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
+{
+ IUnknown *lpObj;
+ HRESULT hRet;
+
+ TRACE("(%p,%d)\n", lpUnknown, bModeless);
+
+ if (!lpUnknown)
+ return E_FAIL;
+
+ if (IsIface(IOleInPlaceActiveObject))
+ EnableModeless(IOleInPlaceActiveObject);
+ else if (IsIface(IOleInPlaceFrame))
+ EnableModeless(IOleInPlaceFrame);
+ else if (IsIface(IShellBrowser))
+ EnableModeless(IShellBrowser);
+#if 0
+ /* FIXME: Wine has no headers for these objects yet */
+ else if (IsIface(IInternetSecurityMgrSite))
+ EnableModeless(IInternetSecurityMgrSite);
+ else if (IsIface(IDocHostUIHandler))
+ EnableModeless(IDocHostUIHandler);
+#endif
+ else
+ return hRet;
+
+ IUnknown_Release(lpObj);
+ return S_OK;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.357]
+ *
+ * See SHGetNewLinkInfoW.
+ */
+BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
+ BOOL *pfMustCopy, UINT uFlags)
+{
+ GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
+ return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.358]
+ *
+ * See SHDefExtractIconW.
+ */
+UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
+ HICON* phiconSmall, UINT nIconSize)
+{
+ GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
+ return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.363]
+ *
+ * Get and show a context menu from a shell folder.
+ *
+ * PARAMS
+ * hWnd [I] Window displaying the shell folder
+ * lpFolder [I] IShellFolder interface
+ * lpApidl [I] Id for the particular folder desired
+ * bInvokeDefault [I] Whether to invoke the default menu item
+ *
+ * RETURNS
+ * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
+ * executed.
+ * Failure: An HRESULT error code indicating the error.
+ */
+HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
+{
+ IContextMenu *iContext;
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
+
+ if (!lpFolder)
+ return hRet;
+
+ /* Get the context menu from the shell folder */
+ hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
+ &IID_IContextMenu, 0, (void**)&iContext);
+ if (SUCCEEDED(hRet))
+ {
+ HMENU hMenu;
+ if ((hMenu = CreatePopupMenu()))
+ {
+ HRESULT hQuery;
+ DWORD dwDefaultId = 0;
+
+ /* Add the context menu entries to the popup */
+ hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
+ bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
+
+ if (SUCCEEDED(hQuery))
+ {
+ if (bInvokeDefault &&
+ (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
+ {
+ CMINVOKECOMMANDINFO cmIci;
+ /* Invoke the default item */
+ memset(&cmIci,0,sizeof(cmIci));
+ cmIci.cbSize = sizeof(cmIci);
+ cmIci.fMask = CMIC_MASK_ASYNCOK;
+ cmIci.hwnd = hWnd;
+ cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
+ cmIci.nShow = SW_SCROLLCHILDREN;
+
+ hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
+ }
+ }
+ DestroyMenu(hMenu);
+ }
+ IContextMenu_Release(iContext);
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.370]
+ *
+ * See ExtractIconW.
+ */
+HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
+ UINT nIconIndex)
+{
+ GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
+ return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.376]
+ */
+LANGID WINAPI MLGetUILanguage()
+{
+ FIXME("() stub\n");
+ /* FIXME: This should be a forward in the .spec file to the win2k function
+ * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
+ */
+ return GetUserDefaultLangID();
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.377]
+ *
+ * Load a library from the directory of a particular process.
+ *
+ * PARAMS
+ * new_mod [I] Library name
+ * inst_hwnd [I] Module whose directory is to be used
+ * dwFlags [I] Flags controlling the load
+ *
+ * RETURNS
+ * Success: A handle to the loaded module
+ * Failure: A NULL handle.
+ */
+HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
+{
+ /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
+ * each call here.
+ * FIXME: Native shows calls to:
+ * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
+ * CheckVersion
+ * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
+ * RegQueryValueExA for "LPKInstalled"
+ * RegCloseKey
+ * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
+ * RegQueryValueExA for "ResourceLocale"
+ * RegCloseKey
+ * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
+ * RegQueryValueExA for "Locale"
+ * RegCloseKey
+ * and then tests the Locale ("en" for me).
+ * code below
+ * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
+ */
+ CHAR mod_path[2*MAX_PATH];
+ LPSTR ptr;
+ DWORD len;
+
+ FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
+ len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
+ if (!len || len >= sizeof(mod_path)) return NULL;
+
+ ptr = strrchr(mod_path, '\\');
+ if (ptr) {
+ strcpy(ptr+1, new_mod);
+ TRACE("loading %s\n", debugstr_a(mod_path));
+ return LoadLibraryA(mod_path);
+ }
+ return NULL;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.378]
+ *
+ * Unicode version of MLLoadLibraryA.
+ */
+HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
+{
+ WCHAR mod_path[2*MAX_PATH];
+ LPWSTR ptr;
+ DWORD len;
+
+ FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
+ len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
+ if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
+
+ ptr = strrchrW(mod_path, '\\');
+ if (ptr) {
+ strcpyW(ptr+1, new_mod);
+ TRACE("loading %s\n", debugstr_w(mod_path));
+ return LoadLibraryW(mod_path);
+ }
+ return NULL;
+}
+
+/*************************************************************************
+ * ColorAdjustLuma [SHLWAPI.@]
+ *
+ * Adjust the luminosity of a color
+ *
+ * PARAMS
+ * cRGB [I] RGB value to convert
+ * dwLuma [I] Luma adjustment
+ * bUnknown [I] Unknown
+ *
+ * RETURNS
+ * The adjusted RGB color.
+ */
+COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
+{
+ TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
+
+ if (dwLuma)
+ {
+ WORD wH, wL, wS;
+
+ ColorRGBToHLS(cRGB, &wH, &wL, &wS);
+
+ FIXME("Ignoring luma adjustment\n");
+
+ /* FIXME: The ajdustment is not linear */
+
+ cRGB = ColorHLSToRGB(wH, wL, wS);
+ }
+ return cRGB;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.389]
+ *
+ * See GetSaveFileNameW.
+ */
+BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
+{
+ GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
+ return pGetSaveFileNameW(ofn);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.390]
+ *
+ * See WNetRestoreConnectionW.
+ */
+DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
+{
+ GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
+ return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.391]
+ *
+ * See WNetGetLastErrorW.
+ */
+DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
+ LPWSTR lpNameBuf, DWORD nNameBufSize)
+{
+ GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
+ return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.401]
+ *
+ * See PageSetupDlgW.
+ */
+BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
+{
+ GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
+ return pPageSetupDlgW(pagedlg);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.402]
+ *
+ * See PrintDlgW.
+ */
+BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
+{
+ GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
+ return pPrintDlgW(printdlg);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.403]
+ *
+ * See GetOpenFileNameW.
+ */
+BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
+{
+ GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
+ return pGetOpenFileNameW(ofn);
+}
+
+/* INTERNAL: Map from HLS color space to RGB */
+static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
+{
+ wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
+
+ if (wHue > 160)
+ return wMid1;
+ else if (wHue > 120)
+ wHue = 160 - wHue;
+ else if (wHue > 40)
+ return wMid2;
+
+ return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
+}
+
+/* Convert to RGB and scale into RGB range (0..255) */
+#define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
+
+/*************************************************************************
+ * ColorHLSToRGB [SHLWAPI.@]
+ *
+ * Convert from hls color space into an rgb COLORREF.
+ *
+ * PARAMS
+ * wHue [I] Hue amount
+ * wLuminosity [I] Luminosity amount
+ * wSaturation [I] Saturation amount
+ *
+ * RETURNS
+ * A COLORREF representing the converted color.
+ *
+ * NOTES
+ * Input hls values are constrained to the range (0..240).
+ */
+COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
+{
+ WORD wRed;
+
+ if (wSaturation)
+ {
+ WORD wGreen, wBlue, wMid1, wMid2;
+
+ if (wLuminosity > 120)
+ wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
+ else
+ wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
+
+ wMid1 = wLuminosity * 2 - wMid2;
+
+ wRed = GET_RGB(wHue + 80);
+ wGreen = GET_RGB(wHue);
+ wBlue = GET_RGB(wHue - 80);
+
+ return RGB(wRed, wGreen, wBlue);
+ }
+
+ wRed = wLuminosity * 255 / 240;
+ return RGB(wRed, wRed, wRed);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.413]
+ *
+ * Get the current docking status of the system.
+ *
+ * PARAMS
+ * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
+ *
+ * RETURNS
+ * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
+ * a notebook.
+ */
+DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
+{
+ HW_PROFILE_INFOA hwInfo;
+
+ TRACE("(0x%08lx)\n", dwFlags);
+
+ GetCurrentHwProfileA(&hwInfo);
+ switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
+ {
+ case DOCKINFO_DOCKED:
+ case DOCKINFO_UNDOCKED:
+ return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
+ default:
+ return 0;
+ }
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.418]
+ *
+ * Function seems to do FreeLibrary plus other things.
+ *
+ * FIXME native shows the following calls:
+ * RtlEnterCriticalSection
+ * LocalFree
+ * GetProcAddress(Comctl32??, 150L)
+ * DPA_DeletePtr
+ * RtlLeaveCriticalSection
+ * followed by the FreeLibrary.
+ * The above code may be related to .377 above.
+ */
+BOOL WINAPI MLFreeLibrary(HMODULE hModule)
+{
+ FIXME("(%p) semi-stub\n", hModule);
+ return FreeLibrary(hModule);
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.419]
+ */
+BOOL WINAPI SHFlushSFCacheWrap(void) {
+ FIXME(": stub\n");
+ return TRUE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.429]
+ * FIXME I have no idea what this function does or what its arguments are.
+ */
+BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
+{
+ FIXME("(%p) stub\n", hInst);
+ return FALSE;
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.430]
+ */
+DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
+{
+ FIXME("(%p,%p) stub\n", hInst, hHeap);
+ return E_FAIL; /* This is what is used if shlwapi not loaded */
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.431]
+ */
+DWORD WINAPI MLClearMLHInstance(DWORD x)
+{
+ FIXME("(0x%08lx)stub\n", x);
+ return 0xabba1247;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.436]
+ *
+ * Convert an Unicode string CLSID into a CLSID.
+ *
+ * PARAMS
+ * idstr [I] string containing a CLSID in text form
+ * id [O] CLSID extracted from the string
+ *
+ * RETURNS
+ * S_OK on success or E_INVALIDARG on failure
+ *
+ * NOTES
+ * This is really CLSIDFromString() which is exported by ole32.dll,
+ * however the native shlwapi.dll does *not* import ole32. Nor does
+ * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
+ * that MS duplicated the code for CLSIDFromString(), and yes they did, only
+ * it returns an E_INVALIDARG error code on failure.
+ * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
+ * in "dlls/ole32/compobj.c".
+ */
+HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
+{
+ LPCWSTR s = idstr;
+ BYTE *p;
+ INT i;
+ WCHAR table[256];
+
+ if (!s) {
+ memset(id, 0, sizeof(CLSID));
+ return S_OK;
+ }
+ else { /* validate the CLSID string */
+
+ if (strlenW(s) != 38)
+ return E_INVALIDARG;
+
+ if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
+ return E_INVALIDARG;
+
+ for (i=1; i<37; i++)
+ {
+ if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
+ continue;
+ if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
+ ((s[i] >= L'a') && (s[i] <= L'f')) ||
+ ((s[i] >= L'A') && (s[i] <= L'F')))
+ )
+ return E_INVALIDARG;
+ }
+ }
+
+ TRACE("%s -> %p\n", debugstr_w(s), id);
+
+ /* quick lookup table */
+ memset(table, 0, 256*sizeof(WCHAR));
+
+ for (i = 0; i < 10; i++) {
+ table['0' + i] = i;
+ }
+ for (i = 0; i < 6; i++) {
+ table['A' + i] = i+10;
+ table['a' + i] = i+10;
+ }
+
+ /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
+
+ p = (BYTE *) id;
+
+ s++; /* skip leading brace */
+ for (i = 0; i < 4; i++) {
+ p[3 - i] = table[*s]<<4 | table[*(s+1)];
+ s += 2;
+ }
+ p += 4;
+ s++; /* skip - */
+
+ for (i = 0; i < 2; i++) {
+ p[1-i] = table[*s]<<4 | table[*(s+1)];
+ s += 2;
+ }
+ p += 2;
+ s++; /* skip - */
+
+ for (i = 0; i < 2; i++) {
+ p[1-i] = table[*s]<<4 | table[*(s+1)];
+ s += 2;
+ }
+ p += 2;
+ s++; /* skip - */
+
+ /* these are just sequential bytes */
+ for (i = 0; i < 2; i++) {
+ *p++ = table[*s]<<4 | table[*(s+1)];
+ s += 2;
+ }
+ s++; /* skip - */
+
+ for (i = 0; i < 6; i++) {
+ *p++ = table[*s]<<4 | table[*(s+1)];
+ s += 2;
+ }
+
+ return S_OK;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.437]
+ *
+ * Determine if the OS supports a given feature.
+ *
+ * PARAMS
+ * dwFeature [I] Feature requested (undocumented)
+ *
+ * RETURNS
+ * TRUE If the feature is available.
+ * FALSE If the feature is not available.
+ */
+BOOL WINAPI IsOS(DWORD feature)
+{
+ OSVERSIONINFOA osvi;
+ DWORD platform, majorv, minorv;
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+ if(!GetVersionExA(&osvi)) {
+ ERR("GetVersionEx failed");
+ return FALSE;
+ }
+
+ majorv = osvi.dwMajorVersion;
+ minorv = osvi.dwMinorVersion;
+ platform = osvi.dwPlatformId;
+
+#define ISOS_RETURN(x) \
+ TRACE("(0x%lx) ret=%d\n",feature,(x)); \
+ return (x);
+
+ switch(feature) {
+ case OS_WIN32SORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32s
+ || platform == VER_PLATFORM_WIN32_WINDOWS)
+ case OS_NT:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_WIN95ORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
+ case OS_NT4ORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
+ case OS_WIN2000ORGREATER_ALT:
+ case OS_WIN2000ORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
+ case OS_WIN98ORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
+ case OS_WIN98_GOLD:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
+ case OS_WIN2000PRO:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
+ case OS_WIN2000SERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
+ case OS_WIN2000ADVSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
+ case OS_WIN2000DATACENTER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
+ case OS_WIN2000TERMINAL:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
+ case OS_EMBEDDED:
+ FIXME("(OS_EMBEDDED) What should we return here?\n");
+ return FALSE;
+ case OS_TERMINALCLIENT:
+ FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
+ return FALSE;
+ case OS_TERMINALREMOTEADMIN:
+ FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
+ return FALSE;
+ case OS_WIN95_GOLD:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
+ case OS_MEORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
+ case OS_XPORGREATER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
+ case OS_HOME:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
+ case OS_PROFESSIONAL:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_DATACENTER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_ADVSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
+ case OS_SERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_TERMINALSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_PERSONALTERMINALSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
+ case OS_FASTUSERSWITCHING:
+ FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
+ return TRUE;
+ case OS_WELCOMELOGONUI:
+ FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
+ return FALSE;
+ case OS_DOMAINMEMBER:
+ FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
+ return TRUE;
+ case OS_ANYSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_WOW6432:
+ FIXME("(OS_WOW6432) Should we check this?\n");
+ return FALSE;
+ case OS_WEBSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_SMALLBUSINESSSERVER:
+ ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
+ case OS_TABLETPC:
+ FIXME("(OS_TABLEPC) What should we return here?\n");
+ return FALSE;
+ case OS_SERVERADMINUI:
+ FIXME("(OS_SERVERADMINUI) What should we return here?\n");
+ return FALSE;
+ case OS_MEDIACENTER:
+ FIXME("(OS_MEDIACENTER) What should we return here?\n");
+ return FALSE;
+ case OS_APPLIANCE:
+ FIXME("(OS_APPLIANCE) What should we return here?\n");
+ return FALSE;
+ }
+
+#undef ISOS_RETURN
+
+ WARN("(0x%lx) unknown parameter\n",feature);
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.478]
+ *
+ * Call IInputObject_TranslateAcceleratorIO() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IInputObject interface.
+ * lpMsg [I] Key message to be processed.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
+ */
+HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
+{
+ IInputObject* lpInput = NULL;
+ HRESULT hRet = E_INVALIDARG;
+
+ TRACE("(%p,%p)\n", lpUnknown, lpMsg);
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
+ (void**)&lpInput);
+ if (SUCCEEDED(hRet) && lpInput)
+ {
+ hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
+ IInputObject_Release(lpInput);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.481]
+ *
+ * Call IInputObject_HasFocusIO() on an object.
+ *
+ * PARAMS
+ * lpUnknown [I] Object supporting the IInputObject interface.
+ *
+ * RETURNS
+ * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
+ * or S_FALSE otherwise.
+ * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
+ */
+HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
+{
+ IInputObject* lpInput = NULL;
+ HRESULT hRet = E_INVALIDARG;
+
+ TRACE("(%p)\n", lpUnknown);
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
+ (void**)&lpInput);
+ if (SUCCEEDED(hRet) && lpInput)
+ {
+ hRet = IInputObject_HasFocusIO(lpInput);
+ IInputObject_Release(lpInput);
+ }
+ }
+ return hRet;
+}
+
+/*************************************************************************
+ * ColorRGBToHLS [SHLWAPI.@]
+ *
+ * Convert an rgb COLORREF into the hls color space.
+ *
+ * PARAMS
+ * cRGB [I] Source rgb value
+ * pwHue [O] Destination for converted hue
+ * pwLuminance [O] Destination for converted luminance
+ * pwSaturation [O] Destination for converted saturation
+ *
+ * RETURNS
+ * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
+ * values.
+ *
+ * NOTES
+ * Output HLS values are constrained to the range (0..240).
+ * For Achromatic conversions, Hue is set to 160.
+ */
+VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
+ LPWORD pwLuminance, LPWORD pwSaturation)
+{
+ int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
+
+ TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
+
+ wR = GetRValue(cRGB);
+ wG = GetGValue(cRGB);
+ wB = GetBValue(cRGB);
+
+ wMax = max(wR, max(wG, wB));
+ wMin = min(wR, min(wG, wB));
+
+ /* Luminosity */
+ wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
+
+ if (wMax == wMin)
+ {
+ /* Achromatic case */
+ wSaturation = 0;
+ /* Hue is now unrepresentable, but this is what native returns... */
+ wHue = 160;
+ }
+ else
+ {
+ /* Chromatic case */
+ int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
+
+ /* Saturation */
+ if (wLuminosity <= 120)
+ wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
+ else
+ wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
+
+ /* Hue */
+ wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
+ wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
+ wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
+
+ if (wR == wMax)
+ wHue = wBNorm - wGNorm;
+ else if (wG == wMax)
+ wHue = 80 + wRNorm - wBNorm;
+ else
+ wHue = 160 + wGNorm - wRNorm;
+ if (wHue < 0)
+ wHue += 240;
+ else if (wHue > 240)
+ wHue -= 240;
+ }
+ if (pwHue)
+ *pwHue = wHue;
+ if (pwLuminance)
+ *pwLuminance = wLuminosity;
+ if (pwSaturation)
+ *pwSaturation = wSaturation;
+}
+
+/*************************************************************************
+ * SHCreateShellPalette [SHLWAPI.@]
+ */
+HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
+{
+ FIXME("stub\n");
+ return CreateHalftonePalette(hdc);
+}
+
+/*************************************************************************
+ * SHGetInverseCMAP (SHLWAPI.@)
+ *
+ * Get an inverse color map table.
+ *
+ * PARAMS
+ * lpCmap [O] Destination for color map
+ * dwSize [I] Size of memory pointed to by lpCmap
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_POINTER, If lpCmap is invalid.
+ * E_INVALIDARG, If dwFlags is invalid
+ * E_OUTOFMEMORY, If there is no memory available
+ *
+ * NOTES
+ * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
+ * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
+ * internal CMap.
+ * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
+ * this DLL's internal CMap.
+ */
+HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
+{
+ if (dwSize == 4) {
+ FIXME(" - returning bogus address for SHGetInverseCMAP\n");
+ *dest = (DWORD)0xabba1249;
+ return 0;
+ }
+ FIXME("(%p, %#lx) stub\n", dest, dwSize);
+ return 0;
+}
+
+/*************************************************************************
+ * SHIsLowMemoryMachine [SHLWAPI.@]
+ *
+ * Determine if the current computer has low memory.
+ *
+ * PARAMS
+ * x [I] FIXME
+ *
+ * RETURNS
+ * TRUE if the users machine has 16 Megabytes of memory or less,
+ * FALSE otherwise.
+ */
+BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
+{
+ FIXME("(0x%08lx) stub\n", x);
+ return FALSE;
+}
+
+/*************************************************************************
+ * GetMenuPosFromID [SHLWAPI.@]
+ *
+ * Return the position of a menu item from its Id.
+ *
+ * PARAMS
+ * hMenu [I] Menu containing the item
+ * wID [I] Id of the menu item
+ *
+ * RETURNS
+ * Success: The index of the menu item in hMenu.
+ * Failure: -1, If the item is not found.
+ */
+INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
+{
+ MENUITEMINFOA mi;
+ INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+
+ while (nIter < nCount)
+ {
+ mi.wID = 0;
+ if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
+ return nIter;
+ nIter++;
+ }
+ return -1;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.179]
+ *
+ * Same as SHLWAPI.GetMenuPosFromID
+ */
+DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
+{
+ return GetMenuPosFromID(hMenu, uID);
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.448]
+ */
+VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
+{
+ while (*lpwstr)
+ {
+ if (*lpwstr == '/')
+ *lpwstr = '\\';
+ lpwstr++;
+ }
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.461]
+ */
+DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
+{
+ FIXME("(0x%08lx) stub\n", dwUnknown);
+ return 0;
+}
+
+
+/*************************************************************************
+ * @ [SHLWAPI.549]
+ */
+HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
+ DWORD dwClsContext, REFIID iid, LPVOID *ppv)
+{
+ return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
+}
+
+/*************************************************************************
+ * SHSkipJunction [SHLWAPI.@]
+ *
+ * Determine if a bind context can be bound to an object
+ *
+ * PARAMS
+ * pbc [I] Bind context to check
+ * pclsid [I] CLSID of object to be bound to
+ *
+ * RETURNS
+ * TRUE: If it is safe to bind
+ * FALSE: If pbc is invalid or binding would not be safe
+ *
+ */
+BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
+{
+ static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
+ 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
+ BOOL bRet = FALSE;
+
+ if (pbc)
+ {
+ IUnknown* lpUnk;
+
+ if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
+ {
+ CLSID clsid;
+
+ if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
+ IsEqualGUID(pclsid, &clsid))
+ bRet = TRUE;
+
+ IUnknown_Release(lpUnk);
+ }
+ }
+ return bRet;
+}
+
+/***********************************************************************
+ * SHGetShellKey (SHLWAPI.@)
+ */
+DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
+{
+ FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
+ return 0x50;
+}
+
+/***********************************************************************
+ * SHQueueUserWorkItem (SHLWAPI.@)
+ */
+HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
+{
+ FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
+ return E_FAIL;
+}
+
+/***********************************************************************
+ * IUnknown_OnFocusChangeIS (SHLWAPI.@)
+ */
+HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
+{
+ IInputObjectSite *pIOS = NULL;
+ HRESULT hRet = E_INVALIDARG;
+
+ TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
+
+ if (lpUnknown)
+ {
+ hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
+ (void **)&pIOS);
+ if (SUCCEEDED(hRet) && pIOS)
+ {
+ hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
+ IInputObjectSite_Release(pIOS);
+ }
+ }
+ return hRet;
+}
+
+/***********************************************************************
+ * SHGetValueW (SHLWAPI.@)
+ */
+HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
+{
+ FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
+ return E_FAIL;
+}
+
+typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
+
+/***********************************************************************
+ * GetUIVersion (SHLWAPI.452)
+ */
+DWORD WINAPI GetUIVersion(void)
+{
+ static DWORD version;
+
+ if (!version)
+ {
+ DllGetVersion_func pDllGetVersion;
+ HMODULE dll = LoadLibraryA("shell32.dll");
+ if (!dll) return 0;
+
+ pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
+ if (pDllGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ dvi.cbSize = sizeof(DLLVERSIONINFO);
+ if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
+ }
+ FreeLibrary( dll );
+ if (!version) version = 3; /* old shell dlls don't have DllGetVersion */
+ }
+ return version;
+}