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 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
78 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
79 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
80 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
81 static fnpPlaySoundW pPlaySoundW;
82 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
83 static fnpSHGetFileInfoW pSHGetFileInfoW;
84 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
85 static fnpDragQueryFileW pDragQueryFileW;
86 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
87 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
88 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
89 static fnpShellExecuteExW pShellExecuteExW;
90 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
91 static fnpSHFileOperationW pSHFileOperationW;
92 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
93 static fnpExtractIconExW pExtractIconExW;
94 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
95 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
96 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
97 static fnpSHDefExtractIconW pSHDefExtractIconW;
98 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
99 static fnpExtractIconW pExtractIconW;
100 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
101 static fnpGetSaveFileNameW pGetSaveFileNameW;
102 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
103 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
104 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
105 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
106 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
107 static fnpPageSetupDlgW pPageSetupDlgW;
108 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
109 static fnpPrintDlgW pPrintDlgW;
110 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
111 static fnpGetOpenFileNameW pGetOpenFileNameW;
112 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
113 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
114 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
115 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
116 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
117 static fnpVerQueryValueW pVerQueryValueW;
118 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
119 static fnpCOMCTL32_417 pCOMCTL32_417;
120 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
121 static fnpDllGetVersion pDllGetVersion;
122 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
123 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
124 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
125 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
127 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
128 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
129 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
130 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
133 NOTES: Most functions exported by ordinal seem to be superflous.
134 The reason for these functions to be there is to provide a wrapper
135 for unicode functions to provide these functions on systems without
136 unicode functions eg. win95/win98. Since we have such functions we just
137 call these. If running Wine with native DLLs, some late bound calls may
138 fail. However, it is better to implement the functions in the forward DLL
139 and recommend the builtin rather than reimplementing the calls here!
142 /*************************************************************************
143 * SHLWAPI_DupSharedHandle
145 * Internal implemetation of SHLWAPI_11.
148 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
149 DWORD dwSrcProcId, DWORD dwAccess,
153 DWORD dwMyProcId = GetCurrentProcessId();
156 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
157 dwAccess, dwOptions);
159 /* Get dest process handle */
160 if (dwDstProcId == dwMyProcId)
161 hDst = GetCurrentProcess();
163 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
167 /* Get src process handle */
168 if (dwSrcProcId == dwMyProcId)
169 hSrc = GetCurrentProcess();
171 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
175 /* Make handle available to dest process */
176 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
177 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
180 if (dwSrcProcId != dwMyProcId)
184 if (dwDstProcId != dwMyProcId)
188 TRACE("Returning handle %p\n", hRet);
192 /*************************************************************************
195 * Create a block of sharable memory and initialise it with data.
198 * lpvData [I] Pointer to data to write
199 * dwSize [I] Size of data
200 * dwProcId [I] ID of process owning data
203 * Success: A shared memory handle
207 * Ordinals 7-11 provide a set of calls to create shared memory between a
208 * group of processes. The shared memory is treated opaquely in that its size
209 * is not exposed to clients who map it. This is accomplished by storing
210 * the size of the map as the first DWORD of mapped data, and then offsetting
211 * the view pointer returned by this size.
214 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
220 TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
222 /* Create file mapping of the correct length */
223 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
224 dwSize + sizeof(dwSize), NULL);
228 /* Get a view in our process address space */
229 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
233 /* Write size of data, followed by the data, to the view */
234 *((DWORD*)pMapped) = dwSize;
236 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
238 /* Release view. All further views mapped will be opaque */
239 UnmapViewOfFile(pMapped);
240 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
241 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
242 DUPLICATE_SAME_ACCESS);
249 /*************************************************************************
252 * Get a pointer to a block of shared memory from a shared memory handle.
255 * hShared [I] Shared memory handle
256 * dwProcId [I] ID of process owning hShared
259 * Success: A pointer to the shared memory
263 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
268 TRACE("(%p %ld)\n", hShared, dwProcId);
270 /* Get handle to shared memory for current process */
271 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
272 FILE_MAP_ALL_ACCESS, 0);
274 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
278 return (char *) pMapped + sizeof(DWORD); /* Hide size */
282 /*************************************************************************
285 * Release a pointer to a block of shared memory.
288 * lpView [I] Shared memory pointer
295 BOOL WINAPI SHUnlockShared(LPVOID lpView)
297 TRACE("(%p)\n", lpView);
298 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
301 /*************************************************************************
304 * Destroy a block of sharable memory.
307 * hShared [I] Shared memory handle
308 * dwProcId [I] ID of process owning hShared
315 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
319 TRACE("(%p %ld)\n", hShared, dwProcId);
321 /* Get a copy of the handle for our process, closing the source handle */
322 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
323 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
324 /* Close local copy */
325 return CloseHandle(hClose);
328 /*************************************************************************
331 * Copy a sharable memory handle from one process to another.
334 * hShared [I] Shared memory handle to duplicate
335 * dwDstProcId [I] ID of the process wanting the duplicated handle
336 * dwSrcProcId [I] ID of the process owning hShared
337 * dwAccess [I] Desired DuplicateHandle() access
338 * dwOptions [I] Desired DuplicateHandle() options
341 * Success: A handle suitable for use by the dwDstProcId process.
342 * Failure: A NULL handle.
345 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
346 DWORD dwAccess, DWORD dwOptions)
350 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
351 dwAccess, dwOptions);
355 /*************************************************************************
358 * Create and register a clipboard enumerator for a web browser.
361 * lpBC [I] Binding context
362 * lpUnknown [I] An object exposing the IWebBrowserApp interface
366 * Failure: An HRESULT error code.
369 * The enumerator is stored as a property of the web browser. If it does not
370 * yet exist, it is created and set before being registered.
372 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
374 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
375 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
376 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
377 IEnumFORMATETC* pIEnumFormatEtc = NULL;
380 IWebBrowserApp* pBrowser = NULL;
382 TRACE("(%p, %p)\n", lpBC, lpUnknown);
384 /* Get An IWebBrowserApp interface from lpUnknown */
385 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
386 if (FAILED(hRet) || !pBrowser)
387 return E_NOINTERFACE;
389 V_VT(&var) = VT_EMPTY;
391 /* The property we get is the browsers clipboard enumerator */
392 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
396 if (V_VT(&var) == VT_EMPTY)
398 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
399 char szKeyBuff[128], szValueBuff[128];
400 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
401 FORMATETC* formatList, *format;
404 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
406 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
407 "Version\\Internet Settings\\Accepted Documents", &hDocs))
410 /* Get count of values in key */
413 dwKeySize = sizeof(szKeyBuff);
414 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
418 dwNumValues = dwCount;
420 /* Note: dwCount = number of items + 1; The extra item is the end node */
421 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
423 return E_OUTOFMEMORY;
432 /* Register clipboard formats for the values and populate format list */
433 while(!dwRet && dwCount < dwNumValues)
435 dwKeySize = sizeof(szKeyBuff);
436 dwValueSize = sizeof(szValueBuff);
437 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
438 (PBYTE)szValueBuff, &dwValueSize);
442 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
444 format->dwAspect = 1;
453 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
454 format->cfFormat = 0;
456 format->dwAspect = 1;
460 /* Create a clipboard enumerator */
461 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
462 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
464 if (FAILED(hRet) || !pIEnumFormatEtc)
467 /* Set our enumerator as the browsers property */
468 V_VT(&var) = VT_UNKNOWN;
469 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
471 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
474 IEnumFORMATETC_Release(pIEnumFormatEtc);
475 goto RegisterDefaultAcceptHeaders_Exit;
479 if (V_VT(&var) == VT_UNKNOWN)
481 /* Our variant is holding the clipboard enumerator */
482 IUnknown* pIUnknown = V_UNKNOWN(&var);
483 IEnumFORMATETC* pClone = NULL;
485 TRACE("Retrieved IEnumFORMATETC property\n");
487 /* Get an IEnumFormatEtc interface from the variants value */
488 pIEnumFormatEtc = NULL;
489 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
490 (PVOID)&pIEnumFormatEtc);
491 if (!hRet && pIEnumFormatEtc)
493 /* Clone and register the enumerator */
494 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
497 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
498 pRegisterFormatEnumerator(lpBC, pClone, 0);
500 IEnumFORMATETC_Release(pClone);
503 /* Release the IEnumFormatEtc interface */
504 IEnumFORMATETC_Release(pIUnknown);
506 IUnknown_Release(V_UNKNOWN(&var));
509 RegisterDefaultAcceptHeaders_Exit:
510 IWebBrowserApp_Release(pBrowser);
514 /*************************************************************************
517 * Get Explorers "AcceptLanguage" setting.
520 * langbuf [O] Destination for language string
521 * buflen [I] Length of langbuf
522 * [0] Success: used length of langbuf
525 * Success: S_OK. langbuf is set to the language string found.
526 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
527 * does not contain the setting.
528 * E_INVALIDARG, If the buffer is not big enough
530 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
532 static const WCHAR szkeyW[] = {
533 'S','o','f','t','w','a','r','e','\\',
534 'M','i','c','r','o','s','o','f','t','\\',
535 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
536 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
537 static const WCHAR valueW[] = {
538 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
539 static const WCHAR enusW[] = {'e','n','-','u','s',0};
540 DWORD mystrlen, mytype;
546 if(!langbuf || !buflen || !*buflen)
549 mystrlen = (*buflen > 20) ? *buflen : 20 ;
550 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
551 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
552 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
553 /* Did not find value */
554 mylcid = GetUserDefaultLCID();
555 /* somehow the mylcid translates into "en-us"
556 * this is similar to "LOCALE_SABBREVLANGNAME"
557 * which could be gotten via GetLocaleInfo.
558 * The only problem is LOCALE_SABBREVLANGUAGE" is
559 * a 3 char string (first 2 are country code and third is
560 * letter for "sublanguage", which does not come close to
563 lstrcpyW(mystr, enusW);
564 mystrlen = lstrlenW(mystr);
566 /* handle returned string */
567 FIXME("missing code\n");
569 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
571 if(*buflen > strlenW(mystr)) {
572 *buflen = strlenW(mystr);
576 retval = E_INVALIDARG;
577 SetLastError(ERROR_INSUFFICIENT_BUFFER);
580 HeapFree(GetProcessHeap(), 0, mystr);
584 /*************************************************************************
587 * Ascii version of GetAcceptLanguagesW.
589 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
592 DWORD buflenW, convlen;
595 if(!langbuf || !buflen || !*buflen) return E_FAIL;
598 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
599 retval = GetAcceptLanguagesW(langbufW, &buflenW);
601 /* FIXME: this is wrong, the string may not be null-terminated */
602 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
603 *buflen, NULL, NULL);
604 *buflen = buflenW ? convlen : 0;
606 HeapFree(GetProcessHeap(), 0, langbufW);
610 /*************************************************************************
613 * Convert a GUID to a string.
616 * guid [I] GUID to convert
617 * lpszDest [O] Destination for string
618 * cchMax [I] Length of output buffer
621 * The length of the string created.
623 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
628 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
630 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
631 guid->Data1, guid->Data2, guid->Data3,
632 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
633 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
635 iLen = strlen(xguid) + 1;
639 memcpy(lpszDest, xguid, iLen);
643 /*************************************************************************
646 * Convert a GUID to a string.
649 * guid [I] GUID to convert
650 * str [O] Destination for string
651 * cmax [I] Length of output buffer
654 * The length of the string created.
656 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
660 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
661 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
662 'X','%','0','2','X','%','0','2','X','}',0};
664 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
666 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
667 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
668 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
670 iLen = strlenW(xguid) + 1;
674 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
678 /*************************************************************************
681 * Determine if a Unicode character is a space.
684 * wc [I] Character to check.
687 * TRUE, if wc is a space,
690 BOOL WINAPI IsCharSpaceW(WCHAR wc)
694 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
697 /*************************************************************************
700 * Determine if a Unicode character is a blank.
703 * wc [I] Character to check.
706 * TRUE, if wc is a blank,
710 BOOL WINAPI IsCharBlankW(WCHAR wc)
714 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
717 /*************************************************************************
720 * Determine if a Unicode character is punctuation.
723 * wc [I] Character to check.
726 * TRUE, if wc is punctuation,
729 BOOL WINAPI IsCharPunctW(WCHAR wc)
733 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
736 /*************************************************************************
739 * Determine if a Unicode character is a control character.
742 * wc [I] Character to check.
745 * TRUE, if wc is a control character,
748 BOOL WINAPI IsCharCntrlW(WCHAR wc)
752 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
755 /*************************************************************************
758 * Determine if a Unicode character is a digit.
761 * wc [I] Character to check.
764 * TRUE, if wc is a digit,
767 BOOL WINAPI IsCharDigitW(WCHAR wc)
771 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
774 /*************************************************************************
777 * Determine if a Unicode character is a hex digit.
780 * wc [I] Character to check.
783 * TRUE, if wc is a hex digit,
786 BOOL WINAPI IsCharXDigitW(WCHAR wc)
790 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
793 /*************************************************************************
797 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
799 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
803 /*************************************************************************
806 * Insert a bitmap menu item at the bottom of a menu.
809 * hMenu [I] Menu to insert into
810 * flags [I] Flags for insertion
811 * id [I] Menu ID of the item
812 * str [I] Menu text for the item
815 * Success: TRUE, the item is inserted into the menu
816 * Failure: FALSE, if any parameter is invalid
818 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
820 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
821 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
824 /*************************************************************************
827 * Get the text from a given dialog item.
830 * hWnd [I] Handle of dialog
831 * nItem [I] Index of item
832 * lpsDest [O] Buffer for receiving window text
833 * nDestLen [I] Length of buffer.
836 * Success: The length of the returned text.
839 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
841 HWND hItem = GetDlgItem(hWnd, nItem);
844 return GetWindowTextW(hItem, lpsDest, nDestLen);
846 *lpsDest = (WCHAR)'\0';
850 /*************************************************************************
853 * Set the text of a given dialog item.
856 * hWnd [I] Handle of dialog
857 * iItem [I] Index of item
858 * lpszText [O] Text to set
861 * Success: TRUE. The text of the dialog is set to lpszText.
862 * Failure: FALSE, Otherwise.
864 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
866 HWND hWndItem = GetDlgItem(hWnd, iItem);
868 return SetWindowTextW(hWndItem, lpszText);
872 /*************************************************************************
875 * Compare two Ascii strings up to a given length.
878 * lpszSrc [I] Source string
879 * lpszCmp [I] String to compare to lpszSrc
880 * len [I] Maximum length
883 * A number greater than, less than or equal to 0 depending on whether
884 * lpszSrc is greater than, less than or equal to lpszCmp.
886 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
888 return strncmp(lpszSrc, lpszCmp, len);
891 /*************************************************************************
894 * Unicode version of StrCmpNCA.
896 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
898 return strncmpW(lpszSrc, lpszCmp, len);
901 /*************************************************************************
904 * Compare two Ascii strings up to a given length, ignoring case.
907 * lpszSrc [I] Source string
908 * lpszCmp [I] String to compare to lpszSrc
909 * len [I] Maximum length
912 * A number greater than, less than or equal to 0 depending on whether
913 * lpszSrc is greater than, less than or equal to lpszCmp.
915 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
917 return strncasecmp(lpszSrc, lpszCmp, len);
920 /*************************************************************************
923 * Unicode version of StrCmpNICA.
925 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
927 return strncmpiW(lpszSrc, lpszCmp, len);
930 /*************************************************************************
933 * Compare two Ascii strings.
936 * lpszSrc [I] Source string
937 * lpszCmp [I] String to compare to lpszSrc
940 * A number greater than, less than or equal to 0 depending on whether
941 * lpszSrc is greater than, less than or equal to lpszCmp.
943 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
945 return strcmp(lpszSrc, lpszCmp);
948 /*************************************************************************
951 * Unicode version of StrCmpCA.
953 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
955 return strcmpW(lpszSrc, lpszCmp);
958 /*************************************************************************
961 * Compare two Ascii strings, ignoring case.
964 * lpszSrc [I] Source string
965 * lpszCmp [I] String to compare to lpszSrc
968 * A number greater than, less than or equal to 0 depending on whether
969 * lpszSrc is greater than, less than or equal to lpszCmp.
971 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
973 return strcasecmp(lpszSrc, lpszCmp);
976 /*************************************************************************
979 * Unicode version of StrCmpICA.
981 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
983 return strcmpiW(lpszSrc, lpszCmp);
986 /*************************************************************************
989 * Get an identification string for the OS and explorer.
992 * lpszDest [O] Destination for Id string
993 * dwDestLen [I] Length of lpszDest
996 * TRUE, If the string was created successfully
999 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1003 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1005 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1007 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1013 /*************************************************************************
1016 * Unicode version of SHAboutInfoA.
1018 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1020 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1021 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1022 ' ','E','x','p','l','o','r','e','r','\0' };
1023 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1024 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1025 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1026 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1027 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1028 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1029 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1030 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1031 ' ','E','x','p','l','o','r','e','r','\\',
1032 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1033 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1034 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1035 'V','e','r','s','i','o','n','\0' };
1036 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1037 'O','w','n','e','r','\0' };
1038 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1039 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1040 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1041 static const WCHAR szUpdate[] = { 'I','E','A','K',
1042 'U','p','d','a','t','e','U','r','l','\0' };
1043 static const WCHAR szHelp[] = { 'I','E','A','K',
1044 'H','e','l','p','S','t','r','i','n','g','\0' };
1047 DWORD dwType, dwLen;
1049 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1056 /* Try the NT key first, followed by 95/98 key */
1057 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1058 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1064 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1066 DWORD dwStrLen = strlenW(buff);
1067 dwLen = 30 - dwStrLen;
1068 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1069 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1071 StrCatBuffW(lpszDest, buff, dwDestLen);
1073 /* ~Registered Owner */
1076 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1078 StrCatBuffW(lpszDest, buff, dwDestLen);
1080 /* ~Registered Organization */
1082 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1084 StrCatBuffW(lpszDest, buff, dwDestLen);
1086 /* FIXME: Not sure where this number comes from */
1090 StrCatBuffW(lpszDest, buff, dwDestLen);
1094 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1096 StrCatBuffW(lpszDest, buff, dwDestLen);
1098 /* ~IE Update Url */
1100 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1102 StrCatBuffW(lpszDest, buff, dwDestLen);
1104 /* ~IE Help String */
1106 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1108 StrCatBuffW(lpszDest, buff, dwDestLen);
1114 /*************************************************************************
1117 * Call IOleCommandTarget_QueryStatus() on an object.
1120 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1121 * pguidCmdGroup [I] GUID for the command group
1123 * prgCmds [O] Commands
1124 * pCmdText [O] Command text
1128 * Failure: E_FAIL, if lpUnknown is NULL.
1129 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1130 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1132 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1133 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1135 HRESULT hRet = E_FAIL;
1137 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1141 IOleCommandTarget* lpOle;
1143 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1146 if (SUCCEEDED(hRet) && lpOle)
1148 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1150 IOleCommandTarget_Release(lpOle);
1156 /*************************************************************************
1159 * Call IOleCommandTarget_Exec() on an object.
1162 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1163 * pguidCmdGroup [I] GUID for the command group
1167 * Failure: E_FAIL, if lpUnknown is NULL.
1168 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1169 * Otherwise, an error code from IOleCommandTarget_Exec().
1171 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1172 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1175 HRESULT hRet = E_FAIL;
1177 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1178 nCmdexecopt, pvaIn, pvaOut);
1182 IOleCommandTarget* lpOle;
1184 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1186 if (SUCCEEDED(hRet) && lpOle)
1188 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1189 nCmdexecopt, pvaIn, pvaOut);
1190 IOleCommandTarget_Release(lpOle);
1196 /*************************************************************************
1199 * Retrieve, modify, and re-set a value from a window.
1202 * hWnd [I] Window to get value from
1203 * offset [I] Offset of value
1204 * wMask [I] Mask for uiFlags
1205 * wFlags [I] Bits to set in window value
1208 * The new value as it was set, or 0 if any parameter is invalid.
1211 * Any bits set in uiMask are cleared from the value, then any bits set in
1212 * uiFlags are set in the value.
1214 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1216 LONG ret = GetWindowLongA(hwnd, offset);
1217 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1219 if (newFlags != ret)
1220 ret = SetWindowLongA(hwnd, offset, newFlags);
1224 /*************************************************************************
1227 * Change a window's parent.
1230 * hWnd [I] Window to change parent of
1231 * hWndParent [I] New parent window
1234 * The old parent of hWnd.
1237 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1238 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1240 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1242 TRACE("%p, %p\n", hWnd, hWndParent);
1244 if(GetParent(hWnd) == hWndParent)
1248 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1250 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1252 return SetParent(hWnd, hWndParent);
1255 /*************************************************************************
1258 * Locate and advise a connection point in an IConnectionPointContainer object.
1261 * lpUnkSink [I] Sink for the connection point advise call
1262 * riid [I] REFIID of connection point to advise
1263 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1264 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1265 * lpCookie [O] Pointer to connection point cookie
1266 * lppCP [O] Destination for the IConnectionPoint found
1269 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1270 * that was advised. The caller is responsable for releasing it.
1271 * Failure: E_FAIL, if any arguments are invalid.
1272 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1273 * Or an HRESULT error code if any call fails.
1275 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1276 IUnknown* lpUnknown, LPDWORD lpCookie,
1277 IConnectionPoint **lppCP)
1280 IConnectionPointContainer* lpContainer;
1281 IConnectionPoint *lpCP;
1283 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1289 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1290 (void**)&lpContainer);
1291 if (SUCCEEDED(hRet))
1293 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1295 if (SUCCEEDED(hRet))
1298 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1299 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1304 if (lppCP && SUCCEEDED(hRet))
1305 *lppCP = lpCP; /* Caller keeps the interface */
1307 IConnectionPoint_Release(lpCP); /* Release it */
1310 IUnknown_Release(lpContainer);
1315 /*************************************************************************
1318 * Release an interface.
1321 * lpUnknown [I] Object to release
1326 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1330 TRACE("(%p)\n",lpUnknown);
1332 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1336 TRACE("doing Release\n");
1338 return IUnknown_Release(temp);
1341 /*************************************************************************
1344 * Skip '//' if present in a string.
1347 * lpszSrc [I] String to check for '//'
1350 * Success: The next character after the '//' or the string if not present
1351 * Failure: NULL, if lpszStr is NULL.
1353 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1355 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1360 /*************************************************************************
1363 * Check if two interfaces come from the same object.
1366 * lpInt1 [I] Interface to check against lpInt2.
1367 * lpInt2 [I] Interface to check against lpInt1.
1370 * TRUE, If the interfaces come from the same object.
1373 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1375 LPVOID lpUnknown1, lpUnknown2;
1377 TRACE("%p %p\n", lpInt1, lpInt2);
1379 if (!lpInt1 || !lpInt2)
1382 if (lpInt1 == lpInt2)
1385 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1386 (LPVOID *)&lpUnknown1)))
1389 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1390 (LPVOID *)&lpUnknown2)))
1393 if (lpUnknown1 == lpUnknown2)
1399 /*************************************************************************
1402 * Get the window handle of an object.
1405 * lpUnknown [I] Object to get the window handle of
1406 * lphWnd [O] Destination for window handle
1409 * Success: S_OK. lphWnd contains the objects window handle.
1410 * Failure: An HRESULT error code.
1413 * lpUnknown is expected to support one of the following interfaces:
1414 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1416 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1418 /* FIXME: Wine has no header for this object */
1419 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1420 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1422 HRESULT hRet = E_FAIL;
1424 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1429 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1433 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1437 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1442 if (SUCCEEDED(hRet))
1444 /* Lazyness here - Since GetWindow() is the first method for the above 3
1445 * interfaces, we use the same call for them all.
1447 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1448 IUnknown_Release(lpOle);
1450 TRACE("Returning HWND=%p\n", *lphWnd);
1456 /*************************************************************************
1459 * Call a method on as as yet unidentified object.
1462 * pUnk [I] Object supporting the unidentified interface,
1463 * arg [I] Argument for the call on the object.
1468 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1470 static const GUID guid_173 = {
1471 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1475 TRACE("(%p,%ld)\n", pUnk, arg);
1477 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1478 * We use this interface as its vtable entry is compatible with the
1479 * object in question.
1480 * FIXME: Find out what this object is and where it should be defined.
1483 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1485 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1486 IMalloc_Release(pUnk2);
1491 /*************************************************************************
1494 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1498 HRESULT WINAPI IUnknown_SetSite(
1499 IUnknown *obj, /* [in] OLE object */
1500 IUnknown *site) /* [in] Site interface */
1503 IObjectWithSite *iobjwithsite;
1504 IInternetSecurityManager *isecmgr;
1506 if (!obj) return E_FAIL;
1508 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite);
1509 TRACE("IID_IObjectWithSite QI ret=%08lx, %p\n", hr, iobjwithsite);
1512 hr = IObjectWithSite_SetSite(iobjwithsite, site);
1513 TRACE("done IObjectWithSite_SetSite ret=%08lx\n", hr);
1514 IUnknown_Release(iobjwithsite);
1518 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr);
1519 TRACE("IID_IInternetSecurityManager QI ret=%08lx, %p\n", hr, isecmgr);
1520 if (FAILED(hr)) return hr;
1522 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site);
1523 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08lx\n", hr);
1524 IUnknown_Release(isecmgr);
1529 /*************************************************************************
1532 * Call IPersist_GetClassID() on an object.
1535 * lpUnknown [I] Object supporting the IPersist interface
1536 * lpClassId [O] Destination for Class Id
1539 * Success: S_OK. lpClassId contains the Class Id requested.
1540 * Failure: E_FAIL, If lpUnknown is NULL,
1541 * E_NOINTERFACE If lpUnknown does not support IPersist,
1542 * Or an HRESULT error code.
1544 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1546 IPersist* lpPersist;
1547 HRESULT hRet = E_FAIL;
1549 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1553 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1554 if (SUCCEEDED(hRet))
1556 IPersist_GetClassID(lpPersist, lpClassId);
1557 IPersist_Release(lpPersist);
1563 /*************************************************************************
1566 * Retrieve a Service Interface from an object.
1569 * lpUnknown [I] Object to get an IServiceProvider interface from
1570 * sid [I] Service ID for IServiceProvider_QueryService() call
1571 * riid [I] Function requested for QueryService call
1572 * lppOut [O] Destination for the service interface pointer
1575 * Success: S_OK. lppOut contains an object providing the requested service
1576 * Failure: An HRESULT error code
1579 * lpUnknown is expected to support the IServiceProvider interface.
1581 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1584 IServiceProvider* pService = NULL;
1595 /* Get an IServiceProvider interface from the object */
1596 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1597 (LPVOID*)&pService);
1599 if (!hRet && pService)
1601 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1603 /* Get a Service interface from the object */
1604 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1606 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1608 /* Release the IServiceProvider interface */
1609 IUnknown_Release(pService);
1614 /*************************************************************************
1617 * Loads a popup menu.
1620 * hInst [I] Instance handle
1621 * szName [I] Menu name
1627 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1629 HMENU hMenu, hSubMenu;
1631 if ((hMenu = LoadMenuW(hInst, szName)))
1633 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1634 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1642 typedef struct _enumWndData
1647 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1650 /* Callback for SHLWAPI_178 */
1651 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1653 enumWndData *data = (enumWndData *)lParam;
1655 TRACE("(%p,%p)\n", hWnd, data);
1656 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1660 /*************************************************************************
1663 * Send or post a message to every child of a window.
1666 * hWnd [I] Window whose children will get the messages
1667 * uiMsgId [I] Message Id
1668 * wParam [I] WPARAM of message
1669 * lParam [I] LPARAM of message
1670 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1676 * The appropriate ASCII or Unicode function is called for the window.
1678 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1682 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1686 data.uiMsgId = uiMsgId;
1687 data.wParam = wParam;
1688 data.lParam = lParam;
1691 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1693 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1695 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1699 /*************************************************************************
1702 * Remove all sub-menus from a menu.
1705 * hMenu [I] Menu to remove sub-menus from
1708 * Success: 0. All sub-menus under hMenu are removed
1709 * Failure: -1, if any parameter is invalid
1711 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1713 int iItemCount = GetMenuItemCount(hMenu) - 1;
1714 while (iItemCount >= 0)
1716 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1718 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1724 /*************************************************************************
1727 * Enable or disable a menu item.
1730 * hMenu [I] Menu holding menu item
1731 * uID [I] ID of menu item to enable/disable
1732 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1735 * The return code from EnableMenuItem.
1737 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1739 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1742 /*************************************************************************
1745 * Check or uncheck a menu item.
1748 * hMenu [I] Menu holding menu item
1749 * uID [I] ID of menu item to check/uncheck
1750 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1753 * The return code from CheckMenuItem.
1755 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1757 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1760 /*************************************************************************
1763 * Register a window class if it isn't already.
1766 * lpWndClass [I] Window class to register
1769 * The result of the RegisterClassA call.
1771 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1774 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1776 return (DWORD)RegisterClassA(wndclass);
1779 /*************************************************************************
1782 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1783 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1785 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1786 POINTL pt = { 0, 0 };
1792 pdwEffect = &dwEffect;
1794 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1797 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1799 IDropTarget_DragLeave(pDrop);
1803 /*************************************************************************
1806 * Call IPersistPropertyBag_Load() on an object.
1809 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1810 * lpPropBag [O] Destination for loaded IPropertyBag
1814 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1816 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1818 IPersistPropertyBag* lpPPBag;
1819 HRESULT hRet = E_FAIL;
1821 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1825 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1827 if (SUCCEEDED(hRet) && lpPPBag)
1829 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1830 IPersistPropertyBag_Release(lpPPBag);
1836 /*************************************************************************
1839 * Call IOleControlSite_TranslateAccelerator() on an object.
1842 * lpUnknown [I] Object supporting the IOleControlSite interface.
1843 * lpMsg [I] Key message to be processed.
1844 * dwModifiers [I] Flags containing the state of the modifier keys.
1848 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1850 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1852 IOleControlSite* lpCSite = NULL;
1853 HRESULT hRet = E_INVALIDARG;
1855 TRACE("(%p,%p,0x%08lx)\n", lpUnknown, lpMsg, dwModifiers);
1858 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1860 if (SUCCEEDED(hRet) && lpCSite)
1862 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1863 IOleControlSite_Release(lpCSite);
1870 /*************************************************************************
1873 * Call IOleControlSite_GetExtendedControl() on an object.
1876 * lpUnknown [I] Object supporting the IOleControlSite interface.
1877 * lppDisp [O] Destination for resulting IDispatch.
1881 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1883 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1885 IOleControlSite* lpCSite = NULL;
1886 HRESULT hRet = E_FAIL;
1888 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1891 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1893 if (SUCCEEDED(hRet) && lpCSite)
1895 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1896 IOleControlSite_Release(lpCSite);
1902 /*************************************************************************
1905 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1906 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1908 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1909 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1910 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1911 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1912 HRESULT hRet = E_INVALIDARG;
1913 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1915 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1917 if (lpUnknown && lpArg4)
1919 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1920 (REFGUID)function_id, (void**)&lpUnkInner);
1922 if (SUCCEEDED(hRet) && lpUnkInner)
1924 /* FIXME: The type of service object requested is unknown, however
1925 * testing shows that its first method is called with 4 parameters.
1926 * Fake this by using IParseDisplayName_ParseDisplayName since the
1927 * signature and position in the vtable matches our unknown object type.
1929 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1930 lpArg1, lpArg2, lpArg3, lpArg4);
1931 IUnknown_Release(lpUnkInner);
1937 /*************************************************************************
1940 * Get a sub-menu from a menu item.
1943 * hMenu [I] Menu to get sub-menu from
1944 * uID [I] ID of menu item containing sub-menu
1947 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1949 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1953 TRACE("(%p,%uld)\n", hMenu, uID);
1955 mi.cbSize = sizeof(mi);
1956 mi.fMask = MIIM_SUBMENU;
1958 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi))
1964 /*************************************************************************
1967 * Get the color depth of the primary display.
1973 * The color depth of the primary display.
1975 DWORD WINAPI SHGetCurColorRes()
1983 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1988 /*************************************************************************
1991 * Wait for a message to arrive, with a timeout.
1994 * hand [I] Handle to query
1995 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1998 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1999 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2000 * message is available.
2002 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
2004 DWORD dwEndTicks = GetTickCount() + dwTimeout;
2007 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
2011 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
2013 if (dwTimeout != INFINITE)
2015 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
2016 return WAIT_TIMEOUT;
2023 /*************************************************************************
2026 * Determine if a shell folder can be expanded.
2029 * lpFolder [I] Parent folder containing the object to test.
2030 * pidl [I] Id of the object to test.
2033 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2034 * Failure: E_INVALIDARG, if any argument is invalid.
2037 * If the object to be tested does not expose the IQueryInfo() interface it
2038 * will not be identified as an expandable folder.
2040 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
2042 HRESULT hRet = E_INVALIDARG;
2045 if (lpFolder && pidl)
2047 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
2048 NULL, (void**)&lpInfo);
2050 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
2055 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2056 * currently used". Really? You wouldn't be holding out on me would you?
2058 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
2060 if (SUCCEEDED(hRet))
2062 /* 0x2 is an undocumented flag apparently indicating expandability */
2063 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
2066 IQueryInfo_Release(lpInfo);
2072 /*************************************************************************
2075 * Blank out a region of text by drawing the background only.
2078 * hDC [I] Device context to draw in
2079 * pRect [I] Area to draw in
2080 * cRef [I] Color to draw in
2085 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2087 COLORREF cOldColor = SetBkColor(hDC, cRef);
2088 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2089 SetBkColor(hDC, cOldColor);
2093 /*************************************************************************
2096 * Return the value asociated with a key in a map.
2099 * lpKeys [I] A list of keys of length iLen
2100 * lpValues [I] A list of values associated with lpKeys, of length iLen
2101 * iLen [I] Length of both lpKeys and lpValues
2102 * iKey [I] The key value to look up in lpKeys
2105 * The value in lpValues associated with iKey, or -1 if iKey is not
2109 * - If two elements in the map share the same key, this function returns
2110 * the value closest to the start of the map
2111 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2113 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2115 if (lpKeys && lpValues)
2121 if (lpKeys[i] == iKey)
2122 return lpValues[i]; /* Found */
2126 return -1; /* Not found */
2130 /*************************************************************************
2133 * Copy an interface pointer
2136 * lppDest [O] Destination for copy
2137 * lpUnknown [I] Source for copy
2142 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2144 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2147 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2152 IUnknown_AddRef(lpUnknown);
2153 *lppDest = lpUnknown;
2157 /*************************************************************************
2161 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2162 REFGUID riidCmdGrp, ULONG cCmds,
2163 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2165 FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",
2166 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2168 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2169 return DRAGDROP_E_NOTREGISTERED;
2172 /*************************************************************************
2176 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2177 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2180 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2181 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2182 return DRAGDROP_E_NOTREGISTERED;
2185 /*************************************************************************
2189 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2191 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2192 return DRAGDROP_E_NOTREGISTERED;
2195 /*************************************************************************
2198 * Determine if a window is not a child of another window.
2201 * hParent [I] Suspected parent window
2202 * hChild [I] Suspected child window
2205 * TRUE: If hChild is a child window of hParent
2206 * FALSE: If hChild is not a child window of hParent, or they are equal
2208 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2210 TRACE("(%p,%p)\n", hParent, hChild);
2212 if (!hParent || !hChild)
2214 else if(hParent == hChild)
2216 return !IsChild(hParent, hChild);
2219 /*************************************************************************
2220 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2225 DWORD num_items; /* Number of elements inserted */
2226 void *mem; /* Ptr to array */
2227 DWORD blocks_alloced; /* Number of elements allocated */
2228 BYTE inc; /* Number of elements to grow by when we need to expand */
2229 BYTE block_size; /* Size in bytes of an element */
2230 BYTE flags; /* Flags */
2233 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2235 /*************************************************************************
2238 * Initialize an FDSA arrary.
2240 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
2243 TRACE("(0x%08lx 0x%08lx %p %p 0x%08lx)\n", block_size, inc, info, mem, init_blocks);
2249 memset(mem, 0, block_size * init_blocks);
2251 info->num_items = 0;
2254 info->blocks_alloced = init_blocks;
2255 info->block_size = block_size;
2261 /*************************************************************************
2264 * Destroy an FDSA array
2266 BOOL WINAPI FDSA_Destroy(FDSA_info *info)
2268 TRACE("(%p)\n", info);
2270 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC)
2272 HeapFree(GetProcessHeap(), 0, info->mem);
2279 /*************************************************************************
2282 * Insert element into an FDSA array
2284 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, void *block)
2286 TRACE("(%p 0x%08lx %p)\n", info, where, block);
2287 if(where > info->num_items)
2288 where = info->num_items;
2290 if(info->num_items >= info->blocks_alloced)
2292 DWORD size = (info->blocks_alloced + info->inc) * info->block_size;
2293 if(info->flags & 0x1)
2294 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size);
2297 void *old_mem = info->mem;
2298 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2299 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size);
2301 info->blocks_alloced += info->inc;
2305 if(where < info->num_items)
2307 memmove((char*)info->mem + (where + 1) * info->block_size,
2308 (char*)info->mem + where * info->block_size,
2309 (info->num_items - where) * info->block_size);
2311 memcpy((char*)info->mem + where * info->block_size, block, info->block_size);
2317 /*************************************************************************
2320 * Delete an element from an FDSA array.
2322 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
2324 TRACE("(%p 0x%08lx)\n", info, where);
2326 if(where >= info->num_items)
2329 if(where < info->num_items - 1)
2331 memmove((char*)info->mem + where * info->block_size,
2332 (char*)info->mem + (where + 1) * info->block_size,
2333 (info->num_items - where - 1) * info->block_size);
2335 memset((char*)info->mem + (info->num_items - 1) * info->block_size,
2336 0, info->block_size);
2347 /*************************************************************************
2350 * Call IUnknown_QueryInterface() on a table of objects.
2354 * Failure: E_POINTER or E_NOINTERFACE.
2356 HRESULT WINAPI QISearch(
2357 LPVOID w, /* [in] Table of interfaces */
2358 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2359 REFIID riid, /* [in] REFIID to get interface for */
2360 LPVOID *ppv) /* [out] Destination for interface pointer */
2364 IFACE_INDEX_TBL *xmove;
2366 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2369 while (xmove->refid) {
2370 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2371 if (IsEqualIID(riid, xmove->refid)) {
2372 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2373 TRACE("matched, returning (%p)\n", a_vtbl);
2374 *ppv = (LPVOID)a_vtbl;
2375 IUnknown_AddRef(a_vtbl);
2381 if (IsEqualIID(riid, &IID_IUnknown)) {
2382 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2383 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2384 *ppv = (LPVOID)a_vtbl;
2385 IUnknown_AddRef(a_vtbl);
2389 ret = E_NOINTERFACE;
2393 TRACE("-- 0x%08lx\n", ret);
2397 /*************************************************************************
2400 * Remove the "PropDlgFont" property from a window.
2403 * hWnd [I] Window to remove the property from
2406 * A handle to the removed property, or NULL if it did not exist.
2408 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2412 TRACE("(%p)\n", hWnd);
2414 hProp = GetPropA(hWnd, "PropDlgFont");
2418 DeleteObject(hProp);
2419 hProp = RemovePropA(hWnd, "PropDlgFont");
2424 /*************************************************************************
2427 * Load the in-process server of a given GUID.
2430 * refiid [I] GUID of the server to load.
2433 * Success: A handle to the loaded server dll.
2434 * Failure: A NULL handle.
2436 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2440 CHAR value[MAX_PATH], string[MAX_PATH];
2442 strcpy(string, "CLSID\\");
2443 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2444 strcat(string, "\\InProcServer32");
2447 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2448 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2449 RegCloseKey(newkey);
2450 return LoadLibraryExA(value, 0, 0);
2453 /*************************************************************************
2456 * Unicode version of SHLWAPI_183.
2458 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2462 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2464 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2466 return RegisterClassW(lpWndClass);
2469 /*************************************************************************
2472 * Unregister a list of classes.
2475 * hInst [I] Application instance that registered the classes
2476 * lppClasses [I] List of class names
2477 * iCount [I] Number of names in lppClasses
2482 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2486 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2490 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2491 UnregisterClassA(*lppClasses, hInst);
2497 /*************************************************************************
2500 * Unicode version of SHUnregisterClassesA.
2502 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2506 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2510 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2511 UnregisterClassW(*lppClasses, hInst);
2517 /*************************************************************************
2520 * Call The correct (Ascii/Unicode) default window procedure for a window.
2523 * hWnd [I] Window to call the default procedure for
2524 * uMessage [I] Message ID
2525 * wParam [I] WPARAM of message
2526 * lParam [I] LPARAM of message
2529 * The result of calling DefWindowProcA() or DefWindowProcW().
2531 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2533 if (IsWindowUnicode(hWnd))
2534 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2535 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2538 /*************************************************************************
2541 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2543 HRESULT hRet = E_INVALIDARG;
2544 LPOBJECTWITHSITE lpSite = NULL;
2546 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2548 if (lpUnknown && iid && lppSite)
2550 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2552 if (SUCCEEDED(hRet) && lpSite)
2554 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2555 IObjectWithSite_Release(lpSite);
2561 /*************************************************************************
2564 * Create a worker window using CreateWindowExA().
2567 * wndProc [I] Window procedure
2568 * hWndParent [I] Parent window
2569 * dwExStyle [I] Extra style flags
2570 * dwStyle [I] Style flags
2571 * hMenu [I] Window menu
2575 * Success: The window handle of the newly created window.
2578 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2579 DWORD dwStyle, HMENU hMenu, LONG z)
2581 static const char* szClass = "WorkerA";
2585 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2586 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2588 /* Create Window class */
2590 wc.lpfnWndProc = DefWindowProcA;
2593 wc.hInstance = shlwapi_hInstance;
2595 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2596 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2597 wc.lpszMenuName = NULL;
2598 wc.lpszClassName = szClass;
2600 SHRegisterClassA(&wc); /* Register class */
2602 /* FIXME: Set extra bits in dwExStyle */
2604 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2605 hWndParent, hMenu, shlwapi_hInstance, 0);
2608 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2611 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2616 typedef struct tagPOLICYDATA
2618 DWORD policy; /* flags value passed to SHRestricted */
2619 LPCWSTR appstr; /* application str such as "Explorer" */
2620 LPCWSTR keystr; /* name of the actual registry key / policy */
2621 } POLICYDATA, *LPPOLICYDATA;
2623 #define SHELL_NO_POLICY 0xffffffff
2625 /* default shell policy registry key */
2626 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2627 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2628 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2629 '\\','P','o','l','i','c','i','e','s',0};
2631 /*************************************************************************
2634 * Retrieve a policy value from the registry.
2637 * lpSubKey [I] registry key name
2638 * lpSubName [I] subname of registry key
2639 * lpValue [I] value name of registry value
2642 * the value associated with the registry key or 0 if not found
2644 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2646 DWORD retval, datsize = sizeof(retval);
2650 lpSubKey = strRegistryPolicyW;
2652 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2653 if (retval != ERROR_SUCCESS)
2654 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2655 if (retval != ERROR_SUCCESS)
2658 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2663 /*************************************************************************
2666 * Helper function to retrieve the possibly cached value for a specific policy
2669 * policy [I] The policy to look for
2670 * initial [I] Main registry key to open, if NULL use default
2671 * polTable [I] Table of known policies, 0 terminated
2672 * polArr [I] Cache array of policy values
2675 * The retrieved policy value or 0 if not successful
2678 * This function is used by the native SHRestricted function to search for the
2679 * policy and cache it once retrieved. The current Wine implementation uses a
2680 * different POLICYDATA structure and implements a similar algorithme adapted to
2683 DWORD WINAPI SHRestrictionLookup(
2686 LPPOLICYDATA polTable,
2689 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2691 if (!polTable || !polArr)
2694 for (;polTable->policy; polTable++, polArr++)
2696 if (policy == polTable->policy)
2698 /* we have a known policy */
2700 /* check if this policy has been cached */
2701 if (*polArr == SHELL_NO_POLICY)
2702 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2706 /* we don't know this policy, return 0 */
2707 TRACE("unknown policy: (%08lx)\n", policy);
2711 /*************************************************************************
2714 * Get an interface from an object.
2717 * Success: S_OK. ppv contains the requested interface.
2718 * Failure: An HRESULT error code.
2721 * This QueryInterface asks the inner object for an interface. In case
2722 * of aggregation this request would be forwarded by the inner to the
2723 * outer object. This function asks the inner object directly for the
2724 * interface circumventing the forwarding to the outer object.
2726 HRESULT WINAPI SHWeakQueryInterface(
2727 IUnknown * pUnk, /* [in] Outer object */
2728 IUnknown * pInner, /* [in] Inner object */
2729 IID * riid, /* [in] Interface GUID to query for */
2730 LPVOID* ppv) /* [out] Destination for queried interface */
2732 HRESULT hret = E_NOINTERFACE;
2733 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2736 if(pUnk && pInner) {
2737 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2738 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2740 TRACE("-- 0x%08lx\n", hret);
2744 /*************************************************************************
2747 * Move a reference from one interface to another.
2750 * lpDest [O] Destination to receive the reference
2751 * lppUnknown [O] Source to give up the reference to lpDest
2756 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2758 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2763 IUnknown_AddRef(lpDest);
2764 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2768 /*************************************************************************
2771 * Convert an ASCII string of a CLSID into a CLSID.
2774 * idstr [I] String representing a CLSID in registry format
2775 * id [O] Destination for the converted CLSID
2778 * Success: TRUE. id contains the converted CLSID.
2781 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2784 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2785 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2788 /*************************************************************************
2791 * Unicode version of GUIDFromStringA.
2793 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2795 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2798 /*************************************************************************
2801 * Determine if the browser is integrated into the shell, and set a registry
2808 * 1, If the browser is not integrated.
2809 * 2, If the browser is integrated.
2812 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2813 * either set to TRUE, or removed depending on whether the browser is deemed
2816 DWORD WINAPI WhichPlatform()
2818 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2819 static DWORD dwState = 0;
2821 DWORD dwRet, dwData, dwSize;
2826 /* If shell32 exports DllGetVersion(), the browser is integrated */
2827 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2828 dwState = pDllGetVersion ? 2 : 1;
2830 /* Set or delete the key accordingly */
2831 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2832 "Software\\Microsoft\\Internet Explorer", 0,
2833 KEY_ALL_ACCESS, &hKey);
2836 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2837 (LPBYTE)&dwData, &dwSize);
2839 if (!dwRet && dwState == 1)
2841 /* Value exists but browser is not integrated */
2842 RegDeleteValueA(hKey, szIntegratedBrowser);
2844 else if (dwRet && dwState == 2)
2846 /* Browser is integrated but value does not exist */
2848 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2849 (LPBYTE)&dwData, sizeof(dwData));
2856 /*************************************************************************
2859 * Unicode version of SHCreateWorkerWindowA.
2861 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2862 DWORD dwStyle, HMENU hMenu, LONG z)
2864 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2868 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2869 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2871 /* If our OS is natively ASCII, use the ASCII version */
2872 if (!(GetVersion() & 0x80000000)) /* NT */
2873 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2875 /* Create Window class */
2877 wc.lpfnWndProc = DefWindowProcW;
2880 wc.hInstance = shlwapi_hInstance;
2882 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2883 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2884 wc.lpszMenuName = NULL;
2885 wc.lpszClassName = szClass;
2887 SHRegisterClassW(&wc); /* Register class */
2889 /* FIXME: Set extra bits in dwExStyle */
2891 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2892 hWndParent, hMenu, shlwapi_hInstance, 0);
2895 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2898 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2903 /*************************************************************************
2906 * Get and show a context menu from a shell folder.
2909 * hWnd [I] Window displaying the shell folder
2910 * lpFolder [I] IShellFolder interface
2911 * lpApidl [I] Id for the particular folder desired
2915 * Failure: An HRESULT error code indicating the error.
2917 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2919 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2922 /*************************************************************************
2925 * _SHPackDispParamsV
2927 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2929 FIXME("%p %p %p %p\n",w,x,y,z);
2933 /*************************************************************************
2936 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2937 * function does...).
2939 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2941 FIXME("%p %p %p %p\n", w, x, y, z);
2945 /*************************************************************************
2948 * _IConnectionPoint_SimpleInvoke
2950 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2955 FIXME("(%p %p %p) stub\n",x,y,z);
2959 /*************************************************************************
2962 * Notify an IConnectionPoint object of changes.
2965 * lpCP [I] Object to notify
2970 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2971 * IConnectionPoint interface.
2973 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2975 IEnumConnections *lpEnum;
2976 HRESULT hRet = E_NOINTERFACE;
2978 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2980 /* Get an enumerator for the connections */
2982 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2984 if (SUCCEEDED(hRet))
2986 IPropertyNotifySink *lpSink;
2987 CONNECTDATA connData;
2990 /* Call OnChanged() for every notify sink in the connection point */
2991 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2993 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2996 IPropertyNotifySink_OnChanged(lpSink, dispID);
2997 IPropertyNotifySink_Release(lpSink);
2999 IUnknown_Release(connData.pUnk);
3002 IEnumConnections_Release(lpEnum);
3007 /*************************************************************************
3010 * Notify an IConnectionPointContainer object of changes.
3013 * lpUnknown [I] Object to notify
3018 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3019 * IConnectionPointContainer interface.
3021 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
3023 IConnectionPointContainer* lpCPC = NULL;
3024 HRESULT hRet = E_NOINTERFACE;
3026 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
3029 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3031 if (SUCCEEDED(hRet))
3033 IConnectionPoint* lpCP;
3035 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3036 IConnectionPointContainer_Release(lpCPC);
3038 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3039 IConnectionPoint_Release(lpCP);
3044 /*************************************************************************
3049 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3051 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
3052 return pPlaySoundW(pszSound, hmod, fdwSound);
3055 /*************************************************************************
3058 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3061 * str1: "I" "I" pushl esp+0x20
3062 * str2: "U" "I" pushl 0x77c93810
3063 * (is "I" and "U" "integer" and "unsigned" ??)
3065 * pStr: "" "" pushl eax
3066 * some_len: 0x824 0x104 pushl 0x824
3067 * lpStr2: "%l" "%l" pushl esp+0xc
3069 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3070 * LocalAlloc(0x00, some_len) -> irrelevant_var
3071 * LocalAlloc(0x40, irrelevant_len) -> pStr
3072 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3073 * shlwapi.PathRemoveBlanksW(pStr);
3075 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3079 /*************************************************************************
3082 * Called by ICQ2000b install via SHDOCVW:
3083 * str1: "InternetShortcut"
3084 * x: some unknown pointer
3085 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3086 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3088 * In short: this one maybe creates a desktop link :-)
3090 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3092 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3096 /*************************************************************************
3101 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3102 LPCWSTR str, UINT count, const INT *lpDx)
3104 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3105 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3108 /*************************************************************************
3111 * See SHGetFileInfoW.
3113 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3114 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3116 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3117 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3120 /*************************************************************************
3123 * See DragQueryFileW.
3125 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3127 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3128 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3131 /*************************************************************************
3134 * See SHBrowseForFolderW.
3136 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3138 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3139 return pSHBrowseForFolderW(lpBi);
3142 /*************************************************************************
3145 * See SHGetPathFromIDListW.
3147 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3149 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3150 return pSHGetPathFromIDListW(pidl, pszPath);
3153 /*************************************************************************
3156 * See ShellExecuteExW.
3158 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3160 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3161 return pShellExecuteExW(lpExecInfo);
3164 /*************************************************************************
3167 * See SHFileOperationW.
3169 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3171 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3172 return pSHFileOperationW(lpFileOp);
3175 /*************************************************************************
3178 * See ExtractIconExW.
3180 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3181 HICON *phiconSmall, UINT nIcons)
3183 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3184 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3187 /*************************************************************************
3191 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3193 return InterlockedCompareExchange(dest, xchg, compare);
3196 /*************************************************************************
3199 * See GetFileVersionInfoSizeW.
3201 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3207 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3208 ret = pGetFileVersionInfoSizeW(x, y);
3212 /*************************************************************************
3215 * See GetFileVersionInfoW.
3217 BOOL WINAPI GetFileVersionInfoWrapW(
3218 LPWSTR w, /* [in] path to dll */
3219 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3220 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3221 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3223 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3224 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3227 /*************************************************************************
3230 * See VerQueryValueW.
3232 WORD WINAPI VerQueryValueWrapW(
3233 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3234 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3235 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3236 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3238 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3239 return pVerQueryValueW((char*)w+0x208, x, y, z);
3242 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3243 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3244 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3246 /*************************************************************************
3249 * Change the modality of a shell object.
3252 * lpUnknown [I] Object to make modeless
3253 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3256 * Success: S_OK. The modality lpUnknown is changed.
3257 * Failure: An HRESULT error code indicating the error.
3260 * lpUnknown must support the IOleInPlaceFrame interface, the
3261 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3262 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3263 * or this call will fail.
3265 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3270 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3275 if (IsIface(IOleInPlaceActiveObject))
3276 EnableModeless(IOleInPlaceActiveObject);
3277 else if (IsIface(IOleInPlaceFrame))
3278 EnableModeless(IOleInPlaceFrame);
3279 else if (IsIface(IShellBrowser))
3280 EnableModeless(IShellBrowser);
3282 /* FIXME: Wine has no headers for these objects yet */
3283 else if (IsIface(IInternetSecurityMgrSite))
3284 EnableModeless(IInternetSecurityMgrSite);
3285 else if (IsIface(IDocHostUIHandler))
3286 EnableModeless(IDocHostUIHandler);
3291 IUnknown_Release(lpObj);
3295 /*************************************************************************
3298 * See SHGetNewLinkInfoW.
3300 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3301 BOOL *pfMustCopy, UINT uFlags)
3303 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3304 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3307 /*************************************************************************
3310 * See SHDefExtractIconW.
3312 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3313 HICON* phiconSmall, UINT nIconSize)
3315 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3316 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3319 /*************************************************************************
3322 * Get and show a context menu from a shell folder.
3325 * hWnd [I] Window displaying the shell folder
3326 * lpFolder [I] IShellFolder interface
3327 * lpApidl [I] Id for the particular folder desired
3328 * bInvokeDefault [I] Whether to invoke the default menu item
3331 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3333 * Failure: An HRESULT error code indicating the error.
3335 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3337 IContextMenu *iContext;
3338 HRESULT hRet = E_FAIL;
3340 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3345 /* Get the context menu from the shell folder */
3346 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3347 &IID_IContextMenu, 0, (void**)&iContext);
3348 if (SUCCEEDED(hRet))
3351 if ((hMenu = CreatePopupMenu()))
3354 DWORD dwDefaultId = 0;
3356 /* Add the context menu entries to the popup */
3357 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3358 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3360 if (SUCCEEDED(hQuery))
3362 if (bInvokeDefault &&
3363 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3365 CMINVOKECOMMANDINFO cmIci;
3366 /* Invoke the default item */
3367 memset(&cmIci,0,sizeof(cmIci));
3368 cmIci.cbSize = sizeof(cmIci);
3369 cmIci.fMask = CMIC_MASK_ASYNCOK;
3371 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3372 cmIci.nShow = SW_SCROLLCHILDREN;
3374 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3379 IContextMenu_Release(iContext);
3384 /*************************************************************************
3389 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3392 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3393 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3396 /*************************************************************************
3399 LANGID WINAPI MLGetUILanguage()
3402 /* FIXME: This should be a forward in the .spec file to the win2k function
3403 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3405 return GetUserDefaultLangID();
3408 /*************************************************************************
3411 * Load a library from the directory of a particular process.
3414 * new_mod [I] Library name
3415 * inst_hwnd [I] Module whose directory is to be used
3416 * dwFlags [I] Flags controlling the load
3419 * Success: A handle to the loaded module
3420 * Failure: A NULL handle.
3422 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3424 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3426 * FIXME: Native shows calls to:
3427 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3429 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3430 * RegQueryValueExA for "LPKInstalled"
3432 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3433 * RegQueryValueExA for "ResourceLocale"
3435 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3436 * RegQueryValueExA for "Locale"
3438 * and then tests the Locale ("en" for me).
3440 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3442 CHAR mod_path[2*MAX_PATH];
3446 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3447 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3448 if (!len || len >= sizeof(mod_path)) return NULL;
3450 ptr = strrchr(mod_path, '\\');
3452 strcpy(ptr+1, new_mod);
3453 TRACE("loading %s\n", debugstr_a(mod_path));
3454 return LoadLibraryA(mod_path);
3459 /*************************************************************************
3462 * Unicode version of MLLoadLibraryA.
3464 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3466 WCHAR mod_path[2*MAX_PATH];
3470 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3471 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3472 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3474 ptr = strrchrW(mod_path, '\\');
3476 strcpyW(ptr+1, new_mod);
3477 TRACE("loading %s\n", debugstr_w(mod_path));
3478 return LoadLibraryW(mod_path);
3483 /*************************************************************************
3484 * ColorAdjustLuma [SHLWAPI.@]
3486 * Adjust the luminosity of a color
3489 * cRGB [I] RGB value to convert
3490 * dwLuma [I] Luma adjustment
3491 * bUnknown [I] Unknown
3494 * The adjusted RGB color.
3496 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3498 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3504 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3506 FIXME("Ignoring luma adjustment\n");
3508 /* FIXME: The ajdustment is not linear */
3510 cRGB = ColorHLSToRGB(wH, wL, wS);
3515 /*************************************************************************
3518 * See GetSaveFileNameW.
3520 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3522 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3523 return pGetSaveFileNameW(ofn);
3526 /*************************************************************************
3529 * See WNetRestoreConnectionW.
3531 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3533 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3534 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3537 /*************************************************************************
3540 * See WNetGetLastErrorW.
3542 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3543 LPWSTR lpNameBuf, DWORD nNameBufSize)
3545 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3546 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3549 /*************************************************************************
3552 * See PageSetupDlgW.
3554 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3556 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3557 return pPageSetupDlgW(pagedlg);
3560 /*************************************************************************
3565 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3567 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3568 return pPrintDlgW(printdlg);
3571 /*************************************************************************
3574 * See GetOpenFileNameW.
3576 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3578 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3579 return pGetOpenFileNameW(ofn);
3582 /*************************************************************************
3585 HRESULT WINAPI IUnknown_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum)
3590 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist);
3594 hr = IPersist_GetClassID(persist, &clsid);
3597 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder))
3598 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum);
3602 IPersist_Release(persist);
3607 /* INTERNAL: Map from HLS color space to RGB */
3608 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3610 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3614 else if (wHue > 120)
3619 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3622 /* Convert to RGB and scale into RGB range (0..255) */
3623 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3625 /*************************************************************************
3626 * ColorHLSToRGB [SHLWAPI.@]
3628 * Convert from hls color space into an rgb COLORREF.
3631 * wHue [I] Hue amount
3632 * wLuminosity [I] Luminosity amount
3633 * wSaturation [I] Saturation amount
3636 * A COLORREF representing the converted color.
3639 * Input hls values are constrained to the range (0..240).
3641 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3647 WORD wGreen, wBlue, wMid1, wMid2;
3649 if (wLuminosity > 120)
3650 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3652 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3654 wMid1 = wLuminosity * 2 - wMid2;
3656 wRed = GET_RGB(wHue + 80);
3657 wGreen = GET_RGB(wHue);
3658 wBlue = GET_RGB(wHue - 80);
3660 return RGB(wRed, wGreen, wBlue);
3663 wRed = wLuminosity * 255 / 240;
3664 return RGB(wRed, wRed, wRed);
3667 /*************************************************************************
3670 * Get the current docking status of the system.
3673 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3676 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3679 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3681 HW_PROFILE_INFOA hwInfo;
3683 TRACE("(0x%08lx)\n", dwFlags);
3685 GetCurrentHwProfileA(&hwInfo);
3686 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3688 case DOCKINFO_DOCKED:
3689 case DOCKINFO_UNDOCKED:
3690 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3696 /*************************************************************************
3699 * Function seems to do FreeLibrary plus other things.
3701 * FIXME native shows the following calls:
3702 * RtlEnterCriticalSection
3704 * GetProcAddress(Comctl32??, 150L)
3706 * RtlLeaveCriticalSection
3707 * followed by the FreeLibrary.
3708 * The above code may be related to .377 above.
3710 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3712 FIXME("(%p) semi-stub\n", hModule);
3713 return FreeLibrary(hModule);
3716 /*************************************************************************
3719 BOOL WINAPI SHFlushSFCacheWrap(void) {
3724 /*************************************************************************
3727 BOOL WINAPI DeleteMenuWrap(HMENU hmenu, UINT pos, UINT flags)
3729 /* FIXME: This should do more than simply call DeleteMenu */
3730 FIXME("%p %08x %08x): semi-stub\n", hmenu, pos, flags);
3731 return DeleteMenu(hmenu, pos, flags);
3734 /*************************************************************************
3736 * FIXME I have no idea what this function does or what its arguments are.
3738 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3740 FIXME("(%p) stub\n", hInst);
3745 /*************************************************************************
3748 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3750 FIXME("(%p,%p) stub\n", hInst, hHeap);
3751 return E_FAIL; /* This is what is used if shlwapi not loaded */
3754 /*************************************************************************
3757 DWORD WINAPI MLClearMLHInstance(DWORD x)
3759 FIXME("(0x%08lx)stub\n", x);
3763 /*************************************************************************
3766 * Convert an Unicode string CLSID into a CLSID.
3769 * idstr [I] string containing a CLSID in text form
3770 * id [O] CLSID extracted from the string
3773 * S_OK on success or E_INVALIDARG on failure
3776 * This is really CLSIDFromString() which is exported by ole32.dll,
3777 * however the native shlwapi.dll does *not* import ole32. Nor does
3778 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3779 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3780 * it returns an E_INVALIDARG error code on failure.
3781 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3782 * in "dlls/ole32/compobj.c".
3784 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3792 memset(id, 0, sizeof(CLSID));
3795 else { /* validate the CLSID string */
3797 if (strlenW(s) != 38)
3798 return E_INVALIDARG;
3800 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3801 return E_INVALIDARG;
3803 for (i=1; i<37; i++)
3805 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3807 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3808 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3809 ((s[i] >= L'A') && (s[i] <= L'F')))
3811 return E_INVALIDARG;
3815 TRACE("%s -> %p\n", debugstr_w(s), id);
3817 /* quick lookup table */
3818 memset(table, 0, 256*sizeof(WCHAR));
3820 for (i = 0; i < 10; i++) {
3823 for (i = 0; i < 6; i++) {
3824 table['A' + i] = i+10;
3825 table['a' + i] = i+10;
3828 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3832 s++; /* skip leading brace */
3833 for (i = 0; i < 4; i++) {
3834 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3840 for (i = 0; i < 2; i++) {
3841 p[1-i] = table[*s]<<4 | table[*(s+1)];
3847 for (i = 0; i < 2; i++) {
3848 p[1-i] = table[*s]<<4 | table[*(s+1)];
3854 /* these are just sequential bytes */
3855 for (i = 0; i < 2; i++) {
3856 *p++ = table[*s]<<4 | table[*(s+1)];
3861 for (i = 0; i < 6; i++) {
3862 *p++ = table[*s]<<4 | table[*(s+1)];
3869 /*************************************************************************
3872 * Determine if the OS supports a given feature.
3875 * dwFeature [I] Feature requested (undocumented)
3878 * TRUE If the feature is available.
3879 * FALSE If the feature is not available.
3881 BOOL WINAPI IsOS(DWORD feature)
3883 OSVERSIONINFOA osvi;
3884 DWORD platform, majorv, minorv;
3886 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3887 if(!GetVersionExA(&osvi)) {
3888 ERR("GetVersionEx failed");
3892 majorv = osvi.dwMajorVersion;
3893 minorv = osvi.dwMinorVersion;
3894 platform = osvi.dwPlatformId;
3896 #define ISOS_RETURN(x) \
3897 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3901 case OS_WIN32SORGREATER:
3902 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3903 || platform == VER_PLATFORM_WIN32_WINDOWS)
3905 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3906 case OS_WIN95ORGREATER:
3907 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3908 case OS_NT4ORGREATER:
3909 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3910 case OS_WIN2000ORGREATER_ALT:
3911 case OS_WIN2000ORGREATER:
3912 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3913 case OS_WIN98ORGREATER:
3914 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3916 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3918 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3919 case OS_WIN2000SERVER:
3920 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3921 case OS_WIN2000ADVSERVER:
3922 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3923 case OS_WIN2000DATACENTER:
3924 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3925 case OS_WIN2000TERMINAL:
3926 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3928 FIXME("(OS_EMBEDDED) What should we return here?\n");
3930 case OS_TERMINALCLIENT:
3931 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3933 case OS_TERMINALREMOTEADMIN:
3934 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3937 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3938 case OS_MEORGREATER:
3939 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3940 case OS_XPORGREATER:
3941 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3943 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3944 case OS_PROFESSIONAL:
3945 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3947 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3949 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3951 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3952 case OS_TERMINALSERVER:
3953 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3954 case OS_PERSONALTERMINALSERVER:
3955 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3956 case OS_FASTUSERSWITCHING:
3957 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3959 case OS_WELCOMELOGONUI:
3960 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3962 case OS_DOMAINMEMBER:
3963 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3966 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3968 FIXME("(OS_WOW6432) Should we check this?\n");
3971 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3972 case OS_SMALLBUSINESSSERVER:
3973 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3975 FIXME("(OS_TABLEPC) What should we return here?\n");
3977 case OS_SERVERADMINUI:
3978 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3980 case OS_MEDIACENTER:
3981 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3984 FIXME("(OS_APPLIANCE) What should we return here?\n");
3990 WARN("(0x%lx) unknown parameter\n",feature);
3995 /*************************************************************************
3998 * Call IInputObject_TranslateAcceleratorIO() on an object.
4001 * lpUnknown [I] Object supporting the IInputObject interface.
4002 * lpMsg [I] Key message to be processed.
4006 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4008 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
4010 IInputObject* lpInput = NULL;
4011 HRESULT hRet = E_INVALIDARG;
4013 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
4016 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
4018 if (SUCCEEDED(hRet) && lpInput)
4020 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
4021 IInputObject_Release(lpInput);
4027 /*************************************************************************
4030 * Call IInputObject_HasFocusIO() on an object.
4033 * lpUnknown [I] Object supporting the IInputObject interface.
4036 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4037 * or S_FALSE otherwise.
4038 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4040 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
4042 IInputObject* lpInput = NULL;
4043 HRESULT hRet = E_INVALIDARG;
4045 TRACE("(%p)\n", lpUnknown);
4048 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
4050 if (SUCCEEDED(hRet) && lpInput)
4052 hRet = IInputObject_HasFocusIO(lpInput);
4053 IInputObject_Release(lpInput);
4059 /*************************************************************************
4060 * ColorRGBToHLS [SHLWAPI.@]
4062 * Convert an rgb COLORREF into the hls color space.
4065 * cRGB [I] Source rgb value
4066 * pwHue [O] Destination for converted hue
4067 * pwLuminance [O] Destination for converted luminance
4068 * pwSaturation [O] Destination for converted saturation
4071 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4075 * Output HLS values are constrained to the range (0..240).
4076 * For Achromatic conversions, Hue is set to 160.
4078 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
4079 LPWORD pwLuminance, LPWORD pwSaturation)
4081 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
4083 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
4085 wR = GetRValue(cRGB);
4086 wG = GetGValue(cRGB);
4087 wB = GetBValue(cRGB);
4089 wMax = max(wR, max(wG, wB));
4090 wMin = min(wR, min(wG, wB));
4093 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
4097 /* Achromatic case */
4099 /* Hue is now unrepresentable, but this is what native returns... */
4104 /* Chromatic case */
4105 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
4108 if (wLuminosity <= 120)
4109 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
4111 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
4114 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
4115 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
4116 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
4119 wHue = wBNorm - wGNorm;
4120 else if (wG == wMax)
4121 wHue = 80 + wRNorm - wBNorm;
4123 wHue = 160 + wGNorm - wRNorm;
4126 else if (wHue > 240)
4132 *pwLuminance = wLuminosity;
4134 *pwSaturation = wSaturation;
4137 /*************************************************************************
4138 * SHCreateShellPalette [SHLWAPI.@]
4140 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4143 return CreateHalftonePalette(hdc);
4146 /*************************************************************************
4147 * SHGetInverseCMAP (SHLWAPI.@)
4149 * Get an inverse color map table.
4152 * lpCmap [O] Destination for color map
4153 * dwSize [I] Size of memory pointed to by lpCmap
4157 * Failure: E_POINTER, If lpCmap is invalid.
4158 * E_INVALIDARG, If dwFlags is invalid
4159 * E_OUTOFMEMORY, If there is no memory available
4162 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4163 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4165 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4166 * this DLL's internal CMap.
4168 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4171 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4172 *dest = (DWORD)0xabba1249;
4175 FIXME("(%p, %#lx) stub\n", dest, dwSize);
4179 /*************************************************************************
4180 * SHIsLowMemoryMachine [SHLWAPI.@]
4182 * Determine if the current computer has low memory.
4188 * TRUE if the users machine has 16 Megabytes of memory or less,
4191 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4193 FIXME("(0x%08lx) stub\n", x);
4197 /*************************************************************************
4198 * GetMenuPosFromID [SHLWAPI.@]
4200 * Return the position of a menu item from its Id.
4203 * hMenu [I] Menu containing the item
4204 * wID [I] Id of the menu item
4207 * Success: The index of the menu item in hMenu.
4208 * Failure: -1, If the item is not found.
4210 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4213 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4215 while (nIter < nCount)
4217 mi.cbSize = sizeof(mi);
4219 if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4226 /*************************************************************************
4229 * Same as SHLWAPI.GetMenuPosFromID
4231 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4233 return GetMenuPosFromID(hMenu, uID);
4237 /*************************************************************************
4240 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4251 /*************************************************************************
4254 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4256 FIXME("(0x%08lx) stub\n", dwUnknown);
4261 /*************************************************************************
4264 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4265 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4267 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4270 /*************************************************************************
4271 * SHSkipJunction [SHLWAPI.@]
4273 * Determine if a bind context can be bound to an object
4276 * pbc [I] Bind context to check
4277 * pclsid [I] CLSID of object to be bound to
4280 * TRUE: If it is safe to bind
4281 * FALSE: If pbc is invalid or binding would not be safe
4284 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4286 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4287 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4294 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4298 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4299 IsEqualGUID(pclsid, &clsid))
4302 IUnknown_Release(lpUnk);
4308 /***********************************************************************
4309 * SHGetShellKey (SHLWAPI.@)
4311 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4313 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4317 /***********************************************************************
4318 * SHQueueUserWorkItem (SHLWAPI.@)
4320 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4322 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4326 /***********************************************************************
4327 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4329 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
4331 IInputObjectSite *pIOS = NULL;
4332 HRESULT hRet = E_INVALIDARG;
4334 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
4338 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
4340 if (SUCCEEDED(hRet) && pIOS)
4342 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
4343 IInputObjectSite_Release(pIOS);
4349 /***********************************************************************
4350 * SHGetValueW (SHLWAPI.@)
4352 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4354 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4358 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4360 /***********************************************************************
4361 * GetUIVersion (SHLWAPI.452)
4363 DWORD WINAPI GetUIVersion(void)
4365 static DWORD version;
4369 DllGetVersion_func pDllGetVersion;
4370 HMODULE dll = LoadLibraryA("shell32.dll");
4373 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4377 dvi.cbSize = sizeof(DLLVERSIONINFO);
4378 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4381 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */