2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
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
33 #include "wine/unicode.h"
34 #include "wine/obj_base.h"
35 #include "wine/obj_inplace.h"
36 #include "wine/obj_serviceprovider.h"
40 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(shell);
46 extern HINSTANCE shlwapi_hInstance;
47 extern HMODULE SHLWAPI_hshell32;
48 extern HMODULE SHLWAPI_hwinmm;
49 extern HMODULE SHLWAPI_hcomdlg32;
50 extern HMODULE SHLWAPI_hcomctl32;
51 extern HMODULE SHLWAPI_hmpr;
52 extern HMODULE SHLWAPI_hmlang;
53 extern HMODULE SHLWAPI_hversion;
55 extern DWORD SHLWAPI_ThreadRef_index;
57 typedef HANDLE HSHARED; /* Shared memory */
59 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
60 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
61 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
62 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
64 /* The following schemes were identified in the native version of
65 * SHLWAPI.DLL version 5.50
68 URL_SCHEME_INVALID = -1,
69 URL_SCHEME_UNKNOWN = 0,
84 URL_SCHEME_JAVASCRIPT,
92 URL_SCHEME scheme_number;
96 static const SHL_2_inet_scheme shlwapi_schemes[] = {
97 {URL_SCHEME_FTP, "ftp"},
98 {URL_SCHEME_HTTP, "http"},
99 {URL_SCHEME_GOPHER, "gopher"},
100 {URL_SCHEME_MAILTO, "mailto"},
101 {URL_SCHEME_NEWS, "news"},
102 {URL_SCHEME_NNTP, "nntp"},
103 {URL_SCHEME_TELNET, "telnet"},
104 {URL_SCHEME_WAIS, "wais"},
105 {URL_SCHEME_FILE, "file"},
106 {URL_SCHEME_MK, "mk"},
107 {URL_SCHEME_HTTPS, "https"},
108 {URL_SCHEME_SHELL, "shell"},
109 {URL_SCHEME_SNEWS, "snews"},
110 {URL_SCHEME_LOCAL, "local"},
111 {URL_SCHEME_JAVASCRIPT, "javascript"},
112 {URL_SCHEME_VBSCRIPT, "vbscript"},
113 {URL_SCHEME_ABOUT, "about"},
114 {URL_SCHEME_RES, "res"},
118 /* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
119 static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
120 static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
121 static BOOL (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
122 static DWORD (WINAPI *pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
123 static UINT (WINAPI *pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
124 static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
125 static BOOL (WINAPI *pShellExecuteExW)(LPSHELLEXECUTEINFOW);
126 static HICON (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
127 static HICON (WINAPI *pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
128 static BOOL (WINAPI *pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
129 static DWORD (WINAPI *pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
130 static HICON (WINAPI *pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
131 static BOOL (WINAPI *pGetSaveFileNameW)(LPOPENFILENAMEW);
132 static DWORD (WINAPI *pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
133 static DWORD (WINAPI *pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
134 static BOOL (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW);
135 static BOOL (WINAPI *pPrintDlgW)(LPPRINTDLGW);
136 static BOOL (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW);
137 static DWORD (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
138 static BOOL (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
139 static WORD (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
140 static BOOL (WINAPI *pCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
143 NOTES: Most functions exported by ordinal seem to be superflous.
144 The reason for these functions to be there is to provide a wrapper
145 for unicode functions to provide these functions on systems without
146 unicode functions eg. win95/win98. Since we have such functions we just
147 call these. If running Wine with native DLL's, some late bound calls may
148 fail. However, its better to implement the functions in the forward DLL
149 and recommend the builtin rather than reimplementing the calls here!
152 /*************************************************************************
155 * Identifies the Internet "scheme" in the passed string. ASCII based.
156 * Also determines start and length of item after the ':'
158 DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
161 const SHL_2_inet_scheme *inet_pro;
163 if (y->size != 0x18) return E_INVALIDARG;
164 /* FIXME: leading white space generates error of 0x80041001 which
167 if (*x <= ' ') return 0x80041001;
182 /* check for no scheme in string start */
183 /* (apparently schemes *must* be larger than a single character) */
184 if ((*x == '\0') || (y->sizep1 <= 1)) {
189 /* found scheme, set length of remainder */
190 y->sizep2 = lstrlenA(y->ap2);
192 /* see if known scheme and return indicator number */
193 y->fcncde = URL_SCHEME_UNKNOWN;
194 inet_pro = shlwapi_schemes;
195 while (inet_pro->scheme_name) {
196 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
197 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
198 y->fcncde = inet_pro->scheme_number;
206 /*************************************************************************
209 * Identifies the Internet "scheme" in the passed string. UNICODE based.
210 * Also determines start and length of item after the ':'
212 DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
215 const SHL_2_inet_scheme *inet_pro;
219 if (y->size != 0x18) return E_INVALIDARG;
220 /* FIXME: leading white space generates error of 0x80041001 which
223 if (*x <= L' ') return 0x80041001;
238 /* check for no scheme in string start */
239 /* (apparently schemes *must* be larger than a single character) */
240 if ((*x == L'\0') || (y->sizep1 <= 1)) {
245 /* found scheme, set length of remainder */
246 y->sizep2 = lstrlenW(y->ap2);
248 /* see if known scheme and return indicator number */
249 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
250 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
251 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
252 y->fcncde = URL_SCHEME_UNKNOWN;
253 inet_pro = shlwapi_schemes;
254 while (inet_pro->scheme_name) {
255 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
256 min(len, lstrlenA(inet_pro->scheme_name)))) {
257 y->fcncde = inet_pro->scheme_number;
262 HeapFree(GetProcessHeap(), 0, cmpstr);
266 /*************************************************************************
269 * Determine if a file exists locally and is of an executable type.
272 * lpszFile [O] File to search for
273 * dwWhich [I] Type of executable to search for
276 * TRUE If the file was found. lpszFile contains the file name.
280 * lpszPath is modified in place and must be at least MAX_PATH in length.
281 * If the function returns FALSE, the path is modified to its orginal state.
282 * If the given path contains an extension or dwWhich is 0, executable
283 * extensions are not checked.
285 * Ordinals 3-6 are a classic case of MS exposing limited functionality to
286 * users (here through PathFindOnPath) and keeping advanced functionality for
287 * their own developers exclusive use. Monopoly, anyone?
289 BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
291 return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
294 /*************************************************************************
297 * Unicode version of SHLWAPI_3.
299 BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
301 return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
304 /*************************************************************************
307 * Search a range of paths for a specific type of executable.
310 * lpszFile [O] File to search for
311 * lppszOtherDirs [I] Other directories to look in
312 * dwWhich [I] Type of executable to search for
315 * Success: TRUE. The path to the executable is stored in sFile.
316 * Failure: FALSE. The path to the executable is unchanged.
318 BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
320 return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
323 /*************************************************************************
326 * Unicode version of SHLWAPI_5.
328 BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
330 return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
333 /*************************************************************************
334 * SHLWAPI_DupSharedHandle
336 * Internal implemetation of SHLWAPI_11.
339 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
340 DWORD dwSrcProcId, DWORD dwAccess,
344 DWORD dwMyProcId = GetCurrentProcessId();
345 HSHARED hRet = (HSHARED)NULL;
347 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
348 dwAccess, dwOptions);
350 /* Get dest process handle */
351 if (dwDstProcId == dwMyProcId)
352 hDst = GetCurrentProcess();
354 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
358 /* Get src process handle */
359 if (dwSrcProcId == dwMyProcId)
360 hSrc = GetCurrentProcess();
362 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
366 /* Make handle available to dest process */
367 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
368 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
369 hRet = (HSHARED)NULL;
371 if (dwSrcProcId != dwMyProcId)
375 if (dwDstProcId != dwMyProcId)
379 TRACE("Returning handle %p\n", (PVOID)hRet);
383 /*************************************************************************
386 * Create a block of sharable memory and initialise it with data.
389 * dwProcId [I] ID of process owning data
390 * lpvData [I] Pointer to data to write
391 * dwSize [I] Size of data
394 * Success: A shared memory handle
398 * Ordinals 7-11 provide a set of calls to create shared memory between a
399 * group of processes. The shared memory is treated opaquely in that its size
400 * is not exposed to clients who map it. This is accomplished by storing
401 * the size of the map as the first DWORD of mapped data, and then offsetting
402 * the view pointer returned by this size.
404 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
405 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
406 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
408 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
412 HSHARED hRet = (HSHARED)NULL;
414 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
416 /* Create file mapping of the correct length */
417 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
418 dwSize + sizeof(dwSize), NULL);
422 /* Get a view in our process address space */
423 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
427 /* Write size of data, followed by the data, to the view */
428 *((DWORD*)pMapped) = dwSize;
430 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
432 /* Release view. All further views mapped will be opaque */
433 UnmapViewOfFile(pMapped);
434 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
435 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
436 DUPLICATE_SAME_ACCESS);
443 /*************************************************************************
446 * Get a pointer to a block of shared memory from a shared memory handle.
449 * hShared [I] Shared memory handle
450 * dwProcId [I] ID of process owning hShared
453 * Success: A pointer to the shared memory
459 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
464 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
466 /* Get handle to shared memory for current process */
467 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
468 FILE_MAP_ALL_ACCESS, 0);
470 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
474 return (char *) pMapped + sizeof(DWORD); /* Hide size */
478 /*************************************************************************
481 * Release a pointer to a block of shared memory.
484 * lpView [I] Shared memory pointer
493 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
495 TRACE("(%p)\n", lpView);
496 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
499 /*************************************************************************
502 * Destroy a block of sharable memory.
505 * hShared [I] Shared memory handle
506 * dwProcId [I] ID of process owning hShared
515 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
519 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
521 /* Get a copy of the handle for our process, closing the source handle */
522 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
523 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
524 /* Close local copy */
525 return CloseHandle((HANDLE)hClose);
528 /*************************************************************************
531 * Copy a sharable memory handle from one process to another.
534 * hShared [I] Shared memory handle to duplicate
535 * dwDstProcId [I] ID of the process wanting the duplicated handle
536 * dwSrcProcId [I] ID of the process owning hShared
537 * dwAccess [I] Desired DuplicateHandle access
538 * dwOptions [I] Desired DuplicateHandle options
541 * Success: A handle suitable for use by the dwDstProcId process.
542 * Failure: A NULL handle.
547 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
548 DWORD dwAccess, DWORD dwOptions)
552 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
553 dwAccess, dwOptions);
557 /*************************************************************************
559 * (Used by IE4 during startup)
561 HRESULT WINAPI SHLWAPI_13 (
565 FIXME("(%p %p)stub\n",w,x);
568 /* pseudo code extracted from relay trace */
569 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Accepted Documents", &newkey);
574 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
578 b1 = LocalAlloc(0x40, size);
582 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
583 RegisterClipBoardFormatA(a4);
586 hmod1 = GetModuleHandleA("URLMON.DLL");
587 proc = GetProcAddress(hmod1, "CreateFormatEnumerator");
588 HeapAlloc(??, 0, 0x14);
589 HeapAlloc(??, 0, 0x50);
590 LocalAlloc(0x40, 0x78);
591 /* FIXME: bad string below */
592 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
593 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
596 IsBadReadPtr(c1 = 0x403fd210,4);
597 InterlockedIncrement(c1+4);
600 IsBadReadPtr(c1 = 0x403fd210,4);
601 InterlockedIncrement(c1+4);
603 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
604 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
605 hmod1 = GetModuleHandleA("URLMON.DLL");
606 proc = GetProcAddress(hmod1, "RegisterFormatEnumerator");
607 /* 0x1a40c88c is in URLMON.DLL just before above proc
608 * content is L"_EnumFORMATETC_"
611 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
614 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
615 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
616 InterlockedIncrement(d2+4);
617 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
618 InterlockedDecrement(d2+4);
619 IsBadReadPtr(c1,00000004);
620 InterlockedDecrement(c1+4);
621 IsBadReadPtr(c1,00000004);
622 InterlockedDecrement(c1+4);
627 /*************************************************************************
631 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
634 HRESULT WINAPI SHLWAPI_14 (
639 DWORD mystrlen, mytype;
643 mystrlen = (*buflen > 6) ? *buflen : 6;
644 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
645 HEAP_ZERO_MEMORY, mystrlen);
646 RegOpenKeyA(HKEY_CURRENT_USER,
647 "Software\\Microsoft\\Internet Explorer\\International",
649 if (RegQueryValueExA(mykey, "AcceptLanguage",
650 0, &mytype, mystr, &mystrlen)) {
651 /* Did not find value */
652 mylcid = GetUserDefaultLCID();
653 /* somehow the mylcid translates into "en-us"
654 * this is similar to "LOCALE_SABBREVLANGNAME"
655 * which could be gotten via GetLocaleInfo.
656 * The only problem is LOCALE_SABBREVLANGUAGE" is
657 * a 3 char string (first 2 are country code and third is
658 * letter for "sublanguage", which does not come close to
661 lstrcpyA(mystr, "en-us");
662 mystrlen = lstrlenA(mystr);
665 /* handle returned string */
666 FIXME("missing code\n");
668 if (mystrlen > *buflen)
669 lstrcpynA(langbuf, mystr, *buflen);
671 lstrcpyA(langbuf, mystr);
672 *buflen = lstrlenA(langbuf);
675 HeapFree(GetProcessHeap(), 0, mystr);
676 TRACE("language is %s\n", debugstr_a(langbuf));
680 /*************************************************************************
684 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
687 HRESULT WINAPI SHLWAPI_15 (
692 DWORD mystrlen, mytype;
696 mystrlen = (*buflen > 6) ? *buflen : 6;
697 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
698 HEAP_ZERO_MEMORY, mystrlen);
699 RegOpenKeyA(HKEY_CURRENT_USER,
700 "Software\\Microsoft\\Internet Explorer\\International",
702 if (RegQueryValueExA(mykey, "AcceptLanguage",
703 0, &mytype, mystr, &mystrlen)) {
704 /* Did not find value */
705 mylcid = GetUserDefaultLCID();
706 /* somehow the mylcid translates into "en-us"
707 * this is similar to "LOCALE_SABBREVLANGNAME"
708 * which could be gotten via GetLocaleInfo.
709 * The only problem is LOCALE_SABBREVLANGUAGE" is
710 * a 3 char string (first 2 are country code and third is
711 * letter for "sublanguage", which does not come close to
714 lstrcpyA(mystr, "en-us");
715 mystrlen = lstrlenA(mystr);
718 /* handle returned string */
719 FIXME("missing code\n");
722 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
723 HeapFree(GetProcessHeap(), 0, mystr);
724 TRACE("language is %s\n", debugstr_w(langbuf));
728 /*************************************************************************
732 * converts a guid to a string
733 * returns strlen(str)
735 DWORD WINAPI SHLWAPI_23 (
736 REFGUID guid, /* [in] clsid */
737 LPSTR str, /* [out] buffer */
738 INT cmax) /* [in] size of buffer */
742 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
743 guid->Data1, guid->Data2, guid->Data3,
744 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
745 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
746 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
747 if (strlen(xguid)>=cmax) return 0;
749 return strlen(xguid) + 1;
752 /*************************************************************************
756 * converts a guid to a string
757 * returns strlen(str)
759 DWORD WINAPI SHLWAPI_24 (
760 REFGUID guid, /* [in] clsid */
761 LPWSTR str, /* [out] buffer */
762 INT cmax) /* [in] size of buffer */
766 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
767 guid->Data1, guid->Data2, guid->Data3,
768 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
769 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
770 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
773 /*************************************************************************
776 * Seems to be iswalpha
778 BOOL WINAPI SHLWAPI_25(WCHAR wc)
780 return (get_char_typeW(wc) & C1_ALPHA) != 0;
783 /*************************************************************************
786 * Seems to be iswupper
788 BOOL WINAPI SHLWAPI_26(WCHAR wc)
790 return (get_char_typeW(wc) & C1_UPPER) != 0;
793 /*************************************************************************
796 * Seems to be iswlower
798 BOOL WINAPI SHLWAPI_27(WCHAR wc)
800 return (get_char_typeW(wc) & C1_LOWER) != 0;
803 /*************************************************************************
806 * Seems to be iswalnum
808 BOOL WINAPI SHLWAPI_28(WCHAR wc)
810 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
813 /*************************************************************************
816 * Seems to be iswspace
818 BOOL WINAPI SHLWAPI_29(WCHAR wc)
820 return (get_char_typeW(wc) & C1_SPACE) != 0;
823 /*************************************************************************
826 * Seems to be iswblank
828 BOOL WINAPI SHLWAPI_30(WCHAR wc)
830 return (get_char_typeW(wc) & C1_BLANK) != 0;
833 /*************************************************************************
836 * Seems to be iswpunct
838 BOOL WINAPI SHLWAPI_31(WCHAR wc)
840 return (get_char_typeW(wc) & C1_PUNCT) != 0;
843 /*************************************************************************
846 * Seems to be iswcntrl
848 BOOL WINAPI SHLWAPI_32(WCHAR wc)
850 return (get_char_typeW(wc) & C1_CNTRL) != 0;
853 /*************************************************************************
856 * Seems to be iswdigit
858 BOOL WINAPI SHLWAPI_33(WCHAR wc)
860 return (get_char_typeW(wc) & C1_DIGIT) != 0;
863 /*************************************************************************
866 * Seems to be iswxdigit
868 BOOL WINAPI SHLWAPI_34(WCHAR wc)
870 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
873 /*************************************************************************
877 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
879 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
883 /*************************************************************************
887 BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
889 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
890 h1, ui2, h3, debugstr_w(p4));
891 return AppendMenuW(h1, ui2, h3, p4);
894 /*************************************************************************
897 * Get the text from a given dialog item.
899 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
901 HWND hItem = GetDlgItem(hWnd, nItem);
904 return GetWindowTextW(hItem, lpsDest, nDestLen);
906 *lpsDest = (WCHAR)'\0';
910 /*************************************************************************
912 * Function: Compare two ASCII strings for "len" bytes.
913 * Returns: *str1-*str2 (case sensitive)
915 DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
917 return strncmp( str1, str2, len );
920 /*************************************************************************
923 * Function: Compare two WIDE strings for "len" bytes.
924 * Returns: *str1-*str2 (case sensitive)
926 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
928 return strncmpW( str1, str2, len );
931 /*************************************************************************
933 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
934 * Returns: *str1-*str2 (case insensitive)
936 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
938 return strncasecmp( str1, str2, len );
941 /*************************************************************************
944 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
945 * Returns: *str1-*str2 (case insensitive)
947 DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
949 return strncmpiW( str1, str2, len );
952 /*************************************************************************
955 * Case sensitive string compare (ASCII). Does not SetLastError().
957 DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
959 return strcmp(str1, str2);
962 /*************************************************************************
965 * Case sensitive string compare. Does not SetLastError().
967 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
969 return strcmpW( str1, str2 );
972 /*************************************************************************
975 * Case insensitive string compare. Does not SetLastError(). ??
977 DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
979 return strcmpiW( str1, str2 );
982 /*************************************************************************
985 * Ensure a multibyte character string doesn't end in a hanging lead byte.
987 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
991 LPSTR lastByte = lpStr + size - 1;
993 while(lpStr < lastByte)
994 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
996 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1006 /*************************************************************************
1009 * _IUnknown_QueryStatus
1011 DWORD WINAPI SHLWAPI_163 (
1018 TRACE("(%p %p %p %p %p) stub\n", v,w,x,y,z);
1023 /*************************************************************************
1028 DWORD WINAPI SHLWAPI_164 (
1036 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1037 return 0x80004002; /* E_NOINTERFACE */
1040 /*************************************************************************
1043 * SetWindowLongA with mask.
1045 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1047 LONG ret = GetWindowLongA(hwnd, offset);
1048 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1050 if (newFlags != ret)
1051 ret = SetWindowLongA(hwnd, offset, newFlags);
1055 /*************************************************************************
1060 DWORD WINAPI SHLWAPI_167(HWND hWnd, LPVOID y)
1062 FIXME("0x%08x %p\n", hWnd,y);
1066 /*************************************************************************
1069 * _IUnknown_AtomicRelease
1071 * Do IUnknown::Release on passed object.
1073 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1077 TRACE("(%p)\n",lpUnknown);
1078 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1081 TRACE("doing Release\n");
1082 return IUnknown_Release(temp);
1085 /*************************************************************************
1088 * Skip URL '//' sequence.
1090 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1092 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1097 /*************************************************************************
1102 BOOL WINAPI SHLWAPI_171(LPVOID x, LPVOID y)
1104 FIXME("%p %p\n",x,y);
1108 /*************************************************************************
1111 * _IUnknown_GetWindow
1113 * Get window handle of OLE object
1115 DWORD WINAPI SHLWAPI_172 (
1116 IUnknown *pUnk, /* [in] OLE object interface */
1117 LPHWND hWnd) /* [out] location to put window handle */
1120 IOleWindow *pOleWnd;
1122 TRACE("(%p %p)\n",pUnk,hWnd);
1125 ret = IUnknown_QueryInterface(pUnk, &IID_IOleWindow,(LPVOID *)&pOleWnd);
1126 if (SUCCEEDED(ret)) {
1127 ret = IOleWindow_GetWindow(pOleWnd, hWnd);
1128 IOleWindow_Release(pOleWnd);
1129 TRACE("result hwnd=%08x\n", *hWnd);
1136 /*************************************************************************
1139 * Seems to do call either IObjectWithSite::SetSite or
1140 * IPersistMoniker::GetClassID. But since we do not implement either
1141 * of those classes in our headers, we will fake it out.
1143 DWORD WINAPI SHLWAPI_174(
1144 IUnknown *p1, /* [in] OLE object */
1145 LPVOID *p2) /* [out] ptr to result of either GetClassID
1150 if (!p1) return E_FAIL;
1152 /* see if SetSite interface exists for IObjectWithSite object */
1153 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1154 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1157 /* see if GetClassId interface exists for IPersistMoniker object */
1158 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1159 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1160 if (ret) return ret;
1162 /* fake a GetClassId call */
1163 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1164 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1166 IUnknown_Release((IUnknown *)aa);
1169 /* fake a SetSite call */
1170 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1171 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1173 IUnknown_Release((IUnknown *)p1);
1178 /*************************************************************************
1182 * Param1 can be an IShellFolder Object
1184 HRESULT WINAPI SHLWAPI_175 (LPVOID x, LPVOID y)
1186 FIXME("(%p %p) stub\n", x,y);
1189 /*************************************************************************
1192 * _IUnknown_QueryService
1194 * Function appears to be interface to IServiceProvider::QueryService
1197 * returns E_NOINTERFACE
1199 * S_OK if _219 called successfully
1201 DWORD WINAPI SHLWAPI_176 (
1202 IUnknown* unk, /* [in] object to give Service Provider */
1203 REFGUID sid, /* [in] Service ID */
1204 REFIID riid, /* [in] Function requested */
1205 LPVOID *ppv) /* [out] place to save interface pointer */
1207 HRESULT ret = E_FAIL;
1208 IServiceProvider *pSP;
1211 TRACE("%p, %s, %s, %p\n", unk, debugstr_guid(sid), debugstr_guid(riid), ppv);
1214 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider,(LPVOID*) &pSP);
1215 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, pSP);
1216 if (SUCCEEDED(ret)) {
1217 ret = IServiceProvider_QueryService(pSP, sid, riid, (LPVOID*)ppv);
1218 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, *ppv);
1219 IServiceProvider_Release(pSP);
1225 /*************************************************************************
1228 * Enable or disable a menu item.
1230 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1232 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1235 /*************************************************************************
1238 * Register a window class if it isn't already.
1240 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1243 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1245 return (DWORD)RegisterClassA(wndclass);
1248 /*************************************************************************
1251 * _IUnknown_OnFocusOCS
1253 DWORD WINAPI SHLWAPI_189(LPVOID x, LPVOID y)
1255 FIXME("%p %p\n", x, y);
1259 /*************************************************************************
1262 DWORD WINAPI SHLWAPI_193 ()
1270 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1275 /*************************************************************************
1278 * Copy interface pointer
1280 DWORD WINAPI SHLWAPI_199 (
1281 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1282 IUnknown *src) /* [in] interface pointer */
1284 TRACE("(%p %p)\n",dest,src);
1287 IUnknown_Release(*dest);
1289 IUnknown_AddRef(src);
1296 /*************************************************************************
1299 * Some sort of memory management process - associated with _210
1301 DWORD WINAPI SHLWAPI_208 (
1308 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1313 /*************************************************************************
1316 * Some sort of memory management process - associated with _208
1318 DWORD WINAPI SHLWAPI_209 (
1321 FIXME("(%p) stub\n",
1326 /*************************************************************************
1329 * Some sort of memory management process - associated with _208
1331 DWORD WINAPI SHLWAPI_210 (
1336 FIXME("(%p 0x%08lx %p) stub\n",
1341 /*************************************************************************
1344 DWORD WINAPI SHLWAPI_211 (
1348 FIXME("(%p 0x%08lx) stub\n",
1353 /*************************************************************************
1359 DWORD WINAPI SHLWAPI_215 (
1366 len_a = lstrlenA(lpStrSrc);
1367 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1368 TRACE("%s %s %d, ret=%d\n",
1369 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1373 /*************************************************************************
1376 * WideCharToMultiByte with multi language support.
1378 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1379 LPINT lpnMultiCharCount)
1381 WCHAR emptyW[] = { '\0' };
1385 if (!lpDstStr || !lpnMultiCharCount)
1393 len = strlenW(lpSrcStr) + 1;
1398 CodePage = CP_UTF8; /* Fall through... */
1399 case 0x0000C350: /* FIXME: CP_ #define */
1404 INT nWideCharCount = len - 1;
1406 GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
1407 if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1411 if (nWideCharCount < len - 1)
1413 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1417 *lpnMultiCharCount = 0;
1419 if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1421 SHLWAPI_162 (mem, *lpnMultiCharCount);
1422 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1423 return *lpnMultiCharCount + 1;
1425 HeapFree(GetProcessHeap(), 0, mem);
1426 return *lpnMultiCharCount;
1428 lpDstStr[*lpnMultiCharCount] = '\0';
1429 return *lpnMultiCharCount;
1436 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1437 *lpnMultiCharCount, NULL, NULL);
1439 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1441 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1444 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1447 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1448 reqLen, NULL, NULL);
1450 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1453 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1455 HeapFree(GetProcessHeap(), 0, mem);
1462 /*************************************************************************
1465 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1466 * --> Crash. Something wrong here.
1468 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1470 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1472 INT myint = MultiCharCount;
1474 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1477 /*************************************************************************
1480 * Seems to be "super" QueryInterface. Supplied with a table of interfaces
1481 * and an array of IIDs and offsets into the table.
1484 * error codes: E_POINTER, E_NOINTERFACE
1491 HRESULT WINAPI SHLWAPI_219 (
1492 LPVOID w, /* [in] table of interfaces */
1493 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1494 REFIID riid, /* [in] REFIID to get interface for */
1495 LPVOID *ppv) /* [out] location to get interface pointer */
1499 IFACE_INDEX_TBL *xmove;
1501 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
1504 while (xmove->refid) {
1505 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
1506 if (IsEqualIID(riid, xmove->refid)) {
1507 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1508 TRACE("matched, returning (%p)\n", a_vtbl);
1509 *ppv = (LPVOID)a_vtbl;
1510 IUnknown_AddRef(a_vtbl);
1516 if (IsEqualIID(riid, &IID_IUnknown)) {
1517 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1518 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1519 *ppv = (LPVOID)a_vtbl;
1520 IUnknown_AddRef(a_vtbl);
1524 ret = E_NOINTERFACE;
1528 TRACE("-- 0x%08lx\n", ret);
1532 /*************************************************************************
1535 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1539 CHAR value[MAX_PATH], string[MAX_PATH];
1541 strcpy(string, "CLSID\\");
1542 strcat(string, debugstr_guid(lpUnknown));
1543 strcat(string, "\\InProcServer32");
1546 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1547 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1548 RegCloseKey(newkey);
1549 return LoadLibraryExA(value, 0, 0);
1552 /*************************************************************************
1555 * Unicode version of SHLWAPI_183.
1557 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1561 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1563 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1565 return RegisterClassW(lpWndClass);
1568 /*************************************************************************
1571 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1573 FIXME("(0x%08x %p 0x%08lx) stub\n",
1574 hInstance, p2, dw3);
1577 /* pseudo code from relay trace */
1578 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1579 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1580 /* above pair repeated for:
1581 TridentThicketUrlDlClass
1590 /*************************************************************************
1593 * Calls ASCII or Unicode WindowProc for the given window.
1595 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1597 if (IsWindowUnicode(hWnd))
1598 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1599 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1602 /*************************************************************************
1606 DWORD WINAPI SHLWAPI_241 ()
1609 return /* 0xabba1243 */ 0;
1612 /*************************************************************************
1615 * native does at least approximately:
1616 * strcpyW(newstr, x);
1617 * strcatW(newstr, "\\Restrictions");
1618 * if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1622 DWORD WINAPI SHLWAPI_266 (
1624 LPVOID x, /* [in] partial registry key */
1628 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1629 return /* 0xabba1248 */ 0;
1632 /*************************************************************************
1636 * This QueryInterface asks the inner object for a interface. In case
1637 * of aggregation this request would be forwarded by the inner to the
1638 * outer object. This function asks the inner object directly for the
1639 * interface circumventing the forwarding to the outer object.
1641 HRESULT WINAPI SHLWAPI_267 (
1642 IUnknown * pUnk, /* [in] outer object */
1643 IUnknown * pInner, /* [in] inner object */
1647 HRESULT hret = E_NOINTERFACE;
1648 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
1651 if(pUnk && pInner) {
1652 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
1653 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
1655 TRACE("-- 0x%08lx\n", hret);
1659 /*************************************************************************
1662 * pInner is returned by SHLWAPI_267 as ppv
1664 DWORD WINAPI SHLWAPI_268 (
1670 TRACE("(pUnk=%p pInner=%p)\n",pUnk,pInner);
1672 IUnknown_AddRef(pUnk);
1673 if (pInner && *pInner) {
1674 ret = IUnknown_Release(*pInner);
1677 TRACE("-- count=%lu\n",ret);
1681 /*************************************************************************
1684 * on first call process does following: other calls just returns 2
1685 * instance = LoadLibraryA("SHELL32.DLL");
1686 * func = GetProcAddress(instance, "DllGetVersion");
1687 * ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
1688 * ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
1689 * RegCloseKey(newkey);
1690 * FreeLibrary(instance);
1693 DWORD WINAPI SHLWAPI_276 ()
1696 return /* 0xabba1244 */ 2;
1699 /*************************************************************************
1703 HWND WINAPI SHLWAPI_278 (
1714 char * clsname = "WorkerA";
1716 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1717 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1719 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1721 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1723 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1724 wndclass.lpfnWndProc = DefWindowProcW;
1725 wndclass.cbWndExtra = 4;
1726 wndclass.hInstance = shlwapi_hInstance;
1727 wndclass.hCursor = hCursor;
1728 wndclass.hbrBackground = COLOR_BTNSHADOW;
1729 wndclass.lpszMenuName = NULL;
1730 wndclass.lpszClassName = clsname;
1731 RegisterClassA (&wndclass);
1733 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1734 hMenu,shlwapi_hInstance,0);
1735 SetWindowLongA(hwnd, 0, z);
1736 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1740 /*************************************************************************
1743 * _SHPackDispParamsV
1745 HRESULT WINAPI SHLWAPI_281(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
1747 FIXME("%p %p %p %p\n",w,x,y,z);
1751 /*************************************************************************
1754 * _IConnectionPoint_SimpleInvoke
1756 DWORD WINAPI SHLWAPI_284 (
1761 TRACE("(%p %p %p) stub\n",x,y,z);
1765 /*************************************************************************
1768 * _IUnknown_CPContainerOnChanged
1770 HRESULT WINAPI SHLWAPI_287(LPVOID x, LPVOID y)
1772 FIXME("%p %p\n", x,y);
1776 /*************************************************************************
1779 * Late bound call to winmm.PlaySoundW
1781 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1783 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
1784 return pPlaySoundW(pszSound, hmod, fdwSound);
1787 /*************************************************************************
1790 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1793 * str1: "I" "I" pushl esp+0x20
1794 * str2: "U" "I" pushl 0x77c93810
1795 * (is "I" and "U" "integer" and "unsigned" ??)
1797 * pStr: "" "" pushl eax
1798 * some_len: 0x824 0x104 pushl 0x824
1799 * lpStr2: "%l" "%l" pushl esp+0xc
1801 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1802 * LocalAlloc(0x00, some_len) -> irrelevant_var
1803 * LocalAlloc(0x40, irrelevant_len) -> pStr
1804 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1805 * shlwapi.PathRemoveBlanksW(pStr);
1807 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1811 /*************************************************************************
1814 * Called by ICQ2000b install via SHDOCVW:
1815 * str1: "InternetShortcut"
1816 * x: some unknown pointer
1817 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
1818 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
1820 * In short: this one maybe creates a desktop link :-)
1822 BOOL WINAPI SHLWAPI_295(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
1824 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
1828 /*************************************************************************
1831 * Late bound call to comctl32.417
1833 BOOL WINAPI SHLWAPI_299(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
1834 LPCWSTR str, UINT count, const INT *lpDx)
1836 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
1837 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
1840 /*************************************************************************
1843 * Late bound call to shell32.SHGetFileInfoW
1845 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1846 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1848 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
1849 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1852 /*************************************************************************
1855 * Late bound call to shell32.DragQueryFileW
1857 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1859 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
1860 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
1863 /*************************************************************************
1866 * Late bound call to shell32.SHBrowseForFolderW
1868 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1870 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
1871 return pSHBrowseForFolderW(lpBi);
1874 /*************************************************************************
1877 * Late bound call to shell32.SHGetPathFromIDListW
1879 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1881 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
1882 return pSHGetPathFromIDListW(pidl, pszPath);
1885 /*************************************************************************
1888 * Late bound call to shell32.ShellExecuteExW
1890 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1892 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
1893 return pShellExecuteExW(lpExecInfo);
1896 /*************************************************************************
1899 * Late bound call to shell32.SHFileOperationW.
1901 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1903 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
1904 return pSHFileOperationW(lpFileOp);
1907 /*************************************************************************
1910 * Late bound call to shell32.ExtractIconExW.
1912 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1913 HICON *phiconSmall, UINT nIcons)
1915 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", (HICON)0);
1916 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1919 /*************************************************************************
1923 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
1925 return InterlockedCompareExchange(dest, xchg, compare);
1928 /*************************************************************************
1931 DWORD WINAPI SHLWAPI_346 (
1936 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1937 lstrcpynW(dest, src, len);
1938 return lstrlenW(dest)+1;
1941 /*************************************************************************
1944 * seems to be late bound call to GetFileVersionInfoSizeW
1946 DWORD WINAPI SHLWAPI_350 (
1952 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
1953 ret = pGetFileVersionInfoSizeW(x, y);
1957 /*************************************************************************
1960 * seems to be late bound call to GetFileVersionInfoW
1962 BOOL WINAPI SHLWAPI_351 (
1963 LPWSTR w, /* [in] path to dll */
1964 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1965 DWORD y, /* [in] return value from .350 - assume length */
1966 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1968 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
1969 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
1972 /*************************************************************************
1975 * seems to be late bound call to VerQueryValueW
1977 WORD WINAPI SHLWAPI_352 (
1978 LPVOID w, /* [in] buffer from _351 */
1979 LPWSTR x, /* [in] value to retrieve -
1980 converted and passed to VerQueryValueA as #2 */
1981 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1982 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1984 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
1985 return pVerQueryValueW((char*)w+0x208, x, y, z);
1988 /*************************************************************************
1991 * Late bound call to shell32.SHGetNewLinkInfoW
1993 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
1994 BOOL *pfMustCopy, UINT uFlags)
1996 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
1997 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
2000 /*************************************************************************
2003 * Late bound call to shell32.SHDefExtractIconW
2005 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2006 LPVOID arg5, LPVOID arg6)
2008 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
2009 return pSHDefExtractIconW(arg1, arg2, arg3, arg4, arg5, arg6);
2012 /*************************************************************************
2015 * Wrapper for lstrcpynA with src and dst swapped.
2017 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
2019 lstrcpynA(dst, src, n);
2023 /*************************************************************************
2026 * Late bound call to shell32.ExtractIconW
2028 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
2031 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", (HICON)0);
2032 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
2035 /*************************************************************************
2038 LANGID WINAPI SHLWAPI_376 ()
2041 /* FIXME: This should be a forward in the .spec file to the win2k function
2042 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2044 return GetUserDefaultLangID();
2047 /*************************************************************************
2050 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2052 * FIXME: Native shows calls to:
2053 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2055 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2056 * RegQueryValueExA for "LPKInstalled"
2058 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2059 * RegQueryValueExA for "ResourceLocale"
2061 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2062 * RegQueryValueExA for "Locale"
2064 * and then tests the Locale ("en" for me).
2066 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2068 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
2070 CHAR mod_path[2*MAX_PATH];
2073 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
2074 ptr = strrchr(mod_path, '\\');
2076 strcpy(ptr+1, new_mod);
2077 TRACE("loading %s\n", debugstr_a(mod_path));
2078 return (DWORD)LoadLibraryA(mod_path);
2083 /*************************************************************************
2086 * This is Unicode version of .377
2088 DWORD WINAPI SHLWAPI_378 (
2089 LPCWSTR new_mod, /* [in] new module name */
2090 HMODULE inst_hwnd, /* [in] calling module handle */
2091 LPVOID z) /* [???] 4 */
2093 WCHAR mod_path[2*MAX_PATH];
2096 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2097 ptr = strrchrW(mod_path, '\\');
2099 strcpyW(ptr+1, new_mod);
2100 TRACE("loading %s\n", debugstr_w(mod_path));
2101 return (DWORD)LoadLibraryW(mod_path);
2106 /*************************************************************************
2109 * Late bound call to comdlg32.GetSaveFileNameW
2111 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2113 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
2114 return pGetSaveFileNameW(ofn);
2117 /*************************************************************************
2120 * Late bound call to mpr.WNetRestoreConnectionW
2122 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2124 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
2125 return pWNetRestoreConnectionW(arg1, arg2);
2128 /*************************************************************************
2131 * Late bound call to mpr.WNetGetLastErrorW
2133 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2136 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
2137 return pWNetGetLastErrorW(arg1, arg2, arg3, arg4, arg5);
2140 /*************************************************************************
2143 * Late bound call to comdlg32.PageSetupDlgW
2145 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2147 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
2148 return pPageSetupDlgW(pagedlg);
2151 /*************************************************************************
2154 * Late bound call to comdlg32.PrintDlgW
2156 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2158 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
2159 return pPrintDlgW(printdlg);
2162 /*************************************************************************
2165 * Late bound call to comdlg32.GetOpenFileNameW
2167 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2169 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
2170 return pGetOpenFileNameW(ofn);
2173 /* INTERNAL: Map from HLS color space to RGB */
2174 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2176 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2180 else if (wHue > 120)
2185 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2188 /* Convert to RGB and scale into RGB range (0..255) */
2189 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2191 /*************************************************************************
2192 * ColorHLSToRGB [SHLWAPI.404]
2194 * Convert from HLS color space into an RGB COLORREF.
2197 * Input HLS values are constrained to the range (0..240).
2199 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2205 WORD wGreen, wBlue, wMid1, wMid2;
2207 if (wLuminosity > 120)
2208 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2210 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2212 wMid1 = wLuminosity * 2 - wMid2;
2214 wRed = GET_RGB(wHue + 80);
2215 wGreen = GET_RGB(wHue);
2216 wBlue = GET_RGB(wHue - 80);
2218 return RGB(wRed, wGreen, wBlue);
2221 wRed = wLuminosity * 255 / 240;
2222 return RGB(wRed, wRed, wRed);
2225 /*************************************************************************
2228 * Function unknown seems to always to return 0
2231 DWORD WINAPI SHLWAPI_413 (DWORD x)
2233 FIXME("(0x%08lx)stub\n", x);
2237 /*************************************************************************
2240 * Function seems to do FreeLibrary plus other things.
2242 * FIXME native shows the following calls:
2243 * RtlEnterCriticalSection
2245 * GetProcAddress(Comctl32??, 150L)
2247 * RtlLeaveCriticalSection
2248 * followed by the FreeLibrary.
2249 * The above code may be related to .377 above.
2251 BOOL WINAPI SHLWAPI_418 (HMODULE x)
2253 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2254 return FreeLibrary(x);
2257 /*************************************************************************
2260 DWORD WINAPI SHLWAPI_430 (HINSTANCE hModule, HANDLE heap)
2262 FIXME("(0x%08lx 0x%08lx) stub\n", (DWORD)hModule, (DWORD)heap);
2263 return E_FAIL; /* This is what is used if shlwapi not loaded */
2266 /*************************************************************************
2269 DWORD WINAPI SHLWAPI_431 (DWORD x)
2271 FIXME("(0x%08lx)stub\n", x);
2275 /*************************************************************************
2278 * This is really CLSIDFromString which is exported by ole32.dll,
2279 * however the native shlwapi.dll does *not* import ole32. Nor does
2280 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2281 * that MS duplicated the code for CLSIDFromString.
2283 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2284 * in dlls/ole32/compobj.c
2286 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2294 memset(s, 0, sizeof(CLSID));
2297 else { /* validate the CLSID string */
2299 if (strlenW(s) != 38)
2300 return CO_E_CLASSSTRING;
2302 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2303 return CO_E_CLASSSTRING;
2305 for (i=1; i<37; i++)
2307 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2308 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2309 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2310 ((s[i] >= L'A') && (s[i] <= L'F')))
2312 return CO_E_CLASSSTRING;
2316 TRACE("%s -> %p\n", debugstr_w(s), id);
2318 /* quick lookup table */
2319 memset(table, 0, 256*sizeof(WCHAR));
2321 for (i = 0; i < 10; i++) {
2324 for (i = 0; i < 6; i++) {
2325 table['A' + i] = i+10;
2326 table['a' + i] = i+10;
2329 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2333 s++; /* skip leading brace */
2334 for (i = 0; i < 4; i++) {
2335 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2341 for (i = 0; i < 2; i++) {
2342 p[1-i] = table[*s]<<4 | table[*(s+1)];
2348 for (i = 0; i < 2; i++) {
2349 p[1-i] = table[*s]<<4 | table[*(s+1)];
2355 /* these are just sequential bytes */
2356 for (i = 0; i < 2; i++) {
2357 *p++ = table[*s]<<4 | table[*(s+1)];
2362 for (i = 0; i < 6; i++) {
2363 *p++ = table[*s]<<4 | table[*(s+1)];
2370 /*************************************************************************
2374 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2375 * the registry to determine what O/S & Service Pack level is running, and
2376 * therefore which functions are available. Currently we always run as NT,
2377 * since this means that we don't need extra code to emulate Unicode calls,
2378 * they are forwarded directly to the appropriate API call instead.
2379 * Since the flags for whether to call or emulate Unicode are internal to
2380 * the dll, this function does not need a full implementation.
2382 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2384 FIXME("(0x%08lx)stub\n", functionToCall);
2385 return /* 0xabba1247 */ 0;
2388 /*************************************************************************
2389 * ColorRGBToHLS [SHLWAPI.445]
2391 * Convert from RGB COLORREF into the HLS color space.
2394 * Input HLS values are constrained to the range (0..240).
2396 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2397 LPWORD wLuminance, LPWORD pwSaturation)
2403 /*************************************************************************
2404 * SHCreateShellPalette [SHLWAPI.@]
2406 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2409 return CreateHalftonePalette(hdc);
2412 /*************************************************************************
2413 * SHGetInverseCMAP (SHLWAPI.@)
2415 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2418 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2419 *x = (LPDWORD)0xabba1249;
2422 FIXME("(%p, %#lx)stub\n", x, why);
2426 /*************************************************************************
2427 * SHIsLowMemoryMachine [SHLWAPI.@]
2429 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2431 FIXME("0x%08lx\n", x);
2435 /*************************************************************************
2436 * GetMenuPosFromID [SHLWAPI.@]
2438 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2441 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2443 while (nIter < nCount)
2446 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)