2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
45 #include "wine/unicode.h"
48 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54 /* Get a function pointer from a DLL handle */
55 #define GET_FUNC(func, module, name, fail) \
58 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
59 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
60 if (!func) return fail; \
64 /* DLL handles for late bound calls */
65 extern HINSTANCE shlwapi_hInstance;
66 extern HMODULE SHLWAPI_hshell32;
67 extern HMODULE SHLWAPI_hwinmm;
68 extern HMODULE SHLWAPI_hcomdlg32;
69 extern HMODULE SHLWAPI_hcomctl32;
70 extern HMODULE SHLWAPI_hmpr;
71 extern HMODULE SHLWAPI_hurlmon;
72 extern HMODULE SHLWAPI_hversion;
74 extern DWORD SHLWAPI_ThreadRef_index;
76 typedef HANDLE HSHARED; /* Shared memory */
78 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
79 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
80 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
81 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
83 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
84 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
85 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
86 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
87 static fnpPlaySoundW pPlaySoundW;
88 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
89 static fnpSHGetFileInfoW pSHGetFileInfoW;
90 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
91 static fnpDragQueryFileW pDragQueryFileW;
92 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
93 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
94 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
95 static fnpShellExecuteExW pShellExecuteExW;
96 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
97 static fnpSHFileOperationW pSHFileOperationW;
98 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
99 static fnpExtractIconExW pExtractIconExW;
100 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
101 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
102 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
103 static fnpSHDefExtractIconW pSHDefExtractIconW;
104 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
105 static fnpExtractIconW pExtractIconW;
106 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
107 static fnpGetSaveFileNameW pGetSaveFileNameW;
108 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
109 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
110 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
111 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
112 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
113 static fnpPageSetupDlgW pPageSetupDlgW;
114 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
115 static fnpPrintDlgW pPrintDlgW;
116 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
117 static fnpGetOpenFileNameW pGetOpenFileNameW;
118 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
119 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
120 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
121 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
122 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
123 static fnpVerQueryValueW pVerQueryValueW;
124 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
125 static fnpCOMCTL32_417 pCOMCTL32_417;
126 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
127 static fnpDllGetVersion pDllGetVersion;
128 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
129 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
130 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
131 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
133 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
134 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
135 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
136 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
139 NOTES: Most functions exported by ordinal seem to be superflous.
140 The reason for these functions to be there is to provide a wrapper
141 for unicode functions to provide these functions on systems without
142 unicode functions eg. win95/win98. Since we have such functions we just
143 call these. If running Wine with native DLL's, some late bound calls may
144 fail. However, its better to implement the functions in the forward DLL
145 and recommend the builtin rather than reimplementing the calls here!
148 /*************************************************************************
149 * SHLWAPI_DupSharedHandle
151 * Internal implemetation of SHLWAPI_11.
154 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
155 DWORD dwSrcProcId, DWORD dwAccess,
159 DWORD dwMyProcId = GetCurrentProcessId();
160 HSHARED hRet = (HSHARED)NULL;
162 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
163 dwAccess, dwOptions);
165 /* Get dest process handle */
166 if (dwDstProcId == dwMyProcId)
167 hDst = GetCurrentProcess();
169 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
173 /* Get src process handle */
174 if (dwSrcProcId == dwMyProcId)
175 hSrc = GetCurrentProcess();
177 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
181 /* Make handle available to dest process */
182 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
183 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
184 hRet = (HSHARED)NULL;
186 if (dwSrcProcId != dwMyProcId)
190 if (dwDstProcId != dwMyProcId)
194 TRACE("Returning handle %p\n", (PVOID)hRet);
198 /*************************************************************************
201 * Create a block of sharable memory and initialise it with data.
204 * dwProcId [I] ID of process owning data
205 * lpvData [I] Pointer to data to write
206 * dwSize [I] Size of data
209 * Success: A shared memory handle
213 * Ordinals 7-11 provide a set of calls to create shared memory between a
214 * group of processes. The shared memory is treated opaquely in that its size
215 * is not exposed to clients who map it. This is accomplished by storing
216 * the size of the map as the first DWORD of mapped data, and then offsetting
217 * the view pointer returned by this size.
220 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
224 HSHARED hRet = (HSHARED)NULL;
226 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
228 /* Create file mapping of the correct length */
229 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
230 dwSize + sizeof(dwSize), NULL);
234 /* Get a view in our process address space */
235 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
239 /* Write size of data, followed by the data, to the view */
240 *((DWORD*)pMapped) = dwSize;
242 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
244 /* Release view. All further views mapped will be opaque */
245 UnmapViewOfFile(pMapped);
246 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
247 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
248 DUPLICATE_SAME_ACCESS);
255 /*************************************************************************
258 * Get a pointer to a block of shared memory from a shared memory handle.
261 * hShared [I] Shared memory handle
262 * dwProcId [I] ID of process owning hShared
265 * Success: A pointer to the shared memory
269 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
274 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
276 /* Get handle to shared memory for current process */
277 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
278 FILE_MAP_ALL_ACCESS, 0);
280 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
284 return (char *) pMapped + sizeof(DWORD); /* Hide size */
288 /*************************************************************************
291 * Release a pointer to a block of shared memory.
294 * lpView [I] Shared memory pointer
301 BOOL WINAPI SHUnlockShared(LPVOID lpView)
303 TRACE("(%p)\n", lpView);
304 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
307 /*************************************************************************
310 * Destroy a block of sharable memory.
313 * hShared [I] Shared memory handle
314 * dwProcId [I] ID of process owning hShared
321 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
325 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
327 /* Get a copy of the handle for our process, closing the source handle */
328 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
329 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
330 /* Close local copy */
331 return CloseHandle((HANDLE)hClose);
334 /*************************************************************************
337 * Copy a sharable memory handle from one process to another.
340 * hShared [I] Shared memory handle to duplicate
341 * dwDstProcId [I] ID of the process wanting the duplicated handle
342 * dwSrcProcId [I] ID of the process owning hShared
343 * dwAccess [I] Desired DuplicateHandle() access
344 * dwOptions [I] Desired DuplicateHandle() options
347 * Success: A handle suitable for use by the dwDstProcId process.
348 * Failure: A NULL handle.
351 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
352 DWORD dwAccess, DWORD dwOptions)
356 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
357 dwAccess, dwOptions);
361 /*************************************************************************
364 * Create and register a clipboard enumerator for a web browser.
367 * lpBC [I] Binding context
368 * lpUnknown [I] An object exposing the IWebBrowserApp interface
372 * Failure: An HRESULT error code.
375 * The enumerator is stored as a property of the web browser. If it does not
376 * yet exist, it is created and set before being registered.
378 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
380 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
381 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
382 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
383 IEnumFORMATETC* pIEnumFormatEtc = NULL;
386 IWebBrowserApp* pBrowser = NULL;
388 TRACE("(%p, %p)\n", lpBC, lpUnknown);
390 /* Get An IWebBrowserApp interface from lpUnknown */
391 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
392 if (FAILED(hRet) || !pBrowser)
393 return E_NOINTERFACE;
395 V_VT(&var) = VT_EMPTY;
397 /* The property we get is the browsers clipboard enumerator */
398 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
402 if (V_VT(&var) == VT_EMPTY)
404 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
405 char szKeyBuff[128], szValueBuff[128];
406 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
407 FORMATETC* formatList, *format;
410 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
412 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
413 "Version\\Internet Settings\\Accepted Documents", &hDocs))
416 /* Get count of values in key */
419 dwKeySize = sizeof(szKeyBuff);
420 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
424 dwNumValues = dwCount;
426 /* Note: dwCount = number of items + 1; The extra item is the end node */
427 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
429 return E_OUTOFMEMORY;
438 /* Register clipboard formats for the values and populate format list */
439 while(!dwRet && dwCount < dwNumValues)
441 dwKeySize = sizeof(szKeyBuff);
442 dwValueSize = sizeof(szValueBuff);
443 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
444 (PBYTE)szValueBuff, &dwValueSize);
448 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
450 format->dwAspect = 1;
459 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
460 format->cfFormat = 0;
462 format->dwAspect = 1;
466 /* Create a clipboard enumerator */
467 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
468 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
470 if (FAILED(hRet) || !pIEnumFormatEtc)
473 /* Set our enumerator as the browsers property */
474 V_VT(&var) = VT_UNKNOWN;
475 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
477 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
480 IEnumFORMATETC_Release(pIEnumFormatEtc);
481 goto RegisterDefaultAcceptHeaders_Exit;
485 if (V_VT(&var) == VT_UNKNOWN)
487 /* Our variant is holding the clipboard enumerator */
488 IUnknown* pIUnknown = V_UNKNOWN(&var);
489 IEnumFORMATETC* pClone = NULL;
491 TRACE("Retrieved IEnumFORMATETC property\n");
493 /* Get an IEnumFormatEtc interface from the variants value */
494 pIEnumFormatEtc = NULL;
495 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
496 (PVOID)&pIEnumFormatEtc);
497 if (!hRet && pIEnumFormatEtc)
499 /* Clone and register the enumerator */
500 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
503 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
504 pRegisterFormatEnumerator(lpBC, pClone, 0);
506 IEnumFORMATETC_Release(pClone);
509 /* Release the IEnumFormatEtc interface */
510 IEnumFORMATETC_Release(pIUnknown);
512 IUnknown_Release(V_UNKNOWN(&var));
515 RegisterDefaultAcceptHeaders_Exit:
516 IWebBrowserApp_Release(pBrowser);
520 /*************************************************************************
523 * Get Explorers "AcceptLanguage" setting.
526 * langbuf [O] Destination for language string
527 * buflen [I] Length of langbuf
530 * Success: S_OK. langbuf is set to the language string found.
531 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
532 * does not contain the setting.
534 HRESULT WINAPI GetAcceptLanguagesA(
539 DWORD mystrlen, mytype;
543 mystrlen = (*buflen > 6) ? *buflen : 6;
544 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
545 HEAP_ZERO_MEMORY, mystrlen);
546 RegOpenKeyA(HKEY_CURRENT_USER,
547 "Software\\Microsoft\\Internet Explorer\\International",
549 if (RegQueryValueExA(mykey, "AcceptLanguage",
550 0, &mytype, (PBYTE)mystr, &mystrlen)) {
551 /* Did not find value */
552 mylcid = GetUserDefaultLCID();
553 /* somehow the mylcid translates into "en-us"
554 * this is similar to "LOCALE_SABBREVLANGNAME"
555 * which could be gotten via GetLocaleInfo.
556 * The only problem is LOCALE_SABBREVLANGUAGE" is
557 * a 3 char string (first 2 are country code and third is
558 * letter for "sublanguage", which does not come close to
561 lstrcpyA(mystr, "en-us");
562 mystrlen = lstrlenA(mystr);
565 /* handle returned string */
566 FIXME("missing code\n");
568 if (mystrlen > *buflen)
569 lstrcpynA(langbuf, mystr, *buflen);
571 lstrcpyA(langbuf, mystr);
572 *buflen = lstrlenA(langbuf);
575 HeapFree(GetProcessHeap(), 0, mystr);
576 TRACE("language is %s\n", debugstr_a(langbuf));
580 /*************************************************************************
583 * Unicode version of GetAcceptLanguagesA.
585 HRESULT WINAPI GetAcceptLanguagesW(
590 DWORD mystrlen, mytype;
594 mystrlen = (*buflen > 6) ? *buflen : 6;
595 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
596 HEAP_ZERO_MEMORY, mystrlen);
597 RegOpenKeyA(HKEY_CURRENT_USER,
598 "Software\\Microsoft\\Internet Explorer\\International",
600 if (RegQueryValueExA(mykey, "AcceptLanguage",
601 0, &mytype, (PBYTE)mystr, &mystrlen)) {
602 /* Did not find value */
603 mylcid = GetUserDefaultLCID();
604 /* somehow the mylcid translates into "en-us"
605 * this is similar to "LOCALE_SABBREVLANGNAME"
606 * which could be gotten via GetLocaleInfo.
607 * The only problem is LOCALE_SABBREVLANGUAGE" is
608 * a 3 char string (first 2 are country code and third is
609 * letter for "sublanguage", which does not come close to
612 lstrcpyA(mystr, "en-us");
613 mystrlen = lstrlenA(mystr);
616 /* handle returned string */
617 FIXME("missing code\n");
620 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
621 HeapFree(GetProcessHeap(), 0, mystr);
622 TRACE("language is %s\n", debugstr_w(langbuf));
626 /*************************************************************************
629 * Convert a GUID to a string.
632 * guid [I] GUID to convert
633 * str [O] Destination for string
634 * cmax [I] Length of output buffer
637 * The length of the string created.
639 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
644 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
646 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
647 guid->Data1, guid->Data2, guid->Data3,
648 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
649 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
651 iLen = strlen(xguid) + 1;
655 memcpy(lpszDest, xguid, iLen);
659 /*************************************************************************
662 * Unicode version of SHStringFromGUIDA.
664 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
667 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
670 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
674 /*************************************************************************
677 * Determine if a Unicode character is alphabetic.
680 * wc [I] Character to check.
683 * TRUE, if wc is alphabetic,
686 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
688 return (get_char_typeW(wc) & C1_ALPHA) != 0;
691 /*************************************************************************
694 * Determine if a Unicode character is upper-case.
697 * wc [I] Character to check.
700 * TRUE, if wc is upper-case,
703 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
705 return (get_char_typeW(wc) & C1_UPPER) != 0;
708 /*************************************************************************
711 * Determine if a Unicode character is lower-case.
714 * wc [I] Character to check.
717 * TRUE, if wc is lower-case,
720 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
722 return (get_char_typeW(wc) & C1_LOWER) != 0;
725 /*************************************************************************
728 * Determine if a Unicode character is alphabetic or a digit.
731 * wc [I] Character to check.
734 * TRUE, if wc is alphabetic or a digit,
737 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
739 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
742 /*************************************************************************
745 * Determine if a Unicode character is a space.
748 * wc [I] Character to check.
751 * TRUE, if wc is a space,
754 BOOL WINAPI IsCharSpaceW(WCHAR wc)
756 return (get_char_typeW(wc) & C1_SPACE) != 0;
759 /*************************************************************************
762 * Determine if a Unicode character is a blank.
765 * wc [I] Character to check.
768 * TRUE, if wc is a blank,
772 BOOL WINAPI IsCharBlankW(WCHAR wc)
774 return (get_char_typeW(wc) & C1_BLANK) != 0;
777 /*************************************************************************
780 * Determine if a Unicode character is punctuation.
783 * wc [I] Character to check.
786 * TRUE, if wc is punctuation,
789 BOOL WINAPI IsCharPunctW(WCHAR wc)
791 return (get_char_typeW(wc) & C1_PUNCT) != 0;
794 /*************************************************************************
797 * Determine if a Unicode character is a control character.
800 * wc [I] Character to check.
803 * TRUE, if wc is a control character,
806 BOOL WINAPI IsCharCntrlW(WCHAR wc)
808 return (get_char_typeW(wc) & C1_CNTRL) != 0;
811 /*************************************************************************
814 * Determine if a Unicode character is a digit.
817 * wc [I] Character to check.
820 * TRUE, if wc is a digit,
823 BOOL WINAPI IsCharDigitW(WCHAR wc)
825 return (get_char_typeW(wc) & C1_DIGIT) != 0;
828 /*************************************************************************
831 * Determine if a Unicode character is a hex digit.
834 * wc [I] Character to check.
837 * TRUE, if wc is a hex digit,
840 BOOL WINAPI IsCharXDigitW(WCHAR wc)
842 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
845 /*************************************************************************
849 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
851 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
855 /*************************************************************************
858 * Insert a bitmap menu item at the bottom of a menu.
861 * hMenu [I] Menu to insert into
862 * flags [I] Flags for insertion
863 * id [I] Menu ID of the item
864 * str [I] Menu text for the item
867 * Success: TRUE, the item is inserted into the menu
868 * Failure: FALSE, if any parameter is invalid
870 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
872 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
873 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
876 /*************************************************************************
879 * Get the text from a given dialog item.
882 * hWnd [I] Handle of dialog
883 * nItem [I] Index of item
884 * lpsDest [O] Buffer for receiving window text
885 * nDestLen [I] Length of buffer.
888 * Success: The length of the returned text.
891 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
893 HWND hItem = GetDlgItem(hWnd, nItem);
896 return GetWindowTextW(hItem, lpsDest, nDestLen);
898 *lpsDest = (WCHAR)'\0';
902 /*************************************************************************
905 * Set the text of a given dialog item.
908 * hWnd [I] Handle of dialog
909 * iItem [I] Index of item
910 * lpszText [O] Text to set
913 * Success: TRUE. The text of the dialog is set to lpszText.
914 * Failure: FALSE, Otherwise.
916 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
918 HWND hWndItem = GetDlgItem(hWnd, iItem);
920 return SetWindowTextW(hWndItem, lpszText);
924 /*************************************************************************
927 * Compare two Ascii strings up to a given length.
930 * lpszSrc [I] Source string
931 * lpszCmp [I] String to compare to lpszSrc
932 * len [I] Maximum length
935 * A number greater than, less than or equal to 0 depending on whether
936 * lpszSrc is greater than, less than or equal to lpszCmp.
938 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
940 return strncmp(lpszSrc, lpszCmp, len);
943 /*************************************************************************
946 * Unicode version of StrCmpNCA.
948 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
950 return strncmpW(lpszSrc, lpszCmp, len);
953 /*************************************************************************
956 * Compare two Ascii strings up to a given length, ignoring case.
959 * lpszSrc [I] Source string
960 * lpszCmp [I] String to compare to lpszSrc
961 * len [I] Maximum length
964 * A number greater than, less than or equal to 0 depending on whether
965 * lpszSrc is greater than, less than or equal to lpszCmp.
967 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
969 return strncasecmp(lpszSrc, lpszCmp, len);
972 /*************************************************************************
975 * Unicode version of StrCmpNICA.
977 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
979 return strncmpiW(lpszSrc, lpszCmp, len);
982 /*************************************************************************
985 * Compare two Ascii strings.
988 * lpszSrc [I] Source string
989 * lpszCmp [I] String to compare to lpszSrc
992 * A number greater than, less than or equal to 0 depending on whether
993 * lpszSrc is greater than, less than or equal to lpszCmp.
995 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
997 return strcmp(lpszSrc, lpszCmp);
1000 /*************************************************************************
1003 * Unicode version of StrCmpCA.
1005 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1007 return strcmpW(lpszSrc, lpszCmp);
1010 /*************************************************************************
1013 * Compare two Ascii strings, ignoring case.
1016 * lpszSrc [I] Source string
1017 * lpszCmp [I] String to compare to lpszSrc
1020 * A number greater than, less than or equal to 0 depending on whether
1021 * lpszSrc is greater than, less than or equal to lpszCmp.
1023 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1025 return strcasecmp(lpszSrc, lpszCmp);
1028 /*************************************************************************
1031 * Unicode version of StrCmpICA.
1033 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1035 return strcmpiW(lpszSrc, lpszCmp);
1038 /*************************************************************************
1041 * Get an identification string for the OS and explorer.
1044 * lpszDest [O] Destination for Id string
1045 * dwDestLen [I] Length of lpszDest
1048 * TRUE, If the string was created successfully
1051 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1055 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1057 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1059 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1065 /*************************************************************************
1068 * Unicode version of SHAboutInfoA.
1070 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1072 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1073 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1074 ' ','E','x','p','l','o','r','e','r','\0' };
1075 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1076 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1077 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1078 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1079 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1080 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1081 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1082 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1083 ' ','E','x','p','l','o','r','e','r','\\',
1084 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1085 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1086 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1087 'V','e','r','s','i','o','n','\0' };
1088 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1089 'O','w','n','e','r','\0' };
1090 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1091 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1092 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1093 static const WCHAR szUpdate[] = { 'I','E','A','K',
1094 'U','p','d','a','t','e','U','r','l','\0' };
1095 static const WCHAR szHelp[] = { 'I','E','A','K',
1096 'H','e','l','p','S','t','r','i','n','g','\0' };
1099 DWORD dwType, dwLen;
1101 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1108 /* Try the NT key first, followed by 95/98 key */
1109 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1110 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1116 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1118 DWORD dwStrLen = strlenW(buff);
1119 dwLen = 30 - dwStrLen;
1120 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1121 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1123 StrCatBuffW(lpszDest, buff, dwDestLen);
1125 /* ~Registered Owner */
1128 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1130 StrCatBuffW(lpszDest, buff, dwDestLen);
1132 /* ~Registered Organization */
1134 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1136 StrCatBuffW(lpszDest, buff, dwDestLen);
1138 /* FIXME: Not sure where this number comes from */
1142 StrCatBuffW(lpszDest, buff, dwDestLen);
1146 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1148 StrCatBuffW(lpszDest, buff, dwDestLen);
1150 /* ~IE Update Url */
1152 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1154 StrCatBuffW(lpszDest, buff, dwDestLen);
1156 /* ~IE Help String */
1158 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1160 StrCatBuffW(lpszDest, buff, dwDestLen);
1166 /*************************************************************************
1169 * Call IOleCommandTarget_QueryStatus() on an object.
1172 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1173 * pguidCmdGroup [I] GUID for the command group
1175 * prgCmds [O] Commands
1176 * pCmdText [O] Command text
1180 * Failure: E_FAIL, if lpUnknown is NULL.
1181 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1182 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1184 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1185 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1187 HRESULT hRet = E_FAIL;
1189 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1193 IOleCommandTarget* lpOle;
1195 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1198 if (SUCCEEDED(hRet) && lpOle)
1200 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1202 IOleCommandTarget_Release(lpOle);
1208 /*************************************************************************
1211 * Call IOleCommandTarget_Exec() on an object.
1214 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1215 * pguidCmdGroup [I] GUID for the command group
1219 * Failure: E_FAIL, if lpUnknown is NULL.
1220 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1221 * Otherwise, an error code from IOleCommandTarget_Exec().
1223 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1224 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1227 HRESULT hRet = E_FAIL;
1229 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1230 nCmdexecopt, pvaIn, pvaOut);
1234 IOleCommandTarget* lpOle;
1236 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1238 if (SUCCEEDED(hRet) && lpOle)
1240 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1241 nCmdexecopt, pvaIn, pvaOut);
1242 IOleCommandTarget_Release(lpOle);
1248 /*************************************************************************
1251 * Retrieve, modify, and re-set a value from a window.
1254 * hWnd [I] Window to get value from
1255 * offset [I] Offset of value
1256 * wMask [I] Mask for uiFlags
1257 * wFlags [I] Bits to set in window value
1260 * The new value as it was set, or 0 if any parameter is invalid.
1263 * Any bits set in uiMask are cleared from the value, then any bits set in
1264 * uiFlags are set in the value.
1266 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1268 LONG ret = GetWindowLongA(hwnd, offset);
1269 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1271 if (newFlags != ret)
1272 ret = SetWindowLongA(hwnd, offset, newFlags);
1276 /*************************************************************************
1279 * Change a window's parent.
1282 * hWnd [I] Window to change parent of
1283 * hWndParent [I] New parent window
1286 * The old parent of hWnd.
1289 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1290 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1292 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1294 TRACE("%p, %p\n", hWnd, hWndParent);
1296 if(GetParent(hWnd) == hWndParent)
1300 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1302 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1304 return SetParent(hWnd, hWndParent);
1307 /*************************************************************************
1310 * Locate and advise a connection point in an IConnectionPointContainer object.
1313 * lpUnkSink [I] Sink for the connection point advise call
1314 * riid [I] REFIID of connection point to advise
1315 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1316 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1317 * lpCookie [O] Pointer to connection point cookie
1318 * lppCP [O] Destination for the IConnectionPoint found
1321 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1322 * that was advised. The caller is responsable for releasing it.
1323 * Failure: E_FAIL, if any arguments are invalid.
1324 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1325 * Or an HRESULT error code if any call fails.
1327 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1328 IUnknown* lpUnknown, LPDWORD lpCookie,
1329 IConnectionPoint **lppCP)
1332 IConnectionPointContainer* lpContainer;
1333 IConnectionPoint *lpCP;
1335 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1341 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1342 (void**)&lpContainer);
1343 if (SUCCEEDED(hRet))
1345 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1347 if (SUCCEEDED(hRet))
1350 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1351 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1356 if (lppCP && SUCCEEDED(hRet))
1357 *lppCP = lpCP; /* Caller keeps the interface */
1359 IConnectionPoint_Release(lpCP); /* Release it */
1362 IUnknown_Release(lpContainer);
1367 /*************************************************************************
1370 * Release an interface.
1373 * lpUnknown [I] Object to release
1378 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1382 TRACE("(%p)\n",lpUnknown);
1384 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1388 TRACE("doing Release\n");
1390 return IUnknown_Release(temp);
1393 /*************************************************************************
1396 * Skip '//' if present in a string.
1399 * lpszSrc [I] String to check for '//'
1402 * Success: The next character after the '//' or the string if not present
1403 * Failure: NULL, if lpszStr is NULL.
1405 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1407 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1412 /*************************************************************************
1415 * Check if two interfaces come from the same object.
1418 * lpInt1 [I] Interface to check against lpInt2.
1419 * lpInt2 [I] Interface to check against lpInt1.
1422 * TRUE, If the interfaces come from the same object.
1425 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1427 LPVOID lpUnknown1, lpUnknown2;
1429 TRACE("%p %p\n", lpInt1, lpInt2);
1431 if (!lpInt1 || !lpInt2)
1434 if (lpInt1 == lpInt2)
1437 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1438 (LPVOID *)&lpUnknown1)))
1441 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1442 (LPVOID *)&lpUnknown2)))
1445 if (lpUnknown1 == lpUnknown2)
1451 /*************************************************************************
1454 * Get the window handle of an object.
1457 * lpUnknown [I] Object to get the window handle of
1458 * lphWnd [O] Destination for window handle
1461 * Success: S_OK. lphWnd contains the objects window handle.
1462 * Failure: An HRESULT error code.
1465 * lpUnknown is expected to support one of the following interfaces:
1466 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1468 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1470 /* FIXME: Wine has no header for this object */
1471 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1472 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1474 HRESULT hRet = E_FAIL;
1476 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1481 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1485 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1489 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1494 if (SUCCEEDED(hRet))
1496 /* Lazyness here - Since GetWindow() is the first method for the above 3
1497 * interfaces, we use the same call for them all.
1499 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1500 IUnknown_Release(lpOle);
1502 TRACE("Returning HWND=%p\n", *lphWnd);
1508 /*************************************************************************
1511 * Call a method on as as yet unidentified object.
1514 * pUnk [I] Object supporting the unidentified interface,
1515 * arg [I] Argument for the call on the object.
1520 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1522 static const GUID guid_173 = {
1523 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1527 TRACE("(%p,%ld)\n", pUnk, arg);
1529 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1530 * We use this interface as its vtable entry is compatible with the
1531 * object in question.
1532 * FIXME: Find out what this object is and where it should be defined.
1535 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1537 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1538 IMalloc_Release(pUnk2);
1543 /*************************************************************************
1546 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1551 * Failure: E_FAIL, if p1 is NULL.
1552 * E_NOINTERFACE If p1 does not support the IPersist interface,
1553 * Or an HRESULT error code.
1555 DWORD WINAPI IUnknown_SetSite(
1556 IUnknown *p1, /* [in] OLE object */
1557 LPVOID *p2) /* [out] ptr for call results */
1561 if (!p1) return E_FAIL;
1563 /* see if SetSite interface exists for IObjectWithSite object */
1564 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1565 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1568 /* see if GetClassId interface exists for IPersistMoniker object */
1569 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1570 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1571 if (ret) return ret;
1573 /* fake a GetClassId call */
1574 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1575 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1577 IUnknown_Release((IUnknown *)aa);
1580 /* fake a SetSite call */
1581 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1582 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1584 IUnknown_Release((IUnknown *)p1);
1589 /*************************************************************************
1592 * Call IPersist_GetClassID() on an object.
1595 * lpUnknown [I] Object supporting the IPersist interface
1596 * lpClassId [O] Destination for Class Id
1599 * Success: S_OK. lpClassId contains the Class Id requested.
1600 * Failure: E_FAIL, If lpUnknown is NULL,
1601 * E_NOINTERFACE If lpUnknown does not support IPersist,
1602 * Or an HRESULT error code.
1604 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1606 IPersist* lpPersist;
1607 HRESULT hRet = E_FAIL;
1609 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1613 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1614 if (SUCCEEDED(hRet))
1616 IPersist_GetClassID(lpPersist, lpClassId);
1617 IPersist_Release(lpPersist);
1623 /*************************************************************************
1626 * Retrieve a Service Interface from an object.
1629 * lpUnknown [I] Object to get an IServiceProvider interface from
1630 * sid [I] Service ID for IServiceProvider_QueryService() call
1631 * riid [I] Function requested for QueryService call
1632 * lppOut [O] Destination for the service interface pointer
1635 * Success: S_OK. lppOut contains an object providing the requested service
1636 * Failure: An HRESULT error code
1639 * lpUnknown is expected to support the IServiceProvider interface.
1641 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1644 IServiceProvider* pService = NULL;
1655 /* Get an IServiceProvider interface from the object */
1656 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1657 (LPVOID*)&pService);
1659 if (!hRet && pService)
1661 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1663 /* Get a Service interface from the object */
1664 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1666 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1668 /* Release the IServiceProvider interface */
1669 IUnknown_Release(pService);
1674 /*************************************************************************
1677 * Loads a popup menu.
1680 * hInst [I] Instance handle
1681 * szName [I] Menu name
1687 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1689 HMENU hMenu, hSubMenu;
1691 if ((hMenu = LoadMenuW(hInst, szName)))
1693 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1694 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1702 typedef struct _enumWndData
1707 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1710 /* Callback for SHLWAPI_178 */
1711 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1713 enumWndData *data = (enumWndData *)lParam;
1715 TRACE("(%p,%p)\n", hWnd, data);
1716 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1720 /*************************************************************************
1723 * Send or post a message to every child of a window.
1726 * hWnd [I] Window whose children will get the messages
1727 * uiMsgId [I] Message Id
1728 * wParam [I] WPARAM of message
1729 * lParam [I] LPARAM of message
1730 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1736 * The appropriate ASCII or Unicode function is called for the window.
1738 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1742 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1746 data.uiMsgId = uiMsgId;
1747 data.wParam = wParam;
1748 data.lParam = lParam;
1751 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1753 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1755 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1759 /*************************************************************************
1762 * Remove all sub-menus from a menu.
1765 * hMenu [I] Menu to remove sub-menus from
1768 * Success: 0. All sub-menus under hMenu are removed
1769 * Failure: -1, if any parameter is invalid
1771 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1773 int iItemCount = GetMenuItemCount(hMenu) - 1;
1774 while (iItemCount >= 0)
1776 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1778 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1784 /*************************************************************************
1787 * Enable or disable a menu item.
1790 * hMenu [I] Menu holding menu item
1791 * uID [I] ID of menu item to enable/disable
1792 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1795 * The return code from EnableMenuItem.
1797 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1799 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1802 /*************************************************************************
1805 * Check or uncheck a menu item.
1808 * hMenu [I] Menu holding menu item
1809 * uID [I] ID of menu item to check/uncheck
1810 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1813 * The return code from CheckMenuItem.
1815 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1817 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1820 /*************************************************************************
1823 * Register a window class if it isn't already.
1826 * lpWndClass [I] Window class to register
1829 * The result of the RegisterClassA call.
1831 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1834 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1836 return (DWORD)RegisterClassA(wndclass);
1839 /*************************************************************************
1842 * Call IPersistPropertyBag_Load() on an object.
1845 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1846 * lpPropBag [O] Destination for loaded IPropertyBag
1850 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1852 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1854 IPersistPropertyBag* lpPPBag;
1855 HRESULT hRet = E_FAIL;
1857 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1861 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1863 if (SUCCEEDED(hRet) && lpPPBag)
1865 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1866 IPersistPropertyBag_Release(lpPPBag);
1872 /*************************************************************************
1875 * Call IOleControlSite_GetExtendedControl() on an object.
1878 * lpUnknown [I] Object supporting the IOleControlSite interface
1879 * lppDisp [O] Destination for resulting IDispatch.
1883 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1885 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1887 IOleControlSite* lpCSite;
1888 HRESULT hRet = E_FAIL;
1890 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1893 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1895 if (SUCCEEDED(hRet) && lpCSite)
1897 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1898 IOleControlSite_Release(lpCSite);
1904 /*************************************************************************
1907 * Get a sub-menu from a menu item.
1910 * hMenu [I] Menu to get sub-menu from
1911 * uID [I] ID of menu item containing sub-menu
1914 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1916 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1920 TRACE("(%p,%uld)\n", hMenu, uID);
1922 mi.cbSize = sizeof(MENUITEMINFOA);
1923 mi.fMask = MIIM_SUBMENU;
1925 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1931 /*************************************************************************
1934 * Get the color depth of the primary display.
1940 * The color depth of the primary display.
1942 DWORD WINAPI SHGetCurColorRes()
1950 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1955 /*************************************************************************
1958 * Wait for a message to arrive, with a timeout.
1961 * hand [I] Handle to query
1962 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1965 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1966 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1967 * message is available.
1969 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1971 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1974 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1978 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1980 if (dwTimeout != INFINITE)
1982 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1983 return WAIT_TIMEOUT;
1990 /*************************************************************************
1993 * Blank out a region of text by drawing the background only.
1996 * hDC [I] Device context to draw in
1997 * pRect [I] Area to draw in
1998 * cRef [I] Color to draw in
2003 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2005 COLORREF cOldColor = SetBkColor(hDC, cRef);
2006 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2007 SetBkColor(hDC, cOldColor);
2011 /*************************************************************************
2014 * Return the value asociated with a key in a map.
2017 * lpKeys [I] A list of keys of length iLen
2018 * lpValues [I] A list of values associated with lpKeys, of length iLen
2019 * iLen [I] Length of both lpKeys and lpValues
2020 * iKey [I] The key value to look up in lpKeys
2023 * The value in lpValues associated with iKey, or -1 if iKey is not
2027 * - If two elements in the map share the same key, this function returns
2028 * the value closest to the start of the map
2029 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2031 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2033 if (lpKeys && lpValues)
2039 if (lpKeys[i] == iKey)
2040 return lpValues[i]; /* Found */
2044 return -1; /* Not found */
2048 /*************************************************************************
2051 * Copy an interface pointer
2054 * lppDest [O] Destination for copy
2055 * lpUnknown [I] Source for copy
2060 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2062 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2065 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2070 IUnknown_AddRef(lpUnknown);
2071 *lppDest = lpUnknown;
2075 /*************************************************************************
2079 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2080 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2083 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2084 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2085 return DRAGDROP_E_NOTREGISTERED;
2088 /*************************************************************************
2092 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2094 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2095 return DRAGDROP_E_NOTREGISTERED;
2098 /*************************************************************************
2101 * Determine if a window is not a child of another window.
2104 * hParent [I] Suspected parent window
2105 * hChild [I] Suspected child window
2108 * TRUE: If hChild is a child window of hParent
2109 * FALSE: If hChild is not a child window of hParent, or they are equal
2111 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2113 TRACE("(%p,%p)\n", hParent, hChild);
2115 if (!hParent || !hChild)
2117 else if(hParent == hChild)
2119 return !IsChild(hParent, hChild);
2122 /*************************************************************************
2125 * Some sort of memory management process.
2127 DWORD WINAPI FDSA_Initialize(
2134 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2139 /*************************************************************************
2142 * Some sort of memory management process.
2144 DWORD WINAPI FDSA_Destroy(
2147 FIXME("(%p) stub\n",
2152 /*************************************************************************
2155 * Some sort of memory management process.
2157 DWORD WINAPI FDSA_InsertItem(
2162 FIXME("(%p 0x%08lx %p) stub\n",
2167 /*************************************************************************
2170 DWORD WINAPI FDSA_DeleteItem(
2174 FIXME("(%p 0x%08lx) stub\n",
2184 /*************************************************************************
2187 * Call IUnknown_QueryInterface() on a table of objects.
2191 * Failure: E_POINTER or E_NOINTERFACE.
2193 HRESULT WINAPI QISearch(
2194 LPVOID w, /* [in] Table of interfaces */
2195 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2196 REFIID riid, /* [in] REFIID to get interface for */
2197 LPVOID *ppv) /* [out] Destination for interface pointer */
2201 IFACE_INDEX_TBL *xmove;
2203 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2206 while (xmove->refid) {
2207 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2208 if (IsEqualIID(riid, xmove->refid)) {
2209 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2210 TRACE("matched, returning (%p)\n", a_vtbl);
2211 *ppv = (LPVOID)a_vtbl;
2212 IUnknown_AddRef(a_vtbl);
2218 if (IsEqualIID(riid, &IID_IUnknown)) {
2219 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2220 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2221 *ppv = (LPVOID)a_vtbl;
2222 IUnknown_AddRef(a_vtbl);
2226 ret = E_NOINTERFACE;
2230 TRACE("-- 0x%08lx\n", ret);
2234 /*************************************************************************
2237 * Remove the "PropDlgFont" property from a window.
2240 * hWnd [I] Window to remove the property from
2243 * A handle to the removed property, or NULL if it did not exist.
2245 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2249 TRACE("(%p)\n", hWnd);
2251 hProp = GetPropA(hWnd, "PropDlgFont");
2255 DeleteObject(hProp);
2256 hProp = RemovePropA(hWnd, "PropDlgFont");
2261 /*************************************************************************
2264 * Load the in-process server of a given GUID.
2267 * refiid [I] GUID of the server to load.
2270 * Success: A handle to the loaded server dll.
2271 * Failure: A NULL handle.
2273 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2277 CHAR value[MAX_PATH], string[MAX_PATH];
2279 strcpy(string, "CLSID\\");
2280 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2281 strcat(string, "\\InProcServer32");
2284 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2285 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2286 RegCloseKey(newkey);
2287 return LoadLibraryExA(value, 0, 0);
2290 /*************************************************************************
2293 * Unicode version of SHLWAPI_183.
2295 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2299 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2301 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2303 return RegisterClassW(lpWndClass);
2306 /*************************************************************************
2309 * Unregister a list of classes.
2312 * hInst [I] Application instance that registered the classes
2313 * lppClasses [I] List of class names
2314 * iCount [I] Number of names in lppClasses
2319 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2323 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2327 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2328 UnregisterClassA(*lppClasses, hInst);
2334 /*************************************************************************
2337 * Unicode version of SHUnregisterClassesA.
2339 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2343 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2347 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2348 UnregisterClassW(*lppClasses, hInst);
2354 /*************************************************************************
2357 * Call The correct (Ascii/Unicode) default window procedure for a window.
2360 * hWnd [I] Window to call the default procedure for
2361 * uMessage [I] Message ID
2362 * wParam [I] WPARAM of message
2363 * lParam [I] LPARAM of message
2366 * The result of calling DefWindowProcA() or DefWindowProcW().
2368 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2370 if (IsWindowUnicode(hWnd))
2371 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2372 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2375 /*************************************************************************
2378 * Create a worker window using CreateWindowExA().
2381 * wndProc [I] Window procedure
2382 * hWndParent [I] Parent window
2383 * dwExStyle [I] Extra style flags
2384 * dwStyle [I] Style flags
2385 * hMenu [I] Window menu
2389 * Success: The window handle of the newly created window.
2392 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2393 DWORD dwStyle, HMENU hMenu, LONG z)
2395 static const char* szClass = "WorkerA";
2399 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2400 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2402 /* Create Window class */
2404 wc.lpfnWndProc = DefWindowProcA;
2407 wc.hInstance = shlwapi_hInstance;
2408 wc.hIcon = (HICON)0;
2409 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2410 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2411 wc.lpszMenuName = NULL;
2412 wc.lpszClassName = szClass;
2414 SHRegisterClassA(&wc); /* Register class */
2416 /* FIXME: Set extra bits in dwExStyle */
2418 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2419 hWndParent, hMenu, shlwapi_hInstance, 0);
2422 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2425 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2430 typedef struct tagPOLICYDATA
2432 DWORD policy; /* flags value passed to SHRestricted */
2433 LPCWSTR appstr; /* application str such as "Explorer" */
2434 LPCWSTR keystr; /* name of the actual registry key / policy */
2435 } POLICYDATA, *LPPOLICYDATA;
2437 #define SHELL_NO_POLICY 0xffffffff
2439 /* default shell policy registry key */
2440 static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2441 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2442 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2443 '\\','P','o','l','i','c','i','e','s',0};
2445 /*************************************************************************
2448 * Retrieve a policy value from the registry.
2451 * lpSubKey [I] registry key name
2452 * lpSubName [I] subname of registry key
2453 * lpValue [I] value name of registry value
2456 * the value associated with the registry key or 0 if not found
2458 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2460 DWORD retval, datsize = sizeof(retval);
2464 lpSubKey = (LPCWSTR)strRegistryPolicyW;
2466 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2467 if (retval != ERROR_SUCCESS)
2468 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2469 if (retval != ERROR_SUCCESS)
2472 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2477 /*************************************************************************
2480 * Helper function to retrieve the possibly cached value for a specific policy
2483 * policy [I] The policy to look for
2484 * initial [I] Main registry key to open, if NULL use default
2485 * polTable [I] Table of known policies, 0 terminated
2486 * polArr [I] Cache array of policy values
2489 * The retrieved policy value or 0 if not successful
2492 * This function is used by the native SHRestricted function to search for the
2493 * policy and cache it once retrieved. The current Wine implementation uses a
2494 * different POLICYDATA structure and implements a similar algorithme adapted to
2497 DWORD WINAPI SHRestrictionLookup(
2500 LPPOLICYDATA polTable,
2503 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2505 if (!polTable || !polArr)
2508 for (;polTable->policy; polTable++, polArr++)
2510 if (policy == polTable->policy)
2512 /* we have a known policy */
2514 /* check if this policy has been cached */
2515 if (*polArr == SHELL_NO_POLICY)
2516 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2520 /* we don't know this policy, return 0 */
2521 TRACE("unknown policy: (%08lx)\n", policy);
2525 /*************************************************************************
2528 * Get an interface from an object.
2531 * Success: S_OK. ppv contains the requested interface.
2532 * Failure: An HRESULT error code.
2535 * This QueryInterface asks the inner object for a interface. In case
2536 * of aggregation this request would be forwarded by the inner to the
2537 * outer object. This function asks the inner object directly for the
2538 * interface circumventing the forwarding to the outer object.
2540 HRESULT WINAPI SHWeakQueryInterface(
2541 IUnknown * pUnk, /* [in] Outer object */
2542 IUnknown * pInner, /* [in] Inner object */
2543 IID * riid, /* [in] Interface GUID to query for */
2544 LPVOID* ppv) /* [out] Destination for queried interface */
2546 HRESULT hret = E_NOINTERFACE;
2547 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2550 if(pUnk && pInner) {
2551 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2552 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2554 TRACE("-- 0x%08lx\n", hret);
2558 /*************************************************************************
2561 * Move a reference from one interface to another.
2564 * lpDest [O] Destination to receive the reference
2565 * lppUnknown [O] Source to give up the reference to lpDest
2570 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2572 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2577 IUnknown_AddRef(lpDest);
2578 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2582 /*************************************************************************
2585 * Convert an ASCII string of a CLSID into a CLSID.
2588 * idstr [I] String representing a CLSID in registry format
2589 * id [O] Destination for the converted CLSID
2592 * Success: TRUE. id contains the converted CLSID.
2595 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2598 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2599 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2602 /*************************************************************************
2605 * Unicode version of GUIDFromStringA.
2607 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2609 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2612 /*************************************************************************
2615 * Determine if the browser is integrated into the shell, and set a registry
2622 * 1, If the browser is not integrated.
2623 * 2, If the browser is integrated.
2626 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2627 * either set to TRUE, or removed depending on whether the browser is deemed
2630 DWORD WINAPI WhichPlatform()
2632 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2633 static DWORD dwState = 0;
2635 DWORD dwRet, dwData, dwSize;
2640 /* If shell32 exports DllGetVersion(), the browser is integrated */
2641 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2642 dwState = pDllGetVersion ? 2 : 1;
2644 /* Set or delete the key accordinly */
2645 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2646 "Software\\Microsoft\\Internet Explorer", 0,
2647 KEY_ALL_ACCESS, &hKey);
2650 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2651 (LPBYTE)&dwData, &dwSize);
2653 if (!dwRet && dwState == 1)
2655 /* Value exists but browser is not integrated */
2656 RegDeleteValueA(hKey, szIntegratedBrowser);
2658 else if (dwRet && dwState == 2)
2660 /* Browser is integrated but value does not exist */
2662 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2663 (LPBYTE)&dwData, sizeof(dwData));
2670 /*************************************************************************
2673 * Unicode version of SHCreateWorkerWindowA.
2675 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2676 DWORD dwStyle, HMENU hMenu, LONG z)
2678 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2682 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2683 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2685 /* If our OS is natively ASCII, use the ASCII version */
2686 if (!(GetVersion() & 0x80000000)) /* NT */
2687 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2689 /* Create Window class */
2691 wc.lpfnWndProc = DefWindowProcW;
2694 wc.hInstance = shlwapi_hInstance;
2695 wc.hIcon = (HICON)0;
2696 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2697 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2698 wc.lpszMenuName = NULL;
2699 wc.lpszClassName = szClass;
2701 SHRegisterClassW(&wc); /* Register class */
2703 /* FIXME: Set extra bits in dwExStyle */
2705 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2706 hWndParent, hMenu, shlwapi_hInstance, 0);
2709 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2712 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2717 /*************************************************************************
2720 * Get and show a context menu from a shell folder.
2723 * hWnd [I] Window displaying the shell folder
2724 * lpFolder [I] IShellFolder interface
2725 * lpApidl [I] Id for the particular folder desired
2729 * Failure: An HRESULT error code indicating the error.
2731 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2733 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2736 /*************************************************************************
2739 * _SHPackDispParamsV
2741 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2743 FIXME("%p %p %p %p\n",w,x,y,z);
2747 /*************************************************************************
2750 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2751 * function does...).
2753 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2755 FIXME("%p %p %p %p\n", w, x, y, z);
2759 /*************************************************************************
2762 * _IConnectionPoint_SimpleInvoke
2764 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2769 FIXME("(%p %p %p) stub\n",x,y,z);
2773 /*************************************************************************
2776 * Notify an IConnectionPoint object of changes.
2779 * lpCP [I] Object to notify
2784 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2785 * IConnectionPoint interface.
2787 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2789 IEnumConnections *lpEnum;
2790 HRESULT hRet = E_NOINTERFACE;
2792 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2794 /* Get an enumerator for the connections */
2796 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2798 if (SUCCEEDED(hRet))
2800 IPropertyNotifySink *lpSink;
2801 CONNECTDATA connData;
2804 /* Call OnChanged() for every notify sink in the connection point */
2805 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2807 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2810 IPropertyNotifySink_OnChanged(lpSink, dispID);
2811 IPropertyNotifySink_Release(lpSink);
2813 IUnknown_Release(connData.pUnk);
2816 IEnumConnections_Release(lpEnum);
2821 /*************************************************************************
2824 * Notify an IConnectionPointContainer object of changes.
2827 * lpUnknown [I] Object to notify
2832 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2833 * IConnectionPointContainer interface.
2835 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2837 IConnectionPointContainer* lpCPC = NULL;
2838 HRESULT hRet = E_NOINTERFACE;
2840 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2843 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2845 if (SUCCEEDED(hRet))
2847 IConnectionPoint* lpCP;
2849 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2850 IConnectionPointContainer_Release(lpCPC);
2852 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2853 IConnectionPoint_Release(lpCP);
2858 /*************************************************************************
2863 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2865 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2866 return pPlaySoundW(pszSound, hmod, fdwSound);
2869 /*************************************************************************
2872 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2875 * str1: "I" "I" pushl esp+0x20
2876 * str2: "U" "I" pushl 0x77c93810
2877 * (is "I" and "U" "integer" and "unsigned" ??)
2879 * pStr: "" "" pushl eax
2880 * some_len: 0x824 0x104 pushl 0x824
2881 * lpStr2: "%l" "%l" pushl esp+0xc
2883 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2884 * LocalAlloc(0x00, some_len) -> irrelevant_var
2885 * LocalAlloc(0x40, irrelevant_len) -> pStr
2886 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2887 * shlwapi.PathRemoveBlanksW(pStr);
2889 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2893 /*************************************************************************
2896 * Called by ICQ2000b install via SHDOCVW:
2897 * str1: "InternetShortcut"
2898 * x: some unknown pointer
2899 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2900 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2902 * In short: this one maybe creates a desktop link :-)
2904 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2906 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2910 /*************************************************************************
2915 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2916 LPCWSTR str, UINT count, const INT *lpDx)
2918 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2919 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2922 /*************************************************************************
2925 * See SHGetFileInfoW.
2927 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2928 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2930 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2931 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2934 /*************************************************************************
2937 * See DragQueryFileW.
2939 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2941 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2942 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2945 /*************************************************************************
2948 * See SHBrowseForFolderW.
2950 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2952 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2953 return pSHBrowseForFolderW(lpBi);
2956 /*************************************************************************
2959 * See SHGetPathFromIDListW.
2961 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2963 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2964 return pSHGetPathFromIDListW(pidl, pszPath);
2967 /*************************************************************************
2970 * See ShellExecuteExW.
2972 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2974 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2975 return pShellExecuteExW(lpExecInfo);
2978 /*************************************************************************
2981 * See SHFileOperationW.
2983 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2985 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2986 return pSHFileOperationW(lpFileOp);
2989 /*************************************************************************
2992 * See ExtractIconExW.
2994 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2995 HICON *phiconSmall, UINT nIcons)
2997 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2998 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3001 /*************************************************************************
3005 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3007 return InterlockedCompareExchange(dest, xchg, compare);
3010 /*************************************************************************
3013 DWORD WINAPI SHUnicodeToUnicode(
3018 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3019 lstrcpynW(dest, src, len);
3020 return lstrlenW(dest)+1;
3023 /*************************************************************************
3026 * See GetFileVersionInfoSizeW.
3028 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3034 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3035 ret = pGetFileVersionInfoSizeW(x, y);
3039 /*************************************************************************
3042 * See GetFileVersionInfoW.
3044 BOOL WINAPI GetFileVersionInfoWrapW(
3045 LPWSTR w, /* [in] path to dll */
3046 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3047 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3048 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3050 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3051 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3054 /*************************************************************************
3057 * See VerQueryValueW.
3059 WORD WINAPI VerQueryValueWrapW(
3060 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3061 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3062 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3063 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3065 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3066 return pVerQueryValueW((char*)w+0x208, x, y, z);
3069 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3070 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3071 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3073 /*************************************************************************
3076 * Change the modality of a shell object.
3079 * lpUnknown [I] Object to make modeless
3080 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3083 * Success: S_OK. The modality lpUnknown is changed.
3084 * Failure: An HRESULT error code indicating the error.
3087 * lpUnknown must support the IOleInPlaceFrame interface, the
3088 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3089 * or the IDocHostUIHandler interface, or this call fails.
3091 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3096 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3101 if (IsIface(IOleInPlaceFrame))
3102 EnableModeless(IOleInPlaceFrame);
3103 else if (IsIface(IShellBrowser))
3104 EnableModeless(IShellBrowser);
3106 /* FIXME: Wine has no headers for these objects yet */
3107 else if (IsIface(IInternetSecurityMgrSite))
3108 EnableModeless(IInternetSecurityMgrSite);
3109 else if (IsIface(IDocHostUIHandler))
3110 EnableModeless(IDocHostUIHandler);
3115 IUnknown_Release(lpObj);
3119 /*************************************************************************
3122 * See SHGetNewLinkInfoW.
3124 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3125 BOOL *pfMustCopy, UINT uFlags)
3127 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3128 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3131 /*************************************************************************
3134 * See SHDefExtractIconW.
3136 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3137 HICON* phiconSmall, UINT nIconSize)
3139 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3140 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3143 /*************************************************************************
3146 * Get and show a context menu from a shell folder.
3149 * hWnd [I] Window displaying the shell folder
3150 * lpFolder [I] IShellFolder interface
3151 * lpApidl [I] Id for the particular folder desired
3152 * bInvokeDefault [I] Whether to invoke the default menu item
3155 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3157 * Failure: An HRESULT error code indicating the error.
3159 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3161 IContextMenu *iContext;
3162 HRESULT hRet = E_FAIL;
3164 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3169 /* Get the context menu from the shell folder */
3170 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3171 &IID_IContextMenu, 0, (void**)&iContext);
3172 if (SUCCEEDED(hRet))
3175 if ((hMenu = CreatePopupMenu()))
3178 DWORD dwDefaultId = 0;
3180 /* Add the context menu entries to the popup */
3181 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3182 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3184 if (SUCCEEDED(hQuery))
3186 if (bInvokeDefault &&
3187 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3189 CMINVOKECOMMANDINFO cmIci;
3190 /* Invoke the default item */
3191 memset(&cmIci,0,sizeof(cmIci));
3192 cmIci.cbSize = sizeof(cmIci);
3193 cmIci.fMask = CMIC_MASK_ASYNCOK;
3195 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3196 cmIci.nShow = SW_SCROLLCHILDREN;
3198 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3203 IContextMenu_Release(iContext);
3208 /*************************************************************************
3213 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3216 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3217 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3220 /*************************************************************************
3223 LANGID WINAPI MLGetUILanguage()
3226 /* FIXME: This should be a forward in the .spec file to the win2k function
3227 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3229 return GetUserDefaultLangID();
3232 /*************************************************************************
3235 * Load a library from the directory of a particular process.
3238 * new_mod [I] Library name
3239 * inst_hwnd [I] Module whose directory is to be used
3240 * dwFlags [I] Flags controlling the load
3243 * Success: A handle to the loaded module
3244 * Failure: A NULL handle.
3246 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3248 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3250 * FIXME: Native shows calls to:
3251 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3253 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3254 * RegQueryValueExA for "LPKInstalled"
3256 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3257 * RegQueryValueExA for "ResourceLocale"
3259 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3260 * RegQueryValueExA for "Locale"
3262 * and then tests the Locale ("en" for me).
3264 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3266 CHAR mod_path[2*MAX_PATH];
3269 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3270 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
3271 ptr = strrchr(mod_path, '\\');
3273 strcpy(ptr+1, new_mod);
3274 TRACE("loading %s\n", debugstr_a(mod_path));
3275 return LoadLibraryA(mod_path);
3280 /*************************************************************************
3283 * Unicode version of MLLoadLibraryA.
3285 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3287 WCHAR mod_path[2*MAX_PATH];
3290 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3291 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
3292 ptr = strrchrW(mod_path, '\\');
3294 strcpyW(ptr+1, new_mod);
3295 TRACE("loading %s\n", debugstr_w(mod_path));
3296 return LoadLibraryW(mod_path);
3301 /*************************************************************************
3302 * ColorAdjustLuma [SHLWAPI.@]
3304 * Adjust the luminosity of a color
3307 * cRGB [I] RGB value to convert
3308 * dwLuma [I] Luma adjustment
3309 * bUnknown [I] Unknown
3312 * The adjusted RGB color.
3314 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3316 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3322 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3324 FIXME("Ignoring luma adjustment\n");
3326 /* FIXME: The ajdustment is not linear */
3328 cRGB = ColorHLSToRGB(wH, wL, wS);
3333 /*************************************************************************
3336 * See GetSaveFileNameW.
3338 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3340 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3341 return pGetSaveFileNameW(ofn);
3344 /*************************************************************************
3347 * See WNetRestoreConnectionW.
3349 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3351 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3352 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3355 /*************************************************************************
3358 * See WNetGetLastErrorW.
3360 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3361 LPWSTR lpNameBuf, DWORD nNameBufSize)
3363 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3364 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3367 /*************************************************************************
3370 * See PageSetupDlgW.
3372 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3374 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3375 return pPageSetupDlgW(pagedlg);
3378 /*************************************************************************
3383 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3385 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3386 return pPrintDlgW(printdlg);
3389 /*************************************************************************
3392 * See GetOpenFileNameW.
3394 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3396 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3397 return pGetOpenFileNameW(ofn);
3400 /* INTERNAL: Map from HLS color space to RGB */
3401 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3403 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3407 else if (wHue > 120)
3412 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3415 /* Convert to RGB and scale into RGB range (0..255) */
3416 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3418 /*************************************************************************
3419 * ColorHLSToRGB [SHLWAPI.@]
3421 * Convert from hls color space into an rgb COLORREF.
3424 * wHue [I] Hue amount
3425 * wLuminosity [I] Luminosity amount
3426 * wSaturation [I] Saturation amount
3429 * A COLORREF representing the converted color.
3432 * Input hls values are constrained to the range (0..240).
3434 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3440 WORD wGreen, wBlue, wMid1, wMid2;
3442 if (wLuminosity > 120)
3443 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3445 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3447 wMid1 = wLuminosity * 2 - wMid2;
3449 wRed = GET_RGB(wHue + 80);
3450 wGreen = GET_RGB(wHue);
3451 wBlue = GET_RGB(wHue - 80);
3453 return RGB(wRed, wGreen, wBlue);
3456 wRed = wLuminosity * 255 / 240;
3457 return RGB(wRed, wRed, wRed);
3460 /*************************************************************************
3463 * Get the current docking status of the system.
3466 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3469 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3472 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3474 HW_PROFILE_INFOA hwInfo;
3476 TRACE("(0x%08lx)\n", dwFlags);
3478 GetCurrentHwProfileA(&hwInfo);
3479 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3481 case DOCKINFO_DOCKED:
3482 case DOCKINFO_UNDOCKED:
3483 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3489 /*************************************************************************
3492 * Function seems to do FreeLibrary plus other things.
3494 * FIXME native shows the following calls:
3495 * RtlEnterCriticalSection
3497 * GetProcAddress(Comctl32??, 150L)
3499 * RtlLeaveCriticalSection
3500 * followed by the FreeLibrary.
3501 * The above code may be related to .377 above.
3503 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3505 FIXME("(%p) semi-stub\n", hModule);
3506 return FreeLibrary(hModule);
3509 /*************************************************************************
3511 * FIXME I have no idea what this function does or what its arguments are.
3513 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3515 FIXME("(%p) stub\n", hInst);
3520 /*************************************************************************
3523 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3525 FIXME("(%p,%p) stub\n", hInst, hHeap);
3526 return E_FAIL; /* This is what is used if shlwapi not loaded */
3529 /*************************************************************************
3532 DWORD WINAPI MLClearMLHInstance(DWORD x)
3534 FIXME("(0x%08lx)stub\n", x);
3538 /*************************************************************************
3541 * Convert an Unicode string CLSID into a CLSID.
3544 * idstr [I] string containing a CLSID in text form
3545 * id [O] CLSID extracted from the string
3548 * S_OK on success or E_INVALIDARG on failure
3551 * This is really CLSIDFromString() which is exported by ole32.dll,
3552 * however the native shlwapi.dll does *not* import ole32. Nor does
3553 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3554 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3555 * it returns an E_INVALIDARG error code on failure.
3556 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3557 * in "dlls/ole32/compobj.c".
3559 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3567 memset(id, 0, sizeof(CLSID));
3570 else { /* validate the CLSID string */
3572 if (strlenW(s) != 38)
3573 return E_INVALIDARG;
3575 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3576 return E_INVALIDARG;
3578 for (i=1; i<37; i++)
3580 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3582 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3583 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3584 ((s[i] >= L'A') && (s[i] <= L'F')))
3586 return E_INVALIDARG;
3590 TRACE("%s -> %p\n", debugstr_w(s), id);
3592 /* quick lookup table */
3593 memset(table, 0, 256*sizeof(WCHAR));
3595 for (i = 0; i < 10; i++) {
3598 for (i = 0; i < 6; i++) {
3599 table['A' + i] = i+10;
3600 table['a' + i] = i+10;
3603 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3607 s++; /* skip leading brace */
3608 for (i = 0; i < 4; i++) {
3609 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3615 for (i = 0; i < 2; i++) {
3616 p[1-i] = table[*s]<<4 | table[*(s+1)];
3622 for (i = 0; i < 2; i++) {
3623 p[1-i] = table[*s]<<4 | table[*(s+1)];
3629 /* these are just sequential bytes */
3630 for (i = 0; i < 2; i++) {
3631 *p++ = table[*s]<<4 | table[*(s+1)];
3636 for (i = 0; i < 6; i++) {
3637 *p++ = table[*s]<<4 | table[*(s+1)];
3644 /*************************************************************************
3647 * Determine if the OS supports a given feature.
3650 * dwFeature [I] Feature requested (undocumented)
3653 * TRUE If the feature is available.
3654 * FALSE If the feature is not available.
3656 DWORD WINAPI IsOS(DWORD feature)
3658 FIXME("(0x%08lx) stub\n", feature);
3664 /*************************************************************************
3665 * ColorRGBToHLS [SHLWAPI.@]
3667 * Convert an rgb COLORREF into the hls color space.
3670 * cRGB [I] Source rgb value
3671 * pwHue [O] Destination for converted hue
3672 * pwLuminance [O] Destination for converted luminance
3673 * pwSaturation [O] Destination for converted saturation
3676 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3680 * Output HLS values are constrained to the range (0..240).
3681 * For Achromatic conversions, Hue is set to 160.
3683 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3684 LPWORD pwLuminance, LPWORD pwSaturation)
3686 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3688 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3690 wR = GetRValue(cRGB);
3691 wG = GetGValue(cRGB);
3692 wB = GetBValue(cRGB);
3694 wMax = max(wR, max(wG, wB));
3695 wMin = min(wR, min(wG, wB));
3698 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3702 /* Achromatic case */
3704 /* Hue is now unrepresentable, but this is what native returns... */
3709 /* Chromatic case */
3710 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3713 if (wLuminosity <= 120)
3714 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3716 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3719 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3720 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3721 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3724 wHue = wBNorm - wGNorm;
3725 else if (wG == wMax)
3726 wHue = 80 + wRNorm - wBNorm;
3728 wHue = 160 + wGNorm - wRNorm;
3731 else if (wHue > 240)
3737 *pwLuminance = wLuminosity;
3739 *pwSaturation = wSaturation;
3742 /*************************************************************************
3743 * SHCreateShellPalette [SHLWAPI.@]
3745 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3748 return CreateHalftonePalette(hdc);
3751 /*************************************************************************
3752 * SHGetInverseCMAP (SHLWAPI.@)
3754 * Get an inverse color map table.
3757 * lpCmap [O] Destination for color map
3758 * dwSize [I] Size of memory pointed to by lpCmap
3762 * Failure: E_POINTER, If lpCmap is invalid.
3763 * E_INVALIDARG, If dwFlags is invalid
3764 * E_OUTOFMEMORY, If there is no memory available
3767 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3768 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3770 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3771 * this DLL's internal CMap.
3773 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3776 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3777 *dest = (DWORD)0xabba1249;
3780 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3784 /*************************************************************************
3785 * SHIsLowMemoryMachine [SHLWAPI.@]
3787 * Determine if the current computer has low memory.
3793 * TRUE if the users machine has 16 Megabytes of memory or less,
3796 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3798 FIXME("(0x%08lx) stub\n", x);
3802 /*************************************************************************
3803 * GetMenuPosFromID [SHLWAPI.@]
3805 * Return the position of a menu item from its Id.
3808 * hMenu [I] Menu containing the item
3809 * wID [I] Id of the menu item
3812 * Success: The index of the menu item in hMenu.
3813 * Failure: -1, If the item is not found.
3815 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3818 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3820 while (nIter < nCount)
3823 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3830 /*************************************************************************
3833 * Same as SHLWAPI.GetMenuPosFromID
3835 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
3837 return GetMenuPosFromID(hMenu, uID);
3841 /*************************************************************************
3844 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
3855 /*************************************************************************
3858 DWORD WINAPI SHGetAppCompatFlags()
3865 /*************************************************************************
3868 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
3869 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
3871 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
3874 /*************************************************************************
3875 * SHSkipJunction [SHLWAPI.@]
3877 * Determine if a bind context can be bound to an object
3880 * pbc [I] Bind context to check
3881 * pclsid [I] CLSID of object to be bound to
3884 * TRUE: If it is safe to bind
3885 * FALSE: If pbc is invalid or binding would not be safe
3888 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
3890 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
3891 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
3898 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
3902 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
3903 IsEqualGUID(pclsid, &clsid))
3906 IUnknown_Release(lpUnk);
3912 /***********************************************************************
3913 * SHGetShellKey (SHLWAPI.@)
3915 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
3917 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
3921 /***********************************************************************
3922 * SHQueueUserWorkItem (SHLWAPI.@)
3924 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
3926 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
3930 /***********************************************************************
3931 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
3933 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
3935 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
3938 IInputObjectSite * pIOS = NULL;
3939 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
3940 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
3946 /***********************************************************************
3947 * SHGetValueW (SHLWAPI.@)
3949 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
3951 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);