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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
46 #include "wine/unicode.h"
48 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54 /* Get a function pointer from a DLL handle */
55 #define GET_FUNC(func, module, name, fail) \
58 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
59 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
60 if (!func) return fail; \
64 /* DLL handles for late bound calls */
65 extern HINSTANCE shlwapi_hInstance;
66 extern HMODULE SHLWAPI_hshell32;
67 extern HMODULE SHLWAPI_hwinmm;
68 extern HMODULE SHLWAPI_hcomdlg32;
69 extern HMODULE SHLWAPI_hcomctl32;
70 extern HMODULE SHLWAPI_hmpr;
71 extern HMODULE SHLWAPI_hurlmon;
72 extern HMODULE SHLWAPI_hversion;
74 extern DWORD SHLWAPI_ThreadRef_index;
76 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
77 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
78 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
79 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
80 static fnpPlaySoundW pPlaySoundW;
81 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
82 static fnpSHGetFileInfoW pSHGetFileInfoW;
83 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
84 static fnpDragQueryFileW pDragQueryFileW;
85 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
86 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
87 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
88 static fnpShellExecuteExW pShellExecuteExW;
89 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
90 static fnpSHFileOperationW pSHFileOperationW;
91 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
92 static fnpExtractIconExW pExtractIconExW;
93 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
94 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
95 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
96 static fnpSHDefExtractIconW pSHDefExtractIconW;
97 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
98 static fnpExtractIconW pExtractIconW;
99 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
100 static fnpGetSaveFileNameW pGetSaveFileNameW;
101 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
102 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
103 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
104 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
105 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
106 static fnpPageSetupDlgW pPageSetupDlgW;
107 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
108 static fnpPrintDlgW pPrintDlgW;
109 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
110 static fnpGetOpenFileNameW pGetOpenFileNameW;
111 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
112 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
113 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
114 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
115 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
116 static fnpVerQueryValueW pVerQueryValueW;
117 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
118 static fnpCOMCTL32_417 pCOMCTL32_417;
119 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
120 static fnpDllGetVersion pDllGetVersion;
121 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
122 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
123 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
124 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
126 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
127 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
128 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
129 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
132 NOTES: Most functions exported by ordinal seem to be superflous.
133 The reason for these functions to be there is to provide a wrapper
134 for unicode functions to provide these functions on systems without
135 unicode functions eg. win95/win98. Since we have such functions we just
136 call these. If running Wine with native DLLs, some late bound calls may
137 fail. However, it is better to implement the functions in the forward DLL
138 and recommend the builtin rather than reimplementing the calls here!
141 /*************************************************************************
142 * SHLWAPI_DupSharedHandle
144 * Internal implemetation of SHLWAPI_11.
147 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
148 DWORD dwSrcProcId, DWORD dwAccess,
152 DWORD dwMyProcId = GetCurrentProcessId();
155 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared, dwDstProcId, dwSrcProcId,
156 dwAccess, dwOptions);
158 /* Get dest process handle */
159 if (dwDstProcId == dwMyProcId)
160 hDst = GetCurrentProcess();
162 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
166 /* Get src process handle */
167 if (dwSrcProcId == dwMyProcId)
168 hSrc = GetCurrentProcess();
170 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
174 /* Make handle available to dest process */
175 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
176 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
179 if (dwSrcProcId != dwMyProcId)
183 if (dwDstProcId != dwMyProcId)
187 TRACE("Returning handle %p\n", hRet);
191 /*************************************************************************
194 * Create a block of sharable memory and initialise it with data.
197 * lpvData [I] Pointer to data to write
198 * dwSize [I] Size of data
199 * dwProcId [I] ID of process owning data
202 * Success: A shared memory handle
206 * Ordinals 7-11 provide a set of calls to create shared memory between a
207 * group of processes. The shared memory is treated opaquely in that its size
208 * is not exposed to clients who map it. This is accomplished by storing
209 * the size of the map as the first DWORD of mapped data, and then offsetting
210 * the view pointer returned by this size.
213 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
219 TRACE("(%p,%d,%d)\n", lpvData, dwSize, dwProcId);
221 /* Create file mapping of the correct length */
222 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
223 dwSize + sizeof(dwSize), NULL);
227 /* Get a view in our process address space */
228 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
232 /* Write size of data, followed by the data, to the view */
233 *((DWORD*)pMapped) = dwSize;
235 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
237 /* Release view. All further views mapped will be opaque */
238 UnmapViewOfFile(pMapped);
239 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
240 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
241 DUPLICATE_SAME_ACCESS);
248 /*************************************************************************
251 * Get a pointer to a block of shared memory from a shared memory handle.
254 * hShared [I] Shared memory handle
255 * dwProcId [I] ID of process owning hShared
258 * Success: A pointer to the shared memory
262 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
267 TRACE("(%p %d)\n", hShared, dwProcId);
269 /* Get handle to shared memory for current process */
270 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
271 FILE_MAP_ALL_ACCESS, 0);
273 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
277 return (char *) pMapped + sizeof(DWORD); /* Hide size */
281 /*************************************************************************
284 * Release a pointer to a block of shared memory.
287 * lpView [I] Shared memory pointer
294 BOOL WINAPI SHUnlockShared(LPVOID lpView)
296 TRACE("(%p)\n", lpView);
297 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
300 /*************************************************************************
303 * Destroy a block of sharable memory.
306 * hShared [I] Shared memory handle
307 * dwProcId [I] ID of process owning hShared
314 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
318 TRACE("(%p %d)\n", hShared, dwProcId);
320 /* Get a copy of the handle for our process, closing the source handle */
321 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
322 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
323 /* Close local copy */
324 return CloseHandle(hClose);
327 /*************************************************************************
330 * Copy a sharable memory handle from one process to another.
333 * hShared [I] Shared memory handle to duplicate
334 * dwDstProcId [I] ID of the process wanting the duplicated handle
335 * dwSrcProcId [I] ID of the process owning hShared
336 * dwAccess [I] Desired DuplicateHandle() access
337 * dwOptions [I] Desired DuplicateHandle() options
340 * Success: A handle suitable for use by the dwDstProcId process.
341 * Failure: A NULL handle.
344 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
345 DWORD dwAccess, DWORD dwOptions)
349 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
350 dwAccess, dwOptions);
354 /*************************************************************************
357 * Create and register a clipboard enumerator for a web browser.
360 * lpBC [I] Binding context
361 * lpUnknown [I] An object exposing the IWebBrowserApp interface
365 * Failure: An HRESULT error code.
368 * The enumerator is stored as a property of the web browser. If it does not
369 * yet exist, it is created and set before being registered.
371 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
373 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
374 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
375 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
376 IEnumFORMATETC* pIEnumFormatEtc = NULL;
379 IWebBrowserApp* pBrowser = NULL;
381 TRACE("(%p, %p)\n", lpBC, lpUnknown);
383 /* Get An IWebBrowserApp interface from lpUnknown */
384 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
385 if (FAILED(hRet) || !pBrowser)
386 return E_NOINTERFACE;
388 V_VT(&var) = VT_EMPTY;
390 /* The property we get is the browsers clipboard enumerator */
391 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
395 if (V_VT(&var) == VT_EMPTY)
397 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
398 char szKeyBuff[128], szValueBuff[128];
399 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
400 FORMATETC* formatList, *format;
403 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
405 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
406 "Version\\Internet Settings\\Accepted Documents", &hDocs))
409 /* Get count of values in key */
412 dwKeySize = sizeof(szKeyBuff);
413 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
417 dwNumValues = dwCount;
419 /* Note: dwCount = number of items + 1; The extra item is the end node */
420 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
422 return E_OUTOFMEMORY;
431 /* Register clipboard formats for the values and populate format list */
432 while(!dwRet && dwCount < dwNumValues)
434 dwKeySize = sizeof(szKeyBuff);
435 dwValueSize = sizeof(szValueBuff);
436 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
437 (PBYTE)szValueBuff, &dwValueSize);
441 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
443 format->dwAspect = 1;
452 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
453 format->cfFormat = 0;
455 format->dwAspect = 1;
459 /* Create a clipboard enumerator */
460 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
461 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
463 if (FAILED(hRet) || !pIEnumFormatEtc)
466 /* Set our enumerator as the browsers property */
467 V_VT(&var) = VT_UNKNOWN;
468 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
470 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
473 IEnumFORMATETC_Release(pIEnumFormatEtc);
474 goto RegisterDefaultAcceptHeaders_Exit;
478 if (V_VT(&var) == VT_UNKNOWN)
480 /* Our variant is holding the clipboard enumerator */
481 IUnknown* pIUnknown = V_UNKNOWN(&var);
482 IEnumFORMATETC* pClone = NULL;
484 TRACE("Retrieved IEnumFORMATETC property\n");
486 /* Get an IEnumFormatEtc interface from the variants value */
487 pIEnumFormatEtc = NULL;
488 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
489 (PVOID)&pIEnumFormatEtc);
490 if (!hRet && pIEnumFormatEtc)
492 /* Clone and register the enumerator */
493 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
496 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
497 pRegisterFormatEnumerator(lpBC, pClone, 0);
499 IEnumFORMATETC_Release(pClone);
502 /* Release the IEnumFormatEtc interface */
503 IEnumFORMATETC_Release(pIUnknown);
505 IUnknown_Release(V_UNKNOWN(&var));
508 RegisterDefaultAcceptHeaders_Exit:
509 IWebBrowserApp_Release(pBrowser);
513 /*************************************************************************
516 * Get Explorers "AcceptLanguage" setting.
519 * langbuf [O] Destination for language string
520 * buflen [I] Length of langbuf
521 * [0] Success: used length of langbuf
524 * Success: S_OK. langbuf is set to the language string found.
525 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
526 * does not contain the setting.
527 * E_INVALIDARG, If the buffer is not big enough
529 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
531 static const WCHAR szkeyW[] = {
532 'S','o','f','t','w','a','r','e','\\',
533 'M','i','c','r','o','s','o','f','t','\\',
534 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
535 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
536 static const WCHAR valueW[] = {
537 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
538 static const WCHAR enusW[] = {'e','n','-','u','s',0};
539 DWORD mystrlen, mytype;
545 if(!langbuf || !buflen || !*buflen)
548 mystrlen = (*buflen > 20) ? *buflen : 20 ;
549 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
550 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
551 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
552 /* Did not find value */
553 mylcid = GetUserDefaultLCID();
554 /* somehow the mylcid translates into "en-us"
555 * this is similar to "LOCALE_SABBREVLANGNAME"
556 * which could be gotten via GetLocaleInfo.
557 * The only problem is LOCALE_SABBREVLANGUAGE" is
558 * a 3 char string (first 2 are country code and third is
559 * letter for "sublanguage", which does not come close to
562 lstrcpyW(mystr, enusW);
563 mystrlen = lstrlenW(mystr);
565 /* handle returned string */
566 FIXME("missing code\n");
568 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
570 if(*buflen > strlenW(mystr)) {
571 *buflen = strlenW(mystr);
575 retval = E_INVALIDARG;
576 SetLastError(ERROR_INSUFFICIENT_BUFFER);
579 HeapFree(GetProcessHeap(), 0, mystr);
583 /*************************************************************************
586 * Ascii version of GetAcceptLanguagesW.
588 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
591 DWORD buflenW, convlen;
594 if(!langbuf || !buflen || !*buflen) return E_FAIL;
597 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
598 retval = GetAcceptLanguagesW(langbufW, &buflenW);
600 /* FIXME: this is wrong, the string may not be null-terminated */
601 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
602 *buflen, NULL, NULL);
603 *buflen = buflenW ? convlen : 0;
605 HeapFree(GetProcessHeap(), 0, langbufW);
609 /*************************************************************************
612 * Convert a GUID to a string.
615 * guid [I] GUID to convert
616 * lpszDest [O] Destination for string
617 * cchMax [I] Length of output buffer
620 * The length of the string created.
622 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
627 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
629 sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
630 guid->Data1, guid->Data2, guid->Data3,
631 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
632 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
634 iLen = strlen(xguid) + 1;
638 memcpy(lpszDest, xguid, iLen);
642 /*************************************************************************
645 * Convert a GUID to a string.
648 * guid [I] GUID to convert
649 * str [O] Destination for string
650 * cmax [I] Length of output buffer
653 * The length of the string created.
655 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
659 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
660 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
661 'X','%','0','2','X','%','0','2','X','}',0};
663 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
665 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
666 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
667 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
669 iLen = strlenW(xguid) + 1;
673 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
677 /*************************************************************************
680 * Determine if a Unicode character is a space.
683 * wc [I] Character to check.
686 * TRUE, if wc is a space,
689 BOOL WINAPI IsCharSpaceW(WCHAR wc)
693 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
696 /*************************************************************************
699 * Determine if a Unicode character is a blank.
702 * wc [I] Character to check.
705 * TRUE, if wc is a blank,
709 BOOL WINAPI IsCharBlankW(WCHAR wc)
713 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
716 /*************************************************************************
719 * Determine if a Unicode character is punctuation.
722 * wc [I] Character to check.
725 * TRUE, if wc is punctuation,
728 BOOL WINAPI IsCharPunctW(WCHAR wc)
732 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
735 /*************************************************************************
738 * Determine if a Unicode character is a control character.
741 * wc [I] Character to check.
744 * TRUE, if wc is a control character,
747 BOOL WINAPI IsCharCntrlW(WCHAR wc)
751 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
754 /*************************************************************************
757 * Determine if a Unicode character is a digit.
760 * wc [I] Character to check.
763 * TRUE, if wc is a digit,
766 BOOL WINAPI IsCharDigitW(WCHAR wc)
770 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
773 /*************************************************************************
776 * Determine if a Unicode character is a hex digit.
779 * wc [I] Character to check.
782 * TRUE, if wc is a hex digit,
785 BOOL WINAPI IsCharXDigitW(WCHAR wc)
789 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
792 /*************************************************************************
796 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
798 FIXME("(%s,0x%08x,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
802 /*************************************************************************
805 * Insert a bitmap menu item at the bottom of a menu.
808 * hMenu [I] Menu to insert into
809 * flags [I] Flags for insertion
810 * id [I] Menu ID of the item
811 * str [I] Menu text for the item
814 * Success: TRUE, the item is inserted into the menu
815 * Failure: FALSE, if any parameter is invalid
817 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
819 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
820 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
823 /*************************************************************************
826 * Get the text from a given dialog item.
829 * hWnd [I] Handle of dialog
830 * nItem [I] Index of item
831 * lpsDest [O] Buffer for receiving window text
832 * nDestLen [I] Length of buffer.
835 * Success: The length of the returned text.
838 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
840 HWND hItem = GetDlgItem(hWnd, nItem);
843 return GetWindowTextW(hItem, lpsDest, nDestLen);
845 *lpsDest = (WCHAR)'\0';
849 /*************************************************************************
852 * Set the text of a given dialog item.
855 * hWnd [I] Handle of dialog
856 * iItem [I] Index of item
857 * lpszText [O] Text to set
860 * Success: TRUE. The text of the dialog is set to lpszText.
861 * Failure: FALSE, Otherwise.
863 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
865 HWND hWndItem = GetDlgItem(hWnd, iItem);
867 return SetWindowTextW(hWndItem, lpszText);
871 /*************************************************************************
874 * Compare two Ascii strings up to a given length.
877 * lpszSrc [I] Source string
878 * lpszCmp [I] String to compare to lpszSrc
879 * len [I] Maximum length
882 * A number greater than, less than or equal to 0 depending on whether
883 * lpszSrc is greater than, less than or equal to lpszCmp.
885 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
887 return strncmp(lpszSrc, lpszCmp, len);
890 /*************************************************************************
893 * Unicode version of StrCmpNCA.
895 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
897 return strncmpW(lpszSrc, lpszCmp, len);
900 /*************************************************************************
903 * Compare two Ascii strings up to a given length, ignoring case.
906 * lpszSrc [I] Source string
907 * lpszCmp [I] String to compare to lpszSrc
908 * len [I] Maximum length
911 * A number greater than, less than or equal to 0 depending on whether
912 * lpszSrc is greater than, less than or equal to lpszCmp.
914 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
916 return strncasecmp(lpszSrc, lpszCmp, len);
919 /*************************************************************************
922 * Unicode version of StrCmpNICA.
924 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
926 return strncmpiW(lpszSrc, lpszCmp, len);
929 /*************************************************************************
932 * Compare two Ascii strings.
935 * lpszSrc [I] Source string
936 * lpszCmp [I] String to compare to lpszSrc
939 * A number greater than, less than or equal to 0 depending on whether
940 * lpszSrc is greater than, less than or equal to lpszCmp.
942 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
944 return strcmp(lpszSrc, lpszCmp);
947 /*************************************************************************
950 * Unicode version of StrCmpCA.
952 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
954 return strcmpW(lpszSrc, lpszCmp);
957 /*************************************************************************
960 * Compare two Ascii strings, ignoring case.
963 * lpszSrc [I] Source string
964 * lpszCmp [I] String to compare to lpszSrc
967 * A number greater than, less than or equal to 0 depending on whether
968 * lpszSrc is greater than, less than or equal to lpszCmp.
970 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
972 return strcasecmp(lpszSrc, lpszCmp);
975 /*************************************************************************
978 * Unicode version of StrCmpICA.
980 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
982 return strcmpiW(lpszSrc, lpszCmp);
985 /*************************************************************************
988 * Get an identification string for the OS and explorer.
991 * lpszDest [O] Destination for Id string
992 * dwDestLen [I] Length of lpszDest
995 * TRUE, If the string was created successfully
998 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1002 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
1004 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1006 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1012 /*************************************************************************
1015 * Unicode version of SHAboutInfoA.
1017 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1019 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1020 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1021 ' ','E','x','p','l','o','r','e','r','\0' };
1022 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1023 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1024 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1025 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1026 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1027 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1028 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1029 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1030 ' ','E','x','p','l','o','r','e','r','\\',
1031 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1032 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1033 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1034 'V','e','r','s','i','o','n','\0' };
1035 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1036 'O','w','n','e','r','\0' };
1037 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1038 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1039 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1040 static const WCHAR szUpdate[] = { 'I','E','A','K',
1041 'U','p','d','a','t','e','U','r','l','\0' };
1042 static const WCHAR szHelp[] = { 'I','E','A','K',
1043 'H','e','l','p','S','t','r','i','n','g','\0' };
1046 DWORD dwType, dwLen;
1048 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
1055 /* Try the NT key first, followed by 95/98 key */
1056 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1057 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1063 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1065 DWORD dwStrLen = strlenW(buff);
1066 dwLen = 30 - dwStrLen;
1067 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1068 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1070 StrCatBuffW(lpszDest, buff, dwDestLen);
1072 /* ~Registered Owner */
1075 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1077 StrCatBuffW(lpszDest, buff, dwDestLen);
1079 /* ~Registered Organization */
1081 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1083 StrCatBuffW(lpszDest, buff, dwDestLen);
1085 /* FIXME: Not sure where this number comes from */
1089 StrCatBuffW(lpszDest, buff, dwDestLen);
1093 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1095 StrCatBuffW(lpszDest, buff, dwDestLen);
1097 /* ~IE Update Url */
1099 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1101 StrCatBuffW(lpszDest, buff, dwDestLen);
1103 /* ~IE Help String */
1105 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1107 StrCatBuffW(lpszDest, buff, dwDestLen);
1113 /*************************************************************************
1116 * Call IOleCommandTarget_QueryStatus() on an object.
1119 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1120 * pguidCmdGroup [I] GUID for the command group
1122 * prgCmds [O] Commands
1123 * pCmdText [O] Command text
1127 * Failure: E_FAIL, if lpUnknown is NULL.
1128 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1129 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1131 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1132 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1134 HRESULT hRet = E_FAIL;
1136 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1140 IOleCommandTarget* lpOle;
1142 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1145 if (SUCCEEDED(hRet) && lpOle)
1147 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1149 IOleCommandTarget_Release(lpOle);
1155 /*************************************************************************
1158 * Call IOleCommandTarget_Exec() on an object.
1161 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1162 * pguidCmdGroup [I] GUID for the command group
1166 * Failure: E_FAIL, if lpUnknown is NULL.
1167 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1168 * Otherwise, an error code from IOleCommandTarget_Exec().
1170 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1171 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1174 HRESULT hRet = E_FAIL;
1176 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1177 nCmdexecopt, pvaIn, pvaOut);
1181 IOleCommandTarget* lpOle;
1183 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1185 if (SUCCEEDED(hRet) && lpOle)
1187 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1188 nCmdexecopt, pvaIn, pvaOut);
1189 IOleCommandTarget_Release(lpOle);
1195 /*************************************************************************
1198 * Retrieve, modify, and re-set a value from a window.
1201 * hWnd [I] Window to get value from
1202 * offset [I] Offset of value
1203 * wMask [I] Mask for uiFlags
1204 * wFlags [I] Bits to set in window value
1207 * The new value as it was set, or 0 if any parameter is invalid.
1210 * Any bits set in uiMask are cleared from the value, then any bits set in
1211 * uiFlags are set in the value.
1213 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1215 LONG ret = GetWindowLongA(hwnd, offset);
1216 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1218 if (newFlags != ret)
1219 ret = SetWindowLongA(hwnd, offset, newFlags);
1223 /*************************************************************************
1226 * Change a window's parent.
1229 * hWnd [I] Window to change parent of
1230 * hWndParent [I] New parent window
1233 * The old parent of hWnd.
1236 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1237 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1239 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1241 TRACE("%p, %p\n", hWnd, hWndParent);
1243 if(GetParent(hWnd) == hWndParent)
1247 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1249 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1251 return SetParent(hWnd, hWndParent);
1254 /*************************************************************************
1257 * Locate and advise a connection point in an IConnectionPointContainer object.
1260 * lpUnkSink [I] Sink for the connection point advise call
1261 * riid [I] REFIID of connection point to advise
1262 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1263 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1264 * lpCookie [O] Pointer to connection point cookie
1265 * lppCP [O] Destination for the IConnectionPoint found
1268 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1269 * that was advised. The caller is responsible for releasing it.
1270 * Failure: E_FAIL, if any arguments are invalid.
1271 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1272 * Or an HRESULT error code if any call fails.
1274 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1275 IUnknown* lpUnknown, LPDWORD lpCookie,
1276 IConnectionPoint **lppCP)
1279 IConnectionPointContainer* lpContainer;
1280 IConnectionPoint *lpCP;
1282 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1288 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1289 (void**)&lpContainer);
1290 if (SUCCEEDED(hRet))
1292 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1294 if (SUCCEEDED(hRet))
1297 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1298 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1303 if (lppCP && SUCCEEDED(hRet))
1304 *lppCP = lpCP; /* Caller keeps the interface */
1306 IConnectionPoint_Release(lpCP); /* Release it */
1309 IUnknown_Release(lpContainer);
1314 /*************************************************************************
1317 * Release an interface.
1320 * lpUnknown [I] Object to release
1325 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1329 TRACE("(%p)\n",lpUnknown);
1331 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1335 TRACE("doing Release\n");
1337 return IUnknown_Release(temp);
1340 /*************************************************************************
1343 * Skip '//' if present in a string.
1346 * lpszSrc [I] String to check for '//'
1349 * Success: The next character after the '//' or the string if not present
1350 * Failure: NULL, if lpszStr is NULL.
1352 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1354 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1359 /*************************************************************************
1362 * Check if two interfaces come from the same object.
1365 * lpInt1 [I] Interface to check against lpInt2.
1366 * lpInt2 [I] Interface to check against lpInt1.
1369 * TRUE, If the interfaces come from the same object.
1372 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1374 LPVOID lpUnknown1, lpUnknown2;
1376 TRACE("%p %p\n", lpInt1, lpInt2);
1378 if (!lpInt1 || !lpInt2)
1381 if (lpInt1 == lpInt2)
1384 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1385 (LPVOID *)&lpUnknown1)))
1388 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1389 (LPVOID *)&lpUnknown2)))
1392 if (lpUnknown1 == lpUnknown2)
1398 /*************************************************************************
1401 * Get the window handle of an object.
1404 * lpUnknown [I] Object to get the window handle of
1405 * lphWnd [O] Destination for window handle
1408 * Success: S_OK. lphWnd contains the objects window handle.
1409 * Failure: An HRESULT error code.
1412 * lpUnknown is expected to support one of the following interfaces:
1413 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1415 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1417 /* FIXME: Wine has no header for this object */
1418 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1419 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1421 HRESULT hRet = E_FAIL;
1423 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1428 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1432 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1436 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1441 if (SUCCEEDED(hRet))
1443 /* Lazyness here - Since GetWindow() is the first method for the above 3
1444 * interfaces, we use the same call for them all.
1446 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1447 IUnknown_Release(lpOle);
1449 TRACE("Returning HWND=%p\n", *lphWnd);
1455 /*************************************************************************
1458 * Call a method on as as yet unidentified object.
1461 * pUnk [I] Object supporting the unidentified interface,
1462 * arg [I] Argument for the call on the object.
1467 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1469 static const GUID guid_173 = {
1470 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1474 TRACE("(%p,%d)\n", pUnk, arg);
1476 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1477 * We use this interface as its vtable entry is compatible with the
1478 * object in question.
1479 * FIXME: Find out what this object is and where it should be defined.
1482 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1484 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1485 IMalloc_Release(pUnk2);
1490 /*************************************************************************
1493 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1497 HRESULT WINAPI IUnknown_SetSite(
1498 IUnknown *obj, /* [in] OLE object */
1499 IUnknown *site) /* [in] Site interface */
1502 IObjectWithSite *iobjwithsite;
1503 IInternetSecurityManager *isecmgr;
1505 if (!obj) return E_FAIL;
1507 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite);
1508 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite);
1511 hr = IObjectWithSite_SetSite(iobjwithsite, site);
1512 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr);
1513 IUnknown_Release(iobjwithsite);
1517 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr);
1518 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr);
1519 if (FAILED(hr)) return hr;
1521 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site);
1522 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr);
1523 IUnknown_Release(isecmgr);
1528 /*************************************************************************
1531 * Call IPersist_GetClassID() on an object.
1534 * lpUnknown [I] Object supporting the IPersist interface
1535 * lpClassId [O] Destination for Class Id
1538 * Success: S_OK. lpClassId contains the Class Id requested.
1539 * Failure: E_FAIL, If lpUnknown is NULL,
1540 * E_NOINTERFACE If lpUnknown does not support IPersist,
1541 * Or an HRESULT error code.
1543 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1545 IPersist* lpPersist;
1546 HRESULT hRet = E_FAIL;
1548 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1552 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1553 if (SUCCEEDED(hRet))
1555 IPersist_GetClassID(lpPersist, lpClassId);
1556 IPersist_Release(lpPersist);
1562 /*************************************************************************
1565 * Retrieve a Service Interface from an object.
1568 * lpUnknown [I] Object to get an IServiceProvider interface from
1569 * sid [I] Service ID for IServiceProvider_QueryService() call
1570 * riid [I] Function requested for QueryService call
1571 * lppOut [O] Destination for the service interface pointer
1574 * Success: S_OK. lppOut contains an object providing the requested service
1575 * Failure: An HRESULT error code
1578 * lpUnknown is expected to support the IServiceProvider interface.
1580 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1583 IServiceProvider* pService = NULL;
1594 /* Get an IServiceProvider interface from the object */
1595 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1596 (LPVOID*)&pService);
1598 if (!hRet && pService)
1600 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1602 /* Get a Service interface from the object */
1603 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1605 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1607 /* Release the IServiceProvider interface */
1608 IUnknown_Release(pService);
1613 /*************************************************************************
1616 * Loads a popup menu.
1619 * hInst [I] Instance handle
1620 * szName [I] Menu name
1626 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1628 HMENU hMenu, hSubMenu;
1630 if ((hMenu = LoadMenuW(hInst, szName)))
1632 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1633 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1641 typedef struct _enumWndData
1646 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1649 /* Callback for SHLWAPI_178 */
1650 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1652 enumWndData *data = (enumWndData *)lParam;
1654 TRACE("(%p,%p)\n", hWnd, data);
1655 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1659 /*************************************************************************
1662 * Send or post a message to every child of a window.
1665 * hWnd [I] Window whose children will get the messages
1666 * uiMsgId [I] Message Id
1667 * wParam [I] WPARAM of message
1668 * lParam [I] LPARAM of message
1669 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1675 * The appropriate ASCII or Unicode function is called for the window.
1677 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1681 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1685 data.uiMsgId = uiMsgId;
1686 data.wParam = wParam;
1687 data.lParam = lParam;
1690 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1692 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1694 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1698 /*************************************************************************
1701 * Remove all sub-menus from a menu.
1704 * hMenu [I] Menu to remove sub-menus from
1707 * Success: 0. All sub-menus under hMenu are removed
1708 * Failure: -1, if any parameter is invalid
1710 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1712 int iItemCount = GetMenuItemCount(hMenu) - 1;
1713 while (iItemCount >= 0)
1715 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1717 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1723 /*************************************************************************
1726 * Enable or disable a menu item.
1729 * hMenu [I] Menu holding menu item
1730 * uID [I] ID of menu item to enable/disable
1731 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1734 * The return code from EnableMenuItem.
1736 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1738 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1741 /*************************************************************************
1744 * Check or uncheck a menu item.
1747 * hMenu [I] Menu holding menu item
1748 * uID [I] ID of menu item to check/uncheck
1749 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1752 * The return code from CheckMenuItem.
1754 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1756 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1759 /*************************************************************************
1762 * Register a window class if it isn't already.
1765 * lpWndClass [I] Window class to register
1768 * The result of the RegisterClassA call.
1770 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1773 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1775 return (DWORD)RegisterClassA(wndclass);
1778 /*************************************************************************
1781 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1782 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1784 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1785 POINTL pt = { 0, 0 };
1791 pdwEffect = &dwEffect;
1793 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1796 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1798 IDropTarget_DragLeave(pDrop);
1802 /*************************************************************************
1805 * Call IPersistPropertyBag_Load() on an object.
1808 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1809 * lpPropBag [O] Destination for loaded IPropertyBag
1813 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1815 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1817 IPersistPropertyBag* lpPPBag;
1818 HRESULT hRet = E_FAIL;
1820 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1824 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1826 if (SUCCEEDED(hRet) && lpPPBag)
1828 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1829 IPersistPropertyBag_Release(lpPPBag);
1835 /*************************************************************************
1838 * Call IOleControlSite_TranslateAccelerator() on an object.
1841 * lpUnknown [I] Object supporting the IOleControlSite interface.
1842 * lpMsg [I] Key message to be processed.
1843 * dwModifiers [I] Flags containing the state of the modifier keys.
1847 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1849 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1851 IOleControlSite* lpCSite = NULL;
1852 HRESULT hRet = E_INVALIDARG;
1854 TRACE("(%p,%p,0x%08x)\n", lpUnknown, lpMsg, dwModifiers);
1857 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1859 if (SUCCEEDED(hRet) && lpCSite)
1861 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1862 IOleControlSite_Release(lpCSite);
1869 /*************************************************************************
1872 * Call IOleControlSite_GetExtendedControl() on an object.
1875 * lpUnknown [I] Object supporting the IOleControlSite interface.
1876 * lppDisp [O] Destination for resulting IDispatch.
1880 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1882 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1884 IOleControlSite* lpCSite = NULL;
1885 HRESULT hRet = E_FAIL;
1887 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1890 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1892 if (SUCCEEDED(hRet) && lpCSite)
1894 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1895 IOleControlSite_Release(lpCSite);
1901 /*************************************************************************
1904 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1905 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1907 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1908 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1909 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1910 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1911 HRESULT hRet = E_INVALIDARG;
1912 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1914 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1916 if (lpUnknown && lpArg4)
1918 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1919 (REFGUID)function_id, (void**)&lpUnkInner);
1921 if (SUCCEEDED(hRet) && lpUnkInner)
1923 /* FIXME: The type of service object requested is unknown, however
1924 * testing shows that its first method is called with 4 parameters.
1925 * Fake this by using IParseDisplayName_ParseDisplayName since the
1926 * signature and position in the vtable matches our unknown object type.
1928 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1929 lpArg1, lpArg2, lpArg3, lpArg4);
1930 IUnknown_Release(lpUnkInner);
1936 /*************************************************************************
1939 * Get a sub-menu from a menu item.
1942 * hMenu [I] Menu to get sub-menu from
1943 * uID [I] ID of menu item containing sub-menu
1946 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1948 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1952 TRACE("(%p,%u)\n", hMenu, uID);
1954 mi.cbSize = sizeof(mi);
1955 mi.fMask = MIIM_SUBMENU;
1957 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi))
1963 /*************************************************************************
1966 * Get the color depth of the primary display.
1972 * The color depth of the primary display.
1974 DWORD WINAPI SHGetCurColorRes(void)
1982 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1987 /*************************************************************************
1990 * Wait for a message to arrive, with a timeout.
1993 * hand [I] Handle to query
1994 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1997 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1998 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1999 * message is available.
2001 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
2003 DWORD dwEndTicks = GetTickCount() + dwTimeout;
2006 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
2010 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
2012 if (dwTimeout != INFINITE)
2014 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
2015 return WAIT_TIMEOUT;
2022 /*************************************************************************
2025 * Determine if a shell folder can be expanded.
2028 * lpFolder [I] Parent folder containing the object to test.
2029 * pidl [I] Id of the object to test.
2032 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2033 * Failure: E_INVALIDARG, if any argument is invalid.
2036 * If the object to be tested does not expose the IQueryInfo() interface it
2037 * will not be identified as an expandable folder.
2039 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
2041 HRESULT hRet = E_INVALIDARG;
2044 if (lpFolder && pidl)
2046 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
2047 NULL, (void**)&lpInfo);
2049 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
2054 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2055 * currently used". Really? You wouldn't be holding out on me would you?
2057 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
2059 if (SUCCEEDED(hRet))
2061 /* 0x2 is an undocumented flag apparently indicating expandability */
2062 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
2065 IQueryInfo_Release(lpInfo);
2071 /*************************************************************************
2074 * Blank out a region of text by drawing the background only.
2077 * hDC [I] Device context to draw in
2078 * pRect [I] Area to draw in
2079 * cRef [I] Color to draw in
2084 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2086 COLORREF cOldColor = SetBkColor(hDC, cRef);
2087 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2088 SetBkColor(hDC, cOldColor);
2092 /*************************************************************************
2095 * Return the value asociated with a key in a map.
2098 * lpKeys [I] A list of keys of length iLen
2099 * lpValues [I] A list of values associated with lpKeys, of length iLen
2100 * iLen [I] Length of both lpKeys and lpValues
2101 * iKey [I] The key value to look up in lpKeys
2104 * The value in lpValues associated with iKey, or -1 if iKey is not
2108 * - If two elements in the map share the same key, this function returns
2109 * the value closest to the start of the map
2110 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2112 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2114 if (lpKeys && lpValues)
2120 if (lpKeys[i] == iKey)
2121 return lpValues[i]; /* Found */
2125 return -1; /* Not found */
2129 /*************************************************************************
2132 * Copy an interface pointer
2135 * lppDest [O] Destination for copy
2136 * lpUnknown [I] Source for copy
2141 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2143 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2146 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2151 IUnknown_AddRef(lpUnknown);
2152 *lppDest = lpUnknown;
2156 /*************************************************************************
2160 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2161 REFGUID riidCmdGrp, ULONG cCmds,
2162 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2164 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2165 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2167 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2168 return DRAGDROP_E_NOTREGISTERED;
2171 /*************************************************************************
2175 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2176 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2179 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2180 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2181 return DRAGDROP_E_NOTREGISTERED;
2184 /*************************************************************************
2188 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2190 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2191 return DRAGDROP_E_NOTREGISTERED;
2194 /*************************************************************************
2197 * Determine if a window is not a child of another window.
2200 * hParent [I] Suspected parent window
2201 * hChild [I] Suspected child window
2204 * TRUE: If hChild is a child window of hParent
2205 * FALSE: If hChild is not a child window of hParent, or they are equal
2207 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2209 TRACE("(%p,%p)\n", hParent, hChild);
2211 if (!hParent || !hChild)
2213 else if(hParent == hChild)
2215 return !IsChild(hParent, hChild);
2218 /*************************************************************************
2219 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2224 DWORD num_items; /* Number of elements inserted */
2225 void *mem; /* Ptr to array */
2226 DWORD blocks_alloced; /* Number of elements allocated */
2227 BYTE inc; /* Number of elements to grow by when we need to expand */
2228 BYTE block_size; /* Size in bytes of an element */
2229 BYTE flags; /* Flags */
2232 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2234 /*************************************************************************
2237 * Initialize an FDSA arrary.
2239 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
2242 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size, inc, info, mem, init_blocks);
2248 memset(mem, 0, block_size * init_blocks);
2250 info->num_items = 0;
2253 info->blocks_alloced = init_blocks;
2254 info->block_size = block_size;
2260 /*************************************************************************
2263 * Destroy an FDSA array
2265 BOOL WINAPI FDSA_Destroy(FDSA_info *info)
2267 TRACE("(%p)\n", info);
2269 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC)
2271 HeapFree(GetProcessHeap(), 0, info->mem);
2278 /*************************************************************************
2281 * Insert element into an FDSA array
2283 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, const void *block)
2285 TRACE("(%p 0x%08x %p)\n", info, where, block);
2286 if(where > info->num_items)
2287 where = info->num_items;
2289 if(info->num_items >= info->blocks_alloced)
2291 DWORD size = (info->blocks_alloced + info->inc) * info->block_size;
2292 if(info->flags & 0x1)
2293 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size);
2296 void *old_mem = info->mem;
2297 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2298 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size);
2300 info->blocks_alloced += info->inc;
2304 if(where < info->num_items)
2306 memmove((char*)info->mem + (where + 1) * info->block_size,
2307 (char*)info->mem + where * info->block_size,
2308 (info->num_items - where) * info->block_size);
2310 memcpy((char*)info->mem + where * info->block_size, block, info->block_size);
2316 /*************************************************************************
2319 * Delete an element from an FDSA array.
2321 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
2323 TRACE("(%p 0x%08x)\n", info, where);
2325 if(where >= info->num_items)
2328 if(where < info->num_items - 1)
2330 memmove((char*)info->mem + where * info->block_size,
2331 (char*)info->mem + (where + 1) * info->block_size,
2332 (info->num_items - where - 1) * info->block_size);
2334 memset((char*)info->mem + (info->num_items - 1) * info->block_size,
2335 0, info->block_size);
2346 /*************************************************************************
2349 * Call IUnknown_QueryInterface() on a table of objects.
2353 * Failure: E_POINTER or E_NOINTERFACE.
2355 HRESULT WINAPI QISearch(
2356 LPVOID w, /* [in] Table of interfaces */
2357 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2358 REFIID riid, /* [in] REFIID to get interface for */
2359 LPVOID *ppv) /* [out] Destination for interface pointer */
2363 IFACE_INDEX_TBL *xmove;
2365 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2368 while (xmove->refid) {
2369 TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2370 if (IsEqualIID(riid, xmove->refid)) {
2371 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2372 TRACE("matched, returning (%p)\n", a_vtbl);
2373 *ppv = (LPVOID)a_vtbl;
2374 IUnknown_AddRef(a_vtbl);
2380 if (IsEqualIID(riid, &IID_IUnknown)) {
2381 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2382 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2383 *ppv = (LPVOID)a_vtbl;
2384 IUnknown_AddRef(a_vtbl);
2388 ret = E_NOINTERFACE;
2392 TRACE("-- 0x%08x\n", ret);
2396 /*************************************************************************
2399 * Remove the "PropDlgFont" property from a window.
2402 * hWnd [I] Window to remove the property from
2405 * A handle to the removed property, or NULL if it did not exist.
2407 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2411 TRACE("(%p)\n", hWnd);
2413 hProp = GetPropA(hWnd, "PropDlgFont");
2417 DeleteObject(hProp);
2418 hProp = RemovePropA(hWnd, "PropDlgFont");
2423 /*************************************************************************
2426 * Load the in-process server of a given GUID.
2429 * refiid [I] GUID of the server to load.
2432 * Success: A handle to the loaded server dll.
2433 * Failure: A NULL handle.
2435 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2439 CHAR value[MAX_PATH], string[MAX_PATH];
2441 strcpy(string, "CLSID\\");
2442 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2443 strcat(string, "\\InProcServer32");
2446 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2447 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2448 RegCloseKey(newkey);
2449 return LoadLibraryExA(value, 0, 0);
2452 /*************************************************************************
2455 * Unicode version of SHLWAPI_183.
2457 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2461 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2463 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2465 return RegisterClassW(lpWndClass);
2468 /*************************************************************************
2471 * Unregister a list of classes.
2474 * hInst [I] Application instance that registered the classes
2475 * lppClasses [I] List of class names
2476 * iCount [I] Number of names in lppClasses
2481 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2485 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2489 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2490 UnregisterClassA(*lppClasses, hInst);
2496 /*************************************************************************
2499 * Unicode version of SHUnregisterClassesA.
2501 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2505 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2509 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2510 UnregisterClassW(*lppClasses, hInst);
2516 /*************************************************************************
2519 * Call The correct (Ascii/Unicode) default window procedure for a window.
2522 * hWnd [I] Window to call the default procedure for
2523 * uMessage [I] Message ID
2524 * wParam [I] WPARAM of message
2525 * lParam [I] LPARAM of message
2528 * The result of calling DefWindowProcA() or DefWindowProcW().
2530 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2532 if (IsWindowUnicode(hWnd))
2533 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2534 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2537 /*************************************************************************
2540 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2542 HRESULT hRet = E_INVALIDARG;
2543 LPOBJECTWITHSITE lpSite = NULL;
2545 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2547 if (lpUnknown && iid && lppSite)
2549 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2551 if (SUCCEEDED(hRet) && lpSite)
2553 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2554 IObjectWithSite_Release(lpSite);
2560 /*************************************************************************
2563 * Create a worker window using CreateWindowExA().
2566 * wndProc [I] Window procedure
2567 * hWndParent [I] Parent window
2568 * dwExStyle [I] Extra style flags
2569 * dwStyle [I] Style flags
2570 * hMenu [I] Window menu
2574 * Success: The window handle of the newly created window.
2577 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2578 DWORD dwStyle, HMENU hMenu, LONG z)
2580 static const char* szClass = "WorkerA";
2584 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2585 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2587 /* Create Window class */
2589 wc.lpfnWndProc = DefWindowProcA;
2592 wc.hInstance = shlwapi_hInstance;
2594 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2595 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2596 wc.lpszMenuName = NULL;
2597 wc.lpszClassName = szClass;
2599 SHRegisterClassA(&wc); /* Register class */
2601 /* FIXME: Set extra bits in dwExStyle */
2603 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2604 hWndParent, hMenu, shlwapi_hInstance, 0);
2607 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2610 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2615 typedef struct tagPOLICYDATA
2617 DWORD policy; /* flags value passed to SHRestricted */
2618 LPCWSTR appstr; /* application str such as "Explorer" */
2619 LPCWSTR keystr; /* name of the actual registry key / policy */
2620 } POLICYDATA, *LPPOLICYDATA;
2622 #define SHELL_NO_POLICY 0xffffffff
2624 /* default shell policy registry key */
2625 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2626 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2627 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2628 '\\','P','o','l','i','c','i','e','s',0};
2630 /*************************************************************************
2633 * Retrieve a policy value from the registry.
2636 * lpSubKey [I] registry key name
2637 * lpSubName [I] subname of registry key
2638 * lpValue [I] value name of registry value
2641 * the value associated with the registry key or 0 if not found
2643 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2645 DWORD retval, datsize = sizeof(retval);
2649 lpSubKey = strRegistryPolicyW;
2651 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2652 if (retval != ERROR_SUCCESS)
2653 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2654 if (retval != ERROR_SUCCESS)
2657 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2662 /*************************************************************************
2665 * Helper function to retrieve the possibly cached value for a specific policy
2668 * policy [I] The policy to look for
2669 * initial [I] Main registry key to open, if NULL use default
2670 * polTable [I] Table of known policies, 0 terminated
2671 * polArr [I] Cache array of policy values
2674 * The retrieved policy value or 0 if not successful
2677 * This function is used by the native SHRestricted function to search for the
2678 * policy and cache it once retrieved. The current Wine implementation uses a
2679 * different POLICYDATA structure and implements a similar algorithme adapted to
2682 DWORD WINAPI SHRestrictionLookup(
2685 LPPOLICYDATA polTable,
2688 TRACE("(0x%08x %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2690 if (!polTable || !polArr)
2693 for (;polTable->policy; polTable++, polArr++)
2695 if (policy == polTable->policy)
2697 /* we have a known policy */
2699 /* check if this policy has been cached */
2700 if (*polArr == SHELL_NO_POLICY)
2701 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2705 /* we don't know this policy, return 0 */
2706 TRACE("unknown policy: (%08x)\n", policy);
2710 /*************************************************************************
2713 * Get an interface from an object.
2716 * Success: S_OK. ppv contains the requested interface.
2717 * Failure: An HRESULT error code.
2720 * This QueryInterface asks the inner object for an interface. In case
2721 * of aggregation this request would be forwarded by the inner to the
2722 * outer object. This function asks the inner object directly for the
2723 * interface circumventing the forwarding to the outer object.
2725 HRESULT WINAPI SHWeakQueryInterface(
2726 IUnknown * pUnk, /* [in] Outer object */
2727 IUnknown * pInner, /* [in] Inner object */
2728 IID * riid, /* [in] Interface GUID to query for */
2729 LPVOID* ppv) /* [out] Destination for queried interface */
2731 HRESULT hret = E_NOINTERFACE;
2732 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2735 if(pUnk && pInner) {
2736 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2737 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2739 TRACE("-- 0x%08x\n", hret);
2743 /*************************************************************************
2746 * Move a reference from one interface to another.
2749 * lpDest [O] Destination to receive the reference
2750 * lppUnknown [O] Source to give up the reference to lpDest
2755 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2757 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2762 IUnknown_AddRef(lpDest);
2763 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2767 /*************************************************************************
2770 * Convert an ASCII string of a CLSID into a CLSID.
2773 * idstr [I] String representing a CLSID in registry format
2774 * id [O] Destination for the converted CLSID
2777 * Success: TRUE. id contains the converted CLSID.
2780 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2783 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2784 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2787 /*************************************************************************
2790 * Unicode version of GUIDFromStringA.
2792 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2794 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2797 /*************************************************************************
2800 * Determine if the browser is integrated into the shell, and set a registry
2807 * 1, If the browser is not integrated.
2808 * 2, If the browser is integrated.
2811 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2812 * either set to TRUE, or removed depending on whether the browser is deemed
2815 DWORD WINAPI WhichPlatform(void)
2817 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2818 static DWORD dwState = 0;
2820 DWORD dwRet, dwData, dwSize;
2825 /* If shell32 exports DllGetVersion(), the browser is integrated */
2826 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2827 dwState = pDllGetVersion ? 2 : 1;
2829 /* Set or delete the key accordingly */
2830 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2831 "Software\\Microsoft\\Internet Explorer", 0,
2832 KEY_ALL_ACCESS, &hKey);
2835 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2836 (LPBYTE)&dwData, &dwSize);
2838 if (!dwRet && dwState == 1)
2840 /* Value exists but browser is not integrated */
2841 RegDeleteValueA(hKey, szIntegratedBrowser);
2843 else if (dwRet && dwState == 2)
2845 /* Browser is integrated but value does not exist */
2847 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2848 (LPBYTE)&dwData, sizeof(dwData));
2855 /*************************************************************************
2858 * Unicode version of SHCreateWorkerWindowA.
2860 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2861 DWORD dwStyle, HMENU hMenu, LONG z)
2863 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2867 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2868 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2870 /* If our OS is natively ASCII, use the ASCII version */
2871 if (!(GetVersion() & 0x80000000)) /* NT */
2872 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2874 /* Create Window class */
2876 wc.lpfnWndProc = DefWindowProcW;
2879 wc.hInstance = shlwapi_hInstance;
2881 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2882 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2883 wc.lpszMenuName = NULL;
2884 wc.lpszClassName = szClass;
2886 SHRegisterClassW(&wc); /* Register class */
2888 /* FIXME: Set extra bits in dwExStyle */
2890 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2891 hWndParent, hMenu, shlwapi_hInstance, 0);
2894 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2897 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2902 /*************************************************************************
2905 * Get and show a context menu from a shell folder.
2908 * hWnd [I] Window displaying the shell folder
2909 * lpFolder [I] IShellFolder interface
2910 * lpApidl [I] Id for the particular folder desired
2914 * Failure: An HRESULT error code indicating the error.
2916 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2918 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2921 /*************************************************************************
2924 * _SHPackDispParamsV
2926 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2928 FIXME("%p %p %p %p\n",w,x,y,z);
2932 /*************************************************************************
2935 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2936 * function does...).
2938 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2940 FIXME("%p %p %p %p\n", w, x, y, z);
2944 /*************************************************************************
2947 * _IConnectionPoint_SimpleInvoke
2949 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2954 FIXME("(%p %p %p) stub\n",x,y,z);
2958 /*************************************************************************
2961 * Notify an IConnectionPoint object of changes.
2964 * lpCP [I] Object to notify
2969 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2970 * IConnectionPoint interface.
2972 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2974 IEnumConnections *lpEnum;
2975 HRESULT hRet = E_NOINTERFACE;
2977 TRACE("(%p,0x%8X)\n", lpCP, dispID);
2979 /* Get an enumerator for the connections */
2981 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2983 if (SUCCEEDED(hRet))
2985 IPropertyNotifySink *lpSink;
2986 CONNECTDATA connData;
2989 /* Call OnChanged() for every notify sink in the connection point */
2990 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2992 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2995 IPropertyNotifySink_OnChanged(lpSink, dispID);
2996 IPropertyNotifySink_Release(lpSink);
2998 IUnknown_Release(connData.pUnk);
3001 IEnumConnections_Release(lpEnum);
3006 /*************************************************************************
3009 * Notify an IConnectionPointContainer object of changes.
3012 * lpUnknown [I] Object to notify
3017 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3018 * IConnectionPointContainer interface.
3020 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
3022 IConnectionPointContainer* lpCPC = NULL;
3023 HRESULT hRet = E_NOINTERFACE;
3025 TRACE("(%p,0x%8X)\n", lpUnknown, dispID);
3028 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3030 if (SUCCEEDED(hRet))
3032 IConnectionPoint* lpCP;
3034 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3035 IConnectionPointContainer_Release(lpCPC);
3037 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3038 IConnectionPoint_Release(lpCP);
3043 /*************************************************************************
3048 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3050 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
3051 return pPlaySoundW(pszSound, hmod, fdwSound);
3054 /*************************************************************************
3057 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3060 * str1: "I" "I" pushl esp+0x20
3061 * str2: "U" "I" pushl 0x77c93810
3062 * (is "I" and "U" "integer" and "unsigned" ??)
3064 * pStr: "" "" pushl eax
3065 * some_len: 0x824 0x104 pushl 0x824
3066 * lpStr2: "%l" "%l" pushl esp+0xc
3068 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3069 * LocalAlloc(0x00, some_len) -> irrelevant_var
3070 * LocalAlloc(0x40, irrelevant_len) -> pStr
3071 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3072 * shlwapi.PathRemoveBlanksW(pStr);
3074 FIXME("('%s', '%s', '%s', %08x, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3078 /*************************************************************************
3081 * Called by ICQ2000b install via SHDOCVW:
3082 * str1: "InternetShortcut"
3083 * x: some unknown pointer
3084 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3085 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3087 * In short: this one maybe creates a desktop link :-)
3089 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3091 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3095 /*************************************************************************
3100 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3101 LPCWSTR str, UINT count, const INT *lpDx)
3103 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3104 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3107 /*************************************************************************
3110 * See SHGetFileInfoW.
3112 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3113 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3115 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3116 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3119 /*************************************************************************
3122 * See DragQueryFileW.
3124 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3126 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3127 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3130 /*************************************************************************
3133 * See SHBrowseForFolderW.
3135 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3137 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3138 return pSHBrowseForFolderW(lpBi);
3141 /*************************************************************************
3144 * See SHGetPathFromIDListW.
3146 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3148 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3149 return pSHGetPathFromIDListW(pidl, pszPath);
3152 /*************************************************************************
3155 * See ShellExecuteExW.
3157 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3159 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3160 return pShellExecuteExW(lpExecInfo);
3163 /*************************************************************************
3166 * See SHFileOperationW.
3168 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3170 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3171 return pSHFileOperationW(lpFileOp);
3174 /*************************************************************************
3177 * See ExtractIconExW.
3179 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3180 HICON *phiconSmall, UINT nIcons)
3182 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3183 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3186 /*************************************************************************
3190 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3192 return InterlockedCompareExchange(dest, xchg, compare);
3195 /*************************************************************************
3198 * See GetFileVersionInfoSizeW.
3200 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3206 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3207 ret = pGetFileVersionInfoSizeW(x, y);
3211 /*************************************************************************
3214 * See GetFileVersionInfoW.
3216 BOOL WINAPI GetFileVersionInfoWrapW(
3217 LPWSTR w, /* [in] path to dll */
3218 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3219 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3220 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3222 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3223 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3226 /*************************************************************************
3229 * See VerQueryValueW.
3231 WORD WINAPI VerQueryValueWrapW(
3232 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3233 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3234 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3235 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3237 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3238 return pVerQueryValueW((char*)w+0x208, x, y, z);
3241 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3242 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3243 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3245 /*************************************************************************
3248 * Change the modality of a shell object.
3251 * lpUnknown [I] Object to make modeless
3252 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3255 * Success: S_OK. The modality lpUnknown is changed.
3256 * Failure: An HRESULT error code indicating the error.
3259 * lpUnknown must support the IOleInPlaceFrame interface, the
3260 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3261 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3262 * or this call will fail.
3264 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3269 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3274 if (IsIface(IOleInPlaceActiveObject))
3275 EnableModeless(IOleInPlaceActiveObject);
3276 else if (IsIface(IOleInPlaceFrame))
3277 EnableModeless(IOleInPlaceFrame);
3278 else if (IsIface(IShellBrowser))
3279 EnableModeless(IShellBrowser);
3281 /* FIXME: Wine has no headers for these objects yet */
3282 else if (IsIface(IInternetSecurityMgrSite))
3283 EnableModeless(IInternetSecurityMgrSite);
3284 else if (IsIface(IDocHostUIHandler))
3285 EnableModeless(IDocHostUIHandler);
3290 IUnknown_Release(lpObj);
3294 /*************************************************************************
3297 * See SHGetNewLinkInfoW.
3299 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3300 BOOL *pfMustCopy, UINT uFlags)
3302 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3303 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3306 /*************************************************************************
3309 * See SHDefExtractIconW.
3311 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3312 HICON* phiconSmall, UINT nIconSize)
3314 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3315 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3318 /*************************************************************************
3321 * Get and show a context menu from a shell folder.
3324 * hWnd [I] Window displaying the shell folder
3325 * lpFolder [I] IShellFolder interface
3326 * lpApidl [I] Id for the particular folder desired
3327 * bInvokeDefault [I] Whether to invoke the default menu item
3330 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3332 * Failure: An HRESULT error code indicating the error.
3334 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3336 IContextMenu *iContext;
3337 HRESULT hRet = E_FAIL;
3339 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3344 /* Get the context menu from the shell folder */
3345 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3346 &IID_IContextMenu, 0, (void**)&iContext);
3347 if (SUCCEEDED(hRet))
3350 if ((hMenu = CreatePopupMenu()))
3353 DWORD dwDefaultId = 0;
3355 /* Add the context menu entries to the popup */
3356 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3357 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3359 if (SUCCEEDED(hQuery))
3361 if (bInvokeDefault &&
3362 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3364 CMINVOKECOMMANDINFO cmIci;
3365 /* Invoke the default item */
3366 memset(&cmIci,0,sizeof(cmIci));
3367 cmIci.cbSize = sizeof(cmIci);
3368 cmIci.fMask = CMIC_MASK_ASYNCOK;
3370 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3371 cmIci.nShow = SW_SCROLLCHILDREN;
3373 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3378 IContextMenu_Release(iContext);
3383 /*************************************************************************
3388 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3391 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3392 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3395 /*************************************************************************
3398 * Load a library from the directory of a particular process.
3401 * new_mod [I] Library name
3402 * inst_hwnd [I] Module whose directory is to be used
3403 * bCrossCodePage [I] Should be FALSE (currently ignored)
3406 * Success: A handle to the loaded module
3407 * Failure: A NULL handle.
3409 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, BOOL bCrossCodePage)
3411 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3413 * FIXME: Native shows calls to:
3414 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3416 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3417 * RegQueryValueExA for "LPKInstalled"
3419 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3420 * RegQueryValueExA for "ResourceLocale"
3422 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3423 * RegQueryValueExA for "Locale"
3425 * and then tests the Locale ("en" for me).
3427 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3429 CHAR mod_path[2*MAX_PATH];
3433 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, bCrossCodePage);
3434 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3435 if (!len || len >= sizeof(mod_path)) return NULL;
3437 ptr = strrchr(mod_path, '\\');
3439 strcpy(ptr+1, new_mod);
3440 TRACE("loading %s\n", debugstr_a(mod_path));
3441 return LoadLibraryA(mod_path);
3446 /*************************************************************************
3449 * Unicode version of MLLoadLibraryA.
3451 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, BOOL bCrossCodePage)
3453 WCHAR mod_path[2*MAX_PATH];
3457 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, bCrossCodePage);
3458 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3459 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3461 ptr = strrchrW(mod_path, '\\');
3463 strcpyW(ptr+1, new_mod);
3464 TRACE("loading %s\n", debugstr_w(mod_path));
3465 return LoadLibraryW(mod_path);
3470 /*************************************************************************
3471 * ColorAdjustLuma [SHLWAPI.@]
3473 * Adjust the luminosity of a color
3476 * cRGB [I] RGB value to convert
3477 * dwLuma [I] Luma adjustment
3478 * bUnknown [I] Unknown
3481 * The adjusted RGB color.
3483 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3485 TRACE("(0x%8x,%d,%d)\n", cRGB, dwLuma, bUnknown);
3491 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3493 FIXME("Ignoring luma adjustment\n");
3495 /* FIXME: The ajdustment is not linear */
3497 cRGB = ColorHLSToRGB(wH, wL, wS);
3502 /*************************************************************************
3505 * See GetSaveFileNameW.
3507 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3509 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3510 return pGetSaveFileNameW(ofn);
3513 /*************************************************************************
3516 * See WNetRestoreConnectionW.
3518 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3520 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3521 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3524 /*************************************************************************
3527 * See WNetGetLastErrorW.
3529 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3530 LPWSTR lpNameBuf, DWORD nNameBufSize)
3532 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3533 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3536 /*************************************************************************
3539 * See PageSetupDlgW.
3541 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3543 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3544 return pPageSetupDlgW(pagedlg);
3547 /*************************************************************************
3552 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3554 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3555 return pPrintDlgW(printdlg);
3558 /*************************************************************************
3561 * See GetOpenFileNameW.
3563 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3565 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3566 return pGetOpenFileNameW(ofn);
3569 /*************************************************************************
3572 HRESULT WINAPI IUnknown_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum)
3577 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist);
3581 hr = IPersist_GetClassID(persist, &clsid);
3584 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder))
3585 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum);
3589 IPersist_Release(persist);
3594 /* INTERNAL: Map from HLS color space to RGB */
3595 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3597 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3601 else if (wHue > 120)
3606 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3609 /* Convert to RGB and scale into RGB range (0..255) */
3610 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3612 /*************************************************************************
3613 * ColorHLSToRGB [SHLWAPI.@]
3615 * Convert from hls color space into an rgb COLORREF.
3618 * wHue [I] Hue amount
3619 * wLuminosity [I] Luminosity amount
3620 * wSaturation [I] Saturation amount
3623 * A COLORREF representing the converted color.
3626 * Input hls values are constrained to the range (0..240).
3628 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3634 WORD wGreen, wBlue, wMid1, wMid2;
3636 if (wLuminosity > 120)
3637 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3639 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3641 wMid1 = wLuminosity * 2 - wMid2;
3643 wRed = GET_RGB(wHue + 80);
3644 wGreen = GET_RGB(wHue);
3645 wBlue = GET_RGB(wHue - 80);
3647 return RGB(wRed, wGreen, wBlue);
3650 wRed = wLuminosity * 255 / 240;
3651 return RGB(wRed, wRed, wRed);
3654 /*************************************************************************
3657 * Get the current docking status of the system.
3660 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3663 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3666 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3668 HW_PROFILE_INFOA hwInfo;
3670 TRACE("(0x%08x)\n", dwFlags);
3672 GetCurrentHwProfileA(&hwInfo);
3673 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3675 case DOCKINFO_DOCKED:
3676 case DOCKINFO_UNDOCKED:
3677 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3683 /*************************************************************************
3686 * Function seems to do FreeLibrary plus other things.
3688 * FIXME native shows the following calls:
3689 * RtlEnterCriticalSection
3691 * GetProcAddress(Comctl32??, 150L)
3693 * RtlLeaveCriticalSection
3694 * followed by the FreeLibrary.
3695 * The above code may be related to .377 above.
3697 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3699 FIXME("(%p) semi-stub\n", hModule);
3700 return FreeLibrary(hModule);
3703 /*************************************************************************
3706 BOOL WINAPI SHFlushSFCacheWrap(void) {
3711 /*************************************************************************
3714 BOOL WINAPI DeleteMenuWrap(HMENU hmenu, UINT pos, UINT flags)
3716 /* FIXME: This should do more than simply call DeleteMenu */
3717 FIXME("%p %08x %08x): semi-stub\n", hmenu, pos, flags);
3718 return DeleteMenu(hmenu, pos, flags);
3721 /*************************************************************************
3723 * FIXME I have no idea what this function does or what its arguments are.
3725 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3727 FIXME("(%p) stub\n", hInst);
3732 /*************************************************************************
3735 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3737 FIXME("(%p,%p) stub\n", hInst, hHeap);
3738 return E_FAIL; /* This is what is used if shlwapi not loaded */
3741 /*************************************************************************
3744 DWORD WINAPI MLClearMLHInstance(DWORD x)
3746 FIXME("(0x%08x)stub\n", x);
3750 /*************************************************************************
3753 * Convert an Unicode string CLSID into a CLSID.
3756 * idstr [I] string containing a CLSID in text form
3757 * id [O] CLSID extracted from the string
3760 * S_OK on success or E_INVALIDARG on failure
3763 * This is really CLSIDFromString() which is exported by ole32.dll,
3764 * however the native shlwapi.dll does *not* import ole32. Nor does
3765 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3766 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3767 * it returns an E_INVALIDARG error code on failure.
3768 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3769 * in "dlls/ole32/compobj.c".
3771 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3779 memset(id, 0, sizeof(CLSID));
3782 else { /* validate the CLSID string */
3784 if (strlenW(s) != 38)
3785 return E_INVALIDARG;
3787 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3788 return E_INVALIDARG;
3790 for (i=1; i<37; i++)
3792 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3794 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3795 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3796 ((s[i] >= L'A') && (s[i] <= L'F')))
3798 return E_INVALIDARG;
3802 TRACE("%s -> %p\n", debugstr_w(s), id);
3804 /* quick lookup table */
3805 memset(table, 0, 256*sizeof(WCHAR));
3807 for (i = 0; i < 10; i++) {
3810 for (i = 0; i < 6; i++) {
3811 table['A' + i] = i+10;
3812 table['a' + i] = i+10;
3815 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3819 s++; /* skip leading brace */
3820 for (i = 0; i < 4; i++) {
3821 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3827 for (i = 0; i < 2; i++) {
3828 p[1-i] = table[*s]<<4 | table[*(s+1)];
3834 for (i = 0; i < 2; i++) {
3835 p[1-i] = table[*s]<<4 | table[*(s+1)];
3841 /* these are just sequential bytes */
3842 for (i = 0; i < 2; i++) {
3843 *p++ = table[*s]<<4 | table[*(s+1)];
3848 for (i = 0; i < 6; i++) {
3849 *p++ = table[*s]<<4 | table[*(s+1)];
3856 /*************************************************************************
3859 * Determine if the OS supports a given feature.
3862 * dwFeature [I] Feature requested (undocumented)
3865 * TRUE If the feature is available.
3866 * FALSE If the feature is not available.
3868 BOOL WINAPI IsOS(DWORD feature)
3870 OSVERSIONINFOA osvi;
3871 DWORD platform, majorv, minorv;
3873 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3874 if(!GetVersionExA(&osvi)) {
3875 ERR("GetVersionEx failed\n");
3879 majorv = osvi.dwMajorVersion;
3880 minorv = osvi.dwMinorVersion;
3881 platform = osvi.dwPlatformId;
3883 #define ISOS_RETURN(x) \
3884 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3888 case OS_WIN32SORGREATER:
3889 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3890 || platform == VER_PLATFORM_WIN32_WINDOWS)
3892 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3893 case OS_WIN95ORGREATER:
3894 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3895 case OS_NT4ORGREATER:
3896 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3897 case OS_WIN2000ORGREATER_ALT:
3898 case OS_WIN2000ORGREATER:
3899 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3900 case OS_WIN98ORGREATER:
3901 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3903 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3905 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3906 case OS_WIN2000SERVER:
3907 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3908 case OS_WIN2000ADVSERVER:
3909 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3910 case OS_WIN2000DATACENTER:
3911 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3912 case OS_WIN2000TERMINAL:
3913 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3915 FIXME("(OS_EMBEDDED) What should we return here?\n");
3917 case OS_TERMINALCLIENT:
3918 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3920 case OS_TERMINALREMOTEADMIN:
3921 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3924 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3925 case OS_MEORGREATER:
3926 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3927 case OS_XPORGREATER:
3928 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3930 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3931 case OS_PROFESSIONAL:
3932 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3934 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3936 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3938 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3939 case OS_TERMINALSERVER:
3940 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3941 case OS_PERSONALTERMINALSERVER:
3942 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3943 case OS_FASTUSERSWITCHING:
3944 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3946 case OS_WELCOMELOGONUI:
3947 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3949 case OS_DOMAINMEMBER:
3950 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3953 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3955 FIXME("(OS_WOW6432) Should we check this?\n");
3958 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3959 case OS_SMALLBUSINESSSERVER:
3960 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3962 FIXME("(OS_TABLEPC) What should we return here?\n");
3964 case OS_SERVERADMINUI:
3965 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3967 case OS_MEDIACENTER:
3968 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3971 FIXME("(OS_APPLIANCE) What should we return here?\n");
3977 WARN("(0x%x) unknown parameter\n",feature);
3982 /*************************************************************************
3985 HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
3987 DWORD type, sz = size;
3989 if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)buf, &sz) != ERROR_SUCCESS)
3992 return SHLoadIndirectString(buf, buf, size, NULL);
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("(%08x,%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, %#x) 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%08x) 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%08x) 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("(%x, %x, %x): 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("(%x, %x, %x, %x, %x, %x, %x): 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("(%x, %s, %s, %x, %x, %x): 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 */
4386 /***********************************************************************
4387 * ShellMessageBoxWrapW [SHLWAPI.388]
4389 * loads a string resource for a module, displays the string in a
4390 * message box and writes it into the logfile
4393 * mod [I] the module containing the string resource
4394 * unknown1 [I] FIXME
4395 * uId [I] the id of the string resource
4396 * title [I] the title of the message box
4397 * unknown2 [I] FIXME
4398 * filename [I] name of the logfile
4403 BOOL WINAPI ShellMessageBoxWrapW(HMODULE mod, DWORD unknown1, UINT uId,
4404 LPCWSTR title, DWORD unknown2, LPCWSTR filename)
4406 FIXME("%p %x %d %s %x %s\n",
4407 mod, unknown1, uId, debugstr_w(title), unknown2, debugstr_w(filename));
4411 HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
4412 DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
4414 FIXME("%p %s %s %08x %08x %08x %p\n", unk,
4415 debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
4419 HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
4421 FIXME("%p %p %p %p\n", unk, x0, x1, x2);
4425 /***********************************************************************
4426 * ZoneComputePaneSize [SHLWAPI.382]
4428 UINT WINAPI ZoneComputePaneSize(HWND hwnd)
4434 typedef void (WINAPI *fnSHChangeNotify)(LONG, UINT, LPCVOID, LPCVOID);
4436 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
4438 static fnSHChangeNotify fn;
4443 hshell32 = LoadLibraryA("shell32");
4445 fn = (fnSHChangeNotify) GetProcAddress(hshell32, "SHChangeNotify");
4447 fn(wEventId, uFlags, dwItem1, dwItem2);