2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
45 #include "wine/unicode.h"
49 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 /* Get a function pointer from a DLL handle */
56 #define GET_FUNC(func, module, name, fail) \
59 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
60 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
61 if (!func) return fail; \
65 /* DLL handles for late bound calls */
66 extern HINSTANCE shlwapi_hInstance;
67 extern HMODULE SHLWAPI_hshell32;
68 extern HMODULE SHLWAPI_hwinmm;
69 extern HMODULE SHLWAPI_hcomdlg32;
70 extern HMODULE SHLWAPI_hcomctl32;
71 extern HMODULE SHLWAPI_hmpr;
72 extern HMODULE SHLWAPI_hurlmon;
73 extern HMODULE SHLWAPI_hversion;
75 extern DWORD SHLWAPI_ThreadRef_index;
77 typedef HANDLE HSHARED; /* Shared memory */
79 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
80 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
81 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
82 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
84 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
85 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
86 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
87 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
88 static fnpPlaySoundW pPlaySoundW;
89 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
90 static fnpSHGetFileInfoW pSHGetFileInfoW;
91 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
92 static fnpDragQueryFileW pDragQueryFileW;
93 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
94 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
95 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
96 static fnpShellExecuteExW pShellExecuteExW;
97 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
98 static fnpSHFileOperationW pSHFileOperationW;
99 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
100 static fnpExtractIconExW pExtractIconExW;
101 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
102 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
103 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
104 static fnpSHDefExtractIconW pSHDefExtractIconW;
105 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
106 static fnpExtractIconW pExtractIconW;
107 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
108 static fnpGetSaveFileNameW pGetSaveFileNameW;
109 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
110 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
111 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
112 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
113 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
114 static fnpPageSetupDlgW pPageSetupDlgW;
115 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
116 static fnpPrintDlgW pPrintDlgW;
117 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
118 static fnpGetOpenFileNameW pGetOpenFileNameW;
119 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
120 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
121 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
122 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
123 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
124 static fnpVerQueryValueW pVerQueryValueW;
125 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
126 static fnpCOMCTL32_417 pCOMCTL32_417;
127 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
128 static fnpDllGetVersion pDllGetVersion;
129 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
130 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
131 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
132 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
134 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
135 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
136 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
137 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
140 NOTES: Most functions exported by ordinal seem to be superflous.
141 The reason for these functions to be there is to provide a wrapper
142 for unicode functions to provide these functions on systems without
143 unicode functions eg. win95/win98. Since we have such functions we just
144 call these. If running Wine with native DLL's, some late bound calls may
145 fail. However, its better to implement the functions in the forward DLL
146 and recommend the builtin rather than reimplementing the calls here!
149 /*************************************************************************
150 * SHLWAPI_DupSharedHandle
152 * Internal implemetation of SHLWAPI_11.
155 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
156 DWORD dwSrcProcId, DWORD dwAccess,
160 DWORD dwMyProcId = GetCurrentProcessId();
161 HSHARED hRet = (HSHARED)NULL;
163 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
164 dwAccess, dwOptions);
166 /* Get dest process handle */
167 if (dwDstProcId == dwMyProcId)
168 hDst = GetCurrentProcess();
170 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
174 /* Get src process handle */
175 if (dwSrcProcId == dwMyProcId)
176 hSrc = GetCurrentProcess();
178 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
182 /* Make handle available to dest process */
183 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
184 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
185 hRet = (HSHARED)NULL;
187 if (dwSrcProcId != dwMyProcId)
191 if (dwDstProcId != dwMyProcId)
195 TRACE("Returning handle %p\n", (PVOID)hRet);
199 /*************************************************************************
202 * Create a block of sharable memory and initialise it with data.
205 * dwProcId [I] ID of process owning data
206 * lpvData [I] Pointer to data to write
207 * dwSize [I] Size of data
210 * Success: A shared memory handle
214 * Ordinals 7-11 provide a set of calls to create shared memory between a
215 * group of processes. The shared memory is treated opaquely in that its size
216 * is not exposed to clients who map it. This is accomplished by storing
217 * the size of the map as the first DWORD of mapped data, and then offsetting
218 * the view pointer returned by this size.
221 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
225 HSHARED hRet = (HSHARED)NULL;
227 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
229 /* Create file mapping of the correct length */
230 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
231 dwSize + sizeof(dwSize), NULL);
235 /* Get a view in our process address space */
236 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
240 /* Write size of data, followed by the data, to the view */
241 *((DWORD*)pMapped) = dwSize;
243 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
245 /* Release view. All further views mapped will be opaque */
246 UnmapViewOfFile(pMapped);
247 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
248 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
249 DUPLICATE_SAME_ACCESS);
256 /*************************************************************************
259 * Get a pointer to a block of shared memory from a shared memory handle.
262 * hShared [I] Shared memory handle
263 * dwProcId [I] ID of process owning hShared
266 * Success: A pointer to the shared memory
270 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
275 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
277 /* Get handle to shared memory for current process */
278 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
279 FILE_MAP_ALL_ACCESS, 0);
281 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
285 return (char *) pMapped + sizeof(DWORD); /* Hide size */
289 /*************************************************************************
292 * Release a pointer to a block of shared memory.
295 * lpView [I] Shared memory pointer
302 BOOL WINAPI SHUnlockShared(LPVOID lpView)
304 TRACE("(%p)\n", lpView);
305 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
308 /*************************************************************************
311 * Destroy a block of sharable memory.
314 * hShared [I] Shared memory handle
315 * dwProcId [I] ID of process owning hShared
322 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
326 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
328 /* Get a copy of the handle for our process, closing the source handle */
329 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
330 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
331 /* Close local copy */
332 return CloseHandle((HANDLE)hClose);
335 /*************************************************************************
338 * Copy a sharable memory handle from one process to another.
341 * hShared [I] Shared memory handle to duplicate
342 * dwDstProcId [I] ID of the process wanting the duplicated handle
343 * dwSrcProcId [I] ID of the process owning hShared
344 * dwAccess [I] Desired DuplicateHandle() access
345 * dwOptions [I] Desired DuplicateHandle() options
348 * Success: A handle suitable for use by the dwDstProcId process.
349 * Failure: A NULL handle.
352 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
353 DWORD dwAccess, DWORD dwOptions)
357 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
358 dwAccess, dwOptions);
362 /*************************************************************************
365 * Create and register a clipboard enumerator for a web browser.
368 * lpBC [I] Binding context
369 * lpUnknown [I] An object exposing the IWebBrowserApp interface
373 * Failure: An HRESULT error code.
376 * The enumerator is stored as a property of the web browser. If it does not
377 * yet exist, it is created and set before being registered.
379 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
381 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
382 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
383 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
384 IEnumFORMATETC* pIEnumFormatEtc = NULL;
387 IWebBrowserApp* pBrowser = NULL;
389 TRACE("(%p, %p)\n", lpBC, lpUnknown);
391 /* Get An IWebBrowserApp interface from lpUnknown */
392 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
393 if (FAILED(hRet) || !pBrowser)
394 return E_NOINTERFACE;
396 V_VT(&var) = VT_EMPTY;
398 /* The property we get is the browsers clipboard enumerator */
399 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
403 if (V_VT(&var) == VT_EMPTY)
405 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
406 char szKeyBuff[128], szValueBuff[128];
407 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
408 FORMATETC* formatList, *format;
411 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
413 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
414 "Version\\Internet Settings\\Accepted Documents", &hDocs))
417 /* Get count of values in key */
420 dwKeySize = sizeof(szKeyBuff);
421 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
425 dwNumValues = dwCount;
427 /* Note: dwCount = number of items + 1; The extra item is the end node */
428 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
430 return E_OUTOFMEMORY;
439 /* Register clipboard formats for the values and populate format list */
440 while(!dwRet && dwCount < dwNumValues)
442 dwKeySize = sizeof(szKeyBuff);
443 dwValueSize = sizeof(szValueBuff);
444 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
445 (PBYTE)szValueBuff, &dwValueSize);
449 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
451 format->dwAspect = 1;
460 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
461 format->cfFormat = 0;
463 format->dwAspect = 1;
467 /* Create a clipboard enumerator */
468 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
469 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
471 if (FAILED(hRet) || !pIEnumFormatEtc)
474 /* Set our enumerator as the browsers property */
475 V_VT(&var) = VT_UNKNOWN;
476 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
478 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
481 IEnumFORMATETC_Release(pIEnumFormatEtc);
482 goto RegisterDefaultAcceptHeaders_Exit;
486 if (V_VT(&var) == VT_UNKNOWN)
488 /* Our variant is holding the clipboard enumerator */
489 IUnknown* pIUnknown = V_UNKNOWN(&var);
490 IEnumFORMATETC* pClone = NULL;
492 TRACE("Retrieved IEnumFORMATETC property\n");
494 /* Get an IEnumFormatEtc interface from the variants value */
495 pIEnumFormatEtc = NULL;
496 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
497 (PVOID)&pIEnumFormatEtc);
498 if (!hRet && pIEnumFormatEtc)
500 /* Clone and register the enumerator */
501 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
504 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
505 pRegisterFormatEnumerator(lpBC, pClone, 0);
507 IEnumFORMATETC_Release(pClone);
510 /* Release the IEnumFormatEtc interface */
511 IEnumFORMATETC_Release(pIUnknown);
513 IUnknown_Release(V_UNKNOWN(&var));
516 RegisterDefaultAcceptHeaders_Exit:
517 IWebBrowserApp_Release(pBrowser);
521 /*************************************************************************
524 * Get Explorers "AcceptLanguage" setting.
527 * langbuf [O] Destination for language string
528 * buflen [I] Length of langbuf
531 * Success: S_OK. langbuf is set to the language string found.
532 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
533 * does not contain the setting.
535 HRESULT WINAPI GetAcceptLanguagesA(
540 DWORD mystrlen, mytype;
544 mystrlen = (*buflen > 6) ? *buflen : 6;
545 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
546 HEAP_ZERO_MEMORY, mystrlen);
547 RegOpenKeyA(HKEY_CURRENT_USER,
548 "Software\\Microsoft\\Internet Explorer\\International",
550 if (RegQueryValueExA(mykey, "AcceptLanguage",
551 0, &mytype, (PBYTE)mystr, &mystrlen)) {
552 /* Did not find value */
553 mylcid = GetUserDefaultLCID();
554 /* somehow the mylcid translates into "en-us"
555 * this is similar to "LOCALE_SABBREVLANGNAME"
556 * which could be gotten via GetLocaleInfo.
557 * The only problem is LOCALE_SABBREVLANGUAGE" is
558 * a 3 char string (first 2 are country code and third is
559 * letter for "sublanguage", which does not come close to
562 lstrcpyA(mystr, "en-us");
563 mystrlen = lstrlenA(mystr);
566 /* handle returned string */
567 FIXME("missing code\n");
569 if (mystrlen > *buflen)
570 lstrcpynA(langbuf, mystr, *buflen);
572 lstrcpyA(langbuf, mystr);
573 *buflen = lstrlenA(langbuf);
576 HeapFree(GetProcessHeap(), 0, mystr);
577 TRACE("language is %s\n", debugstr_a(langbuf));
581 /*************************************************************************
584 * Unicode version of GetAcceptLanguagesA.
586 HRESULT WINAPI GetAcceptLanguagesW(
591 DWORD mystrlen, mytype;
595 mystrlen = (*buflen > 6) ? *buflen : 6;
596 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
597 HEAP_ZERO_MEMORY, mystrlen);
598 RegOpenKeyA(HKEY_CURRENT_USER,
599 "Software\\Microsoft\\Internet Explorer\\International",
601 if (RegQueryValueExA(mykey, "AcceptLanguage",
602 0, &mytype, (PBYTE)mystr, &mystrlen)) {
603 /* Did not find value */
604 mylcid = GetUserDefaultLCID();
605 /* somehow the mylcid translates into "en-us"
606 * this is similar to "LOCALE_SABBREVLANGNAME"
607 * which could be gotten via GetLocaleInfo.
608 * The only problem is LOCALE_SABBREVLANGUAGE" is
609 * a 3 char string (first 2 are country code and third is
610 * letter for "sublanguage", which does not come close to
613 lstrcpyA(mystr, "en-us");
614 mystrlen = lstrlenA(mystr);
617 /* handle returned string */
618 FIXME("missing code\n");
621 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
622 HeapFree(GetProcessHeap(), 0, mystr);
623 TRACE("language is %s\n", debugstr_w(langbuf));
627 /*************************************************************************
630 * Convert a GUID to a string.
633 * guid [I] GUID to convert
634 * str [O] Destination for string
635 * cmax [I] Length of output buffer
638 * The length of the string created.
640 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
645 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
647 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
648 guid->Data1, guid->Data2, guid->Data3,
649 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
650 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
652 iLen = strlen(xguid) + 1;
656 memcpy(lpszDest, xguid, iLen);
660 /*************************************************************************
663 * Unicode version of SHStringFromGUIDA.
665 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
668 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
671 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
675 /*************************************************************************
678 * Determine if a Unicode character is alphabetic.
681 * wc [I] Character to check.
684 * TRUE, if wc is alphabetic,
687 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
689 return (get_char_typeW(wc) & C1_ALPHA) != 0;
692 /*************************************************************************
695 * Determine if a Unicode character is upper-case.
698 * wc [I] Character to check.
701 * TRUE, if wc is upper-case,
704 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
706 return (get_char_typeW(wc) & C1_UPPER) != 0;
709 /*************************************************************************
712 * Determine if a Unicode character is lower-case.
715 * wc [I] Character to check.
718 * TRUE, if wc is lower-case,
721 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
723 return (get_char_typeW(wc) & C1_LOWER) != 0;
726 /*************************************************************************
729 * Determine if a Unicode character is alphabetic or a digit.
732 * wc [I] Character to check.
735 * TRUE, if wc is alphabetic or a digit,
738 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
740 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
743 /*************************************************************************
746 * Determine if a Unicode character is a space.
749 * wc [I] Character to check.
752 * TRUE, if wc is a space,
755 BOOL WINAPI IsCharSpaceW(WCHAR wc)
757 return (get_char_typeW(wc) & C1_SPACE) != 0;
760 /*************************************************************************
763 * Determine if a Unicode character is a blank.
766 * wc [I] Character to check.
769 * TRUE, if wc is a blank,
773 BOOL WINAPI IsCharBlankW(WCHAR wc)
775 return (get_char_typeW(wc) & C1_BLANK) != 0;
778 /*************************************************************************
781 * Determine if a Unicode character is punctuation.
784 * wc [I] Character to check.
787 * TRUE, if wc is punctuation,
790 BOOL WINAPI IsCharPunctW(WCHAR wc)
792 return (get_char_typeW(wc) & C1_PUNCT) != 0;
795 /*************************************************************************
798 * Determine if a Unicode character is a control character.
801 * wc [I] Character to check.
804 * TRUE, if wc is a control character,
807 BOOL WINAPI IsCharCntrlW(WCHAR wc)
809 return (get_char_typeW(wc) & C1_CNTRL) != 0;
812 /*************************************************************************
815 * Determine if a Unicode character is a digit.
818 * wc [I] Character to check.
821 * TRUE, if wc is a digit,
824 BOOL WINAPI IsCharDigitW(WCHAR wc)
826 return (get_char_typeW(wc) & C1_DIGIT) != 0;
829 /*************************************************************************
832 * Determine if a Unicode character is a hex digit.
835 * wc [I] Character to check.
838 * TRUE, if wc is a hex digit,
841 BOOL WINAPI IsCharXDigitW(WCHAR wc)
843 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
846 /*************************************************************************
850 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
852 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
856 /*************************************************************************
859 * Insert a bitmap menu item at the bottom of a menu.
862 * hMenu [I] Menu to insert into
863 * flags [I] Flags for insertion
864 * id [I] Menu ID of the item
865 * str [I] Menu text for the item
868 * Success: TRUE, the item is inserted into the menu
869 * Failure: FALSE, if any parameter is invalid
871 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
873 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
874 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
877 /*************************************************************************
880 * Get the text from a given dialog item.
883 * hWnd [I] Handle of dialog
884 * nItem [I] Index of item
885 * lpsDest [O] Buffer for receiving window text
886 * nDestLen [I] Length of buffer.
889 * Success: The length of the returned text.
892 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
894 HWND hItem = GetDlgItem(hWnd, nItem);
897 return GetWindowTextW(hItem, lpsDest, nDestLen);
899 *lpsDest = (WCHAR)'\0';
903 /*************************************************************************
906 * Set the text of a given dialog item.
909 * hWnd [I] Handle of dialog
910 * iItem [I] Index of item
911 * lpszText [O] Text to set
914 * Success: TRUE. The text of the dialog is set to lpszText.
915 * Failure: FALSE, Otherwise.
917 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
919 HWND hWndItem = GetDlgItem(hWnd, iItem);
921 return SetWindowTextW(hWndItem, lpszText);
925 /*************************************************************************
928 * Compare two Ascii strings up to a given length.
931 * lpszSrc [I] Source string
932 * lpszCmp [I] String to compare to lpszSrc
933 * len [I] Maximum length
936 * A number greater than, less than or equal to 0 depending on whether
937 * lpszSrc is greater than, less than or equal to lpszCmp.
939 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
941 return strncmp(lpszSrc, lpszCmp, len);
944 /*************************************************************************
947 * Unicode version of StrCmpNCA.
949 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
951 return strncmpW(lpszSrc, lpszCmp, len);
954 /*************************************************************************
957 * Compare two Ascii strings up to a given length, ignoring case.
960 * lpszSrc [I] Source string
961 * lpszCmp [I] String to compare to lpszSrc
962 * len [I] Maximum length
965 * A number greater than, less than or equal to 0 depending on whether
966 * lpszSrc is greater than, less than or equal to lpszCmp.
968 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
970 return strncasecmp(lpszSrc, lpszCmp, len);
973 /*************************************************************************
976 * Unicode version of StrCmpNICA.
978 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
980 return strncmpiW(lpszSrc, lpszCmp, len);
983 /*************************************************************************
986 * Compare two Ascii strings.
989 * lpszSrc [I] Source string
990 * lpszCmp [I] String to compare to lpszSrc
993 * A number greater than, less than or equal to 0 depending on whether
994 * lpszSrc is greater than, less than or equal to lpszCmp.
996 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
998 return strcmp(lpszSrc, lpszCmp);
1001 /*************************************************************************
1004 * Unicode version of StrCmpCA.
1006 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1008 return strcmpW(lpszSrc, lpszCmp);
1011 /*************************************************************************
1014 * Compare two Ascii strings, ignoring case.
1017 * lpszSrc [I] Source string
1018 * lpszCmp [I] String to compare to lpszSrc
1021 * A number greater than, less than or equal to 0 depending on whether
1022 * lpszSrc is greater than, less than or equal to lpszCmp.
1024 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1026 return strcasecmp(lpszSrc, lpszCmp);
1029 /*************************************************************************
1032 * Unicode version of StrCmpICA.
1034 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1036 return strcmpiW(lpszSrc, lpszCmp);
1039 /*************************************************************************
1042 * Get an identification string for the OS and explorer.
1045 * lpszDest [O] Destination for Id string
1046 * dwDestLen [I] Length of lpszDest
1049 * TRUE, If the string was created successfully
1052 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1056 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1058 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1060 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1066 /*************************************************************************
1069 * Unicode version of SHAboutInfoA.
1071 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1073 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1074 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1075 ' ','E','x','p','l','o','r','e','r','\0' };
1076 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1077 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1078 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1079 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1080 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1081 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1082 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1083 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1084 ' ','E','x','p','l','o','r','e','r','\\',
1085 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1086 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1087 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1088 'V','e','r','s','i','o','n','\0' };
1089 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1090 'O','w','n','e','r','\0' };
1091 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1092 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1093 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1094 static const WCHAR szUpdate[] = { 'I','E','A','K',
1095 'U','p','d','a','t','e','U','r','l','\0' };
1096 static const WCHAR szHelp[] = { 'I','E','A','K',
1097 'H','e','l','p','S','t','r','i','n','g','\0' };
1100 DWORD dwType, dwLen;
1102 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1109 /* Try the NT key first, followed by 95/98 key */
1110 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1111 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1117 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1119 DWORD dwStrLen = strlenW(buff);
1120 dwLen = 30 - dwStrLen;
1121 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1122 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1124 StrCatBuffW(lpszDest, buff, dwDestLen);
1126 /* ~Registered Owner */
1129 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1131 StrCatBuffW(lpszDest, buff, dwDestLen);
1133 /* ~Registered Organization */
1135 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1137 StrCatBuffW(lpszDest, buff, dwDestLen);
1139 /* FIXME: Not sure where this number comes from */
1143 StrCatBuffW(lpszDest, buff, dwDestLen);
1147 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1149 StrCatBuffW(lpszDest, buff, dwDestLen);
1151 /* ~IE Update Url */
1153 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1155 StrCatBuffW(lpszDest, buff, dwDestLen);
1157 /* ~IE Help String */
1159 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1161 StrCatBuffW(lpszDest, buff, dwDestLen);
1167 /*************************************************************************
1170 * Call IOleCommandTarget_QueryStatus() on an object.
1173 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1174 * pguidCmdGroup [I] GUID for the command group
1176 * prgCmds [O] Commands
1177 * pCmdText [O] Command text
1181 * Failure: E_FAIL, if lpUnknown is NULL.
1182 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1183 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1185 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1186 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1188 HRESULT hRet = E_FAIL;
1190 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1194 IOleCommandTarget* lpOle;
1196 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1199 if (SUCCEEDED(hRet) && lpOle)
1201 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1203 IOleCommandTarget_Release(lpOle);
1209 /*************************************************************************
1212 * Call IOleCommandTarget_Exec() on an object.
1215 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1216 * pguidCmdGroup [I] GUID for the command group
1220 * Failure: E_FAIL, if lpUnknown is NULL.
1221 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1222 * Otherwise, an error code from IOleCommandTarget_Exec().
1224 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1225 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1228 HRESULT hRet = E_FAIL;
1230 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1231 nCmdexecopt, pvaIn, pvaOut);
1235 IOleCommandTarget* lpOle;
1237 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1239 if (SUCCEEDED(hRet) && lpOle)
1241 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1242 nCmdexecopt, pvaIn, pvaOut);
1243 IOleCommandTarget_Release(lpOle);
1249 /*************************************************************************
1252 * Retrieve, modify, and re-set a value from a window.
1255 * hWnd [I] Window to get value from
1256 * offset [I] Offset of value
1257 * wMask [I] Mask for uiFlags
1258 * wFlags [I] Bits to set in window value
1261 * The new value as it was set, or 0 if any parameter is invalid.
1264 * Any bits set in uiMask are cleared from the value, then any bits set in
1265 * uiFlags are set in the value.
1267 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1269 LONG ret = GetWindowLongA(hwnd, offset);
1270 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1272 if (newFlags != ret)
1273 ret = SetWindowLongA(hwnd, offset, newFlags);
1277 /*************************************************************************
1280 * Change a window's parent.
1283 * hWnd [I] Window to change parent of
1284 * hWndParent [I] New parent window
1287 * The old parent of hWnd.
1290 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1291 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1293 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1295 TRACE("%p, %p\n", hWnd, hWndParent);
1297 if(GetParent(hWnd) == hWndParent)
1301 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1303 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1305 return SetParent(hWnd, hWndParent);
1308 /*************************************************************************
1311 * Locate and advise a connection point in an IConnectionPointContainer object.
1314 * lpUnkSink [I] Sink for the connection point advise call
1315 * riid [I] REFIID of connection point to advise
1316 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1317 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1318 * lpCookie [O] Pointer to connection point cookie
1319 * lppCP [O] Destination for the IConnectionPoint found
1322 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1323 * that was advised. The caller is responsable for releasing it.
1324 * Failure: E_FAIL, if any arguments are invalid.
1325 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1326 * Or an HRESULT error code if any call fails.
1328 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1329 IUnknown* lpUnknown, LPDWORD lpCookie,
1330 IConnectionPoint **lppCP)
1333 IConnectionPointContainer* lpContainer;
1334 IConnectionPoint *lpCP;
1336 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1342 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1343 (void**)&lpContainer);
1344 if (SUCCEEDED(hRet))
1346 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1348 if (SUCCEEDED(hRet))
1351 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1352 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1357 if (lppCP && SUCCEEDED(hRet))
1358 *lppCP = lpCP; /* Caller keeps the interface */
1360 IConnectionPoint_Release(lpCP); /* Release it */
1363 IUnknown_Release(lpContainer);
1368 /*************************************************************************
1371 * Release an interface.
1374 * lpUnknown [I] Object to release
1379 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1383 TRACE("(%p)\n",lpUnknown);
1385 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1389 TRACE("doing Release\n");
1391 return IUnknown_Release(temp);
1394 /*************************************************************************
1397 * Skip '//' if present in a string.
1400 * lpszSrc [I] String to check for '//'
1403 * Success: The next character after the '//' or the string if not present
1404 * Failure: NULL, if lpszStr is NULL.
1406 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1408 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1413 /*************************************************************************
1416 * Check if two interfaces come from the same object.
1419 * lpInt1 [I] Interface to check against lpInt2.
1420 * lpInt2 [I] Interface to check against lpInt1.
1423 * TRUE, If the interfaces come from the same object.
1426 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1428 LPVOID lpUnknown1, lpUnknown2;
1430 TRACE("%p %p\n", lpInt1, lpInt2);
1432 if (!lpInt1 || !lpInt2)
1435 if (lpInt1 == lpInt2)
1438 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1439 (LPVOID *)&lpUnknown1)))
1442 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1443 (LPVOID *)&lpUnknown2)))
1446 if (lpUnknown1 == lpUnknown2)
1452 /*************************************************************************
1455 * Get the window handle of an object.
1458 * lpUnknown [I] Object to get the window handle of
1459 * lphWnd [O] Destination for window handle
1462 * Success: S_OK. lphWnd contains the objects window handle.
1463 * Failure: An HRESULT error code.
1466 * lpUnknown is expected to support one of the following interfaces:
1467 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1469 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1471 /* FIXME: Wine has no header for this object */
1472 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1473 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1475 HRESULT hRet = E_FAIL;
1477 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1482 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1486 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1490 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1495 if (SUCCEEDED(hRet))
1497 /* Lazyness here - Since GetWindow() is the first method for the above 3
1498 * interfaces, we use the same call for them all.
1500 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1501 IUnknown_Release(lpOle);
1503 TRACE("Returning HWND=%p\n", *lphWnd);
1509 /*************************************************************************
1512 * Call a method on as as yet unidentified object.
1515 * pUnk [I] Object supporting the unidentified interface,
1516 * arg [I] Argument for the call on the object.
1521 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1523 static const GUID guid_173 = {
1524 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1528 TRACE("(%p,%ld)\n", pUnk, arg);
1530 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1531 * We use this interface as its vtable entry is compatible with the
1532 * object in question.
1533 * FIXME: Find out what this object is and where it should be defined.
1536 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1538 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1539 IMalloc_Release(pUnk2);
1544 /*************************************************************************
1547 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1552 * Failure: E_FAIL, if p1 is NULL.
1553 * E_NOINTERFACE If p1 does not support the IPersist interface,
1554 * Or an HRESULT error code.
1556 DWORD WINAPI IUnknown_SetSite(
1557 IUnknown *p1, /* [in] OLE object */
1558 LPVOID *p2) /* [out] ptr for call results */
1562 if (!p1) return E_FAIL;
1564 /* see if SetSite interface exists for IObjectWithSite object */
1565 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1566 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1569 /* see if GetClassId interface exists for IPersistMoniker object */
1570 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1571 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1572 if (ret) return ret;
1574 /* fake a GetClassId call */
1575 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1576 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1578 IUnknown_Release((IUnknown *)aa);
1581 /* fake a SetSite call */
1582 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1583 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1585 IUnknown_Release((IUnknown *)p1);
1590 /*************************************************************************
1593 * Call IPersist_GetClassID() on an object.
1596 * lpUnknown [I] Object supporting the IPersist interface
1597 * lpClassId [O] Destination for Class Id
1600 * Success: S_OK. lpClassId contains the Class Id requested.
1601 * Failure: E_FAIL, If lpUnknown is NULL,
1602 * E_NOINTERFACE If lpUnknown does not support IPersist,
1603 * Or an HRESULT error code.
1605 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1607 IPersist* lpPersist;
1608 HRESULT hRet = E_FAIL;
1610 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1614 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1615 if (SUCCEEDED(hRet))
1617 IPersist_GetClassID(lpPersist, lpClassId);
1618 IPersist_Release(lpPersist);
1624 /*************************************************************************
1627 * Retrieve a Service Interface from an object.
1630 * lpUnknown [I] Object to get an IServiceProvider interface from
1631 * sid [I] Service ID for IServiceProvider_QueryService() call
1632 * riid [I] Function requested for QueryService call
1633 * lppOut [O] Destination for the service interface pointer
1636 * Success: S_OK. lppOut contains an object providing the requested service
1637 * Failure: An HRESULT error code
1640 * lpUnknown is expected to support the IServiceProvider interface.
1642 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1645 IServiceProvider* pService = NULL;
1656 /* Get an IServiceProvider interface from the object */
1657 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1658 (LPVOID*)&pService);
1660 if (!hRet && pService)
1662 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1664 /* Get a Service interface from the object */
1665 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1667 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1669 /* Release the IServiceProvider interface */
1670 IUnknown_Release(pService);
1675 /*************************************************************************
1678 * Loads a popup menu.
1681 * hInst [I] Instance handle
1682 * szName [I] Menu name
1688 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1690 HMENU hMenu, hSubMenu;
1692 if ((hMenu = LoadMenuW(hInst, szName)))
1694 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1695 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1703 typedef struct _enumWndData
1708 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1711 /* Callback for SHLWAPI_178 */
1712 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1714 enumWndData *data = (enumWndData *)lParam;
1716 TRACE("(%p,%p)\n", hWnd, data);
1717 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1721 /*************************************************************************
1724 * Send or post a message to every child of a window.
1727 * hWnd [I] Window whose children will get the messages
1728 * uiMsgId [I] Message Id
1729 * wParam [I] WPARAM of message
1730 * lParam [I] LPARAM of message
1731 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1737 * The appropriate ASCII or Unicode function is called for the window.
1739 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1743 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1747 data.uiMsgId = uiMsgId;
1748 data.wParam = wParam;
1749 data.lParam = lParam;
1752 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1754 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1756 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1760 /*************************************************************************
1763 * Remove all sub-menus from a menu.
1766 * hMenu [I] Menu to remove sub-menus from
1769 * Success: 0. All sub-menus under hMenu are removed
1770 * Failure: -1, if any parameter is invalid
1772 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1774 int iItemCount = GetMenuItemCount(hMenu) - 1;
1775 while (iItemCount >= 0)
1777 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1779 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1785 /*************************************************************************
1788 * Enable or disable a menu item.
1791 * hMenu [I] Menu holding menu item
1792 * uID [I] ID of menu item to enable/disable
1793 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1796 * The return code from EnableMenuItem.
1798 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1800 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1803 /*************************************************************************
1806 * Check or uncheck a menu item.
1809 * hMenu [I] Menu holding menu item
1810 * uID [I] ID of menu item to check/uncheck
1811 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1814 * The return code from CheckMenuItem.
1816 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1818 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1821 /*************************************************************************
1824 * Register a window class if it isn't already.
1827 * lpWndClass [I] Window class to register
1830 * The result of the RegisterClassA call.
1832 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1835 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1837 return (DWORD)RegisterClassA(wndclass);
1840 /*************************************************************************
1843 * Call IPersistPropertyBag_Load() on an object.
1846 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1847 * lpPropBag [O] Destination for loaded IPropertyBag
1851 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1853 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1855 IPersistPropertyBag* lpPPBag;
1856 HRESULT hRet = E_FAIL;
1858 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1862 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1864 if (SUCCEEDED(hRet) && lpPPBag)
1866 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1867 IPersistPropertyBag_Release(lpPPBag);
1873 /*************************************************************************
1876 * Call IOleControlSite_GetExtendedControl() on an object.
1879 * lpUnknown [I] Object supporting the IOleControlSite interface
1880 * lppDisp [O] Destination for resulting IDispatch.
1884 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1886 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1888 IOleControlSite* lpCSite;
1889 HRESULT hRet = E_FAIL;
1891 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1894 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1896 if (SUCCEEDED(hRet) && lpCSite)
1898 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1899 IOleControlSite_Release(lpCSite);
1905 static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
1906 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1907 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1908 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
1909 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
1912 /*************************************************************************
1915 * Pop up a 'Don't show this message again' error dialog box.
1918 * hWnd [I] Window to own the dialog box
1923 * lpszValue [I] Registry value holding boolean show/don't show.
1928 void WINAPI SHMessageBoxCheckW(HWND hWnd, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5, LPCWSTR lpszValue)
1930 FIXME("(%p,%p,%p,%p,%p,%s) - stub!\n", hWnd, arg2, arg3, arg4, arg5, debugstr_w(lpszValue));
1932 if (SHRegGetBoolUSValueW(szDontShowKey, lpszValue, FALSE, TRUE))
1934 /* FIXME: Should use DialogBoxParamW to load a dialog box; its dlgproc
1935 * should accept clicks on 'Don't show' and set the reg value appropriately.
1940 /*************************************************************************
1943 * Get a sub-menu from a menu item.
1946 * hMenu [I] Menu to get sub-menu from
1947 * uID [I] ID of menu item containing sub-menu
1950 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1952 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1956 TRACE("(%p,%uld)\n", hMenu, uID);
1958 mi.cbSize = sizeof(MENUITEMINFOA);
1959 mi.fMask = MIIM_SUBMENU;
1961 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1967 /*************************************************************************
1970 * Get the color depth of the primary display.
1976 * The color depth of the primary display.
1978 DWORD WINAPI SHGetCurColorRes()
1986 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1991 /*************************************************************************
1994 * Blank out a region of text by drawing the background only.
1997 * hDC [I] Device context to draw in
1998 * pRect [I] Area to draw in
1999 * cRef [I] Color to draw in
2004 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2006 COLORREF cOldColor = SetBkColor(hDC, cRef);
2007 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2008 SetBkColor(hDC, cOldColor);
2012 /*************************************************************************
2015 * Copy an interface pointer
2018 * lppDest [O] Destination for copy
2019 * lpUnknown [I] Source for copy
2024 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2026 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2029 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2034 IUnknown_AddRef(lpUnknown);
2035 *lppDest = lpUnknown;
2039 /*************************************************************************
2043 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2044 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2047 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2048 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2049 return DRAGDROP_E_NOTREGISTERED;
2052 /*************************************************************************
2056 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2058 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2059 return DRAGDROP_E_NOTREGISTERED;
2062 /*************************************************************************
2065 * Determine if a window is not a child of another window.
2068 * hParent [I] Suspected parent window
2069 * hChild [I] Suspected child window
2072 * TRUE: If hChild is a child window of hParent
2073 * FALSE: If hChild is not a child window of hParent, or they are equal
2075 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2077 TRACE("(%p,%p)\n", hParent, hChild);
2079 if (!hParent || !hChild)
2081 else if(hParent == hChild)
2083 return !IsChild(hParent, hChild);
2086 /*************************************************************************
2089 * Some sort of memory management process.
2091 DWORD WINAPI FDSA_Initialize(
2098 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2103 /*************************************************************************
2106 * Some sort of memory management process.
2108 DWORD WINAPI FDSA_Destroy(
2111 FIXME("(%p) stub\n",
2116 /*************************************************************************
2119 * Some sort of memory management process.
2121 DWORD WINAPI FDSA_InsertItem(
2126 FIXME("(%p 0x%08lx %p) stub\n",
2131 /*************************************************************************
2134 DWORD WINAPI FDSA_DeleteItem(
2138 FIXME("(%p 0x%08lx) stub\n",
2148 /*************************************************************************
2151 * Call IUnknown_QueryInterface() on a table of objects.
2155 * Failure: E_POINTER or E_NOINTERFACE.
2157 HRESULT WINAPI QISearch(
2158 LPVOID w, /* [in] Table of interfaces */
2159 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2160 REFIID riid, /* [in] REFIID to get interface for */
2161 LPVOID *ppv) /* [out] Destination for interface pointer */
2165 IFACE_INDEX_TBL *xmove;
2167 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2170 while (xmove->refid) {
2171 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2172 if (IsEqualIID(riid, xmove->refid)) {
2173 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2174 TRACE("matched, returning (%p)\n", a_vtbl);
2175 *ppv = (LPVOID)a_vtbl;
2176 IUnknown_AddRef(a_vtbl);
2182 if (IsEqualIID(riid, &IID_IUnknown)) {
2183 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2184 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2185 *ppv = (LPVOID)a_vtbl;
2186 IUnknown_AddRef(a_vtbl);
2190 ret = E_NOINTERFACE;
2194 TRACE("-- 0x%08lx\n", ret);
2198 /*************************************************************************
2201 * Remove the "PropDlgFont" property from a window.
2204 * hWnd [I] Window to remove the property from
2207 * A handle to the removed property, or NULL if it did not exist.
2209 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2213 TRACE("(%p)\n", hWnd);
2215 hProp = GetPropA(hWnd, "PropDlgFont");
2219 DeleteObject(hProp);
2220 hProp = RemovePropA(hWnd, "PropDlgFont");
2225 /*************************************************************************
2228 * Load the in-process server of a given GUID.
2231 * refiid [I] GUID of the server to load.
2234 * Success: A handle to the loaded server dll.
2235 * Failure: A NULL handle.
2237 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2241 CHAR value[MAX_PATH], string[MAX_PATH];
2243 strcpy(string, "CLSID\\");
2244 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2245 strcat(string, "\\InProcServer32");
2248 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2249 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2250 RegCloseKey(newkey);
2251 return LoadLibraryExA(value, 0, 0);
2254 /*************************************************************************
2257 * Unicode version of SHLWAPI_183.
2259 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2263 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2265 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2267 return RegisterClassW(lpWndClass);
2270 /*************************************************************************
2273 * Unregister a list of classes.
2276 * hInst [I] Application instance that registered the classes
2277 * lppClasses [I] List of class names
2278 * iCount [I] Number of names in lppClasses
2283 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2287 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2291 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2292 UnregisterClassA(*lppClasses, hInst);
2298 /*************************************************************************
2301 * Unicode version of SHUnregisterClassesA.
2303 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2307 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2311 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2312 UnregisterClassW(*lppClasses, hInst);
2318 /*************************************************************************
2321 * Call The correct (Ascii/Unicode) default window procedure for a window.
2324 * hWnd [I] Window to call the default procedure for
2325 * uMessage [I] Message ID
2326 * wParam [I] WPARAM of message
2327 * lParam [I] LPARAM of message
2330 * The result of calling DefWindowProcA() or DefWindowProcW().
2332 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2334 if (IsWindowUnicode(hWnd))
2335 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2336 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2339 /*************************************************************************
2342 * Create a worker window using CreateWindowExA().
2345 * wndProc [I] Window procedure
2346 * hWndParent [I] Parent window
2347 * dwExStyle [I] Extra style flags
2348 * dwStyle [I] Style flags
2349 * hMenu [I] Window menu
2353 * Success: The window handle of the newly created window.
2356 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2357 DWORD dwStyle, HMENU hMenu, LONG z)
2359 static const char* szClass = "WorkerA";
2363 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2364 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2366 /* Create Window class */
2368 wc.lpfnWndProc = DefWindowProcA;
2371 wc.hInstance = shlwapi_hInstance;
2372 wc.hIcon = (HICON)0;
2373 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2374 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2375 wc.lpszMenuName = NULL;
2376 wc.lpszClassName = szClass;
2378 SHRegisterClassA(&wc); /* Register class */
2380 /* FIXME: Set extra bits in dwExStyle */
2382 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2383 hWndParent, hMenu, shlwapi_hInstance, 0);
2386 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2389 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2394 typedef struct tagPOLICYDATA
2396 DWORD policy; /* flags value passed to SHRestricted */
2397 LPCWSTR appstr; /* application str such as "Explorer" */
2398 LPCWSTR keystr; /* name of the actual registry key / policy */
2399 } POLICYDATA, *LPPOLICYDATA;
2401 #define SHELL_NO_POLICY 0xffffffff
2403 /* default shell policy registry key */
2404 static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2405 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2406 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2407 '\\','P','o','l','i','c','i','e','s',0};
2409 /*************************************************************************
2412 * Retrieve a policy value from the registry.
2415 * lpSubKey [I] registry key name
2416 * lpSubName [I] subname of registry key
2417 * lpValue [I] value name of registry value
2420 * the value associated with the registry key or 0 if not found
2422 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2424 DWORD retval, datsize = 4;
2428 lpSubKey = (LPCWSTR)strRegistryPolicyW;
2430 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2431 if (retval != ERROR_SUCCESS)
2432 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2433 if (retval != ERROR_SUCCESS)
2436 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2441 /*************************************************************************
2444 * Helper function to retrieve the possibly cached value for a specific policy
2447 * policy [I] The policy to look for
2448 * initial [I] Main registry key to open, if NULL use default
2449 * polTable [I] Table of known policies, 0 terminated
2450 * polArr [I] Cache array of policy values
2453 * The retrieved policy value or 0 if not successful
2456 * This function is used by the native SHRestricted function to search for the
2457 * policy and cache it once retrieved. The current Wine implementation uses a
2458 * different POLICYDATA structure and implements a similar algorithme adapted to
2461 DWORD WINAPI SHRestrictionLookup(
2464 LPPOLICYDATA polTable,
2467 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2469 if (!polTable || !polArr)
2472 for (;polTable->policy; polTable++, polArr++)
2474 if (policy == polTable->policy)
2476 /* we have a known policy */
2478 /* check if this policy has been cached */
2479 if (*polArr == SHELL_NO_POLICY)
2480 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2484 /* we don't know this policy, return 0 */
2485 TRACE("unknown policy: (%08lx)\n", policy);
2489 /*************************************************************************
2492 * Get an interface from an object.
2495 * Success: S_OK. ppv contains the requested interface.
2496 * Failure: An HRESULT error code.
2499 * This QueryInterface asks the inner object for a interface. In case
2500 * of aggregation this request would be forwarded by the inner to the
2501 * outer object. This function asks the inner object directly for the
2502 * interface circumventing the forwarding to the outer object.
2504 HRESULT WINAPI SHWeakQueryInterface(
2505 IUnknown * pUnk, /* [in] Outer object */
2506 IUnknown * pInner, /* [in] Inner object */
2507 IID * riid, /* [in] Interface GUID to query for */
2508 LPVOID* ppv) /* [out] Destination for queried interface */
2510 HRESULT hret = E_NOINTERFACE;
2511 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2514 if(pUnk && pInner) {
2515 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2516 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2518 TRACE("-- 0x%08lx\n", hret);
2522 /*************************************************************************
2525 * Move a reference from one interface to another.
2528 * lpDest [O] Destination to receive the reference
2529 * lppUnknown [O] Source to give up the reference to lpDest
2534 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2536 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2541 IUnknown_AddRef(lpDest);
2542 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2546 /*************************************************************************
2549 * Convert an ASCII string of a CLSID into a CLSID.
2552 * idstr [I] String representing a CLSID in registry format
2553 * id [O] Destination for the converted CLSID
2556 * Success: TRUE. id contains the converted CLSID.
2559 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2562 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2563 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2566 /*************************************************************************
2569 * Unicode version of GUIDFromStringA.
2571 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2573 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2576 /*************************************************************************
2579 * Determine if the browser is integrated into the shell, and set a registry
2586 * 1, If the browser is not integrated.
2587 * 2, If the browser is integrated.
2590 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2591 * either set to TRUE, or removed depending on whether the browser is deemed
2594 DWORD WINAPI WhichPlatform()
2596 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2597 static DWORD dwState = 0;
2599 DWORD dwRet, dwData, dwSize;
2604 /* If shell32 exports DllGetVersion(), the browser is integrated */
2605 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2606 dwState = pDllGetVersion ? 2 : 1;
2608 /* Set or delete the key accordinly */
2609 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2610 "Software\\Microsoft\\Internet Explorer", 0,
2611 KEY_ALL_ACCESS, &hKey);
2614 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2615 (LPBYTE)&dwData, &dwSize);
2617 if (!dwRet && dwState == 1)
2619 /* Value exists but browser is not integrated */
2620 RegDeleteValueA(hKey, szIntegratedBrowser);
2622 else if (dwRet && dwState == 2)
2624 /* Browser is integrated but value does not exist */
2626 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2627 (LPBYTE)&dwData, sizeof(dwData));
2634 /*************************************************************************
2637 * Unicode version of SHCreateWorkerWindowA.
2639 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2640 DWORD dwStyle, HMENU hMenu, LONG z)
2642 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2646 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2647 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2649 /* If our OS is natively ASCII, use the ASCII version */
2650 if (!(GetVersion() & 0x80000000)) /* NT */
2651 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2653 /* Create Window class */
2655 wc.lpfnWndProc = DefWindowProcW;
2658 wc.hInstance = shlwapi_hInstance;
2659 wc.hIcon = (HICON)0;
2660 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2661 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2662 wc.lpszMenuName = NULL;
2663 wc.lpszClassName = szClass;
2665 SHRegisterClassW(&wc); /* Register class */
2667 /* FIXME: Set extra bits in dwExStyle */
2669 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2670 hWndParent, hMenu, shlwapi_hInstance, 0);
2673 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2676 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2681 /*************************************************************************
2684 * Get and show a context menu from a shell folder.
2687 * hWnd [I] Window displaying the shell folder
2688 * lpFolder [I] IShellFolder interface
2689 * lpApidl [I] Id for the particular folder desired
2693 * Failure: An HRESULT error code indicating the error.
2695 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2697 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2700 /*************************************************************************
2703 * _SHPackDispParamsV
2705 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2707 FIXME("%p %p %p %p\n",w,x,y,z);
2711 /*************************************************************************
2714 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2715 * function does...).
2717 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2719 FIXME("%p %p %p %p\n", w, x, y, z);
2723 /*************************************************************************
2726 * _IConnectionPoint_SimpleInvoke
2728 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2733 FIXME("(%p %p %p) stub\n",x,y,z);
2737 /*************************************************************************
2740 * Notify an IConnectionPoint object of changes.
2743 * lpCP [I] Object to notify
2748 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2749 * IConnectionPoint interface.
2751 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2753 IEnumConnections *lpEnum;
2754 HRESULT hRet = E_NOINTERFACE;
2756 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2758 /* Get an enumerator for the connections */
2760 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2762 if (SUCCEEDED(hRet))
2764 IPropertyNotifySink *lpSink;
2765 CONNECTDATA connData;
2768 /* Call OnChanged() for every notify sink in the connection point */
2769 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2771 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2774 IPropertyNotifySink_OnChanged(lpSink, dispID);
2775 IPropertyNotifySink_Release(lpSink);
2777 IUnknown_Release(connData.pUnk);
2780 IEnumConnections_Release(lpEnum);
2785 /*************************************************************************
2788 * Notify an IConnectionPointContainer object of changes.
2791 * lpUnknown [I] Object to notify
2796 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2797 * IConnectionPointContainer interface.
2799 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2801 IConnectionPointContainer* lpCPC = NULL;
2802 HRESULT hRet = E_NOINTERFACE;
2804 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2807 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2809 if (SUCCEEDED(hRet))
2811 IConnectionPoint* lpCP;
2813 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2814 IConnectionPointContainer_Release(lpCPC);
2816 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2817 IConnectionPoint_Release(lpCP);
2822 /*************************************************************************
2827 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2829 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2830 return pPlaySoundW(pszSound, hmod, fdwSound);
2833 /*************************************************************************
2836 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2839 * str1: "I" "I" pushl esp+0x20
2840 * str2: "U" "I" pushl 0x77c93810
2841 * (is "I" and "U" "integer" and "unsigned" ??)
2843 * pStr: "" "" pushl eax
2844 * some_len: 0x824 0x104 pushl 0x824
2845 * lpStr2: "%l" "%l" pushl esp+0xc
2847 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2848 * LocalAlloc(0x00, some_len) -> irrelevant_var
2849 * LocalAlloc(0x40, irrelevant_len) -> pStr
2850 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2851 * shlwapi.PathRemoveBlanksW(pStr);
2853 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2857 /*************************************************************************
2860 * Called by ICQ2000b install via SHDOCVW:
2861 * str1: "InternetShortcut"
2862 * x: some unknown pointer
2863 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2864 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2866 * In short: this one maybe creates a desktop link :-)
2868 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2870 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2874 /*************************************************************************
2879 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2880 LPCWSTR str, UINT count, const INT *lpDx)
2882 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2883 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2886 /*************************************************************************
2889 * See SHGetFileInfoW.
2891 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2892 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2894 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2895 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2898 /*************************************************************************
2901 * See DragQueryFileW.
2903 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2905 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2906 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2909 /*************************************************************************
2912 * See SHBrowseForFolderW.
2914 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2916 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2917 return pSHBrowseForFolderW(lpBi);
2920 /*************************************************************************
2923 * See SHGetPathFromIDListW.
2925 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2927 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2928 return pSHGetPathFromIDListW(pidl, pszPath);
2931 /*************************************************************************
2934 * See ShellExecuteExW.
2936 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2938 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2939 return pShellExecuteExW(lpExecInfo);
2942 /*************************************************************************
2945 * See SHFileOperationW.
2947 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2949 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2950 return pSHFileOperationW(lpFileOp);
2953 /*************************************************************************
2956 * See ExtractIconExW.
2958 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2959 HICON *phiconSmall, UINT nIcons)
2961 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2962 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
2965 /*************************************************************************
2969 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
2971 return InterlockedCompareExchange(dest, xchg, compare);
2974 /*************************************************************************
2977 DWORD WINAPI SHUnicodeToUnicode(
2982 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
2983 lstrcpynW(dest, src, len);
2984 return lstrlenW(dest)+1;
2987 /*************************************************************************
2990 * See GetFileVersionInfoSizeW.
2992 DWORD WINAPI GetFileVersionInfoSizeWrapW(
2998 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
2999 ret = pGetFileVersionInfoSizeW(x, y);
3003 /*************************************************************************
3006 * See GetFileVersionInfoW.
3008 BOOL WINAPI GetFileVersionInfoWrapW(
3009 LPWSTR w, /* [in] path to dll */
3010 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3011 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3012 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3014 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3015 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3018 /*************************************************************************
3021 * See VerQueryValueW.
3023 WORD WINAPI VerQueryValueWrapW(
3024 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3025 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3026 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3027 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3029 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3030 return pVerQueryValueW((char*)w+0x208, x, y, z);
3033 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3034 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3035 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3037 /*************************************************************************
3040 * Change the modality of a shell object.
3043 * lpUnknown [I] Object to make modeless
3044 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3047 * Success: S_OK. The modality lpUnknown is changed.
3048 * Failure: An HRESULT error code indicating the error.
3051 * lpUnknown must support the IOleInPlaceFrame interface, the
3052 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3053 * or the IDocHostUIHandler interface, or this call fails.
3055 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3060 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3065 if (IsIface(IOleInPlaceFrame))
3066 EnableModeless(IOleInPlaceFrame);
3067 else if (IsIface(IShellBrowser))
3068 EnableModeless(IShellBrowser);
3070 /* FIXME: Wine has no headers for these objects yet */
3071 else if (IsIface(IInternetSecurityMgrSite))
3072 EnableModeless(IInternetSecurityMgrSite);
3073 else if (IsIface(IDocHostUIHandler))
3074 EnableModeless(IDocHostUIHandler);
3079 IUnknown_Release(lpObj);
3083 /*************************************************************************
3086 * See SHGetNewLinkInfoW.
3088 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3089 BOOL *pfMustCopy, UINT uFlags)
3091 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3092 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3095 /*************************************************************************
3098 * See SHDefExtractIconW.
3100 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3101 HICON* phiconSmall, UINT nIconSize)
3103 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3104 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3107 /*************************************************************************
3110 * Get and show a context menu from a shell folder.
3113 * hWnd [I] Window displaying the shell folder
3114 * lpFolder [I] IShellFolder interface
3115 * lpApidl [I] Id for the particular folder desired
3116 * bInvokeDefault [I] Whether to invoke the default menu item
3119 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3121 * Failure: An HRESULT error code indicating the error.
3123 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3125 IContextMenu *iContext;
3126 HRESULT hRet = E_FAIL;
3128 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3133 /* Get the context menu from the shell folder */
3134 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3135 &IID_IContextMenu, 0, (void**)&iContext);
3136 if (SUCCEEDED(hRet))
3139 if ((hMenu = CreatePopupMenu()))
3142 DWORD dwDefaultId = 0;
3144 /* Add the context menu entries to the popup */
3145 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3146 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3148 if (SUCCEEDED(hQuery))
3150 if (bInvokeDefault &&
3151 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3153 CMINVOKECOMMANDINFO cmIci;
3154 /* Invoke the default item */
3155 memset(&cmIci,0,sizeof(cmIci));
3156 cmIci.cbSize = sizeof(cmIci);
3157 cmIci.fMask = CMIC_MASK_ASYNCOK;
3159 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3160 cmIci.nShow = SW_SCROLLCHILDREN;
3162 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3167 IContextMenu_Release(iContext);
3172 /*************************************************************************
3177 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3180 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3181 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3184 /*************************************************************************
3187 LANGID WINAPI MLGetUILanguage()
3190 /* FIXME: This should be a forward in the .spec file to the win2k function
3191 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3193 return GetUserDefaultLangID();
3196 /*************************************************************************
3199 * Load a library from the directory of a particular process.
3202 * new_mod [I] Library name
3203 * inst_hwnd [I] Module whose directory is to be used
3204 * dwFlags [I] Flags controlling the load
3207 * Success: A handle to the loaded module
3208 * Failure: A NULL handle.
3210 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3212 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3214 * FIXME: Native shows calls to:
3215 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3217 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3218 * RegQueryValueExA for "LPKInstalled"
3220 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3221 * RegQueryValueExA for "ResourceLocale"
3223 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3224 * RegQueryValueExA for "Locale"
3226 * and then tests the Locale ("en" for me).
3228 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3230 CHAR mod_path[2*MAX_PATH];
3233 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3234 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
3235 ptr = strrchr(mod_path, '\\');
3237 strcpy(ptr+1, new_mod);
3238 TRACE("loading %s\n", debugstr_a(mod_path));
3239 return LoadLibraryA(mod_path);
3244 /*************************************************************************
3247 * Unicode version of MLLoadLibraryA.
3249 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3251 WCHAR mod_path[2*MAX_PATH];
3254 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3255 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
3256 ptr = strrchrW(mod_path, '\\');
3258 strcpyW(ptr+1, new_mod);
3259 TRACE("loading %s\n", debugstr_w(mod_path));
3260 return LoadLibraryW(mod_path);
3265 /*************************************************************************
3266 * ColorAdjustLuma [SHLWAPI.@]
3268 * Adjust the luminosity of a color
3271 * cRGB [I] RGB value to convert
3272 * dwLuma [I] Luma adjustment
3273 * bUnknown [I] Unknown
3276 * The adjusted RGB color.
3278 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3280 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3286 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3288 FIXME("Ignoring luma adjustment\n");
3290 /* FIXME: The ajdustment is not linear */
3292 cRGB = ColorHLSToRGB(wH, wL, wS);
3297 /*************************************************************************
3300 * See GetSaveFileNameW.
3302 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3304 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3305 return pGetSaveFileNameW(ofn);
3308 /*************************************************************************
3311 * See WNetRestoreConnectionW.
3313 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3315 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3316 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3319 /*************************************************************************
3322 * See WNetGetLastErrorW.
3324 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3325 LPWSTR lpNameBuf, DWORD nNameBufSize)
3327 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3328 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3331 /*************************************************************************
3334 * See PageSetupDlgW.
3336 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3338 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3339 return pPageSetupDlgW(pagedlg);
3342 /*************************************************************************
3347 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3349 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3350 return pPrintDlgW(printdlg);
3353 /*************************************************************************
3356 * See GetOpenFileNameW.
3358 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3360 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3361 return pGetOpenFileNameW(ofn);
3364 /* INTERNAL: Map from HLS color space to RGB */
3365 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3367 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3371 else if (wHue > 120)
3376 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3379 /* Convert to RGB and scale into RGB range (0..255) */
3380 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3382 /*************************************************************************
3383 * ColorHLSToRGB [SHLWAPI.@]
3385 * Convert from hls color space into an rgb COLORREF.
3388 * wHue [I] Hue amount
3389 * wLuminosity [I] Luminosity amount
3390 * wSaturation [I] Saturation amount
3393 * A COLORREF representing the converted color.
3396 * Input hls values are constrained to the range (0..240).
3398 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3404 WORD wGreen, wBlue, wMid1, wMid2;
3406 if (wLuminosity > 120)
3407 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3409 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3411 wMid1 = wLuminosity * 2 - wMid2;
3413 wRed = GET_RGB(wHue + 80);
3414 wGreen = GET_RGB(wHue);
3415 wBlue = GET_RGB(wHue - 80);
3417 return RGB(wRed, wGreen, wBlue);
3420 wRed = wLuminosity * 255 / 240;
3421 return RGB(wRed, wRed, wRed);
3424 /*************************************************************************
3427 * Get the current docking status of the system.
3430 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3433 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3436 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3438 HW_PROFILE_INFOA hwInfo;
3440 TRACE("(0x%08lx)\n", dwFlags);
3442 GetCurrentHwProfileA(&hwInfo);
3443 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3445 case DOCKINFO_DOCKED:
3446 case DOCKINFO_UNDOCKED:
3447 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3453 /*************************************************************************
3456 * Function seems to do FreeLibrary plus other things.
3458 * FIXME native shows the following calls:
3459 * RtlEnterCriticalSection
3461 * GetProcAddress(Comctl32??, 150L)
3463 * RtlLeaveCriticalSection
3464 * followed by the FreeLibrary.
3465 * The above code may be related to .377 above.
3467 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3469 FIXME("(%p) semi-stub\n", hModule);
3470 return FreeLibrary(hModule);
3473 /*************************************************************************
3475 * FIXME I have no idea what this function does or what its arguments are.
3477 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3479 FIXME("(%p) stub\n", hInst);
3484 /*************************************************************************
3487 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3489 FIXME("(%p,%p) stub\n", hInst, hHeap);
3490 return E_FAIL; /* This is what is used if shlwapi not loaded */
3493 /*************************************************************************
3496 DWORD WINAPI MLClearMLHInstance(DWORD x)
3498 FIXME("(0x%08lx)stub\n", x);
3502 /*************************************************************************
3505 * Convert an Unicode string CLSID into a CLSID.
3508 * idstr [I] string containing a CLSID in text form
3509 * id [O] CLSID extracted from the string
3512 * S_OK on success or E_INVALIDARG on failure
3515 * This is really CLSIDFromString() which is exported by ole32.dll,
3516 * however the native shlwapi.dll does *not* import ole32. Nor does
3517 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3518 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3519 * it returns an E_INVALIDARG error code on failure.
3520 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3521 * in "dlls/ole32/compobj.c".
3523 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3531 memset(id, 0, sizeof(CLSID));
3534 else { /* validate the CLSID string */
3536 if (strlenW(s) != 38)
3537 return E_INVALIDARG;
3539 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3540 return E_INVALIDARG;
3542 for (i=1; i<37; i++)
3544 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3546 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3547 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3548 ((s[i] >= L'A') && (s[i] <= L'F')))
3550 return E_INVALIDARG;
3554 TRACE("%s -> %p\n", debugstr_w(s), id);
3556 /* quick lookup table */
3557 memset(table, 0, 256*sizeof(WCHAR));
3559 for (i = 0; i < 10; i++) {
3562 for (i = 0; i < 6; i++) {
3563 table['A' + i] = i+10;
3564 table['a' + i] = i+10;
3567 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3571 s++; /* skip leading brace */
3572 for (i = 0; i < 4; i++) {
3573 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3579 for (i = 0; i < 2; i++) {
3580 p[1-i] = table[*s]<<4 | table[*(s+1)];
3586 for (i = 0; i < 2; i++) {
3587 p[1-i] = table[*s]<<4 | table[*(s+1)];
3593 /* these are just sequential bytes */
3594 for (i = 0; i < 2; i++) {
3595 *p++ = table[*s]<<4 | table[*(s+1)];
3600 for (i = 0; i < 6; i++) {
3601 *p++ = table[*s]<<4 | table[*(s+1)];
3608 /*************************************************************************
3611 * Determine if the OS supports a given feature.
3614 * dwFeature [I] Feature requested (undocumented)
3617 * TRUE If the feature is available.
3618 * FALSE If the feature is not available.
3620 DWORD WINAPI IsOS(DWORD feature)
3622 FIXME("(0x%08lx) stub\n", feature);
3628 /*************************************************************************
3629 * ColorRGBToHLS [SHLWAPI.@]
3631 * Convert an rgb COLORREF into the hls color space.
3634 * cRGB [I] Source rgb value
3635 * pwHue [O] Destination for converted hue
3636 * pwLuminance [O] Destination for converted luminance
3637 * pwSaturation [O] Destination for converted saturation
3640 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3644 * Output HLS values are constrained to the range (0..240).
3645 * For Achromatic conversions, Hue is set to 160.
3647 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3648 LPWORD pwLuminance, LPWORD pwSaturation)
3650 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3652 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3654 wR = GetRValue(cRGB);
3655 wG = GetGValue(cRGB);
3656 wB = GetBValue(cRGB);
3658 wMax = max(wR, max(wG, wB));
3659 wMin = min(wR, min(wG, wB));
3662 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3666 /* Achromatic case */
3668 /* Hue is now unrepresentable, but this is what native returns... */
3673 /* Chromatic case */
3674 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3677 if (wLuminosity <= 120)
3678 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3680 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3683 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3684 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3685 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3688 wHue = wBNorm - wGNorm;
3689 else if (wG == wMax)
3690 wHue = 80 + wRNorm - wBNorm;
3692 wHue = 160 + wGNorm - wRNorm;
3695 else if (wHue > 240)
3701 *pwLuminance = wLuminosity;
3703 *pwSaturation = wSaturation;
3706 /*************************************************************************
3707 * SHCreateShellPalette [SHLWAPI.@]
3709 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3712 return CreateHalftonePalette(hdc);
3715 /*************************************************************************
3716 * SHGetInverseCMAP (SHLWAPI.@)
3718 * Get an inverse color map table.
3721 * lpCmap [O] Destination for color map
3722 * dwSize [I] Size of memory pointed to by lpCmap
3726 * Failure: E_POINTER, If lpCmap is invalid.
3727 * E_INVALIDARG, If dwFlags is invalid
3728 * E_OUTOFMEMORY, If there is no memory available
3731 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3732 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3734 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3735 * this DLL's internal CMap.
3737 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3740 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3741 *dest = (DWORD)0xabba1249;
3744 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3748 /*************************************************************************
3749 * SHIsLowMemoryMachine [SHLWAPI.@]
3751 * Determine if the current computer has low memory.
3757 * TRUE if the users machine has 16 Megabytes of memory or less,
3760 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3762 FIXME("(0x%08lx) stub\n", x);
3766 /*************************************************************************
3767 * GetMenuPosFromID [SHLWAPI.@]
3769 * Return the position of a menu item from its Id.
3772 * hMenu [I] Menu containing the item
3773 * wID [I] Id of the menu item
3776 * Success: The index of the menu item in hMenu.
3777 * Failure: -1, If the item is not found.
3779 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3782 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3784 while (nIter < nCount)
3787 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3794 /*************************************************************************
3795 * SHSkipJunction [SHLWAPI.@]
3797 * Determine if a bind context can be bound to an object
3800 * pbc [I] Bind context to check
3801 * pclsid [I] CLSID of object to be bound to
3804 * TRUE: If it is safe to bind
3805 * FALSE: If pbc is invalid or binding would not be safe
3808 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
3810 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
3811 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
3818 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
3822 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
3823 IsEqualGUID(pclsid, &clsid))
3826 IUnknown_Release(lpUnk);
3832 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
3834 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
3838 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
3840 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
3844 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
3846 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
3849 IInputObjectSite * pIOS = NULL;
3850 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
3851 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
3857 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
3859 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);