2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
47 #include "wine/unicode.h"
49 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 /* Get a function pointer from a DLL handle */
56 #define GET_FUNC(func, module, name, fail) \
59 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
60 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
61 if (!func) return fail; \
65 /* DLL handles for late bound calls */
66 extern HINSTANCE shlwapi_hInstance;
67 extern HMODULE SHLWAPI_hshell32;
68 extern HMODULE SHLWAPI_hwinmm;
69 extern HMODULE SHLWAPI_hcomdlg32;
70 extern HMODULE SHLWAPI_hcomctl32;
71 extern HMODULE SHLWAPI_hmpr;
72 extern HMODULE SHLWAPI_hurlmon;
73 extern HMODULE SHLWAPI_hversion;
75 extern DWORD SHLWAPI_ThreadRef_index;
77 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
78 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
79 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
80 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
82 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
83 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
84 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
85 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
86 static fnpPlaySoundW pPlaySoundW;
87 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
88 static fnpSHGetFileInfoW pSHGetFileInfoW;
89 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
90 static fnpDragQueryFileW pDragQueryFileW;
91 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
92 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
93 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
94 static fnpShellExecuteExW pShellExecuteExW;
95 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
96 static fnpSHFileOperationW pSHFileOperationW;
97 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
98 static fnpExtractIconExW pExtractIconExW;
99 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
100 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
101 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
102 static fnpSHDefExtractIconW pSHDefExtractIconW;
103 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
104 static fnpExtractIconW pExtractIconW;
105 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
106 static fnpGetSaveFileNameW pGetSaveFileNameW;
107 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
108 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
109 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
110 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
111 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
112 static fnpPageSetupDlgW pPageSetupDlgW;
113 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
114 static fnpPrintDlgW pPrintDlgW;
115 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
116 static fnpGetOpenFileNameW pGetOpenFileNameW;
117 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
118 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
119 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
120 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
121 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
122 static fnpVerQueryValueW pVerQueryValueW;
123 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
124 static fnpCOMCTL32_417 pCOMCTL32_417;
125 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
126 static fnpDllGetVersion pDllGetVersion;
127 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
128 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
129 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
130 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
132 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
133 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
134 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
135 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
138 NOTES: Most functions exported by ordinal seem to be superflous.
139 The reason for these functions to be there is to provide a wrapper
140 for unicode functions to provide these functions on systems without
141 unicode functions eg. win95/win98. Since we have such functions we just
142 call these. If running Wine with native DLL's, some late bound calls may
143 fail. However, it is better to implement the functions in the forward DLL
144 and recommend the builtin rather than reimplementing the calls here!
147 /*************************************************************************
148 * SHLWAPI_DupSharedHandle
150 * Internal implemetation of SHLWAPI_11.
153 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
154 DWORD dwSrcProcId, DWORD dwAccess,
158 DWORD dwMyProcId = GetCurrentProcessId();
161 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
162 dwAccess, dwOptions);
164 /* Get dest process handle */
165 if (dwDstProcId == dwMyProcId)
166 hDst = GetCurrentProcess();
168 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
172 /* Get src process handle */
173 if (dwSrcProcId == dwMyProcId)
174 hSrc = GetCurrentProcess();
176 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
180 /* Make handle available to dest process */
181 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
182 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
185 if (dwSrcProcId != dwMyProcId)
189 if (dwDstProcId != dwMyProcId)
193 TRACE("Returning handle %p\n", hRet);
197 /*************************************************************************
200 * Create a block of sharable memory and initialise it with data.
203 * lpvData [I] Pointer to data to write
204 * dwSize [I] Size of data
205 * dwProcId [I] ID of process owning data
208 * Success: A shared memory handle
212 * Ordinals 7-11 provide a set of calls to create shared memory between a
213 * group of processes. The shared memory is treated opaquely in that its size
214 * is not exposed to clients who map it. This is accomplished by storing
215 * the size of the map as the first DWORD of mapped data, and then offsetting
216 * the view pointer returned by this size.
219 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
225 TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
227 /* Create file mapping of the correct length */
228 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
229 dwSize + sizeof(dwSize), NULL);
233 /* Get a view in our process address space */
234 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
238 /* Write size of data, followed by the data, to the view */
239 *((DWORD*)pMapped) = dwSize;
241 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
243 /* Release view. All further views mapped will be opaque */
244 UnmapViewOfFile(pMapped);
245 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
246 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
247 DUPLICATE_SAME_ACCESS);
254 /*************************************************************************
257 * Get a pointer to a block of shared memory from a shared memory handle.
260 * hShared [I] Shared memory handle
261 * dwProcId [I] ID of process owning hShared
264 * Success: A pointer to the shared memory
268 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
273 TRACE("(%p %ld)\n", hShared, dwProcId);
275 /* Get handle to shared memory for current process */
276 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
277 FILE_MAP_ALL_ACCESS, 0);
279 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
283 return (char *) pMapped + sizeof(DWORD); /* Hide size */
287 /*************************************************************************
290 * Release a pointer to a block of shared memory.
293 * lpView [I] Shared memory pointer
300 BOOL WINAPI SHUnlockShared(LPVOID lpView)
302 TRACE("(%p)\n", lpView);
303 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
306 /*************************************************************************
309 * Destroy a block of sharable memory.
312 * hShared [I] Shared memory handle
313 * dwProcId [I] ID of process owning hShared
320 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
324 TRACE("(%p %ld)\n", hShared, dwProcId);
326 /* Get a copy of the handle for our process, closing the source handle */
327 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
328 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
329 /* Close local copy */
330 return CloseHandle(hClose);
333 /*************************************************************************
336 * Copy a sharable memory handle from one process to another.
339 * hShared [I] Shared memory handle to duplicate
340 * dwDstProcId [I] ID of the process wanting the duplicated handle
341 * dwSrcProcId [I] ID of the process owning hShared
342 * dwAccess [I] Desired DuplicateHandle() access
343 * dwOptions [I] Desired DuplicateHandle() options
346 * Success: A handle suitable for use by the dwDstProcId process.
347 * Failure: A NULL handle.
350 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
351 DWORD dwAccess, DWORD dwOptions)
355 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
356 dwAccess, dwOptions);
360 /*************************************************************************
363 * Create and register a clipboard enumerator for a web browser.
366 * lpBC [I] Binding context
367 * lpUnknown [I] An object exposing the IWebBrowserApp interface
371 * Failure: An HRESULT error code.
374 * The enumerator is stored as a property of the web browser. If it does not
375 * yet exist, it is created and set before being registered.
377 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
379 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
380 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
381 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
382 IEnumFORMATETC* pIEnumFormatEtc = NULL;
385 IWebBrowserApp* pBrowser = NULL;
387 TRACE("(%p, %p)\n", lpBC, lpUnknown);
389 /* Get An IWebBrowserApp interface from lpUnknown */
390 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
391 if (FAILED(hRet) || !pBrowser)
392 return E_NOINTERFACE;
394 V_VT(&var) = VT_EMPTY;
396 /* The property we get is the browsers clipboard enumerator */
397 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
401 if (V_VT(&var) == VT_EMPTY)
403 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
404 char szKeyBuff[128], szValueBuff[128];
405 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
406 FORMATETC* formatList, *format;
409 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
411 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
412 "Version\\Internet Settings\\Accepted Documents", &hDocs))
415 /* Get count of values in key */
418 dwKeySize = sizeof(szKeyBuff);
419 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
423 dwNumValues = dwCount;
425 /* Note: dwCount = number of items + 1; The extra item is the end node */
426 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
428 return E_OUTOFMEMORY;
437 /* Register clipboard formats for the values and populate format list */
438 while(!dwRet && dwCount < dwNumValues)
440 dwKeySize = sizeof(szKeyBuff);
441 dwValueSize = sizeof(szValueBuff);
442 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
443 (PBYTE)szValueBuff, &dwValueSize);
447 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
449 format->dwAspect = 1;
458 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
459 format->cfFormat = 0;
461 format->dwAspect = 1;
465 /* Create a clipboard enumerator */
466 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
467 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
469 if (FAILED(hRet) || !pIEnumFormatEtc)
472 /* Set our enumerator as the browsers property */
473 V_VT(&var) = VT_UNKNOWN;
474 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
476 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
479 IEnumFORMATETC_Release(pIEnumFormatEtc);
480 goto RegisterDefaultAcceptHeaders_Exit;
484 if (V_VT(&var) == VT_UNKNOWN)
486 /* Our variant is holding the clipboard enumerator */
487 IUnknown* pIUnknown = V_UNKNOWN(&var);
488 IEnumFORMATETC* pClone = NULL;
490 TRACE("Retrieved IEnumFORMATETC property\n");
492 /* Get an IEnumFormatEtc interface from the variants value */
493 pIEnumFormatEtc = NULL;
494 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
495 (PVOID)&pIEnumFormatEtc);
496 if (!hRet && pIEnumFormatEtc)
498 /* Clone and register the enumerator */
499 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
502 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
503 pRegisterFormatEnumerator(lpBC, pClone, 0);
505 IEnumFORMATETC_Release(pClone);
508 /* Release the IEnumFormatEtc interface */
509 IEnumFORMATETC_Release(pIUnknown);
511 IUnknown_Release(V_UNKNOWN(&var));
514 RegisterDefaultAcceptHeaders_Exit:
515 IWebBrowserApp_Release(pBrowser);
519 /*************************************************************************
522 * Get Explorers "AcceptLanguage" setting.
525 * langbuf [O] Destination for language string
526 * buflen [I] Length of langbuf
527 * [0] Success: used length of langbuf
530 * Success: S_OK. langbuf is set to the language string found.
531 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
532 * does not contain the setting.
533 * E_INVALIDARG, If the buffer is not big enough
535 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
537 static const WCHAR szkeyW[] = {
538 'S','o','f','t','w','a','r','e','\\',
539 'M','i','c','r','o','s','o','f','t','\\',
540 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
541 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
542 static const WCHAR valueW[] = {
543 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
544 static const WCHAR enusW[] = {'e','n','-','u','s',0};
545 DWORD mystrlen, mytype;
551 if(!langbuf || !buflen || !*buflen)
554 mystrlen = (*buflen > 20) ? *buflen : 20 ;
555 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
556 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
557 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
558 /* Did not find value */
559 mylcid = GetUserDefaultLCID();
560 /* somehow the mylcid translates into "en-us"
561 * this is similar to "LOCALE_SABBREVLANGNAME"
562 * which could be gotten via GetLocaleInfo.
563 * The only problem is LOCALE_SABBREVLANGUAGE" is
564 * a 3 char string (first 2 are country code and third is
565 * letter for "sublanguage", which does not come close to
568 lstrcpyW(mystr, enusW);
569 mystrlen = lstrlenW(mystr);
571 /* handle returned string */
572 FIXME("missing code\n");
574 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
576 if(*buflen > strlenW(mystr)) {
577 *buflen = strlenW(mystr);
581 retval = E_INVALIDARG;
582 SetLastError(ERROR_INSUFFICIENT_BUFFER);
585 HeapFree(GetProcessHeap(), 0, mystr);
589 /*************************************************************************
592 * Ascii version of GetAcceptLanguagesW.
594 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
597 DWORD buflenW, convlen;
600 if(!langbuf || !buflen || !*buflen) return E_FAIL;
603 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
604 retval = GetAcceptLanguagesW(langbufW, &buflenW);
606 /* FIXME: this is wrong, the string may not be null-terminated */
607 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
608 *buflen, NULL, NULL);
609 *buflen = buflenW ? convlen : 0;
611 HeapFree(GetProcessHeap(), 0, langbufW);
615 /*************************************************************************
618 * Convert a GUID to a string.
621 * guid [I] GUID to convert
622 * lpszDest [O] Destination for string
623 * cchMax [I] Length of output buffer
626 * The length of the string created.
628 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
633 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
635 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
636 guid->Data1, guid->Data2, guid->Data3,
637 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
638 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
640 iLen = strlen(xguid) + 1;
644 memcpy(lpszDest, xguid, iLen);
648 /*************************************************************************
651 * Convert a GUID to a string.
654 * guid [I] GUID to convert
655 * str [O] Destination for string
656 * cmax [I] Length of output buffer
659 * The length of the string created.
661 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
665 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
666 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
667 'X','%','0','2','X','%','0','2','X','}',0};
669 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
671 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
672 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
673 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
675 iLen = strlenW(xguid) + 1;
679 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
683 /*************************************************************************
686 * Determine if a Unicode character is a space.
689 * wc [I] Character to check.
692 * TRUE, if wc is a space,
695 BOOL WINAPI IsCharSpaceW(WCHAR wc)
699 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
702 /*************************************************************************
705 * Determine if a Unicode character is a blank.
708 * wc [I] Character to check.
711 * TRUE, if wc is a blank,
715 BOOL WINAPI IsCharBlankW(WCHAR wc)
719 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
722 /*************************************************************************
725 * Determine if a Unicode character is punctuation.
728 * wc [I] Character to check.
731 * TRUE, if wc is punctuation,
734 BOOL WINAPI IsCharPunctW(WCHAR wc)
738 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
741 /*************************************************************************
744 * Determine if a Unicode character is a control character.
747 * wc [I] Character to check.
750 * TRUE, if wc is a control character,
753 BOOL WINAPI IsCharCntrlW(WCHAR wc)
757 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
760 /*************************************************************************
763 * Determine if a Unicode character is a digit.
766 * wc [I] Character to check.
769 * TRUE, if wc is a digit,
772 BOOL WINAPI IsCharDigitW(WCHAR wc)
776 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
779 /*************************************************************************
782 * Determine if a Unicode character is a hex digit.
785 * wc [I] Character to check.
788 * TRUE, if wc is a hex digit,
791 BOOL WINAPI IsCharXDigitW(WCHAR wc)
795 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
798 /*************************************************************************
802 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
804 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
808 /*************************************************************************
811 * Insert a bitmap menu item at the bottom of a menu.
814 * hMenu [I] Menu to insert into
815 * flags [I] Flags for insertion
816 * id [I] Menu ID of the item
817 * str [I] Menu text for the item
820 * Success: TRUE, the item is inserted into the menu
821 * Failure: FALSE, if any parameter is invalid
823 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
825 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
826 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
829 /*************************************************************************
832 * Get the text from a given dialog item.
835 * hWnd [I] Handle of dialog
836 * nItem [I] Index of item
837 * lpsDest [O] Buffer for receiving window text
838 * nDestLen [I] Length of buffer.
841 * Success: The length of the returned text.
844 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
846 HWND hItem = GetDlgItem(hWnd, nItem);
849 return GetWindowTextW(hItem, lpsDest, nDestLen);
851 *lpsDest = (WCHAR)'\0';
855 /*************************************************************************
858 * Set the text of a given dialog item.
861 * hWnd [I] Handle of dialog
862 * iItem [I] Index of item
863 * lpszText [O] Text to set
866 * Success: TRUE. The text of the dialog is set to lpszText.
867 * Failure: FALSE, Otherwise.
869 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
871 HWND hWndItem = GetDlgItem(hWnd, iItem);
873 return SetWindowTextW(hWndItem, lpszText);
877 /*************************************************************************
880 * Compare two Ascii strings up to a given length.
883 * lpszSrc [I] Source string
884 * lpszCmp [I] String to compare to lpszSrc
885 * len [I] Maximum length
888 * A number greater than, less than or equal to 0 depending on whether
889 * lpszSrc is greater than, less than or equal to lpszCmp.
891 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
893 return strncmp(lpszSrc, lpszCmp, len);
896 /*************************************************************************
899 * Unicode version of StrCmpNCA.
901 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
903 return strncmpW(lpszSrc, lpszCmp, len);
906 /*************************************************************************
909 * Compare two Ascii strings up to a given length, ignoring case.
912 * lpszSrc [I] Source string
913 * lpszCmp [I] String to compare to lpszSrc
914 * len [I] Maximum length
917 * A number greater than, less than or equal to 0 depending on whether
918 * lpszSrc is greater than, less than or equal to lpszCmp.
920 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
922 return strncasecmp(lpszSrc, lpszCmp, len);
925 /*************************************************************************
928 * Unicode version of StrCmpNICA.
930 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
932 return strncmpiW(lpszSrc, lpszCmp, len);
935 /*************************************************************************
938 * Compare two Ascii strings.
941 * lpszSrc [I] Source string
942 * lpszCmp [I] String to compare to lpszSrc
945 * A number greater than, less than or equal to 0 depending on whether
946 * lpszSrc is greater than, less than or equal to lpszCmp.
948 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
950 return strcmp(lpszSrc, lpszCmp);
953 /*************************************************************************
956 * Unicode version of StrCmpCA.
958 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
960 return strcmpW(lpszSrc, lpszCmp);
963 /*************************************************************************
966 * Compare two Ascii strings, ignoring case.
969 * lpszSrc [I] Source string
970 * lpszCmp [I] String to compare to lpszSrc
973 * A number greater than, less than or equal to 0 depending on whether
974 * lpszSrc is greater than, less than or equal to lpszCmp.
976 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
978 return strcasecmp(lpszSrc, lpszCmp);
981 /*************************************************************************
984 * Unicode version of StrCmpICA.
986 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
988 return strcmpiW(lpszSrc, lpszCmp);
991 /*************************************************************************
994 * Get an identification string for the OS and explorer.
997 * lpszDest [O] Destination for Id string
998 * dwDestLen [I] Length of lpszDest
1001 * TRUE, If the string was created successfully
1004 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1008 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1010 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1012 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1018 /*************************************************************************
1021 * Unicode version of SHAboutInfoA.
1023 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1025 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1026 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1027 ' ','E','x','p','l','o','r','e','r','\0' };
1028 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1029 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1030 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1031 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1032 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1033 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1034 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1035 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1036 ' ','E','x','p','l','o','r','e','r','\\',
1037 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1038 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1039 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1040 'V','e','r','s','i','o','n','\0' };
1041 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1042 'O','w','n','e','r','\0' };
1043 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1044 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1045 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1046 static const WCHAR szUpdate[] = { 'I','E','A','K',
1047 'U','p','d','a','t','e','U','r','l','\0' };
1048 static const WCHAR szHelp[] = { 'I','E','A','K',
1049 'H','e','l','p','S','t','r','i','n','g','\0' };
1052 DWORD dwType, dwLen;
1054 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1061 /* Try the NT key first, followed by 95/98 key */
1062 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1063 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1069 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1071 DWORD dwStrLen = strlenW(buff);
1072 dwLen = 30 - dwStrLen;
1073 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1074 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1076 StrCatBuffW(lpszDest, buff, dwDestLen);
1078 /* ~Registered Owner */
1081 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1083 StrCatBuffW(lpszDest, buff, dwDestLen);
1085 /* ~Registered Organization */
1087 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1089 StrCatBuffW(lpszDest, buff, dwDestLen);
1091 /* FIXME: Not sure where this number comes from */
1095 StrCatBuffW(lpszDest, buff, dwDestLen);
1099 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1101 StrCatBuffW(lpszDest, buff, dwDestLen);
1103 /* ~IE Update Url */
1105 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1107 StrCatBuffW(lpszDest, buff, dwDestLen);
1109 /* ~IE Help String */
1111 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1113 StrCatBuffW(lpszDest, buff, dwDestLen);
1119 /*************************************************************************
1122 * Call IOleCommandTarget_QueryStatus() on an object.
1125 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1126 * pguidCmdGroup [I] GUID for the command group
1128 * prgCmds [O] Commands
1129 * pCmdText [O] Command text
1133 * Failure: E_FAIL, if lpUnknown is NULL.
1134 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1135 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1137 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1138 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1140 HRESULT hRet = E_FAIL;
1142 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1146 IOleCommandTarget* lpOle;
1148 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1151 if (SUCCEEDED(hRet) && lpOle)
1153 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1155 IOleCommandTarget_Release(lpOle);
1161 /*************************************************************************
1164 * Call IOleCommandTarget_Exec() on an object.
1167 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1168 * pguidCmdGroup [I] GUID for the command group
1172 * Failure: E_FAIL, if lpUnknown is NULL.
1173 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1174 * Otherwise, an error code from IOleCommandTarget_Exec().
1176 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1177 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1180 HRESULT hRet = E_FAIL;
1182 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1183 nCmdexecopt, pvaIn, pvaOut);
1187 IOleCommandTarget* lpOle;
1189 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1191 if (SUCCEEDED(hRet) && lpOle)
1193 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1194 nCmdexecopt, pvaIn, pvaOut);
1195 IOleCommandTarget_Release(lpOle);
1201 /*************************************************************************
1204 * Retrieve, modify, and re-set a value from a window.
1207 * hWnd [I] Window to get value from
1208 * offset [I] Offset of value
1209 * wMask [I] Mask for uiFlags
1210 * wFlags [I] Bits to set in window value
1213 * The new value as it was set, or 0 if any parameter is invalid.
1216 * Any bits set in uiMask are cleared from the value, then any bits set in
1217 * uiFlags are set in the value.
1219 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1221 LONG ret = GetWindowLongA(hwnd, offset);
1222 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1224 if (newFlags != ret)
1225 ret = SetWindowLongA(hwnd, offset, newFlags);
1229 /*************************************************************************
1232 * Change a window's parent.
1235 * hWnd [I] Window to change parent of
1236 * hWndParent [I] New parent window
1239 * The old parent of hWnd.
1242 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1243 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1245 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1247 TRACE("%p, %p\n", hWnd, hWndParent);
1249 if(GetParent(hWnd) == hWndParent)
1253 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1255 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1257 return SetParent(hWnd, hWndParent);
1260 /*************************************************************************
1263 * Locate and advise a connection point in an IConnectionPointContainer object.
1266 * lpUnkSink [I] Sink for the connection point advise call
1267 * riid [I] REFIID of connection point to advise
1268 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1269 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1270 * lpCookie [O] Pointer to connection point cookie
1271 * lppCP [O] Destination for the IConnectionPoint found
1274 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1275 * that was advised. The caller is responsable for releasing it.
1276 * Failure: E_FAIL, if any arguments are invalid.
1277 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1278 * Or an HRESULT error code if any call fails.
1280 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1281 IUnknown* lpUnknown, LPDWORD lpCookie,
1282 IConnectionPoint **lppCP)
1285 IConnectionPointContainer* lpContainer;
1286 IConnectionPoint *lpCP;
1288 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1294 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1295 (void**)&lpContainer);
1296 if (SUCCEEDED(hRet))
1298 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1300 if (SUCCEEDED(hRet))
1303 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1304 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1309 if (lppCP && SUCCEEDED(hRet))
1310 *lppCP = lpCP; /* Caller keeps the interface */
1312 IConnectionPoint_Release(lpCP); /* Release it */
1315 IUnknown_Release(lpContainer);
1320 /*************************************************************************
1323 * Release an interface.
1326 * lpUnknown [I] Object to release
1331 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1335 TRACE("(%p)\n",lpUnknown);
1337 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1341 TRACE("doing Release\n");
1343 return IUnknown_Release(temp);
1346 /*************************************************************************
1349 * Skip '//' if present in a string.
1352 * lpszSrc [I] String to check for '//'
1355 * Success: The next character after the '//' or the string if not present
1356 * Failure: NULL, if lpszStr is NULL.
1358 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1360 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1365 /*************************************************************************
1368 * Check if two interfaces come from the same object.
1371 * lpInt1 [I] Interface to check against lpInt2.
1372 * lpInt2 [I] Interface to check against lpInt1.
1375 * TRUE, If the interfaces come from the same object.
1378 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1380 LPVOID lpUnknown1, lpUnknown2;
1382 TRACE("%p %p\n", lpInt1, lpInt2);
1384 if (!lpInt1 || !lpInt2)
1387 if (lpInt1 == lpInt2)
1390 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1391 (LPVOID *)&lpUnknown1)))
1394 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1395 (LPVOID *)&lpUnknown2)))
1398 if (lpUnknown1 == lpUnknown2)
1404 /*************************************************************************
1407 * Get the window handle of an object.
1410 * lpUnknown [I] Object to get the window handle of
1411 * lphWnd [O] Destination for window handle
1414 * Success: S_OK. lphWnd contains the objects window handle.
1415 * Failure: An HRESULT error code.
1418 * lpUnknown is expected to support one of the following interfaces:
1419 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1421 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1423 /* FIXME: Wine has no header for this object */
1424 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1425 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1427 HRESULT hRet = E_FAIL;
1429 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1434 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1438 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1442 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1447 if (SUCCEEDED(hRet))
1449 /* Lazyness here - Since GetWindow() is the first method for the above 3
1450 * interfaces, we use the same call for them all.
1452 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1453 IUnknown_Release(lpOle);
1455 TRACE("Returning HWND=%p\n", *lphWnd);
1461 /*************************************************************************
1464 * Call a method on as as yet unidentified object.
1467 * pUnk [I] Object supporting the unidentified interface,
1468 * arg [I] Argument for the call on the object.
1473 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1475 static const GUID guid_173 = {
1476 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1480 TRACE("(%p,%ld)\n", pUnk, arg);
1482 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1483 * We use this interface as its vtable entry is compatible with the
1484 * object in question.
1485 * FIXME: Find out what this object is and where it should be defined.
1488 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1490 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1491 IMalloc_Release(pUnk2);
1496 /*************************************************************************
1499 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1504 * Failure: E_FAIL, if p1 is NULL.
1505 * E_NOINTERFACE If p1 does not support the IPersist interface,
1506 * Or an HRESULT error code.
1508 DWORD WINAPI IUnknown_SetSite(
1509 IUnknown *p1, /* [in] OLE object */
1510 LPVOID *p2) /* [out] ptr for call results */
1514 if (!p1) return E_FAIL;
1516 /* see if SetSite interface exists for IObjectWithSite object */
1517 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1518 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1521 /* see if GetClassId interface exists for IPersistMoniker object */
1522 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1523 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1524 if (ret) return ret;
1526 /* fake a GetClassId call */
1527 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1528 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1530 IUnknown_Release((IUnknown *)aa);
1533 /* fake a SetSite call */
1534 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1535 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1537 IUnknown_Release((IUnknown *)p1);
1542 /*************************************************************************
1545 * Call IPersist_GetClassID() on an object.
1548 * lpUnknown [I] Object supporting the IPersist interface
1549 * lpClassId [O] Destination for Class Id
1552 * Success: S_OK. lpClassId contains the Class Id requested.
1553 * Failure: E_FAIL, If lpUnknown is NULL,
1554 * E_NOINTERFACE If lpUnknown does not support IPersist,
1555 * Or an HRESULT error code.
1557 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1559 IPersist* lpPersist;
1560 HRESULT hRet = E_FAIL;
1562 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1566 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1567 if (SUCCEEDED(hRet))
1569 IPersist_GetClassID(lpPersist, lpClassId);
1570 IPersist_Release(lpPersist);
1576 /*************************************************************************
1579 * Retrieve a Service Interface from an object.
1582 * lpUnknown [I] Object to get an IServiceProvider interface from
1583 * sid [I] Service ID for IServiceProvider_QueryService() call
1584 * riid [I] Function requested for QueryService call
1585 * lppOut [O] Destination for the service interface pointer
1588 * Success: S_OK. lppOut contains an object providing the requested service
1589 * Failure: An HRESULT error code
1592 * lpUnknown is expected to support the IServiceProvider interface.
1594 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1597 IServiceProvider* pService = NULL;
1608 /* Get an IServiceProvider interface from the object */
1609 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1610 (LPVOID*)&pService);
1612 if (!hRet && pService)
1614 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1616 /* Get a Service interface from the object */
1617 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1619 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1621 /* Release the IServiceProvider interface */
1622 IUnknown_Release(pService);
1627 /*************************************************************************
1630 * Loads a popup menu.
1633 * hInst [I] Instance handle
1634 * szName [I] Menu name
1640 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1642 HMENU hMenu, hSubMenu;
1644 if ((hMenu = LoadMenuW(hInst, szName)))
1646 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1647 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1655 typedef struct _enumWndData
1660 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1663 /* Callback for SHLWAPI_178 */
1664 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1666 enumWndData *data = (enumWndData *)lParam;
1668 TRACE("(%p,%p)\n", hWnd, data);
1669 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1673 /*************************************************************************
1676 * Send or post a message to every child of a window.
1679 * hWnd [I] Window whose children will get the messages
1680 * uiMsgId [I] Message Id
1681 * wParam [I] WPARAM of message
1682 * lParam [I] LPARAM of message
1683 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1689 * The appropriate ASCII or Unicode function is called for the window.
1691 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1695 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1699 data.uiMsgId = uiMsgId;
1700 data.wParam = wParam;
1701 data.lParam = lParam;
1704 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1706 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1708 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1712 /*************************************************************************
1715 * Remove all sub-menus from a menu.
1718 * hMenu [I] Menu to remove sub-menus from
1721 * Success: 0. All sub-menus under hMenu are removed
1722 * Failure: -1, if any parameter is invalid
1724 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1726 int iItemCount = GetMenuItemCount(hMenu) - 1;
1727 while (iItemCount >= 0)
1729 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1731 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1737 /*************************************************************************
1740 * Enable or disable a menu item.
1743 * hMenu [I] Menu holding menu item
1744 * uID [I] ID of menu item to enable/disable
1745 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1748 * The return code from EnableMenuItem.
1750 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1752 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1755 /*************************************************************************
1758 * Check or uncheck a menu item.
1761 * hMenu [I] Menu holding menu item
1762 * uID [I] ID of menu item to check/uncheck
1763 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1766 * The return code from CheckMenuItem.
1768 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1770 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1773 /*************************************************************************
1776 * Register a window class if it isn't already.
1779 * lpWndClass [I] Window class to register
1782 * The result of the RegisterClassA call.
1784 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1787 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1789 return (DWORD)RegisterClassA(wndclass);
1792 /*************************************************************************
1795 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1796 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1798 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1799 POINTL pt = { 0, 0 };
1805 pdwEffect = &dwEffect;
1807 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1810 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1812 IDropTarget_DragLeave(pDrop);
1816 /*************************************************************************
1819 * Call IPersistPropertyBag_Load() on an object.
1822 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1823 * lpPropBag [O] Destination for loaded IPropertyBag
1827 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1829 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1831 IPersistPropertyBag* lpPPBag;
1832 HRESULT hRet = E_FAIL;
1834 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1838 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1840 if (SUCCEEDED(hRet) && lpPPBag)
1842 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1843 IPersistPropertyBag_Release(lpPPBag);
1849 /*************************************************************************
1852 * Call IOleControlSite_TranslateAccelerator() on an object.
1855 * lpUnknown [I] Object supporting the IOleControlSite interface.
1856 * lpMsg [I] Key message to be processed.
1857 * dwModifiers [I] Flags containing the state of the modifier keys.
1861 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1863 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1865 IOleControlSite* lpCSite = NULL;
1866 HRESULT hRet = E_INVALIDARG;
1868 TRACE("(%p,%p,0x%08lx)\n", lpUnknown, lpMsg, dwModifiers);
1871 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1873 if (SUCCEEDED(hRet) && lpCSite)
1875 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1876 IOleControlSite_Release(lpCSite);
1883 /*************************************************************************
1886 * Call IOleControlSite_GetExtendedControl() on an object.
1889 * lpUnknown [I] Object supporting the IOleControlSite interface.
1890 * lppDisp [O] Destination for resulting IDispatch.
1894 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1896 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1898 IOleControlSite* lpCSite = NULL;
1899 HRESULT hRet = E_FAIL;
1901 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1904 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1906 if (SUCCEEDED(hRet) && lpCSite)
1908 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1909 IOleControlSite_Release(lpCSite);
1915 /*************************************************************************
1918 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1919 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1921 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1922 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1923 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1924 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1925 HRESULT hRet = E_INVALIDARG;
1926 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1928 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1930 if (lpUnknown && lpArg4)
1932 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1933 (REFGUID)function_id, (void**)&lpUnkInner);
1935 if (SUCCEEDED(hRet) && lpUnkInner)
1937 /* FIXME: The type of service object requested is unknown, however
1938 * testing shows that its first method is called with 4 parameters.
1939 * Fake this by using IParseDisplayName_ParseDisplayName since the
1940 * signature and position in the vtable matches our unknown object type.
1942 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1943 lpArg1, lpArg2, lpArg3, lpArg4);
1944 IUnknown_Release(lpUnkInner);
1950 /*************************************************************************
1953 * Get a sub-menu from a menu item.
1956 * hMenu [I] Menu to get sub-menu from
1957 * uID [I] ID of menu item containing sub-menu
1960 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1962 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1966 TRACE("(%p,%uld)\n", hMenu, uID);
1968 mi.cbSize = sizeof(MENUITEMINFOA);
1969 mi.fMask = MIIM_SUBMENU;
1971 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1977 /*************************************************************************
1980 * Get the color depth of the primary display.
1986 * The color depth of the primary display.
1988 DWORD WINAPI SHGetCurColorRes()
1996 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
2001 /*************************************************************************
2004 * Wait for a message to arrive, with a timeout.
2007 * hand [I] Handle to query
2008 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
2011 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
2012 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2013 * message is available.
2015 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
2017 DWORD dwEndTicks = GetTickCount() + dwTimeout;
2020 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
2024 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
2026 if (dwTimeout != INFINITE)
2028 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
2029 return WAIT_TIMEOUT;
2036 /*************************************************************************
2039 * Determine if a shell folder can be expanded.
2042 * lpFolder [I] Parent folder containing the object to test.
2043 * pidl [I] Id of the object to test.
2046 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2047 * Failure: E_INVALIDARG, if any argument is invalid.
2050 * If the object to be tested does not expose the IQueryInfo() interface it
2051 * will not be identified as an expandable folder.
2053 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
2055 HRESULT hRet = E_INVALIDARG;
2058 if (lpFolder && pidl)
2060 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
2061 NULL, (void**)&lpInfo);
2063 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
2068 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2069 * currently used". Really? You wouldn't be holding out on me would you?
2071 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
2073 if (SUCCEEDED(hRet))
2075 /* 0x2 is an undocumented flag apparently indicating expandability */
2076 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
2079 IQueryInfo_Release(lpInfo);
2085 /*************************************************************************
2088 * Blank out a region of text by drawing the background only.
2091 * hDC [I] Device context to draw in
2092 * pRect [I] Area to draw in
2093 * cRef [I] Color to draw in
2098 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2100 COLORREF cOldColor = SetBkColor(hDC, cRef);
2101 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2102 SetBkColor(hDC, cOldColor);
2106 /*************************************************************************
2109 * Return the value asociated with a key in a map.
2112 * lpKeys [I] A list of keys of length iLen
2113 * lpValues [I] A list of values associated with lpKeys, of length iLen
2114 * iLen [I] Length of both lpKeys and lpValues
2115 * iKey [I] The key value to look up in lpKeys
2118 * The value in lpValues associated with iKey, or -1 if iKey is not
2122 * - If two elements in the map share the same key, this function returns
2123 * the value closest to the start of the map
2124 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2126 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2128 if (lpKeys && lpValues)
2134 if (lpKeys[i] == iKey)
2135 return lpValues[i]; /* Found */
2139 return -1; /* Not found */
2143 /*************************************************************************
2146 * Copy an interface pointer
2149 * lppDest [O] Destination for copy
2150 * lpUnknown [I] Source for copy
2155 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2157 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2160 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2165 IUnknown_AddRef(lpUnknown);
2166 *lppDest = lpUnknown;
2170 /*************************************************************************
2174 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2175 REFGUID riidCmdGrp, ULONG cCmds,
2176 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2178 FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",
2179 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2181 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2182 return DRAGDROP_E_NOTREGISTERED;
2185 /*************************************************************************
2189 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2190 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2193 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2194 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2195 return DRAGDROP_E_NOTREGISTERED;
2198 /*************************************************************************
2202 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2204 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2205 return DRAGDROP_E_NOTREGISTERED;
2208 /*************************************************************************
2211 * Determine if a window is not a child of another window.
2214 * hParent [I] Suspected parent window
2215 * hChild [I] Suspected child window
2218 * TRUE: If hChild is a child window of hParent
2219 * FALSE: If hChild is not a child window of hParent, or they are equal
2221 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2223 TRACE("(%p,%p)\n", hParent, hChild);
2225 if (!hParent || !hChild)
2227 else if(hParent == hChild)
2229 return !IsChild(hParent, hChild);
2232 /*************************************************************************
2235 * Some sort of memory management process.
2237 DWORD WINAPI FDSA_Initialize(
2244 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2249 /*************************************************************************
2252 * Some sort of memory management process.
2254 DWORD WINAPI FDSA_Destroy(
2257 FIXME("(%p) stub\n",
2262 /*************************************************************************
2265 * Some sort of memory management process.
2267 DWORD WINAPI FDSA_InsertItem(
2272 FIXME("(%p 0x%08lx %p) stub\n",
2277 /*************************************************************************
2280 DWORD WINAPI FDSA_DeleteItem(
2284 FIXME("(%p 0x%08lx) stub\n",
2294 /*************************************************************************
2297 * Call IUnknown_QueryInterface() on a table of objects.
2301 * Failure: E_POINTER or E_NOINTERFACE.
2303 HRESULT WINAPI QISearch(
2304 LPVOID w, /* [in] Table of interfaces */
2305 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2306 REFIID riid, /* [in] REFIID to get interface for */
2307 LPVOID *ppv) /* [out] Destination for interface pointer */
2311 IFACE_INDEX_TBL *xmove;
2313 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2316 while (xmove->refid) {
2317 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2318 if (IsEqualIID(riid, xmove->refid)) {
2319 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2320 TRACE("matched, returning (%p)\n", a_vtbl);
2321 *ppv = (LPVOID)a_vtbl;
2322 IUnknown_AddRef(a_vtbl);
2328 if (IsEqualIID(riid, &IID_IUnknown)) {
2329 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2330 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2331 *ppv = (LPVOID)a_vtbl;
2332 IUnknown_AddRef(a_vtbl);
2336 ret = E_NOINTERFACE;
2340 TRACE("-- 0x%08lx\n", ret);
2344 /*************************************************************************
2347 * Remove the "PropDlgFont" property from a window.
2350 * hWnd [I] Window to remove the property from
2353 * A handle to the removed property, or NULL if it did not exist.
2355 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2359 TRACE("(%p)\n", hWnd);
2361 hProp = GetPropA(hWnd, "PropDlgFont");
2365 DeleteObject(hProp);
2366 hProp = RemovePropA(hWnd, "PropDlgFont");
2371 /*************************************************************************
2374 * Load the in-process server of a given GUID.
2377 * refiid [I] GUID of the server to load.
2380 * Success: A handle to the loaded server dll.
2381 * Failure: A NULL handle.
2383 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2387 CHAR value[MAX_PATH], string[MAX_PATH];
2389 strcpy(string, "CLSID\\");
2390 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2391 strcat(string, "\\InProcServer32");
2394 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2395 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2396 RegCloseKey(newkey);
2397 return LoadLibraryExA(value, 0, 0);
2400 /*************************************************************************
2403 * Unicode version of SHLWAPI_183.
2405 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2409 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2411 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2413 return RegisterClassW(lpWndClass);
2416 /*************************************************************************
2419 * Unregister a list of classes.
2422 * hInst [I] Application instance that registered the classes
2423 * lppClasses [I] List of class names
2424 * iCount [I] Number of names in lppClasses
2429 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2433 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2437 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2438 UnregisterClassA(*lppClasses, hInst);
2444 /*************************************************************************
2447 * Unicode version of SHUnregisterClassesA.
2449 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2453 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2457 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2458 UnregisterClassW(*lppClasses, hInst);
2464 /*************************************************************************
2467 * Call The correct (Ascii/Unicode) default window procedure for a window.
2470 * hWnd [I] Window to call the default procedure for
2471 * uMessage [I] Message ID
2472 * wParam [I] WPARAM of message
2473 * lParam [I] LPARAM of message
2476 * The result of calling DefWindowProcA() or DefWindowProcW().
2478 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2480 if (IsWindowUnicode(hWnd))
2481 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2482 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2485 /*************************************************************************
2488 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2490 HRESULT hRet = E_INVALIDARG;
2491 LPOBJECTWITHSITE lpSite = NULL;
2493 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2495 if (lpUnknown && iid && lppSite)
2497 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2499 if (SUCCEEDED(hRet) && lpSite)
2501 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2502 IObjectWithSite_Release(lpSite);
2508 /*************************************************************************
2511 * Create a worker window using CreateWindowExA().
2514 * wndProc [I] Window procedure
2515 * hWndParent [I] Parent window
2516 * dwExStyle [I] Extra style flags
2517 * dwStyle [I] Style flags
2518 * hMenu [I] Window menu
2522 * Success: The window handle of the newly created window.
2525 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2526 DWORD dwStyle, HMENU hMenu, LONG z)
2528 static const char* szClass = "WorkerA";
2532 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2533 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2535 /* Create Window class */
2537 wc.lpfnWndProc = DefWindowProcA;
2540 wc.hInstance = shlwapi_hInstance;
2542 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2543 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2544 wc.lpszMenuName = NULL;
2545 wc.lpszClassName = szClass;
2547 SHRegisterClassA(&wc); /* Register class */
2549 /* FIXME: Set extra bits in dwExStyle */
2551 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2552 hWndParent, hMenu, shlwapi_hInstance, 0);
2555 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2558 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2563 typedef struct tagPOLICYDATA
2565 DWORD policy; /* flags value passed to SHRestricted */
2566 LPCWSTR appstr; /* application str such as "Explorer" */
2567 LPCWSTR keystr; /* name of the actual registry key / policy */
2568 } POLICYDATA, *LPPOLICYDATA;
2570 #define SHELL_NO_POLICY 0xffffffff
2572 /* default shell policy registry key */
2573 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2574 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2575 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2576 '\\','P','o','l','i','c','i','e','s',0};
2578 /*************************************************************************
2581 * Retrieve a policy value from the registry.
2584 * lpSubKey [I] registry key name
2585 * lpSubName [I] subname of registry key
2586 * lpValue [I] value name of registry value
2589 * the value associated with the registry key or 0 if not found
2591 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2593 DWORD retval, datsize = sizeof(retval);
2597 lpSubKey = strRegistryPolicyW;
2599 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2600 if (retval != ERROR_SUCCESS)
2601 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2602 if (retval != ERROR_SUCCESS)
2605 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2610 /*************************************************************************
2613 * Helper function to retrieve the possibly cached value for a specific policy
2616 * policy [I] The policy to look for
2617 * initial [I] Main registry key to open, if NULL use default
2618 * polTable [I] Table of known policies, 0 terminated
2619 * polArr [I] Cache array of policy values
2622 * The retrieved policy value or 0 if not successful
2625 * This function is used by the native SHRestricted function to search for the
2626 * policy and cache it once retrieved. The current Wine implementation uses a
2627 * different POLICYDATA structure and implements a similar algorithme adapted to
2630 DWORD WINAPI SHRestrictionLookup(
2633 LPPOLICYDATA polTable,
2636 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2638 if (!polTable || !polArr)
2641 for (;polTable->policy; polTable++, polArr++)
2643 if (policy == polTable->policy)
2645 /* we have a known policy */
2647 /* check if this policy has been cached */
2648 if (*polArr == SHELL_NO_POLICY)
2649 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2653 /* we don't know this policy, return 0 */
2654 TRACE("unknown policy: (%08lx)\n", policy);
2658 /*************************************************************************
2661 * Get an interface from an object.
2664 * Success: S_OK. ppv contains the requested interface.
2665 * Failure: An HRESULT error code.
2668 * This QueryInterface asks the inner object for an interface. In case
2669 * of aggregation this request would be forwarded by the inner to the
2670 * outer object. This function asks the inner object directly for the
2671 * interface circumventing the forwarding to the outer object.
2673 HRESULT WINAPI SHWeakQueryInterface(
2674 IUnknown * pUnk, /* [in] Outer object */
2675 IUnknown * pInner, /* [in] Inner object */
2676 IID * riid, /* [in] Interface GUID to query for */
2677 LPVOID* ppv) /* [out] Destination for queried interface */
2679 HRESULT hret = E_NOINTERFACE;
2680 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2683 if(pUnk && pInner) {
2684 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2685 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2687 TRACE("-- 0x%08lx\n", hret);
2691 /*************************************************************************
2694 * Move a reference from one interface to another.
2697 * lpDest [O] Destination to receive the reference
2698 * lppUnknown [O] Source to give up the reference to lpDest
2703 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2705 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2710 IUnknown_AddRef(lpDest);
2711 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2715 /*************************************************************************
2718 * Convert an ASCII string of a CLSID into a CLSID.
2721 * idstr [I] String representing a CLSID in registry format
2722 * id [O] Destination for the converted CLSID
2725 * Success: TRUE. id contains the converted CLSID.
2728 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2731 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2732 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2735 /*************************************************************************
2738 * Unicode version of GUIDFromStringA.
2740 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2742 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2745 /*************************************************************************
2748 * Determine if the browser is integrated into the shell, and set a registry
2755 * 1, If the browser is not integrated.
2756 * 2, If the browser is integrated.
2759 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2760 * either set to TRUE, or removed depending on whether the browser is deemed
2763 DWORD WINAPI WhichPlatform()
2765 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2766 static DWORD dwState = 0;
2768 DWORD dwRet, dwData, dwSize;
2773 /* If shell32 exports DllGetVersion(), the browser is integrated */
2774 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2775 dwState = pDllGetVersion ? 2 : 1;
2777 /* Set or delete the key accordingly */
2778 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2779 "Software\\Microsoft\\Internet Explorer", 0,
2780 KEY_ALL_ACCESS, &hKey);
2783 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2784 (LPBYTE)&dwData, &dwSize);
2786 if (!dwRet && dwState == 1)
2788 /* Value exists but browser is not integrated */
2789 RegDeleteValueA(hKey, szIntegratedBrowser);
2791 else if (dwRet && dwState == 2)
2793 /* Browser is integrated but value does not exist */
2795 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2796 (LPBYTE)&dwData, sizeof(dwData));
2803 /*************************************************************************
2806 * Unicode version of SHCreateWorkerWindowA.
2808 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2809 DWORD dwStyle, HMENU hMenu, LONG z)
2811 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2815 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2816 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2818 /* If our OS is natively ASCII, use the ASCII version */
2819 if (!(GetVersion() & 0x80000000)) /* NT */
2820 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2822 /* Create Window class */
2824 wc.lpfnWndProc = DefWindowProcW;
2827 wc.hInstance = shlwapi_hInstance;
2829 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2830 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2831 wc.lpszMenuName = NULL;
2832 wc.lpszClassName = szClass;
2834 SHRegisterClassW(&wc); /* Register class */
2836 /* FIXME: Set extra bits in dwExStyle */
2838 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2839 hWndParent, hMenu, shlwapi_hInstance, 0);
2842 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2845 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2850 /*************************************************************************
2853 * Get and show a context menu from a shell folder.
2856 * hWnd [I] Window displaying the shell folder
2857 * lpFolder [I] IShellFolder interface
2858 * lpApidl [I] Id for the particular folder desired
2862 * Failure: An HRESULT error code indicating the error.
2864 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2866 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2869 /*************************************************************************
2872 * _SHPackDispParamsV
2874 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2876 FIXME("%p %p %p %p\n",w,x,y,z);
2880 /*************************************************************************
2883 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2884 * function does...).
2886 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2888 FIXME("%p %p %p %p\n", w, x, y, z);
2892 /*************************************************************************
2895 * _IConnectionPoint_SimpleInvoke
2897 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2902 FIXME("(%p %p %p) stub\n",x,y,z);
2906 /*************************************************************************
2909 * Notify an IConnectionPoint object of changes.
2912 * lpCP [I] Object to notify
2917 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2918 * IConnectionPoint interface.
2920 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2922 IEnumConnections *lpEnum;
2923 HRESULT hRet = E_NOINTERFACE;
2925 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2927 /* Get an enumerator for the connections */
2929 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2931 if (SUCCEEDED(hRet))
2933 IPropertyNotifySink *lpSink;
2934 CONNECTDATA connData;
2937 /* Call OnChanged() for every notify sink in the connection point */
2938 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2940 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2943 IPropertyNotifySink_OnChanged(lpSink, dispID);
2944 IPropertyNotifySink_Release(lpSink);
2946 IUnknown_Release(connData.pUnk);
2949 IEnumConnections_Release(lpEnum);
2954 /*************************************************************************
2957 * Notify an IConnectionPointContainer object of changes.
2960 * lpUnknown [I] Object to notify
2965 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2966 * IConnectionPointContainer interface.
2968 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2970 IConnectionPointContainer* lpCPC = NULL;
2971 HRESULT hRet = E_NOINTERFACE;
2973 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2976 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2978 if (SUCCEEDED(hRet))
2980 IConnectionPoint* lpCP;
2982 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2983 IConnectionPointContainer_Release(lpCPC);
2985 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2986 IConnectionPoint_Release(lpCP);
2991 /*************************************************************************
2996 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2998 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2999 return pPlaySoundW(pszSound, hmod, fdwSound);
3002 /*************************************************************************
3005 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3008 * str1: "I" "I" pushl esp+0x20
3009 * str2: "U" "I" pushl 0x77c93810
3010 * (is "I" and "U" "integer" and "unsigned" ??)
3012 * pStr: "" "" pushl eax
3013 * some_len: 0x824 0x104 pushl 0x824
3014 * lpStr2: "%l" "%l" pushl esp+0xc
3016 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3017 * LocalAlloc(0x00, some_len) -> irrelevant_var
3018 * LocalAlloc(0x40, irrelevant_len) -> pStr
3019 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3020 * shlwapi.PathRemoveBlanksW(pStr);
3022 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3026 /*************************************************************************
3029 * Called by ICQ2000b install via SHDOCVW:
3030 * str1: "InternetShortcut"
3031 * x: some unknown pointer
3032 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3033 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3035 * In short: this one maybe creates a desktop link :-)
3037 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3039 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3043 /*************************************************************************
3048 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3049 LPCWSTR str, UINT count, const INT *lpDx)
3051 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3052 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3055 /*************************************************************************
3058 * See SHGetFileInfoW.
3060 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3061 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3063 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3064 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3067 /*************************************************************************
3070 * See DragQueryFileW.
3072 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3074 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3075 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3078 /*************************************************************************
3081 * See SHBrowseForFolderW.
3083 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3085 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3086 return pSHBrowseForFolderW(lpBi);
3089 /*************************************************************************
3092 * See SHGetPathFromIDListW.
3094 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3096 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3097 return pSHGetPathFromIDListW(pidl, pszPath);
3100 /*************************************************************************
3103 * See ShellExecuteExW.
3105 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3107 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3108 return pShellExecuteExW(lpExecInfo);
3111 /*************************************************************************
3114 * See SHFileOperationW.
3116 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3118 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3119 return pSHFileOperationW(lpFileOp);
3122 /*************************************************************************
3125 * See ExtractIconExW.
3127 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3128 HICON *phiconSmall, UINT nIcons)
3130 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3131 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3134 /*************************************************************************
3138 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3140 return InterlockedCompareExchange(dest, xchg, compare);
3143 /*************************************************************************
3146 * See GetFileVersionInfoSizeW.
3148 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3154 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3155 ret = pGetFileVersionInfoSizeW(x, y);
3159 /*************************************************************************
3162 * See GetFileVersionInfoW.
3164 BOOL WINAPI GetFileVersionInfoWrapW(
3165 LPWSTR w, /* [in] path to dll */
3166 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3167 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3168 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3170 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3171 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3174 /*************************************************************************
3177 * See VerQueryValueW.
3179 WORD WINAPI VerQueryValueWrapW(
3180 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3181 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3182 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3183 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3185 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3186 return pVerQueryValueW((char*)w+0x208, x, y, z);
3189 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3190 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3191 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3193 /*************************************************************************
3196 * Change the modality of a shell object.
3199 * lpUnknown [I] Object to make modeless
3200 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3203 * Success: S_OK. The modality lpUnknown is changed.
3204 * Failure: An HRESULT error code indicating the error.
3207 * lpUnknown must support the IOleInPlaceFrame interface, the
3208 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3209 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3210 * or this call will fail.
3212 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3217 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3222 if (IsIface(IOleInPlaceActiveObject))
3223 EnableModeless(IOleInPlaceActiveObject);
3224 else if (IsIface(IOleInPlaceFrame))
3225 EnableModeless(IOleInPlaceFrame);
3226 else if (IsIface(IShellBrowser))
3227 EnableModeless(IShellBrowser);
3229 /* FIXME: Wine has no headers for these objects yet */
3230 else if (IsIface(IInternetSecurityMgrSite))
3231 EnableModeless(IInternetSecurityMgrSite);
3232 else if (IsIface(IDocHostUIHandler))
3233 EnableModeless(IDocHostUIHandler);
3238 IUnknown_Release(lpObj);
3242 /*************************************************************************
3245 * See SHGetNewLinkInfoW.
3247 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3248 BOOL *pfMustCopy, UINT uFlags)
3250 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3251 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3254 /*************************************************************************
3257 * See SHDefExtractIconW.
3259 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3260 HICON* phiconSmall, UINT nIconSize)
3262 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3263 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3266 /*************************************************************************
3269 * Get and show a context menu from a shell folder.
3272 * hWnd [I] Window displaying the shell folder
3273 * lpFolder [I] IShellFolder interface
3274 * lpApidl [I] Id for the particular folder desired
3275 * bInvokeDefault [I] Whether to invoke the default menu item
3278 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3280 * Failure: An HRESULT error code indicating the error.
3282 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3284 IContextMenu *iContext;
3285 HRESULT hRet = E_FAIL;
3287 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3292 /* Get the context menu from the shell folder */
3293 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3294 &IID_IContextMenu, 0, (void**)&iContext);
3295 if (SUCCEEDED(hRet))
3298 if ((hMenu = CreatePopupMenu()))
3301 DWORD dwDefaultId = 0;
3303 /* Add the context menu entries to the popup */
3304 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3305 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3307 if (SUCCEEDED(hQuery))
3309 if (bInvokeDefault &&
3310 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3312 CMINVOKECOMMANDINFO cmIci;
3313 /* Invoke the default item */
3314 memset(&cmIci,0,sizeof(cmIci));
3315 cmIci.cbSize = sizeof(cmIci);
3316 cmIci.fMask = CMIC_MASK_ASYNCOK;
3318 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3319 cmIci.nShow = SW_SCROLLCHILDREN;
3321 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3326 IContextMenu_Release(iContext);
3331 /*************************************************************************
3336 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3339 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3340 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3343 /*************************************************************************
3346 LANGID WINAPI MLGetUILanguage()
3349 /* FIXME: This should be a forward in the .spec file to the win2k function
3350 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3352 return GetUserDefaultLangID();
3355 /*************************************************************************
3358 * Load a library from the directory of a particular process.
3361 * new_mod [I] Library name
3362 * inst_hwnd [I] Module whose directory is to be used
3363 * dwFlags [I] Flags controlling the load
3366 * Success: A handle to the loaded module
3367 * Failure: A NULL handle.
3369 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3371 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3373 * FIXME: Native shows calls to:
3374 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3376 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3377 * RegQueryValueExA for "LPKInstalled"
3379 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3380 * RegQueryValueExA for "ResourceLocale"
3382 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3383 * RegQueryValueExA for "Locale"
3385 * and then tests the Locale ("en" for me).
3387 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3389 CHAR mod_path[2*MAX_PATH];
3393 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3394 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3395 if (!len || len >= sizeof(mod_path)) return NULL;
3397 ptr = strrchr(mod_path, '\\');
3399 strcpy(ptr+1, new_mod);
3400 TRACE("loading %s\n", debugstr_a(mod_path));
3401 return LoadLibraryA(mod_path);
3406 /*************************************************************************
3409 * Unicode version of MLLoadLibraryA.
3411 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3413 WCHAR mod_path[2*MAX_PATH];
3417 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3418 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3419 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3421 ptr = strrchrW(mod_path, '\\');
3423 strcpyW(ptr+1, new_mod);
3424 TRACE("loading %s\n", debugstr_w(mod_path));
3425 return LoadLibraryW(mod_path);
3430 /*************************************************************************
3431 * ColorAdjustLuma [SHLWAPI.@]
3433 * Adjust the luminosity of a color
3436 * cRGB [I] RGB value to convert
3437 * dwLuma [I] Luma adjustment
3438 * bUnknown [I] Unknown
3441 * The adjusted RGB color.
3443 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3445 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3451 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3453 FIXME("Ignoring luma adjustment\n");
3455 /* FIXME: The ajdustment is not linear */
3457 cRGB = ColorHLSToRGB(wH, wL, wS);
3462 /*************************************************************************
3465 * See GetSaveFileNameW.
3467 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3469 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3470 return pGetSaveFileNameW(ofn);
3473 /*************************************************************************
3476 * See WNetRestoreConnectionW.
3478 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3480 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3481 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3484 /*************************************************************************
3487 * See WNetGetLastErrorW.
3489 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3490 LPWSTR lpNameBuf, DWORD nNameBufSize)
3492 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3493 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3496 /*************************************************************************
3499 * See PageSetupDlgW.
3501 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3503 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3504 return pPageSetupDlgW(pagedlg);
3507 /*************************************************************************
3512 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3514 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3515 return pPrintDlgW(printdlg);
3518 /*************************************************************************
3521 * See GetOpenFileNameW.
3523 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3525 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3526 return pGetOpenFileNameW(ofn);
3529 /* INTERNAL: Map from HLS color space to RGB */
3530 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3532 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3536 else if (wHue > 120)
3541 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3544 /* Convert to RGB and scale into RGB range (0..255) */
3545 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3547 /*************************************************************************
3548 * ColorHLSToRGB [SHLWAPI.@]
3550 * Convert from hls color space into an rgb COLORREF.
3553 * wHue [I] Hue amount
3554 * wLuminosity [I] Luminosity amount
3555 * wSaturation [I] Saturation amount
3558 * A COLORREF representing the converted color.
3561 * Input hls values are constrained to the range (0..240).
3563 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3569 WORD wGreen, wBlue, wMid1, wMid2;
3571 if (wLuminosity > 120)
3572 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3574 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3576 wMid1 = wLuminosity * 2 - wMid2;
3578 wRed = GET_RGB(wHue + 80);
3579 wGreen = GET_RGB(wHue);
3580 wBlue = GET_RGB(wHue - 80);
3582 return RGB(wRed, wGreen, wBlue);
3585 wRed = wLuminosity * 255 / 240;
3586 return RGB(wRed, wRed, wRed);
3589 /*************************************************************************
3592 * Get the current docking status of the system.
3595 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3598 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3601 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3603 HW_PROFILE_INFOA hwInfo;
3605 TRACE("(0x%08lx)\n", dwFlags);
3607 GetCurrentHwProfileA(&hwInfo);
3608 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3610 case DOCKINFO_DOCKED:
3611 case DOCKINFO_UNDOCKED:
3612 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3618 /*************************************************************************
3621 * Function seems to do FreeLibrary plus other things.
3623 * FIXME native shows the following calls:
3624 * RtlEnterCriticalSection
3626 * GetProcAddress(Comctl32??, 150L)
3628 * RtlLeaveCriticalSection
3629 * followed by the FreeLibrary.
3630 * The above code may be related to .377 above.
3632 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3634 FIXME("(%p) semi-stub\n", hModule);
3635 return FreeLibrary(hModule);
3638 /*************************************************************************
3641 BOOL WINAPI SHFlushSFCacheWrap(void) {
3646 /*************************************************************************
3648 * FIXME I have no idea what this function does or what its arguments are.
3650 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3652 FIXME("(%p) stub\n", hInst);
3657 /*************************************************************************
3660 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3662 FIXME("(%p,%p) stub\n", hInst, hHeap);
3663 return E_FAIL; /* This is what is used if shlwapi not loaded */
3666 /*************************************************************************
3669 DWORD WINAPI MLClearMLHInstance(DWORD x)
3671 FIXME("(0x%08lx)stub\n", x);
3675 /*************************************************************************
3678 * Convert an Unicode string CLSID into a CLSID.
3681 * idstr [I] string containing a CLSID in text form
3682 * id [O] CLSID extracted from the string
3685 * S_OK on success or E_INVALIDARG on failure
3688 * This is really CLSIDFromString() which is exported by ole32.dll,
3689 * however the native shlwapi.dll does *not* import ole32. Nor does
3690 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3691 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3692 * it returns an E_INVALIDARG error code on failure.
3693 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3694 * in "dlls/ole32/compobj.c".
3696 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3704 memset(id, 0, sizeof(CLSID));
3707 else { /* validate the CLSID string */
3709 if (strlenW(s) != 38)
3710 return E_INVALIDARG;
3712 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3713 return E_INVALIDARG;
3715 for (i=1; i<37; i++)
3717 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3719 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3720 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3721 ((s[i] >= L'A') && (s[i] <= L'F')))
3723 return E_INVALIDARG;
3727 TRACE("%s -> %p\n", debugstr_w(s), id);
3729 /* quick lookup table */
3730 memset(table, 0, 256*sizeof(WCHAR));
3732 for (i = 0; i < 10; i++) {
3735 for (i = 0; i < 6; i++) {
3736 table['A' + i] = i+10;
3737 table['a' + i] = i+10;
3740 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3744 s++; /* skip leading brace */
3745 for (i = 0; i < 4; i++) {
3746 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3752 for (i = 0; i < 2; i++) {
3753 p[1-i] = table[*s]<<4 | table[*(s+1)];
3759 for (i = 0; i < 2; i++) {
3760 p[1-i] = table[*s]<<4 | table[*(s+1)];
3766 /* these are just sequential bytes */
3767 for (i = 0; i < 2; i++) {
3768 *p++ = table[*s]<<4 | table[*(s+1)];
3773 for (i = 0; i < 6; i++) {
3774 *p++ = table[*s]<<4 | table[*(s+1)];
3781 /*************************************************************************
3784 * Determine if the OS supports a given feature.
3787 * dwFeature [I] Feature requested (undocumented)
3790 * TRUE If the feature is available.
3791 * FALSE If the feature is not available.
3793 BOOL WINAPI IsOS(DWORD feature)
3795 OSVERSIONINFOA osvi;
3796 DWORD platform, majorv, minorv;
3798 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3799 if(!GetVersionExA(&osvi)) {
3800 ERR("GetVersionEx failed");
3804 majorv = osvi.dwMajorVersion;
3805 minorv = osvi.dwMinorVersion;
3806 platform = osvi.dwPlatformId;
3808 #define ISOS_RETURN(x) \
3809 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3813 case OS_WIN32SORGREATER:
3814 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3815 || platform == VER_PLATFORM_WIN32_WINDOWS)
3817 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3818 case OS_WIN95ORGREATER:
3819 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3820 case OS_NT4ORGREATER:
3821 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3822 case OS_WIN2000ORGREATER_ALT:
3823 case OS_WIN2000ORGREATER:
3824 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3825 case OS_WIN98ORGREATER:
3826 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3828 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3830 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3831 case OS_WIN2000SERVER:
3832 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3833 case OS_WIN2000ADVSERVER:
3834 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3835 case OS_WIN2000DATACENTER:
3836 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3837 case OS_WIN2000TERMINAL:
3838 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3840 FIXME("(OS_EMBEDDED) What should we return here?\n");
3842 case OS_TERMINALCLIENT:
3843 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3845 case OS_TERMINALREMOTEADMIN:
3846 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3849 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3850 case OS_MEORGREATER:
3851 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3852 case OS_XPORGREATER:
3853 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3855 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3856 case OS_PROFESSIONAL:
3857 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3859 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3861 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3863 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3864 case OS_TERMINALSERVER:
3865 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3866 case OS_PERSONALTERMINALSERVER:
3867 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3868 case OS_FASTUSERSWITCHING:
3869 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3871 case OS_WELCOMELOGONUI:
3872 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3874 case OS_DOMAINMEMBER:
3875 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3878 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3880 FIXME("(OS_WOW6432) Should we check this?\n");
3883 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3884 case OS_SMALLBUSINESSSERVER:
3885 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3887 FIXME("(OS_TABLEPC) What should we return here?\n");
3889 case OS_SERVERADMINUI:
3890 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3892 case OS_MEDIACENTER:
3893 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3896 FIXME("(OS_APPLIANCE) What should we return here?\n");
3902 WARN("(0x%lx) unknown parameter\n",feature);
3907 /*************************************************************************
3910 * Call IInputObject_TranslateAcceleratorIO() on an object.
3913 * lpUnknown [I] Object supporting the IInputObject interface.
3914 * lpMsg [I] Key message to be processed.
3918 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3920 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
3922 IInputObject* lpInput = NULL;
3923 HRESULT hRet = E_INVALIDARG;
3925 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
3928 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3930 if (SUCCEEDED(hRet) && lpInput)
3932 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
3933 IInputObject_Release(lpInput);
3939 /*************************************************************************
3942 * Call IInputObject_HasFocusIO() on an object.
3945 * lpUnknown [I] Object supporting the IInputObject interface.
3948 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3949 * or S_FALSE otherwise.
3950 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3952 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
3954 IInputObject* lpInput = NULL;
3955 HRESULT hRet = E_INVALIDARG;
3957 TRACE("(%p)\n", lpUnknown);
3960 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3962 if (SUCCEEDED(hRet) && lpInput)
3964 hRet = IInputObject_HasFocusIO(lpInput);
3965 IInputObject_Release(lpInput);
3971 /*************************************************************************
3972 * ColorRGBToHLS [SHLWAPI.@]
3974 * Convert an rgb COLORREF into the hls color space.
3977 * cRGB [I] Source rgb value
3978 * pwHue [O] Destination for converted hue
3979 * pwLuminance [O] Destination for converted luminance
3980 * pwSaturation [O] Destination for converted saturation
3983 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3987 * Output HLS values are constrained to the range (0..240).
3988 * For Achromatic conversions, Hue is set to 160.
3990 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3991 LPWORD pwLuminance, LPWORD pwSaturation)
3993 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3995 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3997 wR = GetRValue(cRGB);
3998 wG = GetGValue(cRGB);
3999 wB = GetBValue(cRGB);
4001 wMax = max(wR, max(wG, wB));
4002 wMin = min(wR, min(wG, wB));
4005 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
4009 /* Achromatic case */
4011 /* Hue is now unrepresentable, but this is what native returns... */
4016 /* Chromatic case */
4017 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
4020 if (wLuminosity <= 120)
4021 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
4023 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
4026 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
4027 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
4028 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
4031 wHue = wBNorm - wGNorm;
4032 else if (wG == wMax)
4033 wHue = 80 + wRNorm - wBNorm;
4035 wHue = 160 + wGNorm - wRNorm;
4038 else if (wHue > 240)
4044 *pwLuminance = wLuminosity;
4046 *pwSaturation = wSaturation;
4049 /*************************************************************************
4050 * SHCreateShellPalette [SHLWAPI.@]
4052 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4055 return CreateHalftonePalette(hdc);
4058 /*************************************************************************
4059 * SHGetInverseCMAP (SHLWAPI.@)
4061 * Get an inverse color map table.
4064 * lpCmap [O] Destination for color map
4065 * dwSize [I] Size of memory pointed to by lpCmap
4069 * Failure: E_POINTER, If lpCmap is invalid.
4070 * E_INVALIDARG, If dwFlags is invalid
4071 * E_OUTOFMEMORY, If there is no memory available
4074 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4075 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4077 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4078 * this DLL's internal CMap.
4080 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4083 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4084 *dest = (DWORD)0xabba1249;
4087 FIXME("(%p, %#lx) stub\n", dest, dwSize);
4091 /*************************************************************************
4092 * SHIsLowMemoryMachine [SHLWAPI.@]
4094 * Determine if the current computer has low memory.
4100 * TRUE if the users machine has 16 Megabytes of memory or less,
4103 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4105 FIXME("(0x%08lx) stub\n", x);
4109 /*************************************************************************
4110 * GetMenuPosFromID [SHLWAPI.@]
4112 * Return the position of a menu item from its Id.
4115 * hMenu [I] Menu containing the item
4116 * wID [I] Id of the menu item
4119 * Success: The index of the menu item in hMenu.
4120 * Failure: -1, If the item is not found.
4122 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4125 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4127 while (nIter < nCount)
4130 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4137 /*************************************************************************
4140 * Same as SHLWAPI.GetMenuPosFromID
4142 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4144 return GetMenuPosFromID(hMenu, uID);
4148 /*************************************************************************
4151 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4162 /*************************************************************************
4165 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4167 FIXME("(0x%08lx) stub\n", dwUnknown);
4172 /*************************************************************************
4175 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4176 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4178 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4181 /*************************************************************************
4182 * SHSkipJunction [SHLWAPI.@]
4184 * Determine if a bind context can be bound to an object
4187 * pbc [I] Bind context to check
4188 * pclsid [I] CLSID of object to be bound to
4191 * TRUE: If it is safe to bind
4192 * FALSE: If pbc is invalid or binding would not be safe
4195 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4197 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4198 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4205 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4209 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4210 IsEqualGUID(pclsid, &clsid))
4213 IUnknown_Release(lpUnk);
4219 /***********************************************************************
4220 * SHGetShellKey (SHLWAPI.@)
4222 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4224 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4228 /***********************************************************************
4229 * SHQueueUserWorkItem (SHLWAPI.@)
4231 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4233 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4237 /***********************************************************************
4238 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4240 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
4242 IInputObjectSite *pIOS = NULL;
4243 HRESULT hRet = E_INVALIDARG;
4245 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
4249 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
4251 if (SUCCEEDED(hRet) && pIOS)
4253 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
4254 IInputObjectSite_Release(pIOS);
4260 /***********************************************************************
4261 * SHGetValueW (SHLWAPI.@)
4263 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4265 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4269 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4271 /***********************************************************************
4272 * GetUIVersion (SHLWAPI.452)
4274 DWORD WINAPI GetUIVersion(void)
4276 static DWORD version;
4280 DllGetVersion_func pDllGetVersion;
4281 HMODULE dll = LoadLibraryA("shell32.dll");
4284 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4288 dvi.cbSize = sizeof(DLLVERSIONINFO);
4289 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4292 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */