2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
45 #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 typedef HANDLE HSHARED; /* Shared memory */
78 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
79 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
80 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
81 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
83 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
84 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
85 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
86 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
87 static fnpPlaySoundW pPlaySoundW;
88 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
89 static fnpSHGetFileInfoW pSHGetFileInfoW;
90 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
91 static fnpDragQueryFileW pDragQueryFileW;
92 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
93 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
94 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
95 static fnpShellExecuteExW pShellExecuteExW;
96 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
97 static fnpSHFileOperationW pSHFileOperationW;
98 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
99 static fnpExtractIconExW pExtractIconExW;
100 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
101 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
102 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
103 static fnpSHDefExtractIconW pSHDefExtractIconW;
104 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
105 static fnpExtractIconW pExtractIconW;
106 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
107 static fnpGetSaveFileNameW pGetSaveFileNameW;
108 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
109 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
110 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
111 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
112 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
113 static fnpPageSetupDlgW pPageSetupDlgW;
114 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
115 static fnpPrintDlgW pPrintDlgW;
116 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
117 static fnpGetOpenFileNameW pGetOpenFileNameW;
118 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
119 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
120 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
121 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
122 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
123 static fnpVerQueryValueW pVerQueryValueW;
124 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
125 static fnpCOMCTL32_417 pCOMCTL32_417;
126 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
127 static fnpDllGetVersion pDllGetVersion;
128 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
129 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
130 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
131 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
133 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
134 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
135 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
136 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
139 NOTES: Most functions exported by ordinal seem to be superflous.
140 The reason for these functions to be there is to provide a wrapper
141 for unicode functions to provide these functions on systems without
142 unicode functions eg. win95/win98. Since we have such functions we just
143 call these. If running Wine with native DLL's, some late bound calls may
144 fail. However, its better to implement the functions in the forward DLL
145 and recommend the builtin rather than reimplementing the calls here!
148 /*************************************************************************
149 * SHLWAPI_DupSharedHandle
151 * Internal implemetation of SHLWAPI_11.
154 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
155 DWORD dwSrcProcId, DWORD dwAccess,
159 DWORD dwMyProcId = GetCurrentProcessId();
160 HSHARED hRet = (HSHARED)NULL;
162 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
163 dwAccess, dwOptions);
165 /* Get dest process handle */
166 if (dwDstProcId == dwMyProcId)
167 hDst = GetCurrentProcess();
169 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
173 /* Get src process handle */
174 if (dwSrcProcId == dwMyProcId)
175 hSrc = GetCurrentProcess();
177 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
181 /* Make handle available to dest process */
182 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
183 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
184 hRet = (HSHARED)NULL;
186 if (dwSrcProcId != dwMyProcId)
190 if (dwDstProcId != dwMyProcId)
194 TRACE("Returning handle %p\n", (PVOID)hRet);
198 /*************************************************************************
201 * Create a block of sharable memory and initialise it with data.
204 * dwProcId [I] ID of process owning data
205 * lpvData [I] Pointer to data to write
206 * dwSize [I] Size of data
209 * Success: A shared memory handle
213 * Ordinals 7-11 provide a set of calls to create shared memory between a
214 * group of processes. The shared memory is treated opaquely in that its size
215 * is not exposed to clients who map it. This is accomplished by storing
216 * the size of the map as the first DWORD of mapped data, and then offsetting
217 * the view pointer returned by this size.
220 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
224 HSHARED hRet = (HSHARED)NULL;
226 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
228 /* Create file mapping of the correct length */
229 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
230 dwSize + sizeof(dwSize), NULL);
234 /* Get a view in our process address space */
235 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
239 /* Write size of data, followed by the data, to the view */
240 *((DWORD*)pMapped) = dwSize;
242 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
244 /* Release view. All further views mapped will be opaque */
245 UnmapViewOfFile(pMapped);
246 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
247 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
248 DUPLICATE_SAME_ACCESS);
255 /*************************************************************************
258 * Get a pointer to a block of shared memory from a shared memory handle.
261 * hShared [I] Shared memory handle
262 * dwProcId [I] ID of process owning hShared
265 * Success: A pointer to the shared memory
269 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
274 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
276 /* Get handle to shared memory for current process */
277 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
278 FILE_MAP_ALL_ACCESS, 0);
280 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
284 return (char *) pMapped + sizeof(DWORD); /* Hide size */
288 /*************************************************************************
291 * Release a pointer to a block of shared memory.
294 * lpView [I] Shared memory pointer
301 BOOL WINAPI SHUnlockShared(LPVOID lpView)
303 TRACE("(%p)\n", lpView);
304 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
307 /*************************************************************************
310 * Destroy a block of sharable memory.
313 * hShared [I] Shared memory handle
314 * dwProcId [I] ID of process owning hShared
321 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
325 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
327 /* Get a copy of the handle for our process, closing the source handle */
328 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
329 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
330 /* Close local copy */
331 return CloseHandle((HANDLE)hClose);
334 /*************************************************************************
337 * Copy a sharable memory handle from one process to another.
340 * hShared [I] Shared memory handle to duplicate
341 * dwDstProcId [I] ID of the process wanting the duplicated handle
342 * dwSrcProcId [I] ID of the process owning hShared
343 * dwAccess [I] Desired DuplicateHandle() access
344 * dwOptions [I] Desired DuplicateHandle() options
347 * Success: A handle suitable for use by the dwDstProcId process.
348 * Failure: A NULL handle.
351 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
352 DWORD dwAccess, DWORD dwOptions)
356 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
357 dwAccess, dwOptions);
361 /*************************************************************************
364 * Create and register a clipboard enumerator for a web browser.
367 * lpBC [I] Binding context
368 * lpUnknown [I] An object exposing the IWebBrowserApp interface
372 * Failure: An HRESULT error code.
375 * The enumerator is stored as a property of the web browser. If it does not
376 * yet exist, it is created and set before being registered.
378 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
380 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
381 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
382 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
383 IEnumFORMATETC* pIEnumFormatEtc = NULL;
386 IWebBrowserApp* pBrowser = NULL;
388 TRACE("(%p, %p)\n", lpBC, lpUnknown);
390 /* Get An IWebBrowserApp interface from lpUnknown */
391 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
392 if (FAILED(hRet) || !pBrowser)
393 return E_NOINTERFACE;
395 V_VT(&var) = VT_EMPTY;
397 /* The property we get is the browsers clipboard enumerator */
398 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
402 if (V_VT(&var) == VT_EMPTY)
404 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
405 char szKeyBuff[128], szValueBuff[128];
406 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
407 FORMATETC* formatList, *format;
410 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
412 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
413 "Version\\Internet Settings\\Accepted Documents", &hDocs))
416 /* Get count of values in key */
419 dwKeySize = sizeof(szKeyBuff);
420 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
424 dwNumValues = dwCount;
426 /* Note: dwCount = number of items + 1; The extra item is the end node */
427 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
429 return E_OUTOFMEMORY;
438 /* Register clipboard formats for the values and populate format list */
439 while(!dwRet && dwCount < dwNumValues)
441 dwKeySize = sizeof(szKeyBuff);
442 dwValueSize = sizeof(szValueBuff);
443 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
444 (PBYTE)szValueBuff, &dwValueSize);
448 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
450 format->dwAspect = 1;
459 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
460 format->cfFormat = 0;
462 format->dwAspect = 1;
466 /* Create a clipboard enumerator */
467 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
468 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
470 if (FAILED(hRet) || !pIEnumFormatEtc)
473 /* Set our enumerator as the browsers property */
474 V_VT(&var) = VT_UNKNOWN;
475 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
477 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
480 IEnumFORMATETC_Release(pIEnumFormatEtc);
481 goto RegisterDefaultAcceptHeaders_Exit;
485 if (V_VT(&var) == VT_UNKNOWN)
487 /* Our variant is holding the clipboard enumerator */
488 IUnknown* pIUnknown = V_UNKNOWN(&var);
489 IEnumFORMATETC* pClone = NULL;
491 TRACE("Retrieved IEnumFORMATETC property\n");
493 /* Get an IEnumFormatEtc interface from the variants value */
494 pIEnumFormatEtc = NULL;
495 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
496 (PVOID)&pIEnumFormatEtc);
497 if (!hRet && pIEnumFormatEtc)
499 /* Clone and register the enumerator */
500 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
503 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
504 pRegisterFormatEnumerator(lpBC, pClone, 0);
506 IEnumFORMATETC_Release(pClone);
509 /* Release the IEnumFormatEtc interface */
510 IEnumFORMATETC_Release(pIUnknown);
512 IUnknown_Release(V_UNKNOWN(&var));
515 RegisterDefaultAcceptHeaders_Exit:
516 IWebBrowserApp_Release(pBrowser);
520 /*************************************************************************
523 * Get Explorers "AcceptLanguage" setting.
526 * langbuf [O] Destination for language string
527 * buflen [I] Length of langbuf
528 * [0] Success: used length of langbuf
531 * Success: S_OK. langbuf is set to the language string found.
532 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
533 * does not contain the setting.
534 * E_INVALIDARG, If the buffer is not big enough
536 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
538 static const WCHAR szkeyW[] = {
539 'S','o','f','t','w','a','r','e','\\',
540 'M','i','c','r','o','s','o','f','t','\\',
541 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
542 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
543 static const WCHAR valueW[] = {
544 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
545 static const WCHAR enusW[] = {'e','n','-','u','s',0};
546 DWORD mystrlen, mytype;
552 if(!langbuf || !buflen || !*buflen)
555 mystrlen = (*buflen > 20) ? *buflen : 20 ;
556 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
557 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
558 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
559 /* Did not find value */
560 mylcid = GetUserDefaultLCID();
561 /* somehow the mylcid translates into "en-us"
562 * this is similar to "LOCALE_SABBREVLANGNAME"
563 * which could be gotten via GetLocaleInfo.
564 * The only problem is LOCALE_SABBREVLANGUAGE" is
565 * a 3 char string (first 2 are country code and third is
566 * letter for "sublanguage", which does not come close to
569 lstrcpyW(mystr, enusW);
570 mystrlen = lstrlenW(mystr);
572 /* handle returned string */
573 FIXME("missing code\n");
575 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
577 if(*buflen > lstrlenW(mystr)) {
578 *buflen = lstrlenW(mystr);
582 retval = E_INVALIDARG;
583 SetLastError(ERROR_INSUFFICIENT_BUFFER);
586 HeapFree(GetProcessHeap(), 0, mystr);
590 /*************************************************************************
593 * Ascii version of GetAcceptLanguagesW.
595 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
598 DWORD buflenW, convlen;
601 if(!langbuf || !buflen || !*buflen) return E_FAIL;
604 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
605 retval = GetAcceptLanguagesW(langbufW, &buflenW);
607 /* FIXME: this is wrong, the string may not be null-terminated */
608 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
609 *buflen, NULL, NULL);
610 *buflen = buflenW ? convlen : 0;
612 if(langbufW) HeapFree(GetProcessHeap(), 0, langbufW);
616 /*************************************************************************
619 * Convert a GUID to a string.
622 * guid [I] GUID to convert
623 * str [O] Destination for string
624 * cmax [I] Length of output buffer
627 * The length of the string created.
629 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
634 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
636 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
637 guid->Data1, guid->Data2, guid->Data3,
638 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
639 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
641 iLen = strlen(xguid) + 1;
645 memcpy(lpszDest, xguid, iLen);
649 /*************************************************************************
652 * Unicode version of SHStringFromGUIDA.
654 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
657 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
660 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
664 /*************************************************************************
667 * Determine if a Unicode character is alphabetic.
670 * wc [I] Character to check.
673 * TRUE, if wc is alphabetic,
676 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
678 return (get_char_typeW(wc) & C1_ALPHA) != 0;
681 /*************************************************************************
684 * Determine if a Unicode character is upper-case.
687 * wc [I] Character to check.
690 * TRUE, if wc is upper-case,
693 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
695 return (get_char_typeW(wc) & C1_UPPER) != 0;
698 /*************************************************************************
701 * Determine if a Unicode character is lower-case.
704 * wc [I] Character to check.
707 * TRUE, if wc is lower-case,
710 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
712 return (get_char_typeW(wc) & C1_LOWER) != 0;
715 /*************************************************************************
718 * Determine if a Unicode character is alphabetic or a digit.
721 * wc [I] Character to check.
724 * TRUE, if wc is alphabetic or a digit,
727 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
729 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
732 /*************************************************************************
735 * Determine if a Unicode character is a space.
738 * wc [I] Character to check.
741 * TRUE, if wc is a space,
744 BOOL WINAPI IsCharSpaceW(WCHAR wc)
746 return (get_char_typeW(wc) & C1_SPACE) != 0;
749 /*************************************************************************
752 * Determine if a Unicode character is a blank.
755 * wc [I] Character to check.
758 * TRUE, if wc is a blank,
762 BOOL WINAPI IsCharBlankW(WCHAR wc)
764 return (get_char_typeW(wc) & C1_BLANK) != 0;
767 /*************************************************************************
770 * Determine if a Unicode character is punctuation.
773 * wc [I] Character to check.
776 * TRUE, if wc is punctuation,
779 BOOL WINAPI IsCharPunctW(WCHAR wc)
781 return (get_char_typeW(wc) & C1_PUNCT) != 0;
784 /*************************************************************************
787 * Determine if a Unicode character is a control character.
790 * wc [I] Character to check.
793 * TRUE, if wc is a control character,
796 BOOL WINAPI IsCharCntrlW(WCHAR wc)
798 return (get_char_typeW(wc) & C1_CNTRL) != 0;
801 /*************************************************************************
804 * Determine if a Unicode character is a digit.
807 * wc [I] Character to check.
810 * TRUE, if wc is a digit,
813 BOOL WINAPI IsCharDigitW(WCHAR wc)
815 return (get_char_typeW(wc) & C1_DIGIT) != 0;
818 /*************************************************************************
821 * Determine if a Unicode character is a hex digit.
824 * wc [I] Character to check.
827 * TRUE, if wc is a hex digit,
830 BOOL WINAPI IsCharXDigitW(WCHAR wc)
832 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
835 /*************************************************************************
839 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
841 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
845 /*************************************************************************
848 * Insert a bitmap menu item at the bottom of a menu.
851 * hMenu [I] Menu to insert into
852 * flags [I] Flags for insertion
853 * id [I] Menu ID of the item
854 * str [I] Menu text for the item
857 * Success: TRUE, the item is inserted into the menu
858 * Failure: FALSE, if any parameter is invalid
860 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
862 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
863 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
866 /*************************************************************************
869 * Get the text from a given dialog item.
872 * hWnd [I] Handle of dialog
873 * nItem [I] Index of item
874 * lpsDest [O] Buffer for receiving window text
875 * nDestLen [I] Length of buffer.
878 * Success: The length of the returned text.
881 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
883 HWND hItem = GetDlgItem(hWnd, nItem);
886 return GetWindowTextW(hItem, lpsDest, nDestLen);
888 *lpsDest = (WCHAR)'\0';
892 /*************************************************************************
895 * Set the text of a given dialog item.
898 * hWnd [I] Handle of dialog
899 * iItem [I] Index of item
900 * lpszText [O] Text to set
903 * Success: TRUE. The text of the dialog is set to lpszText.
904 * Failure: FALSE, Otherwise.
906 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
908 HWND hWndItem = GetDlgItem(hWnd, iItem);
910 return SetWindowTextW(hWndItem, lpszText);
914 /*************************************************************************
917 * Compare two Ascii strings up to a given length.
920 * lpszSrc [I] Source string
921 * lpszCmp [I] String to compare to lpszSrc
922 * len [I] Maximum length
925 * A number greater than, less than or equal to 0 depending on whether
926 * lpszSrc is greater than, less than or equal to lpszCmp.
928 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
930 return strncmp(lpszSrc, lpszCmp, len);
933 /*************************************************************************
936 * Unicode version of StrCmpNCA.
938 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
940 return strncmpW(lpszSrc, lpszCmp, len);
943 /*************************************************************************
946 * Compare two Ascii strings up to a given length, ignoring case.
949 * lpszSrc [I] Source string
950 * lpszCmp [I] String to compare to lpszSrc
951 * len [I] Maximum length
954 * A number greater than, less than or equal to 0 depending on whether
955 * lpszSrc is greater than, less than or equal to lpszCmp.
957 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
959 return strncasecmp(lpszSrc, lpszCmp, len);
962 /*************************************************************************
965 * Unicode version of StrCmpNICA.
967 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
969 return strncmpiW(lpszSrc, lpszCmp, len);
972 /*************************************************************************
975 * Compare two Ascii strings.
978 * lpszSrc [I] Source string
979 * lpszCmp [I] String to compare to lpszSrc
982 * A number greater than, less than or equal to 0 depending on whether
983 * lpszSrc is greater than, less than or equal to lpszCmp.
985 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
987 return strcmp(lpszSrc, lpszCmp);
990 /*************************************************************************
993 * Unicode version of StrCmpCA.
995 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
997 return strcmpW(lpszSrc, lpszCmp);
1000 /*************************************************************************
1003 * Compare two Ascii strings, ignoring case.
1006 * lpszSrc [I] Source string
1007 * lpszCmp [I] String to compare to lpszSrc
1010 * A number greater than, less than or equal to 0 depending on whether
1011 * lpszSrc is greater than, less than or equal to lpszCmp.
1013 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1015 return strcasecmp(lpszSrc, lpszCmp);
1018 /*************************************************************************
1021 * Unicode version of StrCmpICA.
1023 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1025 return strcmpiW(lpszSrc, lpszCmp);
1028 /*************************************************************************
1031 * Get an identification string for the OS and explorer.
1034 * lpszDest [O] Destination for Id string
1035 * dwDestLen [I] Length of lpszDest
1038 * TRUE, If the string was created successfully
1041 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1045 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1047 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1049 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1055 /*************************************************************************
1058 * Unicode version of SHAboutInfoA.
1060 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1062 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1063 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1064 ' ','E','x','p','l','o','r','e','r','\0' };
1065 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1066 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1067 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1068 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1069 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1070 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1071 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1072 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1073 ' ','E','x','p','l','o','r','e','r','\\',
1074 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1075 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1076 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1077 'V','e','r','s','i','o','n','\0' };
1078 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1079 'O','w','n','e','r','\0' };
1080 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1081 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1082 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1083 static const WCHAR szUpdate[] = { 'I','E','A','K',
1084 'U','p','d','a','t','e','U','r','l','\0' };
1085 static const WCHAR szHelp[] = { 'I','E','A','K',
1086 'H','e','l','p','S','t','r','i','n','g','\0' };
1089 DWORD dwType, dwLen;
1091 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1098 /* Try the NT key first, followed by 95/98 key */
1099 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1100 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1106 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1108 DWORD dwStrLen = strlenW(buff);
1109 dwLen = 30 - dwStrLen;
1110 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1111 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1113 StrCatBuffW(lpszDest, buff, dwDestLen);
1115 /* ~Registered Owner */
1118 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1120 StrCatBuffW(lpszDest, buff, dwDestLen);
1122 /* ~Registered Organization */
1124 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1126 StrCatBuffW(lpszDest, buff, dwDestLen);
1128 /* FIXME: Not sure where this number comes from */
1132 StrCatBuffW(lpszDest, buff, dwDestLen);
1136 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1138 StrCatBuffW(lpszDest, buff, dwDestLen);
1140 /* ~IE Update Url */
1142 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1144 StrCatBuffW(lpszDest, buff, dwDestLen);
1146 /* ~IE Help String */
1148 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1150 StrCatBuffW(lpszDest, buff, dwDestLen);
1156 /*************************************************************************
1159 * Call IOleCommandTarget_QueryStatus() on an object.
1162 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1163 * pguidCmdGroup [I] GUID for the command group
1165 * prgCmds [O] Commands
1166 * pCmdText [O] Command text
1170 * Failure: E_FAIL, if lpUnknown is NULL.
1171 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1172 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1174 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1175 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1177 HRESULT hRet = E_FAIL;
1179 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1183 IOleCommandTarget* lpOle;
1185 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1188 if (SUCCEEDED(hRet) && lpOle)
1190 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1192 IOleCommandTarget_Release(lpOle);
1198 /*************************************************************************
1201 * Call IOleCommandTarget_Exec() on an object.
1204 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1205 * pguidCmdGroup [I] GUID for the command group
1209 * Failure: E_FAIL, if lpUnknown is NULL.
1210 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1211 * Otherwise, an error code from IOleCommandTarget_Exec().
1213 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1214 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1217 HRESULT hRet = E_FAIL;
1219 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1220 nCmdexecopt, pvaIn, pvaOut);
1224 IOleCommandTarget* lpOle;
1226 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1228 if (SUCCEEDED(hRet) && lpOle)
1230 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1231 nCmdexecopt, pvaIn, pvaOut);
1232 IOleCommandTarget_Release(lpOle);
1238 /*************************************************************************
1241 * Retrieve, modify, and re-set a value from a window.
1244 * hWnd [I] Window to get value from
1245 * offset [I] Offset of value
1246 * wMask [I] Mask for uiFlags
1247 * wFlags [I] Bits to set in window value
1250 * The new value as it was set, or 0 if any parameter is invalid.
1253 * Any bits set in uiMask are cleared from the value, then any bits set in
1254 * uiFlags are set in the value.
1256 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1258 LONG ret = GetWindowLongA(hwnd, offset);
1259 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1261 if (newFlags != ret)
1262 ret = SetWindowLongA(hwnd, offset, newFlags);
1266 /*************************************************************************
1269 * Change a window's parent.
1272 * hWnd [I] Window to change parent of
1273 * hWndParent [I] New parent window
1276 * The old parent of hWnd.
1279 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1280 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1282 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1284 TRACE("%p, %p\n", hWnd, hWndParent);
1286 if(GetParent(hWnd) == hWndParent)
1290 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1292 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1294 return SetParent(hWnd, hWndParent);
1297 /*************************************************************************
1300 * Locate and advise a connection point in an IConnectionPointContainer object.
1303 * lpUnkSink [I] Sink for the connection point advise call
1304 * riid [I] REFIID of connection point to advise
1305 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1306 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1307 * lpCookie [O] Pointer to connection point cookie
1308 * lppCP [O] Destination for the IConnectionPoint found
1311 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1312 * that was advised. The caller is responsable for releasing it.
1313 * Failure: E_FAIL, if any arguments are invalid.
1314 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1315 * Or an HRESULT error code if any call fails.
1317 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1318 IUnknown* lpUnknown, LPDWORD lpCookie,
1319 IConnectionPoint **lppCP)
1322 IConnectionPointContainer* lpContainer;
1323 IConnectionPoint *lpCP;
1325 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1331 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1332 (void**)&lpContainer);
1333 if (SUCCEEDED(hRet))
1335 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1337 if (SUCCEEDED(hRet))
1340 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1341 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1346 if (lppCP && SUCCEEDED(hRet))
1347 *lppCP = lpCP; /* Caller keeps the interface */
1349 IConnectionPoint_Release(lpCP); /* Release it */
1352 IUnknown_Release(lpContainer);
1357 /*************************************************************************
1360 * Release an interface.
1363 * lpUnknown [I] Object to release
1368 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1372 TRACE("(%p)\n",lpUnknown);
1374 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1378 TRACE("doing Release\n");
1380 return IUnknown_Release(temp);
1383 /*************************************************************************
1386 * Skip '//' if present in a string.
1389 * lpszSrc [I] String to check for '//'
1392 * Success: The next character after the '//' or the string if not present
1393 * Failure: NULL, if lpszStr is NULL.
1395 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1397 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1402 /*************************************************************************
1405 * Check if two interfaces come from the same object.
1408 * lpInt1 [I] Interface to check against lpInt2.
1409 * lpInt2 [I] Interface to check against lpInt1.
1412 * TRUE, If the interfaces come from the same object.
1415 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1417 LPVOID lpUnknown1, lpUnknown2;
1419 TRACE("%p %p\n", lpInt1, lpInt2);
1421 if (!lpInt1 || !lpInt2)
1424 if (lpInt1 == lpInt2)
1427 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1428 (LPVOID *)&lpUnknown1)))
1431 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1432 (LPVOID *)&lpUnknown2)))
1435 if (lpUnknown1 == lpUnknown2)
1441 /*************************************************************************
1444 * Get the window handle of an object.
1447 * lpUnknown [I] Object to get the window handle of
1448 * lphWnd [O] Destination for window handle
1451 * Success: S_OK. lphWnd contains the objects window handle.
1452 * Failure: An HRESULT error code.
1455 * lpUnknown is expected to support one of the following interfaces:
1456 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1458 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1460 /* FIXME: Wine has no header for this object */
1461 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1462 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1464 HRESULT hRet = E_FAIL;
1466 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1471 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1475 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1479 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1484 if (SUCCEEDED(hRet))
1486 /* Lazyness here - Since GetWindow() is the first method for the above 3
1487 * interfaces, we use the same call for them all.
1489 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1490 IUnknown_Release(lpOle);
1492 TRACE("Returning HWND=%p\n", *lphWnd);
1498 /*************************************************************************
1501 * Call a method on as as yet unidentified object.
1504 * pUnk [I] Object supporting the unidentified interface,
1505 * arg [I] Argument for the call on the object.
1510 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1512 static const GUID guid_173 = {
1513 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1517 TRACE("(%p,%ld)\n", pUnk, arg);
1519 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1520 * We use this interface as its vtable entry is compatible with the
1521 * object in question.
1522 * FIXME: Find out what this object is and where it should be defined.
1525 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1527 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1528 IMalloc_Release(pUnk2);
1533 /*************************************************************************
1536 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1541 * Failure: E_FAIL, if p1 is NULL.
1542 * E_NOINTERFACE If p1 does not support the IPersist interface,
1543 * Or an HRESULT error code.
1545 DWORD WINAPI IUnknown_SetSite(
1546 IUnknown *p1, /* [in] OLE object */
1547 LPVOID *p2) /* [out] ptr for call results */
1551 if (!p1) return E_FAIL;
1553 /* see if SetSite interface exists for IObjectWithSite object */
1554 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1555 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1558 /* see if GetClassId interface exists for IPersistMoniker object */
1559 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1560 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1561 if (ret) return ret;
1563 /* fake a GetClassId call */
1564 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1565 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1567 IUnknown_Release((IUnknown *)aa);
1570 /* fake a SetSite call */
1571 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1572 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1574 IUnknown_Release((IUnknown *)p1);
1579 /*************************************************************************
1582 * Call IPersist_GetClassID() on an object.
1585 * lpUnknown [I] Object supporting the IPersist interface
1586 * lpClassId [O] Destination for Class Id
1589 * Success: S_OK. lpClassId contains the Class Id requested.
1590 * Failure: E_FAIL, If lpUnknown is NULL,
1591 * E_NOINTERFACE If lpUnknown does not support IPersist,
1592 * Or an HRESULT error code.
1594 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1596 IPersist* lpPersist;
1597 HRESULT hRet = E_FAIL;
1599 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1603 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1604 if (SUCCEEDED(hRet))
1606 IPersist_GetClassID(lpPersist, lpClassId);
1607 IPersist_Release(lpPersist);
1613 /*************************************************************************
1616 * Retrieve a Service Interface from an object.
1619 * lpUnknown [I] Object to get an IServiceProvider interface from
1620 * sid [I] Service ID for IServiceProvider_QueryService() call
1621 * riid [I] Function requested for QueryService call
1622 * lppOut [O] Destination for the service interface pointer
1625 * Success: S_OK. lppOut contains an object providing the requested service
1626 * Failure: An HRESULT error code
1629 * lpUnknown is expected to support the IServiceProvider interface.
1631 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1634 IServiceProvider* pService = NULL;
1645 /* Get an IServiceProvider interface from the object */
1646 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1647 (LPVOID*)&pService);
1649 if (!hRet && pService)
1651 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1653 /* Get a Service interface from the object */
1654 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1656 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1658 /* Release the IServiceProvider interface */
1659 IUnknown_Release(pService);
1664 /*************************************************************************
1667 * Loads a popup menu.
1670 * hInst [I] Instance handle
1671 * szName [I] Menu name
1677 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1679 HMENU hMenu, hSubMenu;
1681 if ((hMenu = LoadMenuW(hInst, szName)))
1683 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1684 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1692 typedef struct _enumWndData
1697 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1700 /* Callback for SHLWAPI_178 */
1701 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1703 enumWndData *data = (enumWndData *)lParam;
1705 TRACE("(%p,%p)\n", hWnd, data);
1706 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1710 /*************************************************************************
1713 * Send or post a message to every child of a window.
1716 * hWnd [I] Window whose children will get the messages
1717 * uiMsgId [I] Message Id
1718 * wParam [I] WPARAM of message
1719 * lParam [I] LPARAM of message
1720 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1726 * The appropriate ASCII or Unicode function is called for the window.
1728 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1732 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1736 data.uiMsgId = uiMsgId;
1737 data.wParam = wParam;
1738 data.lParam = lParam;
1741 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1743 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1745 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1749 /*************************************************************************
1752 * Remove all sub-menus from a menu.
1755 * hMenu [I] Menu to remove sub-menus from
1758 * Success: 0. All sub-menus under hMenu are removed
1759 * Failure: -1, if any parameter is invalid
1761 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1763 int iItemCount = GetMenuItemCount(hMenu) - 1;
1764 while (iItemCount >= 0)
1766 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1768 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1774 /*************************************************************************
1777 * Enable or disable a menu item.
1780 * hMenu [I] Menu holding menu item
1781 * uID [I] ID of menu item to enable/disable
1782 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1785 * The return code from EnableMenuItem.
1787 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1789 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1792 /*************************************************************************
1795 * Check or uncheck a menu item.
1798 * hMenu [I] Menu holding menu item
1799 * uID [I] ID of menu item to check/uncheck
1800 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1803 * The return code from CheckMenuItem.
1805 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1807 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1810 /*************************************************************************
1813 * Register a window class if it isn't already.
1816 * lpWndClass [I] Window class to register
1819 * The result of the RegisterClassA call.
1821 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1824 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1826 return (DWORD)RegisterClassA(wndclass);
1829 /*************************************************************************
1832 * Call IPersistPropertyBag_Load() on an object.
1835 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1836 * lpPropBag [O] Destination for loaded IPropertyBag
1840 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1842 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1844 IPersistPropertyBag* lpPPBag;
1845 HRESULT hRet = E_FAIL;
1847 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1851 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1853 if (SUCCEEDED(hRet) && lpPPBag)
1855 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1856 IPersistPropertyBag_Release(lpPPBag);
1862 /*************************************************************************
1865 * Call IOleControlSite_GetExtendedControl() on an object.
1868 * lpUnknown [I] Object supporting the IOleControlSite interface
1869 * lppDisp [O] Destination for resulting IDispatch.
1873 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1875 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1877 IOleControlSite* lpCSite;
1878 HRESULT hRet = E_FAIL;
1880 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1883 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1885 if (SUCCEEDED(hRet) && lpCSite)
1887 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1888 IOleControlSite_Release(lpCSite);
1894 /*************************************************************************
1897 * Get a sub-menu from a menu item.
1900 * hMenu [I] Menu to get sub-menu from
1901 * uID [I] ID of menu item containing sub-menu
1904 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1906 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1910 TRACE("(%p,%uld)\n", hMenu, uID);
1912 mi.cbSize = sizeof(MENUITEMINFOA);
1913 mi.fMask = MIIM_SUBMENU;
1915 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1921 /*************************************************************************
1924 * Get the color depth of the primary display.
1930 * The color depth of the primary display.
1932 DWORD WINAPI SHGetCurColorRes()
1940 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1945 /*************************************************************************
1948 * Wait for a message to arrive, with a timeout.
1951 * hand [I] Handle to query
1952 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1955 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1956 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1957 * message is available.
1959 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1961 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1964 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1968 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1970 if (dwTimeout != INFINITE)
1972 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1973 return WAIT_TIMEOUT;
1980 /*************************************************************************
1983 * Blank out a region of text by drawing the background only.
1986 * hDC [I] Device context to draw in
1987 * pRect [I] Area to draw in
1988 * cRef [I] Color to draw in
1993 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
1995 COLORREF cOldColor = SetBkColor(hDC, cRef);
1996 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
1997 SetBkColor(hDC, cOldColor);
2001 /*************************************************************************
2004 * Return the value asociated with a key in a map.
2007 * lpKeys [I] A list of keys of length iLen
2008 * lpValues [I] A list of values associated with lpKeys, of length iLen
2009 * iLen [I] Length of both lpKeys and lpValues
2010 * iKey [I] The key value to look up in lpKeys
2013 * The value in lpValues associated with iKey, or -1 if iKey is not
2017 * - If two elements in the map share the same key, this function returns
2018 * the value closest to the start of the map
2019 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2021 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2023 if (lpKeys && lpValues)
2029 if (lpKeys[i] == iKey)
2030 return lpValues[i]; /* Found */
2034 return -1; /* Not found */
2038 /*************************************************************************
2041 * Copy an interface pointer
2044 * lppDest [O] Destination for copy
2045 * lpUnknown [I] Source for copy
2050 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2052 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2055 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2060 IUnknown_AddRef(lpUnknown);
2061 *lppDest = lpUnknown;
2065 /*************************************************************************
2069 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2070 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2073 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2074 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2075 return DRAGDROP_E_NOTREGISTERED;
2078 /*************************************************************************
2082 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2084 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2085 return DRAGDROP_E_NOTREGISTERED;
2088 /*************************************************************************
2091 * Determine if a window is not a child of another window.
2094 * hParent [I] Suspected parent window
2095 * hChild [I] Suspected child window
2098 * TRUE: If hChild is a child window of hParent
2099 * FALSE: If hChild is not a child window of hParent, or they are equal
2101 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2103 TRACE("(%p,%p)\n", hParent, hChild);
2105 if (!hParent || !hChild)
2107 else if(hParent == hChild)
2109 return !IsChild(hParent, hChild);
2112 /*************************************************************************
2115 * Some sort of memory management process.
2117 DWORD WINAPI FDSA_Initialize(
2124 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2129 /*************************************************************************
2132 * Some sort of memory management process.
2134 DWORD WINAPI FDSA_Destroy(
2137 FIXME("(%p) stub\n",
2142 /*************************************************************************
2145 * Some sort of memory management process.
2147 DWORD WINAPI FDSA_InsertItem(
2152 FIXME("(%p 0x%08lx %p) stub\n",
2157 /*************************************************************************
2160 DWORD WINAPI FDSA_DeleteItem(
2164 FIXME("(%p 0x%08lx) stub\n",
2174 /*************************************************************************
2177 * Call IUnknown_QueryInterface() on a table of objects.
2181 * Failure: E_POINTER or E_NOINTERFACE.
2183 HRESULT WINAPI QISearch(
2184 LPVOID w, /* [in] Table of interfaces */
2185 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2186 REFIID riid, /* [in] REFIID to get interface for */
2187 LPVOID *ppv) /* [out] Destination for interface pointer */
2191 IFACE_INDEX_TBL *xmove;
2193 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2196 while (xmove->refid) {
2197 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2198 if (IsEqualIID(riid, xmove->refid)) {
2199 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2200 TRACE("matched, returning (%p)\n", a_vtbl);
2201 *ppv = (LPVOID)a_vtbl;
2202 IUnknown_AddRef(a_vtbl);
2208 if (IsEqualIID(riid, &IID_IUnknown)) {
2209 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2210 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2211 *ppv = (LPVOID)a_vtbl;
2212 IUnknown_AddRef(a_vtbl);
2216 ret = E_NOINTERFACE;
2220 TRACE("-- 0x%08lx\n", ret);
2224 /*************************************************************************
2227 * Remove the "PropDlgFont" property from a window.
2230 * hWnd [I] Window to remove the property from
2233 * A handle to the removed property, or NULL if it did not exist.
2235 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2239 TRACE("(%p)\n", hWnd);
2241 hProp = GetPropA(hWnd, "PropDlgFont");
2245 DeleteObject(hProp);
2246 hProp = RemovePropA(hWnd, "PropDlgFont");
2251 /*************************************************************************
2254 * Load the in-process server of a given GUID.
2257 * refiid [I] GUID of the server to load.
2260 * Success: A handle to the loaded server dll.
2261 * Failure: A NULL handle.
2263 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2267 CHAR value[MAX_PATH], string[MAX_PATH];
2269 strcpy(string, "CLSID\\");
2270 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2271 strcat(string, "\\InProcServer32");
2274 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2275 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2276 RegCloseKey(newkey);
2277 return LoadLibraryExA(value, 0, 0);
2280 /*************************************************************************
2283 * Unicode version of SHLWAPI_183.
2285 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2289 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2291 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2293 return RegisterClassW(lpWndClass);
2296 /*************************************************************************
2299 * Unregister a list of classes.
2302 * hInst [I] Application instance that registered the classes
2303 * lppClasses [I] List of class names
2304 * iCount [I] Number of names in lppClasses
2309 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2313 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2317 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2318 UnregisterClassA(*lppClasses, hInst);
2324 /*************************************************************************
2327 * Unicode version of SHUnregisterClassesA.
2329 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2333 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2337 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2338 UnregisterClassW(*lppClasses, hInst);
2344 /*************************************************************************
2347 * Call The correct (Ascii/Unicode) default window procedure for a window.
2350 * hWnd [I] Window to call the default procedure for
2351 * uMessage [I] Message ID
2352 * wParam [I] WPARAM of message
2353 * lParam [I] LPARAM of message
2356 * The result of calling DefWindowProcA() or DefWindowProcW().
2358 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2360 if (IsWindowUnicode(hWnd))
2361 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2362 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2365 /*************************************************************************
2368 * Create a worker window using CreateWindowExA().
2371 * wndProc [I] Window procedure
2372 * hWndParent [I] Parent window
2373 * dwExStyle [I] Extra style flags
2374 * dwStyle [I] Style flags
2375 * hMenu [I] Window menu
2379 * Success: The window handle of the newly created window.
2382 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2383 DWORD dwStyle, HMENU hMenu, LONG z)
2385 static const char* szClass = "WorkerA";
2389 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2390 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2392 /* Create Window class */
2394 wc.lpfnWndProc = DefWindowProcA;
2397 wc.hInstance = shlwapi_hInstance;
2398 wc.hIcon = (HICON)0;
2399 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2400 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2401 wc.lpszMenuName = NULL;
2402 wc.lpszClassName = szClass;
2404 SHRegisterClassA(&wc); /* Register class */
2406 /* FIXME: Set extra bits in dwExStyle */
2408 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2409 hWndParent, hMenu, shlwapi_hInstance, 0);
2412 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2415 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2420 typedef struct tagPOLICYDATA
2422 DWORD policy; /* flags value passed to SHRestricted */
2423 LPCWSTR appstr; /* application str such as "Explorer" */
2424 LPCWSTR keystr; /* name of the actual registry key / policy */
2425 } POLICYDATA, *LPPOLICYDATA;
2427 #define SHELL_NO_POLICY 0xffffffff
2429 /* default shell policy registry key */
2430 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2431 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2432 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2433 '\\','P','o','l','i','c','i','e','s',0};
2435 /*************************************************************************
2438 * Retrieve a policy value from the registry.
2441 * lpSubKey [I] registry key name
2442 * lpSubName [I] subname of registry key
2443 * lpValue [I] value name of registry value
2446 * the value associated with the registry key or 0 if not found
2448 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2450 DWORD retval, datsize = sizeof(retval);
2454 lpSubKey = strRegistryPolicyW;
2456 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2457 if (retval != ERROR_SUCCESS)
2458 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2459 if (retval != ERROR_SUCCESS)
2462 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2467 /*************************************************************************
2470 * Helper function to retrieve the possibly cached value for a specific policy
2473 * policy [I] The policy to look for
2474 * initial [I] Main registry key to open, if NULL use default
2475 * polTable [I] Table of known policies, 0 terminated
2476 * polArr [I] Cache array of policy values
2479 * The retrieved policy value or 0 if not successful
2482 * This function is used by the native SHRestricted function to search for the
2483 * policy and cache it once retrieved. The current Wine implementation uses a
2484 * different POLICYDATA structure and implements a similar algorithme adapted to
2487 DWORD WINAPI SHRestrictionLookup(
2490 LPPOLICYDATA polTable,
2493 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2495 if (!polTable || !polArr)
2498 for (;polTable->policy; polTable++, polArr++)
2500 if (policy == polTable->policy)
2502 /* we have a known policy */
2504 /* check if this policy has been cached */
2505 if (*polArr == SHELL_NO_POLICY)
2506 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2510 /* we don't know this policy, return 0 */
2511 TRACE("unknown policy: (%08lx)\n", policy);
2515 /*************************************************************************
2518 * Get an interface from an object.
2521 * Success: S_OK. ppv contains the requested interface.
2522 * Failure: An HRESULT error code.
2525 * This QueryInterface asks the inner object for a interface. In case
2526 * of aggregation this request would be forwarded by the inner to the
2527 * outer object. This function asks the inner object directly for the
2528 * interface circumventing the forwarding to the outer object.
2530 HRESULT WINAPI SHWeakQueryInterface(
2531 IUnknown * pUnk, /* [in] Outer object */
2532 IUnknown * pInner, /* [in] Inner object */
2533 IID * riid, /* [in] Interface GUID to query for */
2534 LPVOID* ppv) /* [out] Destination for queried interface */
2536 HRESULT hret = E_NOINTERFACE;
2537 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2540 if(pUnk && pInner) {
2541 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2542 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2544 TRACE("-- 0x%08lx\n", hret);
2548 /*************************************************************************
2551 * Move a reference from one interface to another.
2554 * lpDest [O] Destination to receive the reference
2555 * lppUnknown [O] Source to give up the reference to lpDest
2560 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2562 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2567 IUnknown_AddRef(lpDest);
2568 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2572 /*************************************************************************
2575 * Convert an ASCII string of a CLSID into a CLSID.
2578 * idstr [I] String representing a CLSID in registry format
2579 * id [O] Destination for the converted CLSID
2582 * Success: TRUE. id contains the converted CLSID.
2585 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2588 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2589 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2592 /*************************************************************************
2595 * Unicode version of GUIDFromStringA.
2597 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2599 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2602 /*************************************************************************
2605 * Determine if the browser is integrated into the shell, and set a registry
2612 * 1, If the browser is not integrated.
2613 * 2, If the browser is integrated.
2616 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2617 * either set to TRUE, or removed depending on whether the browser is deemed
2620 DWORD WINAPI WhichPlatform()
2622 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2623 static DWORD dwState = 0;
2625 DWORD dwRet, dwData, dwSize;
2630 /* If shell32 exports DllGetVersion(), the browser is integrated */
2631 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2632 dwState = pDllGetVersion ? 2 : 1;
2634 /* Set or delete the key accordingly */
2635 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2636 "Software\\Microsoft\\Internet Explorer", 0,
2637 KEY_ALL_ACCESS, &hKey);
2640 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2641 (LPBYTE)&dwData, &dwSize);
2643 if (!dwRet && dwState == 1)
2645 /* Value exists but browser is not integrated */
2646 RegDeleteValueA(hKey, szIntegratedBrowser);
2648 else if (dwRet && dwState == 2)
2650 /* Browser is integrated but value does not exist */
2652 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2653 (LPBYTE)&dwData, sizeof(dwData));
2660 /*************************************************************************
2663 * Unicode version of SHCreateWorkerWindowA.
2665 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2666 DWORD dwStyle, HMENU hMenu, LONG z)
2668 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2672 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2673 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2675 /* If our OS is natively ASCII, use the ASCII version */
2676 if (!(GetVersion() & 0x80000000)) /* NT */
2677 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2679 /* Create Window class */
2681 wc.lpfnWndProc = DefWindowProcW;
2684 wc.hInstance = shlwapi_hInstance;
2685 wc.hIcon = (HICON)0;
2686 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2687 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2688 wc.lpszMenuName = NULL;
2689 wc.lpszClassName = szClass;
2691 SHRegisterClassW(&wc); /* Register class */
2693 /* FIXME: Set extra bits in dwExStyle */
2695 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2696 hWndParent, hMenu, shlwapi_hInstance, 0);
2699 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2702 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2707 /*************************************************************************
2710 * Get and show a context menu from a shell folder.
2713 * hWnd [I] Window displaying the shell folder
2714 * lpFolder [I] IShellFolder interface
2715 * lpApidl [I] Id for the particular folder desired
2719 * Failure: An HRESULT error code indicating the error.
2721 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2723 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2726 /*************************************************************************
2729 * _SHPackDispParamsV
2731 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2733 FIXME("%p %p %p %p\n",w,x,y,z);
2737 /*************************************************************************
2740 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2741 * function does...).
2743 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2745 FIXME("%p %p %p %p\n", w, x, y, z);
2749 /*************************************************************************
2752 * _IConnectionPoint_SimpleInvoke
2754 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2759 FIXME("(%p %p %p) stub\n",x,y,z);
2763 /*************************************************************************
2766 * Notify an IConnectionPoint object of changes.
2769 * lpCP [I] Object to notify
2774 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2775 * IConnectionPoint interface.
2777 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2779 IEnumConnections *lpEnum;
2780 HRESULT hRet = E_NOINTERFACE;
2782 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2784 /* Get an enumerator for the connections */
2786 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2788 if (SUCCEEDED(hRet))
2790 IPropertyNotifySink *lpSink;
2791 CONNECTDATA connData;
2794 /* Call OnChanged() for every notify sink in the connection point */
2795 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2797 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2800 IPropertyNotifySink_OnChanged(lpSink, dispID);
2801 IPropertyNotifySink_Release(lpSink);
2803 IUnknown_Release(connData.pUnk);
2806 IEnumConnections_Release(lpEnum);
2811 /*************************************************************************
2814 * Notify an IConnectionPointContainer object of changes.
2817 * lpUnknown [I] Object to notify
2822 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2823 * IConnectionPointContainer interface.
2825 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2827 IConnectionPointContainer* lpCPC = NULL;
2828 HRESULT hRet = E_NOINTERFACE;
2830 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2833 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2835 if (SUCCEEDED(hRet))
2837 IConnectionPoint* lpCP;
2839 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2840 IConnectionPointContainer_Release(lpCPC);
2842 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2843 IConnectionPoint_Release(lpCP);
2848 /*************************************************************************
2853 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2855 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2856 return pPlaySoundW(pszSound, hmod, fdwSound);
2859 /*************************************************************************
2862 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2865 * str1: "I" "I" pushl esp+0x20
2866 * str2: "U" "I" pushl 0x77c93810
2867 * (is "I" and "U" "integer" and "unsigned" ??)
2869 * pStr: "" "" pushl eax
2870 * some_len: 0x824 0x104 pushl 0x824
2871 * lpStr2: "%l" "%l" pushl esp+0xc
2873 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2874 * LocalAlloc(0x00, some_len) -> irrelevant_var
2875 * LocalAlloc(0x40, irrelevant_len) -> pStr
2876 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2877 * shlwapi.PathRemoveBlanksW(pStr);
2879 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2883 /*************************************************************************
2886 * Called by ICQ2000b install via SHDOCVW:
2887 * str1: "InternetShortcut"
2888 * x: some unknown pointer
2889 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2890 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2892 * In short: this one maybe creates a desktop link :-)
2894 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2896 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2900 /*************************************************************************
2905 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2906 LPCWSTR str, UINT count, const INT *lpDx)
2908 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2909 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2912 /*************************************************************************
2915 * See SHGetFileInfoW.
2917 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2918 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2920 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2921 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2924 /*************************************************************************
2927 * See DragQueryFileW.
2929 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2931 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2932 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2935 /*************************************************************************
2938 * See SHBrowseForFolderW.
2940 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2942 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2943 return pSHBrowseForFolderW(lpBi);
2946 /*************************************************************************
2949 * See SHGetPathFromIDListW.
2951 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2953 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2954 return pSHGetPathFromIDListW(pidl, pszPath);
2957 /*************************************************************************
2960 * See ShellExecuteExW.
2962 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2964 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2965 return pShellExecuteExW(lpExecInfo);
2968 /*************************************************************************
2971 * See SHFileOperationW.
2973 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2975 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2976 return pSHFileOperationW(lpFileOp);
2979 /*************************************************************************
2982 * See ExtractIconExW.
2984 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2985 HICON *phiconSmall, UINT nIcons)
2987 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2988 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
2991 /*************************************************************************
2995 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
2997 return InterlockedCompareExchange(dest, xchg, compare);
3000 /*************************************************************************
3003 DWORD WINAPI SHUnicodeToUnicode(
3008 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3009 lstrcpynW(dest, src, len);
3010 return lstrlenW(dest)+1;
3013 /*************************************************************************
3016 * See GetFileVersionInfoSizeW.
3018 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3024 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3025 ret = pGetFileVersionInfoSizeW(x, y);
3029 /*************************************************************************
3032 * See GetFileVersionInfoW.
3034 BOOL WINAPI GetFileVersionInfoWrapW(
3035 LPWSTR w, /* [in] path to dll */
3036 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3037 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3038 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3040 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3041 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3044 /*************************************************************************
3047 * See VerQueryValueW.
3049 WORD WINAPI VerQueryValueWrapW(
3050 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3051 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3052 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3053 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3055 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3056 return pVerQueryValueW((char*)w+0x208, x, y, z);
3059 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3060 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3061 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3063 /*************************************************************************
3066 * Change the modality of a shell object.
3069 * lpUnknown [I] Object to make modeless
3070 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3073 * Success: S_OK. The modality lpUnknown is changed.
3074 * Failure: An HRESULT error code indicating the error.
3077 * lpUnknown must support the IOleInPlaceFrame interface, the
3078 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3079 * or the IDocHostUIHandler interface, or this call fails.
3081 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3086 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3091 if (IsIface(IOleInPlaceFrame))
3092 EnableModeless(IOleInPlaceFrame);
3093 else if (IsIface(IShellBrowser))
3094 EnableModeless(IShellBrowser);
3096 /* FIXME: Wine has no headers for these objects yet */
3097 else if (IsIface(IInternetSecurityMgrSite))
3098 EnableModeless(IInternetSecurityMgrSite);
3099 else if (IsIface(IDocHostUIHandler))
3100 EnableModeless(IDocHostUIHandler);
3105 IUnknown_Release(lpObj);
3109 /*************************************************************************
3112 * See SHGetNewLinkInfoW.
3114 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3115 BOOL *pfMustCopy, UINT uFlags)
3117 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3118 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3121 /*************************************************************************
3124 * See SHDefExtractIconW.
3126 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3127 HICON* phiconSmall, UINT nIconSize)
3129 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3130 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3133 /*************************************************************************
3136 * Get and show a context menu from a shell folder.
3139 * hWnd [I] Window displaying the shell folder
3140 * lpFolder [I] IShellFolder interface
3141 * lpApidl [I] Id for the particular folder desired
3142 * bInvokeDefault [I] Whether to invoke the default menu item
3145 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3147 * Failure: An HRESULT error code indicating the error.
3149 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3151 IContextMenu *iContext;
3152 HRESULT hRet = E_FAIL;
3154 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3159 /* Get the context menu from the shell folder */
3160 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3161 &IID_IContextMenu, 0, (void**)&iContext);
3162 if (SUCCEEDED(hRet))
3165 if ((hMenu = CreatePopupMenu()))
3168 DWORD dwDefaultId = 0;
3170 /* Add the context menu entries to the popup */
3171 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3172 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3174 if (SUCCEEDED(hQuery))
3176 if (bInvokeDefault &&
3177 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3179 CMINVOKECOMMANDINFO cmIci;
3180 /* Invoke the default item */
3181 memset(&cmIci,0,sizeof(cmIci));
3182 cmIci.cbSize = sizeof(cmIci);
3183 cmIci.fMask = CMIC_MASK_ASYNCOK;
3185 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3186 cmIci.nShow = SW_SCROLLCHILDREN;
3188 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3193 IContextMenu_Release(iContext);
3198 /*************************************************************************
3203 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3206 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3207 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3210 /*************************************************************************
3213 LANGID WINAPI MLGetUILanguage()
3216 /* FIXME: This should be a forward in the .spec file to the win2k function
3217 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3219 return GetUserDefaultLangID();
3222 /*************************************************************************
3225 * Load a library from the directory of a particular process.
3228 * new_mod [I] Library name
3229 * inst_hwnd [I] Module whose directory is to be used
3230 * dwFlags [I] Flags controlling the load
3233 * Success: A handle to the loaded module
3234 * Failure: A NULL handle.
3236 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3238 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3240 * FIXME: Native shows calls to:
3241 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3243 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3244 * RegQueryValueExA for "LPKInstalled"
3246 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3247 * RegQueryValueExA for "ResourceLocale"
3249 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3250 * RegQueryValueExA for "Locale"
3252 * and then tests the Locale ("en" for me).
3254 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3256 CHAR mod_path[2*MAX_PATH];
3260 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3261 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3262 if (!len || len >= sizeof(mod_path)) return NULL;
3264 ptr = strrchr(mod_path, '\\');
3266 strcpy(ptr+1, new_mod);
3267 TRACE("loading %s\n", debugstr_a(mod_path));
3268 return LoadLibraryA(mod_path);
3273 /*************************************************************************
3276 * Unicode version of MLLoadLibraryA.
3278 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3280 WCHAR mod_path[2*MAX_PATH];
3284 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3285 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3286 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3288 ptr = strrchrW(mod_path, '\\');
3290 strcpyW(ptr+1, new_mod);
3291 TRACE("loading %s\n", debugstr_w(mod_path));
3292 return LoadLibraryW(mod_path);
3297 /*************************************************************************
3298 * ColorAdjustLuma [SHLWAPI.@]
3300 * Adjust the luminosity of a color
3303 * cRGB [I] RGB value to convert
3304 * dwLuma [I] Luma adjustment
3305 * bUnknown [I] Unknown
3308 * The adjusted RGB color.
3310 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3312 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3318 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3320 FIXME("Ignoring luma adjustment\n");
3322 /* FIXME: The ajdustment is not linear */
3324 cRGB = ColorHLSToRGB(wH, wL, wS);
3329 /*************************************************************************
3332 * See GetSaveFileNameW.
3334 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3336 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3337 return pGetSaveFileNameW(ofn);
3340 /*************************************************************************
3343 * See WNetRestoreConnectionW.
3345 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3347 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3348 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3351 /*************************************************************************
3354 * See WNetGetLastErrorW.
3356 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3357 LPWSTR lpNameBuf, DWORD nNameBufSize)
3359 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3360 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3363 /*************************************************************************
3366 * See PageSetupDlgW.
3368 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3370 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3371 return pPageSetupDlgW(pagedlg);
3374 /*************************************************************************
3379 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3381 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3382 return pPrintDlgW(printdlg);
3385 /*************************************************************************
3388 * See GetOpenFileNameW.
3390 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3392 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3393 return pGetOpenFileNameW(ofn);
3396 /* INTERNAL: Map from HLS color space to RGB */
3397 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3399 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3403 else if (wHue > 120)
3408 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3411 /* Convert to RGB and scale into RGB range (0..255) */
3412 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3414 /*************************************************************************
3415 * ColorHLSToRGB [SHLWAPI.@]
3417 * Convert from hls color space into an rgb COLORREF.
3420 * wHue [I] Hue amount
3421 * wLuminosity [I] Luminosity amount
3422 * wSaturation [I] Saturation amount
3425 * A COLORREF representing the converted color.
3428 * Input hls values are constrained to the range (0..240).
3430 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3436 WORD wGreen, wBlue, wMid1, wMid2;
3438 if (wLuminosity > 120)
3439 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3441 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3443 wMid1 = wLuminosity * 2 - wMid2;
3445 wRed = GET_RGB(wHue + 80);
3446 wGreen = GET_RGB(wHue);
3447 wBlue = GET_RGB(wHue - 80);
3449 return RGB(wRed, wGreen, wBlue);
3452 wRed = wLuminosity * 255 / 240;
3453 return RGB(wRed, wRed, wRed);
3456 /*************************************************************************
3459 * Get the current docking status of the system.
3462 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3465 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3468 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3470 HW_PROFILE_INFOA hwInfo;
3472 TRACE("(0x%08lx)\n", dwFlags);
3474 GetCurrentHwProfileA(&hwInfo);
3475 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3477 case DOCKINFO_DOCKED:
3478 case DOCKINFO_UNDOCKED:
3479 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3485 /*************************************************************************
3488 * Function seems to do FreeLibrary plus other things.
3490 * FIXME native shows the following calls:
3491 * RtlEnterCriticalSection
3493 * GetProcAddress(Comctl32??, 150L)
3495 * RtlLeaveCriticalSection
3496 * followed by the FreeLibrary.
3497 * The above code may be related to .377 above.
3499 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3501 FIXME("(%p) semi-stub\n", hModule);
3502 return FreeLibrary(hModule);
3505 /*************************************************************************
3508 BOOL WINAPI SHFlushSFCacheWrap(void) {
3513 /*************************************************************************
3515 * FIXME I have no idea what this function does or what its arguments are.
3517 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3519 FIXME("(%p) stub\n", hInst);
3524 /*************************************************************************
3527 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3529 FIXME("(%p,%p) stub\n", hInst, hHeap);
3530 return E_FAIL; /* This is what is used if shlwapi not loaded */
3533 /*************************************************************************
3536 DWORD WINAPI MLClearMLHInstance(DWORD x)
3538 FIXME("(0x%08lx)stub\n", x);
3542 /*************************************************************************
3545 * Convert an Unicode string CLSID into a CLSID.
3548 * idstr [I] string containing a CLSID in text form
3549 * id [O] CLSID extracted from the string
3552 * S_OK on success or E_INVALIDARG on failure
3555 * This is really CLSIDFromString() which is exported by ole32.dll,
3556 * however the native shlwapi.dll does *not* import ole32. Nor does
3557 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3558 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3559 * it returns an E_INVALIDARG error code on failure.
3560 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3561 * in "dlls/ole32/compobj.c".
3563 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3571 memset(id, 0, sizeof(CLSID));
3574 else { /* validate the CLSID string */
3576 if (strlenW(s) != 38)
3577 return E_INVALIDARG;
3579 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3580 return E_INVALIDARG;
3582 for (i=1; i<37; i++)
3584 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3586 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3587 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3588 ((s[i] >= L'A') && (s[i] <= L'F')))
3590 return E_INVALIDARG;
3594 TRACE("%s -> %p\n", debugstr_w(s), id);
3596 /* quick lookup table */
3597 memset(table, 0, 256*sizeof(WCHAR));
3599 for (i = 0; i < 10; i++) {
3602 for (i = 0; i < 6; i++) {
3603 table['A' + i] = i+10;
3604 table['a' + i] = i+10;
3607 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3611 s++; /* skip leading brace */
3612 for (i = 0; i < 4; i++) {
3613 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3619 for (i = 0; i < 2; i++) {
3620 p[1-i] = table[*s]<<4 | table[*(s+1)];
3626 for (i = 0; i < 2; i++) {
3627 p[1-i] = table[*s]<<4 | table[*(s+1)];
3633 /* these are just sequential bytes */
3634 for (i = 0; i < 2; i++) {
3635 *p++ = table[*s]<<4 | table[*(s+1)];
3640 for (i = 0; i < 6; i++) {
3641 *p++ = table[*s]<<4 | table[*(s+1)];
3648 /*************************************************************************
3651 * Determine if the OS supports a given feature.
3654 * dwFeature [I] Feature requested (undocumented)
3657 * TRUE If the feature is available.
3658 * FALSE If the feature is not available.
3660 DWORD WINAPI IsOS(DWORD feature)
3662 FIXME("(0x%08lx) stub\n", feature);
3668 /*************************************************************************
3669 * ColorRGBToHLS [SHLWAPI.@]
3671 * Convert an rgb COLORREF into the hls color space.
3674 * cRGB [I] Source rgb value
3675 * pwHue [O] Destination for converted hue
3676 * pwLuminance [O] Destination for converted luminance
3677 * pwSaturation [O] Destination for converted saturation
3680 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3684 * Output HLS values are constrained to the range (0..240).
3685 * For Achromatic conversions, Hue is set to 160.
3687 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3688 LPWORD pwLuminance, LPWORD pwSaturation)
3690 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3692 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3694 wR = GetRValue(cRGB);
3695 wG = GetGValue(cRGB);
3696 wB = GetBValue(cRGB);
3698 wMax = max(wR, max(wG, wB));
3699 wMin = min(wR, min(wG, wB));
3702 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3706 /* Achromatic case */
3708 /* Hue is now unrepresentable, but this is what native returns... */
3713 /* Chromatic case */
3714 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3717 if (wLuminosity <= 120)
3718 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3720 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3723 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3724 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3725 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3728 wHue = wBNorm - wGNorm;
3729 else if (wG == wMax)
3730 wHue = 80 + wRNorm - wBNorm;
3732 wHue = 160 + wGNorm - wRNorm;
3735 else if (wHue > 240)
3741 *pwLuminance = wLuminosity;
3743 *pwSaturation = wSaturation;
3746 /*************************************************************************
3747 * SHCreateShellPalette [SHLWAPI.@]
3749 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3752 return CreateHalftonePalette(hdc);
3755 /*************************************************************************
3756 * SHGetInverseCMAP (SHLWAPI.@)
3758 * Get an inverse color map table.
3761 * lpCmap [O] Destination for color map
3762 * dwSize [I] Size of memory pointed to by lpCmap
3766 * Failure: E_POINTER, If lpCmap is invalid.
3767 * E_INVALIDARG, If dwFlags is invalid
3768 * E_OUTOFMEMORY, If there is no memory available
3771 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3772 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3774 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3775 * this DLL's internal CMap.
3777 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3780 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3781 *dest = (DWORD)0xabba1249;
3784 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3788 /*************************************************************************
3789 * SHIsLowMemoryMachine [SHLWAPI.@]
3791 * Determine if the current computer has low memory.
3797 * TRUE if the users machine has 16 Megabytes of memory or less,
3800 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3802 FIXME("(0x%08lx) stub\n", x);
3806 /*************************************************************************
3807 * GetMenuPosFromID [SHLWAPI.@]
3809 * Return the position of a menu item from its Id.
3812 * hMenu [I] Menu containing the item
3813 * wID [I] Id of the menu item
3816 * Success: The index of the menu item in hMenu.
3817 * Failure: -1, If the item is not found.
3819 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3822 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3824 while (nIter < nCount)
3827 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3834 /*************************************************************************
3837 * Same as SHLWAPI.GetMenuPosFromID
3839 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
3841 return GetMenuPosFromID(hMenu, uID);
3845 /*************************************************************************
3848 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
3859 /*************************************************************************
3862 DWORD WINAPI SHGetAppCompatFlags()
3869 /*************************************************************************
3872 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
3873 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
3875 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
3878 /*************************************************************************
3879 * SHSkipJunction [SHLWAPI.@]
3881 * Determine if a bind context can be bound to an object
3884 * pbc [I] Bind context to check
3885 * pclsid [I] CLSID of object to be bound to
3888 * TRUE: If it is safe to bind
3889 * FALSE: If pbc is invalid or binding would not be safe
3892 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
3894 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
3895 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
3902 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
3906 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
3907 IsEqualGUID(pclsid, &clsid))
3910 IUnknown_Release(lpUnk);
3916 /***********************************************************************
3917 * SHGetShellKey (SHLWAPI.@)
3919 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
3921 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
3925 /***********************************************************************
3926 * SHQueueUserWorkItem (SHLWAPI.@)
3928 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
3930 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
3934 /***********************************************************************
3935 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
3937 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
3939 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
3942 IInputObjectSite * pIOS = NULL;
3943 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
3944 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
3950 /***********************************************************************
3951 * SHGetValueW (SHLWAPI.@)
3953 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
3955 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
3959 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
3961 /***********************************************************************
3962 * GetUIVersion (SHLWAPI.452)
3964 DWORD WINAPI GetUIVersion(void)
3966 static DWORD version;
3970 DllGetVersion_func pDllGetVersion;
3971 HMODULE dll = LoadLibraryA("shell32.dll");
3974 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
3978 dvi.cbSize = sizeof(DLLVERSIONINFO);
3979 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
3982 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */