2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
47 #include "wine/unicode.h"
50 #include "wine/debug.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(shell);
57 /* Get a function pointer from a DLL handle */
58 #define GET_FUNC(func, module, name, fail) \
61 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
62 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
63 if (!func) return fail; \
67 /* DLL handles for late bound calls */
68 extern HINSTANCE shlwapi_hInstance;
69 extern HMODULE SHLWAPI_hshell32;
70 extern HMODULE SHLWAPI_hwinmm;
71 extern HMODULE SHLWAPI_hcomdlg32;
72 extern HMODULE SHLWAPI_hcomctl32;
73 extern HMODULE SHLWAPI_hmpr;
74 extern HMODULE SHLWAPI_hurlmon;
75 extern HMODULE SHLWAPI_hversion;
77 extern DWORD SHLWAPI_ThreadRef_index;
79 typedef HANDLE HSHARED; /* Shared memory */
81 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
82 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
83 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
84 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
86 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
87 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
88 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
89 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
90 static fnpPlaySoundW pPlaySoundW;
91 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
92 static fnpSHGetFileInfoW pSHGetFileInfoW;
93 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
94 static fnpDragQueryFileW pDragQueryFileW;
95 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
96 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
97 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
98 static fnpShellExecuteExW pShellExecuteExW;
99 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
100 static fnpSHFileOperationW pSHFileOperationW;
101 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
102 static fnpExtractIconExW pExtractIconExW;
103 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
104 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
105 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
106 static fnpSHDefExtractIconW pSHDefExtractIconW;
107 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
108 static fnpExtractIconW pExtractIconW;
109 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
110 static fnpGetSaveFileNameW pGetSaveFileNameW;
111 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
112 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
113 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
114 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
115 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
116 static fnpPageSetupDlgW pPageSetupDlgW;
117 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
118 static fnpPrintDlgW pPrintDlgW;
119 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
120 static fnpGetOpenFileNameW pGetOpenFileNameW;
121 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
122 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
123 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
124 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
125 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
126 static fnpVerQueryValueW pVerQueryValueW;
127 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
128 static fnpCOMCTL32_417 pCOMCTL32_417;
129 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
130 static fnpDllGetVersion pDllGetVersion;
131 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
132 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
133 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
134 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
136 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
137 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
138 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
139 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
142 NOTES: Most functions exported by ordinal seem to be superflous.
143 The reason for these functions to be there is to provide a wrapper
144 for unicode functions to provide these functions on systems without
145 unicode functions eg. win95/win98. Since we have such functions we just
146 call these. If running Wine with native DLL's, some late bound calls may
147 fail. However, its better to implement the functions in the forward DLL
148 and recommend the builtin rather than reimplementing the calls here!
151 /*************************************************************************
152 * SHLWAPI_DupSharedHandle
154 * Internal implemetation of SHLWAPI_11.
157 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
158 DWORD dwSrcProcId, DWORD dwAccess,
162 DWORD dwMyProcId = GetCurrentProcessId();
163 HSHARED hRet = (HSHARED)NULL;
165 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
166 dwAccess, dwOptions);
168 /* Get dest process handle */
169 if (dwDstProcId == dwMyProcId)
170 hDst = GetCurrentProcess();
172 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
176 /* Get src process handle */
177 if (dwSrcProcId == dwMyProcId)
178 hSrc = GetCurrentProcess();
180 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
184 /* Make handle available to dest process */
185 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
186 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
187 hRet = (HSHARED)NULL;
189 if (dwSrcProcId != dwMyProcId)
193 if (dwDstProcId != dwMyProcId)
197 TRACE("Returning handle %p\n", (PVOID)hRet);
201 /*************************************************************************
204 * Create a block of sharable memory and initialise it with data.
207 * dwProcId [I] ID of process owning data
208 * lpvData [I] Pointer to data to write
209 * dwSize [I] Size of data
212 * Success: A shared memory handle
216 * Ordinals 7-11 provide a set of calls to create shared memory between a
217 * group of processes. The shared memory is treated opaquely in that its size
218 * is not exposed to clients who map it. This is accomplished by storing
219 * the size of the map as the first DWORD of mapped data, and then offsetting
220 * the view pointer returned by this size.
223 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
227 HSHARED hRet = (HSHARED)NULL;
229 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
231 /* Create file mapping of the correct length */
232 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
233 dwSize + sizeof(dwSize), NULL);
237 /* Get a view in our process address space */
238 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
242 /* Write size of data, followed by the data, to the view */
243 *((DWORD*)pMapped) = dwSize;
245 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
247 /* Release view. All further views mapped will be opaque */
248 UnmapViewOfFile(pMapped);
249 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
250 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
251 DUPLICATE_SAME_ACCESS);
258 /*************************************************************************
261 * Get a pointer to a block of shared memory from a shared memory handle.
264 * hShared [I] Shared memory handle
265 * dwProcId [I] ID of process owning hShared
268 * Success: A pointer to the shared memory
272 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
277 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
279 /* Get handle to shared memory for current process */
280 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
281 FILE_MAP_ALL_ACCESS, 0);
283 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
287 return (char *) pMapped + sizeof(DWORD); /* Hide size */
291 /*************************************************************************
294 * Release a pointer to a block of shared memory.
297 * lpView [I] Shared memory pointer
304 BOOL WINAPI SHUnlockShared(LPVOID lpView)
306 TRACE("(%p)\n", lpView);
307 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
310 /*************************************************************************
313 * Destroy a block of sharable memory.
316 * hShared [I] Shared memory handle
317 * dwProcId [I] ID of process owning hShared
324 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
328 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
330 /* Get a copy of the handle for our process, closing the source handle */
331 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
332 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
333 /* Close local copy */
334 return CloseHandle((HANDLE)hClose);
337 /*************************************************************************
340 * Copy a sharable memory handle from one process to another.
343 * hShared [I] Shared memory handle to duplicate
344 * dwDstProcId [I] ID of the process wanting the duplicated handle
345 * dwSrcProcId [I] ID of the process owning hShared
346 * dwAccess [I] Desired DuplicateHandle() access
347 * dwOptions [I] Desired DuplicateHandle() options
350 * Success: A handle suitable for use by the dwDstProcId process.
351 * Failure: A NULL handle.
354 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
355 DWORD dwAccess, DWORD dwOptions)
359 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
360 dwAccess, dwOptions);
364 /*************************************************************************
367 * Create and register a clipboard enumerator for a web browser.
370 * lpBC [I] Binding context
371 * lpUnknown [I] An object exposing the IWebBrowserApp interface
375 * Failure: An HRESULT error code.
378 * The enumerator is stored as a property of the web browser. If it does not
379 * yet exist, it is created and set before being registered.
381 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
383 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
384 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
385 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
386 IEnumFORMATETC* pIEnumFormatEtc = NULL;
389 IWebBrowserApp* pBrowser = NULL;
391 TRACE("(%p, %p)\n", lpBC, lpUnknown);
393 /* Get An IWebBrowserApp interface from lpUnknown */
394 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
395 if (FAILED(hRet) || !pBrowser)
396 return E_NOINTERFACE;
398 V_VT(&var) = VT_EMPTY;
400 /* The property we get is the browsers clipboard enumerator */
401 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
405 if (V_VT(&var) == VT_EMPTY)
407 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
408 char szKeyBuff[128], szValueBuff[128];
409 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
410 FORMATETC* formatList, *format;
413 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
415 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
416 "Version\\Internet Settings\\Accepted Documents", &hDocs))
419 /* Get count of values in key */
422 dwKeySize = sizeof(szKeyBuff);
423 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
427 dwNumValues = dwCount;
429 /* Note: dwCount = number of items + 1; The extra item is the end node */
430 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
432 return E_OUTOFMEMORY;
441 /* Register clipboard formats for the values and populate format list */
442 while(!dwRet && dwCount < dwNumValues)
444 dwKeySize = sizeof(szKeyBuff);
445 dwValueSize = sizeof(szValueBuff);
446 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
447 (PBYTE)szValueBuff, &dwValueSize);
451 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
453 format->dwAspect = 1;
462 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
463 format->cfFormat = 0;
465 format->dwAspect = 1;
469 /* Create a clipboard enumerator */
470 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
471 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
473 if (FAILED(hRet) || !pIEnumFormatEtc)
476 /* Set our enumerator as the browsers property */
477 V_VT(&var) = VT_UNKNOWN;
478 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
480 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
483 IEnumFORMATETC_Release(pIEnumFormatEtc);
484 goto RegisterDefaultAcceptHeaders_Exit;
488 if (V_VT(&var) == VT_UNKNOWN)
490 /* Our variant is holding the clipboard enumerator */
491 IUnknown* pIUnknown = V_UNKNOWN(&var);
492 IEnumFORMATETC* pClone = NULL;
494 TRACE("Retrieved IEnumFORMATETC property\n");
496 /* Get an IEnumFormatEtc interface from the variants value */
497 pIEnumFormatEtc = NULL;
498 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
499 (PVOID)&pIEnumFormatEtc);
500 if (!hRet && pIEnumFormatEtc)
502 /* Clone and register the enumerator */
503 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
506 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
507 pRegisterFormatEnumerator(lpBC, pClone, 0);
509 IEnumFORMATETC_Release(pClone);
512 /* Release the IEnumFormatEtc interface */
513 IEnumFORMATETC_Release(pIUnknown);
515 IUnknown_Release(V_UNKNOWN(&var));
518 RegisterDefaultAcceptHeaders_Exit:
519 IWebBrowserApp_Release(pBrowser);
523 /*************************************************************************
526 * Get Explorers "AcceptLanguage" setting.
529 * langbuf [O] Destination for language string
530 * buflen [I] Length of langbuf
531 * [0] Success: used length of langbuf
534 * Success: S_OK. langbuf is set to the language string found.
535 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
536 * does not contain the setting.
537 * E_INVALIDARG, If the buffer is not big enough
539 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
541 static const WCHAR szkeyW[] = {
542 'S','o','f','t','w','a','r','e','\\',
543 'M','i','c','r','o','s','o','f','t','\\',
544 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
545 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
546 static const WCHAR valueW[] = {
547 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
548 static const WCHAR enusW[] = {'e','n','-','u','s',0};
549 DWORD mystrlen, mytype;
555 if(!langbuf || !buflen || !*buflen)
558 mystrlen = (*buflen > 20) ? *buflen : 20 ;
559 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
560 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
561 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
562 /* Did not find value */
563 mylcid = GetUserDefaultLCID();
564 /* somehow the mylcid translates into "en-us"
565 * this is similar to "LOCALE_SABBREVLANGNAME"
566 * which could be gotten via GetLocaleInfo.
567 * The only problem is LOCALE_SABBREVLANGUAGE" is
568 * a 3 char string (first 2 are country code and third is
569 * letter for "sublanguage", which does not come close to
572 lstrcpyW(mystr, enusW);
573 mystrlen = lstrlenW(mystr);
575 /* handle returned string */
576 FIXME("missing code\n");
578 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
580 if(*buflen > lstrlenW(mystr)) {
581 *buflen = lstrlenW(mystr);
585 retval = E_INVALIDARG;
586 SetLastError(ERROR_INSUFFICIENT_BUFFER);
589 HeapFree(GetProcessHeap(), 0, mystr);
593 /*************************************************************************
596 * Ascii version of GetAcceptLanguagesW.
598 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
601 DWORD buflenW, convlen;
604 if(!langbuf || !buflen || !*buflen) return E_FAIL;
607 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
608 retval = GetAcceptLanguagesW(langbufW, &buflenW);
610 /* FIXME: this is wrong, the string may not be null-terminated */
611 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
612 *buflen, NULL, NULL);
613 *buflen = buflenW ? convlen : 0;
615 if(langbufW) HeapFree(GetProcessHeap(), 0, langbufW);
619 /*************************************************************************
622 * Convert a GUID to a string.
625 * guid [I] GUID to convert
626 * str [O] Destination for string
627 * cmax [I] Length of output buffer
630 * The length of the string created.
632 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
637 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
639 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
640 guid->Data1, guid->Data2, guid->Data3,
641 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
642 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
644 iLen = strlen(xguid) + 1;
648 memcpy(lpszDest, xguid, iLen);
652 /*************************************************************************
655 * Unicode version of SHStringFromGUIDA.
657 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
660 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
663 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
667 /*************************************************************************
670 * Determine if a Unicode character is alphabetic.
673 * wc [I] Character to check.
676 * TRUE, if wc is alphabetic,
679 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
681 return (get_char_typeW(wc) & C1_ALPHA) != 0;
684 /*************************************************************************
687 * Determine if a Unicode character is upper-case.
690 * wc [I] Character to check.
693 * TRUE, if wc is upper-case,
696 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
698 return (get_char_typeW(wc) & C1_UPPER) != 0;
701 /*************************************************************************
704 * Determine if a Unicode character is lower-case.
707 * wc [I] Character to check.
710 * TRUE, if wc is lower-case,
713 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
715 return (get_char_typeW(wc) & C1_LOWER) != 0;
718 /*************************************************************************
721 * Determine if a Unicode character is alphabetic or a digit.
724 * wc [I] Character to check.
727 * TRUE, if wc is alphabetic or a digit,
730 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
732 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
735 /*************************************************************************
738 * Determine if a Unicode character is a space.
741 * wc [I] Character to check.
744 * TRUE, if wc is a space,
747 BOOL WINAPI IsCharSpaceW(WCHAR wc)
749 return (get_char_typeW(wc) & C1_SPACE) != 0;
752 /*************************************************************************
755 * Determine if a Unicode character is a blank.
758 * wc [I] Character to check.
761 * TRUE, if wc is a blank,
765 BOOL WINAPI IsCharBlankW(WCHAR wc)
767 return (get_char_typeW(wc) & C1_BLANK) != 0;
770 /*************************************************************************
773 * Determine if a Unicode character is punctuation.
776 * wc [I] Character to check.
779 * TRUE, if wc is punctuation,
782 BOOL WINAPI IsCharPunctW(WCHAR wc)
784 return (get_char_typeW(wc) & C1_PUNCT) != 0;
787 /*************************************************************************
790 * Determine if a Unicode character is a control character.
793 * wc [I] Character to check.
796 * TRUE, if wc is a control character,
799 BOOL WINAPI IsCharCntrlW(WCHAR wc)
801 return (get_char_typeW(wc) & C1_CNTRL) != 0;
804 /*************************************************************************
807 * Determine if a Unicode character is a digit.
810 * wc [I] Character to check.
813 * TRUE, if wc is a digit,
816 BOOL WINAPI IsCharDigitW(WCHAR wc)
818 return (get_char_typeW(wc) & C1_DIGIT) != 0;
821 /*************************************************************************
824 * Determine if a Unicode character is a hex digit.
827 * wc [I] Character to check.
830 * TRUE, if wc is a hex digit,
833 BOOL WINAPI IsCharXDigitW(WCHAR wc)
835 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
838 /*************************************************************************
842 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
844 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
848 /*************************************************************************
851 * Insert a bitmap menu item at the bottom of a menu.
854 * hMenu [I] Menu to insert into
855 * flags [I] Flags for insertion
856 * id [I] Menu ID of the item
857 * str [I] Menu text for the item
860 * Success: TRUE, the item is inserted into the menu
861 * Failure: FALSE, if any parameter is invalid
863 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
865 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
866 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
869 /*************************************************************************
872 * Get the text from a given dialog item.
875 * hWnd [I] Handle of dialog
876 * nItem [I] Index of item
877 * lpsDest [O] Buffer for receiving window text
878 * nDestLen [I] Length of buffer.
881 * Success: The length of the returned text.
884 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
886 HWND hItem = GetDlgItem(hWnd, nItem);
889 return GetWindowTextW(hItem, lpsDest, nDestLen);
891 *lpsDest = (WCHAR)'\0';
895 /*************************************************************************
898 * Set the text of a given dialog item.
901 * hWnd [I] Handle of dialog
902 * iItem [I] Index of item
903 * lpszText [O] Text to set
906 * Success: TRUE. The text of the dialog is set to lpszText.
907 * Failure: FALSE, Otherwise.
909 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
911 HWND hWndItem = GetDlgItem(hWnd, iItem);
913 return SetWindowTextW(hWndItem, lpszText);
917 /*************************************************************************
920 * Compare two Ascii strings up to a given length.
923 * lpszSrc [I] Source string
924 * lpszCmp [I] String to compare to lpszSrc
925 * len [I] Maximum length
928 * A number greater than, less than or equal to 0 depending on whether
929 * lpszSrc is greater than, less than or equal to lpszCmp.
931 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
933 return strncmp(lpszSrc, lpszCmp, len);
936 /*************************************************************************
939 * Unicode version of StrCmpNCA.
941 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
943 return strncmpW(lpszSrc, lpszCmp, len);
946 /*************************************************************************
949 * Compare two Ascii strings up to a given length, ignoring case.
952 * lpszSrc [I] Source string
953 * lpszCmp [I] String to compare to lpszSrc
954 * len [I] Maximum length
957 * A number greater than, less than or equal to 0 depending on whether
958 * lpszSrc is greater than, less than or equal to lpszCmp.
960 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
962 return strncasecmp(lpszSrc, lpszCmp, len);
965 /*************************************************************************
968 * Unicode version of StrCmpNICA.
970 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
972 return strncmpiW(lpszSrc, lpszCmp, len);
975 /*************************************************************************
978 * Compare two Ascii strings.
981 * lpszSrc [I] Source string
982 * lpszCmp [I] String to compare to lpszSrc
985 * A number greater than, less than or equal to 0 depending on whether
986 * lpszSrc is greater than, less than or equal to lpszCmp.
988 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
990 return strcmp(lpszSrc, lpszCmp);
993 /*************************************************************************
996 * Unicode version of StrCmpCA.
998 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1000 return strcmpW(lpszSrc, lpszCmp);
1003 /*************************************************************************
1006 * Compare two Ascii strings, ignoring case.
1009 * lpszSrc [I] Source string
1010 * lpszCmp [I] String to compare to lpszSrc
1013 * A number greater than, less than or equal to 0 depending on whether
1014 * lpszSrc is greater than, less than or equal to lpszCmp.
1016 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1018 return strcasecmp(lpszSrc, lpszCmp);
1021 /*************************************************************************
1024 * Unicode version of StrCmpICA.
1026 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1028 return strcmpiW(lpszSrc, lpszCmp);
1031 /*************************************************************************
1034 * Get an identification string for the OS and explorer.
1037 * lpszDest [O] Destination for Id string
1038 * dwDestLen [I] Length of lpszDest
1041 * TRUE, If the string was created successfully
1044 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1048 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1050 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1052 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1058 /*************************************************************************
1061 * Unicode version of SHAboutInfoA.
1063 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1065 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1066 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1067 ' ','E','x','p','l','o','r','e','r','\0' };
1068 static const WCHAR szWinNtKey[] = { '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 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1071 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1072 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1073 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1074 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1075 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1076 ' ','E','x','p','l','o','r','e','r','\\',
1077 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1078 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1079 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1080 'V','e','r','s','i','o','n','\0' };
1081 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1082 'O','w','n','e','r','\0' };
1083 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1084 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1085 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1086 static const WCHAR szUpdate[] = { 'I','E','A','K',
1087 'U','p','d','a','t','e','U','r','l','\0' };
1088 static const WCHAR szHelp[] = { 'I','E','A','K',
1089 'H','e','l','p','S','t','r','i','n','g','\0' };
1092 DWORD dwType, dwLen;
1094 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1101 /* Try the NT key first, followed by 95/98 key */
1102 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1103 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1109 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1111 DWORD dwStrLen = strlenW(buff);
1112 dwLen = 30 - dwStrLen;
1113 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1114 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1116 StrCatBuffW(lpszDest, buff, dwDestLen);
1118 /* ~Registered Owner */
1121 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1123 StrCatBuffW(lpszDest, buff, dwDestLen);
1125 /* ~Registered Organization */
1127 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1129 StrCatBuffW(lpszDest, buff, dwDestLen);
1131 /* FIXME: Not sure where this number comes from */
1135 StrCatBuffW(lpszDest, buff, dwDestLen);
1139 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1141 StrCatBuffW(lpszDest, buff, dwDestLen);
1143 /* ~IE Update Url */
1145 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1147 StrCatBuffW(lpszDest, buff, dwDestLen);
1149 /* ~IE Help String */
1151 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1153 StrCatBuffW(lpszDest, buff, dwDestLen);
1159 /*************************************************************************
1162 * Call IOleCommandTarget_QueryStatus() on an object.
1165 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1166 * pguidCmdGroup [I] GUID for the command group
1168 * prgCmds [O] Commands
1169 * pCmdText [O] Command text
1173 * Failure: E_FAIL, if lpUnknown is NULL.
1174 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1175 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1177 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1178 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1180 HRESULT hRet = E_FAIL;
1182 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1186 IOleCommandTarget* lpOle;
1188 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1191 if (SUCCEEDED(hRet) && lpOle)
1193 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1195 IOleCommandTarget_Release(lpOle);
1201 /*************************************************************************
1204 * Call IOleCommandTarget_Exec() on an object.
1207 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1208 * pguidCmdGroup [I] GUID for the command group
1212 * Failure: E_FAIL, if lpUnknown is NULL.
1213 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1214 * Otherwise, an error code from IOleCommandTarget_Exec().
1216 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1217 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1220 HRESULT hRet = E_FAIL;
1222 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1223 nCmdexecopt, pvaIn, pvaOut);
1227 IOleCommandTarget* lpOle;
1229 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1231 if (SUCCEEDED(hRet) && lpOle)
1233 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1234 nCmdexecopt, pvaIn, pvaOut);
1235 IOleCommandTarget_Release(lpOle);
1241 /*************************************************************************
1244 * Retrieve, modify, and re-set a value from a window.
1247 * hWnd [I] Window to get value from
1248 * offset [I] Offset of value
1249 * wMask [I] Mask for uiFlags
1250 * wFlags [I] Bits to set in window value
1253 * The new value as it was set, or 0 if any parameter is invalid.
1256 * Any bits set in uiMask are cleared from the value, then any bits set in
1257 * uiFlags are set in the value.
1259 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1261 LONG ret = GetWindowLongA(hwnd, offset);
1262 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1264 if (newFlags != ret)
1265 ret = SetWindowLongA(hwnd, offset, newFlags);
1269 /*************************************************************************
1272 * Change a window's parent.
1275 * hWnd [I] Window to change parent of
1276 * hWndParent [I] New parent window
1279 * The old parent of hWnd.
1282 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1283 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1285 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1287 TRACE("%p, %p\n", hWnd, hWndParent);
1289 if(GetParent(hWnd) == hWndParent)
1293 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1295 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1297 return SetParent(hWnd, hWndParent);
1300 /*************************************************************************
1303 * Locate and advise a connection point in an IConnectionPointContainer object.
1306 * lpUnkSink [I] Sink for the connection point advise call
1307 * riid [I] REFIID of connection point to advise
1308 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1309 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1310 * lpCookie [O] Pointer to connection point cookie
1311 * lppCP [O] Destination for the IConnectionPoint found
1314 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1315 * that was advised. The caller is responsable for releasing it.
1316 * Failure: E_FAIL, if any arguments are invalid.
1317 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1318 * Or an HRESULT error code if any call fails.
1320 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1321 IUnknown* lpUnknown, LPDWORD lpCookie,
1322 IConnectionPoint **lppCP)
1325 IConnectionPointContainer* lpContainer;
1326 IConnectionPoint *lpCP;
1328 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1334 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1335 (void**)&lpContainer);
1336 if (SUCCEEDED(hRet))
1338 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1340 if (SUCCEEDED(hRet))
1343 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1344 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1349 if (lppCP && SUCCEEDED(hRet))
1350 *lppCP = lpCP; /* Caller keeps the interface */
1352 IConnectionPoint_Release(lpCP); /* Release it */
1355 IUnknown_Release(lpContainer);
1360 /*************************************************************************
1363 * Release an interface.
1366 * lpUnknown [I] Object to release
1371 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1375 TRACE("(%p)\n",lpUnknown);
1377 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1381 TRACE("doing Release\n");
1383 return IUnknown_Release(temp);
1386 /*************************************************************************
1389 * Skip '//' if present in a string.
1392 * lpszSrc [I] String to check for '//'
1395 * Success: The next character after the '//' or the string if not present
1396 * Failure: NULL, if lpszStr is NULL.
1398 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1400 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1405 /*************************************************************************
1408 * Check if two interfaces come from the same object.
1411 * lpInt1 [I] Interface to check against lpInt2.
1412 * lpInt2 [I] Interface to check against lpInt1.
1415 * TRUE, If the interfaces come from the same object.
1418 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1420 LPVOID lpUnknown1, lpUnknown2;
1422 TRACE("%p %p\n", lpInt1, lpInt2);
1424 if (!lpInt1 || !lpInt2)
1427 if (lpInt1 == lpInt2)
1430 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1431 (LPVOID *)&lpUnknown1)))
1434 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1435 (LPVOID *)&lpUnknown2)))
1438 if (lpUnknown1 == lpUnknown2)
1444 /*************************************************************************
1447 * Get the window handle of an object.
1450 * lpUnknown [I] Object to get the window handle of
1451 * lphWnd [O] Destination for window handle
1454 * Success: S_OK. lphWnd contains the objects window handle.
1455 * Failure: An HRESULT error code.
1458 * lpUnknown is expected to support one of the following interfaces:
1459 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1461 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1463 /* FIXME: Wine has no header for this object */
1464 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1465 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1467 HRESULT hRet = E_FAIL;
1469 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1474 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1478 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1482 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1487 if (SUCCEEDED(hRet))
1489 /* Lazyness here - Since GetWindow() is the first method for the above 3
1490 * interfaces, we use the same call for them all.
1492 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1493 IUnknown_Release(lpOle);
1495 TRACE("Returning HWND=%p\n", *lphWnd);
1501 /*************************************************************************
1504 * Call a method on as as yet unidentified object.
1507 * pUnk [I] Object supporting the unidentified interface,
1508 * arg [I] Argument for the call on the object.
1513 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1515 static const GUID guid_173 = {
1516 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1520 TRACE("(%p,%ld)\n", pUnk, arg);
1522 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1523 * We use this interface as its vtable entry is compatible with the
1524 * object in question.
1525 * FIXME: Find out what this object is and where it should be defined.
1528 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1530 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1531 IMalloc_Release(pUnk2);
1536 /*************************************************************************
1539 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1544 * Failure: E_FAIL, if p1 is NULL.
1545 * E_NOINTERFACE If p1 does not support the IPersist interface,
1546 * Or an HRESULT error code.
1548 DWORD WINAPI IUnknown_SetSite(
1549 IUnknown *p1, /* [in] OLE object */
1550 LPVOID *p2) /* [out] ptr for call results */
1554 if (!p1) return E_FAIL;
1556 /* see if SetSite interface exists for IObjectWithSite object */
1557 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1558 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1561 /* see if GetClassId interface exists for IPersistMoniker object */
1562 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1563 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1564 if (ret) return ret;
1566 /* fake a GetClassId call */
1567 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1568 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1570 IUnknown_Release((IUnknown *)aa);
1573 /* fake a SetSite call */
1574 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1575 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1577 IUnknown_Release((IUnknown *)p1);
1582 /*************************************************************************
1585 * Call IPersist_GetClassID() on an object.
1588 * lpUnknown [I] Object supporting the IPersist interface
1589 * lpClassId [O] Destination for Class Id
1592 * Success: S_OK. lpClassId contains the Class Id requested.
1593 * Failure: E_FAIL, If lpUnknown is NULL,
1594 * E_NOINTERFACE If lpUnknown does not support IPersist,
1595 * Or an HRESULT error code.
1597 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1599 IPersist* lpPersist;
1600 HRESULT hRet = E_FAIL;
1602 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1606 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1607 if (SUCCEEDED(hRet))
1609 IPersist_GetClassID(lpPersist, lpClassId);
1610 IPersist_Release(lpPersist);
1616 /*************************************************************************
1619 * Retrieve a Service Interface from an object.
1622 * lpUnknown [I] Object to get an IServiceProvider interface from
1623 * sid [I] Service ID for IServiceProvider_QueryService() call
1624 * riid [I] Function requested for QueryService call
1625 * lppOut [O] Destination for the service interface pointer
1628 * Success: S_OK. lppOut contains an object providing the requested service
1629 * Failure: An HRESULT error code
1632 * lpUnknown is expected to support the IServiceProvider interface.
1634 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1637 IServiceProvider* pService = NULL;
1648 /* Get an IServiceProvider interface from the object */
1649 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1650 (LPVOID*)&pService);
1652 if (!hRet && pService)
1654 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1656 /* Get a Service interface from the object */
1657 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1659 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1661 /* Release the IServiceProvider interface */
1662 IUnknown_Release(pService);
1667 /*************************************************************************
1670 * Loads a popup menu.
1673 * hInst [I] Instance handle
1674 * szName [I] Menu name
1680 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1682 HMENU hMenu, hSubMenu;
1684 if ((hMenu = LoadMenuW(hInst, szName)))
1686 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1687 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1695 typedef struct _enumWndData
1700 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1703 /* Callback for SHLWAPI_178 */
1704 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1706 enumWndData *data = (enumWndData *)lParam;
1708 TRACE("(%p,%p)\n", hWnd, data);
1709 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1713 /*************************************************************************
1716 * Send or post a message to every child of a window.
1719 * hWnd [I] Window whose children will get the messages
1720 * uiMsgId [I] Message Id
1721 * wParam [I] WPARAM of message
1722 * lParam [I] LPARAM of message
1723 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1729 * The appropriate ASCII or Unicode function is called for the window.
1731 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1735 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1739 data.uiMsgId = uiMsgId;
1740 data.wParam = wParam;
1741 data.lParam = lParam;
1744 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1746 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1748 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1752 /*************************************************************************
1755 * Remove all sub-menus from a menu.
1758 * hMenu [I] Menu to remove sub-menus from
1761 * Success: 0. All sub-menus under hMenu are removed
1762 * Failure: -1, if any parameter is invalid
1764 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1766 int iItemCount = GetMenuItemCount(hMenu) - 1;
1767 while (iItemCount >= 0)
1769 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1771 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1777 /*************************************************************************
1780 * Enable or disable a menu item.
1783 * hMenu [I] Menu holding menu item
1784 * uID [I] ID of menu item to enable/disable
1785 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1788 * The return code from EnableMenuItem.
1790 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1792 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1795 /*************************************************************************
1798 * Check or uncheck a menu item.
1801 * hMenu [I] Menu holding menu item
1802 * uID [I] ID of menu item to check/uncheck
1803 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1806 * The return code from CheckMenuItem.
1808 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1810 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1813 /*************************************************************************
1816 * Register a window class if it isn't already.
1819 * lpWndClass [I] Window class to register
1822 * The result of the RegisterClassA call.
1824 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1827 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1829 return (DWORD)RegisterClassA(wndclass);
1832 /*************************************************************************
1835 * Call IPersistPropertyBag_Load() on an object.
1838 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1839 * lpPropBag [O] Destination for loaded IPropertyBag
1843 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1845 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1847 IPersistPropertyBag* lpPPBag;
1848 HRESULT hRet = E_FAIL;
1850 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1854 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1856 if (SUCCEEDED(hRet) && lpPPBag)
1858 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1859 IPersistPropertyBag_Release(lpPPBag);
1865 /*************************************************************************
1868 * Call IOleControlSite_GetExtendedControl() on an object.
1871 * lpUnknown [I] Object supporting the IOleControlSite interface
1872 * lppDisp [O] Destination for resulting IDispatch.
1876 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1878 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1880 IOleControlSite* lpCSite;
1881 HRESULT hRet = E_FAIL;
1883 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1886 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1888 if (SUCCEEDED(hRet) && lpCSite)
1890 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1891 IOleControlSite_Release(lpCSite);
1897 /*************************************************************************
1900 * Get a sub-menu from a menu item.
1903 * hMenu [I] Menu to get sub-menu from
1904 * uID [I] ID of menu item containing sub-menu
1907 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1909 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1913 TRACE("(%p,%uld)\n", hMenu, uID);
1915 mi.cbSize = sizeof(MENUITEMINFOA);
1916 mi.fMask = MIIM_SUBMENU;
1918 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1924 /*************************************************************************
1927 * Get the color depth of the primary display.
1933 * The color depth of the primary display.
1935 DWORD WINAPI SHGetCurColorRes()
1943 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1948 /*************************************************************************
1951 * Wait for a message to arrive, with a timeout.
1954 * hand [I] Handle to query
1955 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1958 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1959 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1960 * message is available.
1962 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1964 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1967 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1971 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1973 if (dwTimeout != INFINITE)
1975 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1976 return WAIT_TIMEOUT;
1983 /*************************************************************************
1986 * Blank out a region of text by drawing the background only.
1989 * hDC [I] Device context to draw in
1990 * pRect [I] Area to draw in
1991 * cRef [I] Color to draw in
1996 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
1998 COLORREF cOldColor = SetBkColor(hDC, cRef);
1999 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2000 SetBkColor(hDC, cOldColor);
2004 /*************************************************************************
2007 * Return the value asociated with a key in a map.
2010 * lpKeys [I] A list of keys of length iLen
2011 * lpValues [I] A list of values associated with lpKeys, of length iLen
2012 * iLen [I] Length of both lpKeys and lpValues
2013 * iKey [I] The key value to look up in lpKeys
2016 * The value in lpValues associated with iKey, or -1 if iKey is not
2020 * - If two elements in the map share the same key, this function returns
2021 * the value closest to the start of the map
2022 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2024 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2026 if (lpKeys && lpValues)
2032 if (lpKeys[i] == iKey)
2033 return lpValues[i]; /* Found */
2037 return -1; /* Not found */
2041 /*************************************************************************
2044 * Copy an interface pointer
2047 * lppDest [O] Destination for copy
2048 * lpUnknown [I] Source for copy
2053 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2055 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2058 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2063 IUnknown_AddRef(lpUnknown);
2064 *lppDest = lpUnknown;
2068 /*************************************************************************
2072 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2073 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2076 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2077 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2078 return DRAGDROP_E_NOTREGISTERED;
2081 /*************************************************************************
2085 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2087 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2088 return DRAGDROP_E_NOTREGISTERED;
2091 /*************************************************************************
2094 * Determine if a window is not a child of another window.
2097 * hParent [I] Suspected parent window
2098 * hChild [I] Suspected child window
2101 * TRUE: If hChild is a child window of hParent
2102 * FALSE: If hChild is not a child window of hParent, or they are equal
2104 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2106 TRACE("(%p,%p)\n", hParent, hChild);
2108 if (!hParent || !hChild)
2110 else if(hParent == hChild)
2112 return !IsChild(hParent, hChild);
2115 /*************************************************************************
2118 * Some sort of memory management process.
2120 DWORD WINAPI FDSA_Initialize(
2127 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2132 /*************************************************************************
2135 * Some sort of memory management process.
2137 DWORD WINAPI FDSA_Destroy(
2140 FIXME("(%p) stub\n",
2145 /*************************************************************************
2148 * Some sort of memory management process.
2150 DWORD WINAPI FDSA_InsertItem(
2155 FIXME("(%p 0x%08lx %p) stub\n",
2160 /*************************************************************************
2163 DWORD WINAPI FDSA_DeleteItem(
2167 FIXME("(%p 0x%08lx) stub\n",
2177 /*************************************************************************
2180 * Call IUnknown_QueryInterface() on a table of objects.
2184 * Failure: E_POINTER or E_NOINTERFACE.
2186 HRESULT WINAPI QISearch(
2187 LPVOID w, /* [in] Table of interfaces */
2188 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2189 REFIID riid, /* [in] REFIID to get interface for */
2190 LPVOID *ppv) /* [out] Destination for interface pointer */
2194 IFACE_INDEX_TBL *xmove;
2196 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2199 while (xmove->refid) {
2200 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2201 if (IsEqualIID(riid, xmove->refid)) {
2202 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2203 TRACE("matched, returning (%p)\n", a_vtbl);
2204 *ppv = (LPVOID)a_vtbl;
2205 IUnknown_AddRef(a_vtbl);
2211 if (IsEqualIID(riid, &IID_IUnknown)) {
2212 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2213 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2214 *ppv = (LPVOID)a_vtbl;
2215 IUnknown_AddRef(a_vtbl);
2219 ret = E_NOINTERFACE;
2223 TRACE("-- 0x%08lx\n", ret);
2227 /*************************************************************************
2230 * Remove the "PropDlgFont" property from a window.
2233 * hWnd [I] Window to remove the property from
2236 * A handle to the removed property, or NULL if it did not exist.
2238 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2242 TRACE("(%p)\n", hWnd);
2244 hProp = GetPropA(hWnd, "PropDlgFont");
2248 DeleteObject(hProp);
2249 hProp = RemovePropA(hWnd, "PropDlgFont");
2254 /*************************************************************************
2257 * Load the in-process server of a given GUID.
2260 * refiid [I] GUID of the server to load.
2263 * Success: A handle to the loaded server dll.
2264 * Failure: A NULL handle.
2266 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2270 CHAR value[MAX_PATH], string[MAX_PATH];
2272 strcpy(string, "CLSID\\");
2273 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2274 strcat(string, "\\InProcServer32");
2277 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2278 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2279 RegCloseKey(newkey);
2280 return LoadLibraryExA(value, 0, 0);
2283 /*************************************************************************
2286 * Unicode version of SHLWAPI_183.
2288 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2292 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2294 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2296 return RegisterClassW(lpWndClass);
2299 /*************************************************************************
2302 * Unregister a list of classes.
2305 * hInst [I] Application instance that registered the classes
2306 * lppClasses [I] List of class names
2307 * iCount [I] Number of names in lppClasses
2312 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2316 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2320 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2321 UnregisterClassA(*lppClasses, hInst);
2327 /*************************************************************************
2330 * Unicode version of SHUnregisterClassesA.
2332 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2336 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2340 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2341 UnregisterClassW(*lppClasses, hInst);
2347 /*************************************************************************
2350 * Call The correct (Ascii/Unicode) default window procedure for a window.
2353 * hWnd [I] Window to call the default procedure for
2354 * uMessage [I] Message ID
2355 * wParam [I] WPARAM of message
2356 * lParam [I] LPARAM of message
2359 * The result of calling DefWindowProcA() or DefWindowProcW().
2361 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2363 if (IsWindowUnicode(hWnd))
2364 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2365 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2368 /*************************************************************************
2371 * Create a worker window using CreateWindowExA().
2374 * wndProc [I] Window procedure
2375 * hWndParent [I] Parent window
2376 * dwExStyle [I] Extra style flags
2377 * dwStyle [I] Style flags
2378 * hMenu [I] Window menu
2382 * Success: The window handle of the newly created window.
2385 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2386 DWORD dwStyle, HMENU hMenu, LONG z)
2388 static const char* szClass = "WorkerA";
2392 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2393 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2395 /* Create Window class */
2397 wc.lpfnWndProc = DefWindowProcA;
2400 wc.hInstance = shlwapi_hInstance;
2401 wc.hIcon = (HICON)0;
2402 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2403 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2404 wc.lpszMenuName = NULL;
2405 wc.lpszClassName = szClass;
2407 SHRegisterClassA(&wc); /* Register class */
2409 /* FIXME: Set extra bits in dwExStyle */
2411 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2412 hWndParent, hMenu, shlwapi_hInstance, 0);
2415 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2418 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2423 typedef struct tagPOLICYDATA
2425 DWORD policy; /* flags value passed to SHRestricted */
2426 LPCWSTR appstr; /* application str such as "Explorer" */
2427 LPCWSTR keystr; /* name of the actual registry key / policy */
2428 } POLICYDATA, *LPPOLICYDATA;
2430 #define SHELL_NO_POLICY 0xffffffff
2432 /* default shell policy registry key */
2433 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2434 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2435 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2436 '\\','P','o','l','i','c','i','e','s',0};
2438 /*************************************************************************
2441 * Retrieve a policy value from the registry.
2444 * lpSubKey [I] registry key name
2445 * lpSubName [I] subname of registry key
2446 * lpValue [I] value name of registry value
2449 * the value associated with the registry key or 0 if not found
2451 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2453 DWORD retval, datsize = sizeof(retval);
2457 lpSubKey = strRegistryPolicyW;
2459 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2460 if (retval != ERROR_SUCCESS)
2461 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2462 if (retval != ERROR_SUCCESS)
2465 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2470 /*************************************************************************
2473 * Helper function to retrieve the possibly cached value for a specific policy
2476 * policy [I] The policy to look for
2477 * initial [I] Main registry key to open, if NULL use default
2478 * polTable [I] Table of known policies, 0 terminated
2479 * polArr [I] Cache array of policy values
2482 * The retrieved policy value or 0 if not successful
2485 * This function is used by the native SHRestricted function to search for the
2486 * policy and cache it once retrieved. The current Wine implementation uses a
2487 * different POLICYDATA structure and implements a similar algorithme adapted to
2490 DWORD WINAPI SHRestrictionLookup(
2493 LPPOLICYDATA polTable,
2496 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2498 if (!polTable || !polArr)
2501 for (;polTable->policy; polTable++, polArr++)
2503 if (policy == polTable->policy)
2505 /* we have a known policy */
2507 /* check if this policy has been cached */
2508 if (*polArr == SHELL_NO_POLICY)
2509 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2513 /* we don't know this policy, return 0 */
2514 TRACE("unknown policy: (%08lx)\n", policy);
2518 /*************************************************************************
2521 * Get an interface from an object.
2524 * Success: S_OK. ppv contains the requested interface.
2525 * Failure: An HRESULT error code.
2528 * This QueryInterface asks the inner object for a interface. In case
2529 * of aggregation this request would be forwarded by the inner to the
2530 * outer object. This function asks the inner object directly for the
2531 * interface circumventing the forwarding to the outer object.
2533 HRESULT WINAPI SHWeakQueryInterface(
2534 IUnknown * pUnk, /* [in] Outer object */
2535 IUnknown * pInner, /* [in] Inner object */
2536 IID * riid, /* [in] Interface GUID to query for */
2537 LPVOID* ppv) /* [out] Destination for queried interface */
2539 HRESULT hret = E_NOINTERFACE;
2540 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2543 if(pUnk && pInner) {
2544 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2545 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2547 TRACE("-- 0x%08lx\n", hret);
2551 /*************************************************************************
2554 * Move a reference from one interface to another.
2557 * lpDest [O] Destination to receive the reference
2558 * lppUnknown [O] Source to give up the reference to lpDest
2563 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2565 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2570 IUnknown_AddRef(lpDest);
2571 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2575 /*************************************************************************
2578 * Convert an ASCII string of a CLSID into a CLSID.
2581 * idstr [I] String representing a CLSID in registry format
2582 * id [O] Destination for the converted CLSID
2585 * Success: TRUE. id contains the converted CLSID.
2588 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2591 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2592 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2595 /*************************************************************************
2598 * Unicode version of GUIDFromStringA.
2600 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2602 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2605 /*************************************************************************
2608 * Determine if the browser is integrated into the shell, and set a registry
2615 * 1, If the browser is not integrated.
2616 * 2, If the browser is integrated.
2619 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2620 * either set to TRUE, or removed depending on whether the browser is deemed
2623 DWORD WINAPI WhichPlatform()
2625 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2626 static DWORD dwState = 0;
2628 DWORD dwRet, dwData, dwSize;
2633 /* If shell32 exports DllGetVersion(), the browser is integrated */
2634 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2635 dwState = pDllGetVersion ? 2 : 1;
2637 /* Set or delete the key accordingly */
2638 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2639 "Software\\Microsoft\\Internet Explorer", 0,
2640 KEY_ALL_ACCESS, &hKey);
2643 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2644 (LPBYTE)&dwData, &dwSize);
2646 if (!dwRet && dwState == 1)
2648 /* Value exists but browser is not integrated */
2649 RegDeleteValueA(hKey, szIntegratedBrowser);
2651 else if (dwRet && dwState == 2)
2653 /* Browser is integrated but value does not exist */
2655 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2656 (LPBYTE)&dwData, sizeof(dwData));
2663 /*************************************************************************
2666 * Unicode version of SHCreateWorkerWindowA.
2668 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2669 DWORD dwStyle, HMENU hMenu, LONG z)
2671 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2675 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2676 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2678 /* If our OS is natively ASCII, use the ASCII version */
2679 if (!(GetVersion() & 0x80000000)) /* NT */
2680 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2682 /* Create Window class */
2684 wc.lpfnWndProc = DefWindowProcW;
2687 wc.hInstance = shlwapi_hInstance;
2688 wc.hIcon = (HICON)0;
2689 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2690 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2691 wc.lpszMenuName = NULL;
2692 wc.lpszClassName = szClass;
2694 SHRegisterClassW(&wc); /* Register class */
2696 /* FIXME: Set extra bits in dwExStyle */
2698 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2699 hWndParent, hMenu, shlwapi_hInstance, 0);
2702 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2705 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2710 /*************************************************************************
2713 * Get and show a context menu from a shell folder.
2716 * hWnd [I] Window displaying the shell folder
2717 * lpFolder [I] IShellFolder interface
2718 * lpApidl [I] Id for the particular folder desired
2722 * Failure: An HRESULT error code indicating the error.
2724 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2726 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2729 /*************************************************************************
2732 * _SHPackDispParamsV
2734 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2736 FIXME("%p %p %p %p\n",w,x,y,z);
2740 /*************************************************************************
2743 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2744 * function does...).
2746 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2748 FIXME("%p %p %p %p\n", w, x, y, z);
2752 /*************************************************************************
2755 * _IConnectionPoint_SimpleInvoke
2757 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2762 FIXME("(%p %p %p) stub\n",x,y,z);
2766 /*************************************************************************
2769 * Notify an IConnectionPoint object of changes.
2772 * lpCP [I] Object to notify
2777 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2778 * IConnectionPoint interface.
2780 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2782 IEnumConnections *lpEnum;
2783 HRESULT hRet = E_NOINTERFACE;
2785 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2787 /* Get an enumerator for the connections */
2789 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2791 if (SUCCEEDED(hRet))
2793 IPropertyNotifySink *lpSink;
2794 CONNECTDATA connData;
2797 /* Call OnChanged() for every notify sink in the connection point */
2798 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2800 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2803 IPropertyNotifySink_OnChanged(lpSink, dispID);
2804 IPropertyNotifySink_Release(lpSink);
2806 IUnknown_Release(connData.pUnk);
2809 IEnumConnections_Release(lpEnum);
2814 /*************************************************************************
2817 * Notify an IConnectionPointContainer object of changes.
2820 * lpUnknown [I] Object to notify
2825 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2826 * IConnectionPointContainer interface.
2828 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2830 IConnectionPointContainer* lpCPC = NULL;
2831 HRESULT hRet = E_NOINTERFACE;
2833 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2836 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2838 if (SUCCEEDED(hRet))
2840 IConnectionPoint* lpCP;
2842 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2843 IConnectionPointContainer_Release(lpCPC);
2845 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2846 IConnectionPoint_Release(lpCP);
2851 /*************************************************************************
2856 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2858 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2859 return pPlaySoundW(pszSound, hmod, fdwSound);
2862 /*************************************************************************
2865 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2868 * str1: "I" "I" pushl esp+0x20
2869 * str2: "U" "I" pushl 0x77c93810
2870 * (is "I" and "U" "integer" and "unsigned" ??)
2872 * pStr: "" "" pushl eax
2873 * some_len: 0x824 0x104 pushl 0x824
2874 * lpStr2: "%l" "%l" pushl esp+0xc
2876 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2877 * LocalAlloc(0x00, some_len) -> irrelevant_var
2878 * LocalAlloc(0x40, irrelevant_len) -> pStr
2879 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2880 * shlwapi.PathRemoveBlanksW(pStr);
2882 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2886 /*************************************************************************
2889 * Called by ICQ2000b install via SHDOCVW:
2890 * str1: "InternetShortcut"
2891 * x: some unknown pointer
2892 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2893 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2895 * In short: this one maybe creates a desktop link :-)
2897 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2899 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2903 /*************************************************************************
2908 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2909 LPCWSTR str, UINT count, const INT *lpDx)
2911 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2912 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2915 /*************************************************************************
2918 * See SHGetFileInfoW.
2920 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2921 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2923 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2924 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2927 /*************************************************************************
2930 * See DragQueryFileW.
2932 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2934 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2935 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2938 /*************************************************************************
2941 * See SHBrowseForFolderW.
2943 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2945 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2946 return pSHBrowseForFolderW(lpBi);
2949 /*************************************************************************
2952 * See SHGetPathFromIDListW.
2954 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2956 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2957 return pSHGetPathFromIDListW(pidl, pszPath);
2960 /*************************************************************************
2963 * See ShellExecuteExW.
2965 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2967 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2968 return pShellExecuteExW(lpExecInfo);
2971 /*************************************************************************
2974 * See SHFileOperationW.
2976 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2978 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2979 return pSHFileOperationW(lpFileOp);
2982 /*************************************************************************
2985 * See ExtractIconExW.
2987 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2988 HICON *phiconSmall, UINT nIcons)
2990 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2991 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
2994 /*************************************************************************
2998 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3000 return InterlockedCompareExchange(dest, xchg, compare);
3003 /*************************************************************************
3006 DWORD WINAPI SHUnicodeToUnicode(
3011 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3012 lstrcpynW(dest, src, len);
3013 return lstrlenW(dest)+1;
3016 /*************************************************************************
3019 * See GetFileVersionInfoSizeW.
3021 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3027 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3028 ret = pGetFileVersionInfoSizeW(x, y);
3032 /*************************************************************************
3035 * See GetFileVersionInfoW.
3037 BOOL WINAPI GetFileVersionInfoWrapW(
3038 LPWSTR w, /* [in] path to dll */
3039 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3040 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3041 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3043 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3044 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3047 /*************************************************************************
3050 * See VerQueryValueW.
3052 WORD WINAPI VerQueryValueWrapW(
3053 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3054 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3055 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3056 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3058 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3059 return pVerQueryValueW((char*)w+0x208, x, y, z);
3062 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3063 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3064 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3066 /*************************************************************************
3069 * Change the modality of a shell object.
3072 * lpUnknown [I] Object to make modeless
3073 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3076 * Success: S_OK. The modality lpUnknown is changed.
3077 * Failure: An HRESULT error code indicating the error.
3080 * lpUnknown must support the IOleInPlaceFrame interface, the
3081 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3082 * or the IDocHostUIHandler interface, or this call fails.
3084 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3089 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3094 if (IsIface(IOleInPlaceFrame))
3095 EnableModeless(IOleInPlaceFrame);
3096 else if (IsIface(IShellBrowser))
3097 EnableModeless(IShellBrowser);
3099 /* FIXME: Wine has no headers for these objects yet */
3100 else if (IsIface(IInternetSecurityMgrSite))
3101 EnableModeless(IInternetSecurityMgrSite);
3102 else if (IsIface(IDocHostUIHandler))
3103 EnableModeless(IDocHostUIHandler);
3108 IUnknown_Release(lpObj);
3112 /*************************************************************************
3115 * See SHGetNewLinkInfoW.
3117 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3118 BOOL *pfMustCopy, UINT uFlags)
3120 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3121 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3124 /*************************************************************************
3127 * See SHDefExtractIconW.
3129 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3130 HICON* phiconSmall, UINT nIconSize)
3132 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3133 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3136 /*************************************************************************
3139 * Get and show a context menu from a shell folder.
3142 * hWnd [I] Window displaying the shell folder
3143 * lpFolder [I] IShellFolder interface
3144 * lpApidl [I] Id for the particular folder desired
3145 * bInvokeDefault [I] Whether to invoke the default menu item
3148 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3150 * Failure: An HRESULT error code indicating the error.
3152 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3154 IContextMenu *iContext;
3155 HRESULT hRet = E_FAIL;
3157 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3162 /* Get the context menu from the shell folder */
3163 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3164 &IID_IContextMenu, 0, (void**)&iContext);
3165 if (SUCCEEDED(hRet))
3168 if ((hMenu = CreatePopupMenu()))
3171 DWORD dwDefaultId = 0;
3173 /* Add the context menu entries to the popup */
3174 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3175 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3177 if (SUCCEEDED(hQuery))
3179 if (bInvokeDefault &&
3180 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3182 CMINVOKECOMMANDINFO cmIci;
3183 /* Invoke the default item */
3184 memset(&cmIci,0,sizeof(cmIci));
3185 cmIci.cbSize = sizeof(cmIci);
3186 cmIci.fMask = CMIC_MASK_ASYNCOK;
3188 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3189 cmIci.nShow = SW_SCROLLCHILDREN;
3191 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3196 IContextMenu_Release(iContext);
3201 /*************************************************************************
3206 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3209 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3210 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3213 /*************************************************************************
3216 LANGID WINAPI MLGetUILanguage()
3219 /* FIXME: This should be a forward in the .spec file to the win2k function
3220 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3222 return GetUserDefaultLangID();
3225 /*************************************************************************
3228 * Load a library from the directory of a particular process.
3231 * new_mod [I] Library name
3232 * inst_hwnd [I] Module whose directory is to be used
3233 * dwFlags [I] Flags controlling the load
3236 * Success: A handle to the loaded module
3237 * Failure: A NULL handle.
3239 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3241 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3243 * FIXME: Native shows calls to:
3244 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3246 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3247 * RegQueryValueExA for "LPKInstalled"
3249 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3250 * RegQueryValueExA for "ResourceLocale"
3252 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3253 * RegQueryValueExA for "Locale"
3255 * and then tests the Locale ("en" for me).
3257 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3259 CHAR mod_path[2*MAX_PATH];
3263 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3264 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3265 if (!len || len >= sizeof(mod_path)) return NULL;
3267 ptr = strrchr(mod_path, '\\');
3269 strcpy(ptr+1, new_mod);
3270 TRACE("loading %s\n", debugstr_a(mod_path));
3271 return LoadLibraryA(mod_path);
3276 /*************************************************************************
3279 * Unicode version of MLLoadLibraryA.
3281 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3283 WCHAR mod_path[2*MAX_PATH];
3287 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3288 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3289 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3291 ptr = strrchrW(mod_path, '\\');
3293 strcpyW(ptr+1, new_mod);
3294 TRACE("loading %s\n", debugstr_w(mod_path));
3295 return LoadLibraryW(mod_path);
3300 /*************************************************************************
3301 * ColorAdjustLuma [SHLWAPI.@]
3303 * Adjust the luminosity of a color
3306 * cRGB [I] RGB value to convert
3307 * dwLuma [I] Luma adjustment
3308 * bUnknown [I] Unknown
3311 * The adjusted RGB color.
3313 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3315 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3321 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3323 FIXME("Ignoring luma adjustment\n");
3325 /* FIXME: The ajdustment is not linear */
3327 cRGB = ColorHLSToRGB(wH, wL, wS);
3332 /*************************************************************************
3335 * See GetSaveFileNameW.
3337 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3339 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3340 return pGetSaveFileNameW(ofn);
3343 /*************************************************************************
3346 * See WNetRestoreConnectionW.
3348 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3350 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3351 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3354 /*************************************************************************
3357 * See WNetGetLastErrorW.
3359 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3360 LPWSTR lpNameBuf, DWORD nNameBufSize)
3362 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3363 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3366 /*************************************************************************
3369 * See PageSetupDlgW.
3371 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3373 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3374 return pPageSetupDlgW(pagedlg);
3377 /*************************************************************************
3382 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3384 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3385 return pPrintDlgW(printdlg);
3388 /*************************************************************************
3391 * See GetOpenFileNameW.
3393 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3395 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3396 return pGetOpenFileNameW(ofn);
3399 /* INTERNAL: Map from HLS color space to RGB */
3400 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3402 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3406 else if (wHue > 120)
3411 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3414 /* Convert to RGB and scale into RGB range (0..255) */
3415 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3417 /*************************************************************************
3418 * ColorHLSToRGB [SHLWAPI.@]
3420 * Convert from hls color space into an rgb COLORREF.
3423 * wHue [I] Hue amount
3424 * wLuminosity [I] Luminosity amount
3425 * wSaturation [I] Saturation amount
3428 * A COLORREF representing the converted color.
3431 * Input hls values are constrained to the range (0..240).
3433 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3439 WORD wGreen, wBlue, wMid1, wMid2;
3441 if (wLuminosity > 120)
3442 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3444 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3446 wMid1 = wLuminosity * 2 - wMid2;
3448 wRed = GET_RGB(wHue + 80);
3449 wGreen = GET_RGB(wHue);
3450 wBlue = GET_RGB(wHue - 80);
3452 return RGB(wRed, wGreen, wBlue);
3455 wRed = wLuminosity * 255 / 240;
3456 return RGB(wRed, wRed, wRed);
3459 /*************************************************************************
3462 * Get the current docking status of the system.
3465 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3468 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3471 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3473 HW_PROFILE_INFOA hwInfo;
3475 TRACE("(0x%08lx)\n", dwFlags);
3477 GetCurrentHwProfileA(&hwInfo);
3478 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3480 case DOCKINFO_DOCKED:
3481 case DOCKINFO_UNDOCKED:
3482 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3488 /*************************************************************************
3491 * Function seems to do FreeLibrary plus other things.
3493 * FIXME native shows the following calls:
3494 * RtlEnterCriticalSection
3496 * GetProcAddress(Comctl32??, 150L)
3498 * RtlLeaveCriticalSection
3499 * followed by the FreeLibrary.
3500 * The above code may be related to .377 above.
3502 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3504 FIXME("(%p) semi-stub\n", hModule);
3505 return FreeLibrary(hModule);
3508 /*************************************************************************
3511 BOOL WINAPI SHFlushSFCacheWrap(void) {
3516 /*************************************************************************
3518 * FIXME I have no idea what this function does or what its arguments are.
3520 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3522 FIXME("(%p) stub\n", hInst);
3527 /*************************************************************************
3530 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3532 FIXME("(%p,%p) stub\n", hInst, hHeap);
3533 return E_FAIL; /* This is what is used if shlwapi not loaded */
3536 /*************************************************************************
3539 DWORD WINAPI MLClearMLHInstance(DWORD x)
3541 FIXME("(0x%08lx)stub\n", x);
3545 /*************************************************************************
3548 * Convert an Unicode string CLSID into a CLSID.
3551 * idstr [I] string containing a CLSID in text form
3552 * id [O] CLSID extracted from the string
3555 * S_OK on success or E_INVALIDARG on failure
3558 * This is really CLSIDFromString() which is exported by ole32.dll,
3559 * however the native shlwapi.dll does *not* import ole32. Nor does
3560 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3561 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3562 * it returns an E_INVALIDARG error code on failure.
3563 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3564 * in "dlls/ole32/compobj.c".
3566 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3574 memset(id, 0, sizeof(CLSID));
3577 else { /* validate the CLSID string */
3579 if (strlenW(s) != 38)
3580 return E_INVALIDARG;
3582 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3583 return E_INVALIDARG;
3585 for (i=1; i<37; i++)
3587 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3589 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3590 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3591 ((s[i] >= L'A') && (s[i] <= L'F')))
3593 return E_INVALIDARG;
3597 TRACE("%s -> %p\n", debugstr_w(s), id);
3599 /* quick lookup table */
3600 memset(table, 0, 256*sizeof(WCHAR));
3602 for (i = 0; i < 10; i++) {
3605 for (i = 0; i < 6; i++) {
3606 table['A' + i] = i+10;
3607 table['a' + i] = i+10;
3610 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3614 s++; /* skip leading brace */
3615 for (i = 0; i < 4; i++) {
3616 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3622 for (i = 0; i < 2; i++) {
3623 p[1-i] = table[*s]<<4 | table[*(s+1)];
3629 for (i = 0; i < 2; i++) {
3630 p[1-i] = table[*s]<<4 | table[*(s+1)];
3636 /* these are just sequential bytes */
3637 for (i = 0; i < 2; i++) {
3638 *p++ = table[*s]<<4 | table[*(s+1)];
3643 for (i = 0; i < 6; i++) {
3644 *p++ = table[*s]<<4 | table[*(s+1)];
3651 /*************************************************************************
3654 * Determine if the OS supports a given feature.
3657 * dwFeature [I] Feature requested (undocumented)
3660 * TRUE If the feature is available.
3661 * FALSE If the feature is not available.
3663 BOOL WINAPI IsOS(DWORD feature)
3665 OSVERSIONINFOA osvi;
3666 DWORD platform, majorv, minorv;
3668 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3669 if(!GetVersionExA(&osvi)) {
3670 ERR("GetVersionEx failed");
3674 majorv = osvi.dwMajorVersion;
3675 minorv = osvi.dwMinorVersion;
3676 platform = osvi.dwPlatformId;
3678 #define ISOS_RETURN(x) \
3679 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3683 case OS_WIN32SORGREATER:
3684 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3685 || platform == VER_PLATFORM_WIN32_WINDOWS)
3687 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3688 case OS_WIN95ORGREATER:
3689 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3690 case OS_NT4ORGREATER:
3691 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3692 case OS_WIN2000ORGREATER_ALT:
3693 case OS_WIN2000ORGREATER:
3694 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3695 case OS_WIN98ORGREATER:
3696 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3698 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3700 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3701 case OS_WIN2000SERVER:
3702 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3703 case OS_WIN2000ADVSERVER:
3704 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3705 case OS_WIN2000DATACENTER:
3706 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3707 case OS_WIN2000TERMINAL:
3708 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3710 FIXME("(OS_EMBEDDED) What should we return here?\n");
3712 case OS_TERMINALCLIENT:
3713 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3715 case OS_TERMINALREMOTEADMIN:
3716 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3719 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3720 case OS_MEORGREATER:
3721 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3722 case OS_XPORGREATER:
3723 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3725 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3726 case OS_PROFESSIONAL:
3727 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3729 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3731 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3733 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3734 case OS_TERMINALSERVER:
3735 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3736 case OS_PERSONALTERMINALSERVER:
3737 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3738 case OS_FASTUSERSWITCHING:
3739 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3741 case OS_WELCOMELOGONUI:
3742 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3744 case OS_DOMAINMEMBER:
3745 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3748 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3750 FIXME("(OS_WOW6432) Should we check this?\n");
3753 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3754 case OS_SMALLBUSINESSSERVER:
3755 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3757 FIXME("(OS_TABLEPC) What should we return here?\n");
3759 case OS_SERVERADMINUI:
3760 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3762 case OS_MEDIACENTER:
3763 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3766 FIXME("(OS_APPLIANCE) What should we return here?\n");
3772 WARN("(0x%lx) unknown parameter\n",feature);
3777 /*************************************************************************
3778 * ColorRGBToHLS [SHLWAPI.@]
3780 * Convert an rgb COLORREF into the hls color space.
3783 * cRGB [I] Source rgb value
3784 * pwHue [O] Destination for converted hue
3785 * pwLuminance [O] Destination for converted luminance
3786 * pwSaturation [O] Destination for converted saturation
3789 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3793 * Output HLS values are constrained to the range (0..240).
3794 * For Achromatic conversions, Hue is set to 160.
3796 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3797 LPWORD pwLuminance, LPWORD pwSaturation)
3799 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3801 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3803 wR = GetRValue(cRGB);
3804 wG = GetGValue(cRGB);
3805 wB = GetBValue(cRGB);
3807 wMax = max(wR, max(wG, wB));
3808 wMin = min(wR, min(wG, wB));
3811 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3815 /* Achromatic case */
3817 /* Hue is now unrepresentable, but this is what native returns... */
3822 /* Chromatic case */
3823 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3826 if (wLuminosity <= 120)
3827 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3829 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3832 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3833 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3834 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3837 wHue = wBNorm - wGNorm;
3838 else if (wG == wMax)
3839 wHue = 80 + wRNorm - wBNorm;
3841 wHue = 160 + wGNorm - wRNorm;
3844 else if (wHue > 240)
3850 *pwLuminance = wLuminosity;
3852 *pwSaturation = wSaturation;
3855 /*************************************************************************
3856 * SHCreateShellPalette [SHLWAPI.@]
3858 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3861 return CreateHalftonePalette(hdc);
3864 /*************************************************************************
3865 * SHGetInverseCMAP (SHLWAPI.@)
3867 * Get an inverse color map table.
3870 * lpCmap [O] Destination for color map
3871 * dwSize [I] Size of memory pointed to by lpCmap
3875 * Failure: E_POINTER, If lpCmap is invalid.
3876 * E_INVALIDARG, If dwFlags is invalid
3877 * E_OUTOFMEMORY, If there is no memory available
3880 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3881 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3883 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3884 * this DLL's internal CMap.
3886 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3889 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3890 *dest = (DWORD)0xabba1249;
3893 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3897 /*************************************************************************
3898 * SHIsLowMemoryMachine [SHLWAPI.@]
3900 * Determine if the current computer has low memory.
3906 * TRUE if the users machine has 16 Megabytes of memory or less,
3909 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3911 FIXME("(0x%08lx) stub\n", x);
3915 /*************************************************************************
3916 * GetMenuPosFromID [SHLWAPI.@]
3918 * Return the position of a menu item from its Id.
3921 * hMenu [I] Menu containing the item
3922 * wID [I] Id of the menu item
3925 * Success: The index of the menu item in hMenu.
3926 * Failure: -1, If the item is not found.
3928 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3931 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3933 while (nIter < nCount)
3936 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3943 /*************************************************************************
3946 * Same as SHLWAPI.GetMenuPosFromID
3948 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
3950 return GetMenuPosFromID(hMenu, uID);
3954 /*************************************************************************
3957 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
3968 /*************************************************************************
3971 DWORD WINAPI SHGetAppCompatFlags()
3978 /*************************************************************************
3981 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
3982 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
3984 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
3987 /*************************************************************************
3988 * SHSkipJunction [SHLWAPI.@]
3990 * Determine if a bind context can be bound to an object
3993 * pbc [I] Bind context to check
3994 * pclsid [I] CLSID of object to be bound to
3997 * TRUE: If it is safe to bind
3998 * FALSE: If pbc is invalid or binding would not be safe
4001 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4003 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4004 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4011 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4015 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4016 IsEqualGUID(pclsid, &clsid))
4019 IUnknown_Release(lpUnk);
4025 /***********************************************************************
4026 * SHGetShellKey (SHLWAPI.@)
4028 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4030 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4034 /***********************************************************************
4035 * SHQueueUserWorkItem (SHLWAPI.@)
4037 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4039 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4043 /***********************************************************************
4044 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4046 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
4048 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
4051 IInputObjectSite * pIOS = NULL;
4052 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
4053 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
4059 /***********************************************************************
4060 * SHGetValueW (SHLWAPI.@)
4062 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4064 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4068 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4070 /***********************************************************************
4071 * GetUIVersion (SHLWAPI.452)
4073 DWORD WINAPI GetUIVersion(void)
4075 static DWORD version;
4079 DllGetVersion_func pDllGetVersion;
4080 HMODULE dll = LoadLibraryA("shell32.dll");
4083 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4087 dvi.cbSize = sizeof(DLLVERSIONINFO);
4088 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4091 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */