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_hmpr;
51 extern HMODULE SHLWAPI_hmlang;
52 extern HMODULE SHLWAPI_hversion;
54 extern DWORD SHLWAPI_ThreadRef_index;
56 typedef HANDLE HSHARED; /* Shared memory */
58 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
59 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
60 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
61 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
63 /* The following schemes were identified in the native version of
64 * SHLWAPI.DLL version 5.50
67 URL_SCHEME_INVALID = -1,
68 URL_SCHEME_UNKNOWN = 0,
83 URL_SCHEME_JAVASCRIPT,
91 URL_SCHEME scheme_number;
95 static const SHL_2_inet_scheme shlwapi_schemes[] = {
96 {URL_SCHEME_FTP, "ftp"},
97 {URL_SCHEME_HTTP, "http"},
98 {URL_SCHEME_GOPHER, "gopher"},
99 {URL_SCHEME_MAILTO, "mailto"},
100 {URL_SCHEME_NEWS, "news"},
101 {URL_SCHEME_NNTP, "nntp"},
102 {URL_SCHEME_TELNET, "telnet"},
103 {URL_SCHEME_WAIS, "wais"},
104 {URL_SCHEME_FILE, "file"},
105 {URL_SCHEME_MK, "mk"},
106 {URL_SCHEME_HTTPS, "https"},
107 {URL_SCHEME_SHELL, "shell"},
108 {URL_SCHEME_SNEWS, "snews"},
109 {URL_SCHEME_LOCAL, "local"},
110 {URL_SCHEME_JAVASCRIPT, "javascript"},
111 {URL_SCHEME_VBSCRIPT, "vbscript"},
112 {URL_SCHEME_ABOUT, "about"},
113 {URL_SCHEME_RES, "res"},
118 NOTES: Most functions exported by ordinal seem to be superflous.
119 The reason for these functions to be there is to provide a wraper
120 for unicode functions to provide these functions on systems without
121 unicode functions eg. win95/win98. Since we have such functions we just
122 call these. If running Wine with native DLL's, some late bound calls may
123 fail. However, its better to implement the functions in the forward DLL
124 and recommend the builtin rather than reimplementing the calls here!
127 /*************************************************************************
130 * Identifies the Internet "scheme" in the passed string. ASCII based.
131 * Also determines start and length of item after the ':'
133 DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
136 const SHL_2_inet_scheme *inet_pro;
138 if (y->size != 0x18) return E_INVALIDARG;
139 /* FIXME: leading white space generates error of 0x80041001 which
142 if (*x <= ' ') return 0x80041001;
157 /* check for no scheme in string start */
158 /* (apparently schemes *must* be larger than a single character) */
159 if ((*x == '\0') || (y->sizep1 <= 1)) {
164 /* found scheme, set length of remainder */
165 y->sizep2 = lstrlenA(y->ap2);
167 /* see if known scheme and return indicator number */
168 y->fcncde = URL_SCHEME_UNKNOWN;
169 inet_pro = shlwapi_schemes;
170 while (inet_pro->scheme_name) {
171 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
172 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
173 y->fcncde = inet_pro->scheme_number;
181 /*************************************************************************
184 * Identifies the Internet "scheme" in the passed string. UNICODE based.
185 * Also determines start and length of item after the ':'
187 DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
190 const SHL_2_inet_scheme *inet_pro;
194 if (y->size != 0x18) return E_INVALIDARG;
195 /* FIXME: leading white space generates error of 0x80041001 which
198 if (*x <= L' ') return 0x80041001;
213 /* check for no scheme in string start */
214 /* (apparently schemes *must* be larger than a single character) */
215 if ((*x == L'\0') || (y->sizep1 <= 1)) {
220 /* found scheme, set length of remainder */
221 y->sizep2 = lstrlenW(y->ap2);
223 /* see if known scheme and return indicator number */
224 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
225 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
226 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
227 y->fcncde = URL_SCHEME_UNKNOWN;
228 inet_pro = shlwapi_schemes;
229 while (inet_pro->scheme_name) {
230 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
231 min(len, lstrlenA(inet_pro->scheme_name)))) {
232 y->fcncde = inet_pro->scheme_number;
237 HeapFree(GetProcessHeap(), 0, cmpstr);
241 /*************************************************************************
244 * Determine if a file exists locally and is of an executable type.
247 * lpszFile [O] File to search for
248 * dwWhich [I] Type of executable to search for
251 * TRUE If the file was found. lpszFile contains the file name.
255 * lpszPath is modified in place and must be at least MAX_PATH in length.
256 * If the function returns FALSE, the path is modified to its orginal state.
257 * If the given path contains an extension or dwWhich is 0, executable
258 * extensions are not checked.
260 * Ordinals 3-6 are a classic case of MS exposing limited functionality to
261 * users (here through PathFindOnPath) and keeping advanced functionality for
262 * their own developers exclusive use. Monopoly, anyone?
264 BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
266 return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
269 /*************************************************************************
272 * Unicode version of SHLWAPI_3.
274 BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
276 return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
279 /*************************************************************************
282 * Search a range of paths for a specific type of executable.
285 * lpszFile [O] File to search for
286 * lppszOtherDirs [I] Other directories to look in
287 * dwWhich [I] Type of executable to search for
290 * Success: TRUE. The path to the executable is stored in sFile.
291 * Failure: FALSE. The path to the executable is unchanged.
293 BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
295 return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
298 /*************************************************************************
301 * Unicode version of SHLWAPI_5.
303 BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
305 return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
308 /*************************************************************************
309 * SHLWAPI_DupSharedHandle
311 * Internal implemetation of SHLWAPI_11.
314 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
315 DWORD dwSrcProcId, DWORD dwAccess,
319 DWORD dwMyProcId = GetCurrentProcessId();
320 HSHARED hRet = (HSHARED)NULL;
322 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
323 dwAccess, dwOptions);
325 /* Get dest process handle */
326 if (dwDstProcId == dwMyProcId)
327 hDst = GetCurrentProcess();
329 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
333 /* Get src process handle */
334 if (dwSrcProcId == dwMyProcId)
335 hSrc = GetCurrentProcess();
337 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
341 /* Make handle available to dest process */
342 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
343 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
344 hRet = (HSHARED)NULL;
346 if (dwSrcProcId != dwMyProcId)
350 if (dwDstProcId != dwMyProcId)
354 TRACE("Returning handle %p\n", (PVOID)hRet);
358 /*************************************************************************
361 * Create a block of sharable memory and initialise it with data.
364 * dwProcId [I] ID of process owning data
365 * lpvData [I] Pointer to data to write
366 * dwSize [I] Size of data
369 * Success: A shared memory handle
373 * Ordinals 7-11 provide a set of calls to create shared memory between a
374 * group of processes. The shared memory is treated opaquely in that its size
375 * is not exposed to clients who map it. This is accomplished by storing
376 * the size of the map as the first DWORD of mapped data, and then offsetting
377 * the view pointer returned by this size.
379 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
380 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
381 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
383 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
387 HSHARED hRet = (HSHARED)NULL;
389 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
391 /* Create file mapping of the correct length */
392 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
393 dwSize + sizeof(dwSize), NULL);
397 /* Get a view in our process address space */
398 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
402 /* Write size of data, followed by the data, to the view */
403 *((DWORD*)pMapped) = dwSize;
405 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
407 /* Release view. All further views mapped will be opaque */
408 UnmapViewOfFile(pMapped);
409 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
410 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
411 DUPLICATE_SAME_ACCESS);
418 /*************************************************************************
421 * Get a pointer to a block of shared memory from a shared memory handle.
424 * hShared [I] Shared memory handle
425 * dwProcId [I] ID of process owning hShared
428 * Success: A pointer to the shared memory
434 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
439 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
441 /* Get handle to shared memory for current process */
442 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
443 FILE_MAP_ALL_ACCESS, 0);
445 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
449 return (char *) pMapped + sizeof(DWORD); /* Hide size */
453 /*************************************************************************
456 * Release a pointer to a block of shared memory.
459 * lpView [I] Shared memory pointer
468 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
470 TRACE("(%p)\n", lpView);
471 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
474 /*************************************************************************
477 * Destroy a block of sharable memory.
480 * hShared [I] Shared memory handle
481 * dwProcId [I] ID of process owning hShared
490 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
494 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
496 /* Get a copy of the handle for our process, closing the source handle */
497 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
498 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
499 /* Close local copy */
500 return CloseHandle((HANDLE)hClose);
503 /*************************************************************************
506 * Copy a sharable memory handle from one process to another.
509 * hShared [I] Shared memory handle to duplicate
510 * dwDstProcId [I] ID of the process wanting the duplicated handle
511 * dwSrcProcId [I] ID of the process owning hShared
512 * dwAccess [I] Desired DuplicateHandle access
513 * dwOptions [I] Desired DuplicateHandle options
516 * Success: A handle suitable for use by the dwDstProcId process.
517 * Failure: A NULL handle.
522 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
523 DWORD dwAccess, DWORD dwOptions)
527 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
528 dwAccess, dwOptions);
532 /*************************************************************************
534 * (Used by IE4 during startup)
536 HRESULT WINAPI SHLWAPI_13 (
540 FIXME("(%p %p)stub\n",w,x);
543 /* pseudo code extracted from relay trace */
544 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Aceepted Documents", &newkey);
549 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
553 b1 = LocalAlloc(0x40, size);
557 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
558 RegisterClipBoardFormatA(a4);
561 hwnd1 = GetModuleHandleA("URLMON.DLL");
562 proc = GetProcAddress(hwnd1, "CreateFormatEnumerator");
563 HeapAlloc(??, 0, 0x14);
564 HeapAlloc(??, 0, 0x50);
565 LocalAlloc(0x40, 0x78);
566 /* FIXME: bad string below */
567 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
568 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
571 IsBadReadPtr(c1 = 0x403fd210,4);
572 InterlockedIncrement(c1+4);
575 IsBadReadPtr(c1 = 0x403fd210,4);
576 InterlockedIncrement(c1+4);
578 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
579 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
580 hwnd1 = GetModuleHandleA("URLMON.DLL");
581 proc = GetProcAddress(hwnd1, "RegisterFormatEnumerator");
582 /* 0x1a40c88c is in URLMON.DLL just before above proc
583 * content is L"_EnumFORMATETC_"
586 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
589 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
590 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
591 InterlockedIncrement(d2+4);
592 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
593 InterlockedDecrement(d2+4);
594 IsBadReadPtr(c1,00000004);
595 InterlockedDecrement(c1+4);
596 IsBadReadPtr(c1,00000004);
597 InterlockedDecrement(c1+4);
602 /*************************************************************************
606 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
609 HRESULT WINAPI SHLWAPI_14 (
614 DWORD mystrlen, mytype;
618 mystrlen = (*buflen > 6) ? *buflen : 6;
619 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
620 HEAP_ZERO_MEMORY, mystrlen);
621 RegOpenKeyA(HKEY_CURRENT_USER,
622 "Software\\Microsoft\\Internet Explorer\\International",
624 if (RegQueryValueExA(mykey, "AcceptLanguage",
625 0, &mytype, mystr, &mystrlen)) {
626 /* Did not find value */
627 mylcid = GetUserDefaultLCID();
628 /* somehow the mylcid translates into "en-us"
629 * this is similar to "LOCALE_SABBREVLANGNAME"
630 * which could be gotten via GetLocaleInfo.
631 * The only problem is LOCALE_SABBREVLANGUAGE" is
632 * a 3 char string (first 2 are country code and third is
633 * letter for "sublanguage", which does not come close to
636 lstrcpyA(mystr, "en-us");
637 mystrlen = lstrlenA(mystr);
640 /* handle returned string */
641 FIXME("missing code\n");
643 if (mystrlen > *buflen)
644 lstrcpynA(langbuf, mystr, *buflen);
646 lstrcpyA(langbuf, mystr);
647 *buflen = lstrlenA(langbuf);
650 HeapFree(GetProcessHeap(), 0, mystr);
651 TRACE("language is %s\n", debugstr_a(langbuf));
655 /*************************************************************************
659 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
662 HRESULT WINAPI SHLWAPI_15 (
667 DWORD mystrlen, mytype;
671 mystrlen = (*buflen > 6) ? *buflen : 6;
672 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
673 HEAP_ZERO_MEMORY, mystrlen);
674 RegOpenKeyA(HKEY_CURRENT_USER,
675 "Software\\Microsoft\\Internet Explorer\\International",
677 if (RegQueryValueExA(mykey, "AcceptLanguage",
678 0, &mytype, mystr, &mystrlen)) {
679 /* Did not find value */
680 mylcid = GetUserDefaultLCID();
681 /* somehow the mylcid translates into "en-us"
682 * this is similar to "LOCALE_SABBREVLANGNAME"
683 * which could be gotten via GetLocaleInfo.
684 * The only problem is LOCALE_SABBREVLANGUAGE" is
685 * a 3 char string (first 2 are country code and third is
686 * letter for "sublanguage", which does not come close to
689 lstrcpyA(mystr, "en-us");
690 mystrlen = lstrlenA(mystr);
693 /* handle returned string */
694 FIXME("missing code\n");
697 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
698 HeapFree(GetProcessHeap(), 0, mystr);
699 TRACE("language is %s\n", debugstr_w(langbuf));
703 /*************************************************************************
706 HRESULT WINAPI SHLWAPI_16 (
712 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
716 /*************************************************************************
719 * w is pointer to address of callback routine
720 * x is pointer to LPVOID to receive address of locally allocated
722 * return is 0 (unless out of memory???)
724 * related to _19, _21 and _22 below
725 * only seen invoked by SHDOCVW
727 LONG WINAPI SHLWAPI_18 (
731 FIXME("(%p %p)stub\n",w,x);
736 /*************************************************************************
739 * w is address of allocated memory from _21
740 * return is 0 (unless out of memory???)
742 * related to _18, _21 and _22 below
743 * only seen invoked by SHDOCVW
745 LONG WINAPI SHLWAPI_19 (
748 FIXME("(%p) stub\n",w);
752 /*************************************************************************
755 * w points to space allocated via .18 above
756 * LocalSize is done on it (retrieves 18)
757 * LocalReAlloc is done on it to size 8 with LMEM_MOVEABLE & LMEM_ZEROINIT
758 * x values seen 0xa0000005
761 * relates to _18, _19 and _22 above and below
762 * only seen invoked by SHDOCVW
764 LONG WINAPI SHLWAPI_21 (
768 FIXME("(%p %lx)stub\n",w,x);
772 /*************************************************************************
775 * return is 'w' value seen in x is 0xa0000005
777 * relates to _18, _19 and _21 above
778 * only seen invoked by SHDOCVW
780 LPVOID WINAPI SHLWAPI_22 (
784 FIXME("(%p %lx)stub\n",w,x);
788 /*************************************************************************
792 * converts a guid to a string
793 * returns strlen(str)
795 DWORD WINAPI SHLWAPI_23 (
796 REFGUID guid, /* [in] clsid */
797 LPSTR str, /* [out] buffer */
798 INT cmax) /* [in] size of buffer */
802 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
803 guid->Data1, guid->Data2, guid->Data3,
804 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
805 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
806 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
807 if (strlen(xguid)>=cmax) return 0;
809 return strlen(xguid) + 1;
812 /*************************************************************************
816 * converts a guid to a string
817 * returns strlen(str)
819 DWORD WINAPI SHLWAPI_24 (
820 REFGUID guid, /* [in] clsid */
821 LPWSTR str, /* [out] buffer */
822 INT cmax) /* [in] size of buffer */
826 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
827 guid->Data1, guid->Data2, guid->Data3,
828 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
829 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
830 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
833 /*************************************************************************
836 * Seems to be iswalpha
838 BOOL WINAPI SHLWAPI_25(WCHAR wc)
840 return (get_char_typeW(wc) & C1_ALPHA) != 0;
843 /*************************************************************************
846 * Seems to be iswupper
848 BOOL WINAPI SHLWAPI_26(WCHAR wc)
850 return (get_char_typeW(wc) & C1_UPPER) != 0;
853 /*************************************************************************
856 * Seems to be iswlower
858 BOOL WINAPI SHLWAPI_27(WCHAR wc)
860 return (get_char_typeW(wc) & C1_LOWER) != 0;
863 /*************************************************************************
866 * Seems to be iswalnum
868 BOOL WINAPI SHLWAPI_28(WCHAR wc)
870 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
873 /*************************************************************************
876 * Seems to be iswspace
878 BOOL WINAPI SHLWAPI_29(WCHAR wc)
880 return (get_char_typeW(wc) & C1_SPACE) != 0;
883 /*************************************************************************
886 * Seems to be iswblank
888 BOOL WINAPI SHLWAPI_30(WCHAR wc)
890 return (get_char_typeW(wc) & C1_BLANK) != 0;
893 /*************************************************************************
896 * Seems to be iswpunct
898 BOOL WINAPI SHLWAPI_31(WCHAR wc)
900 return (get_char_typeW(wc) & C1_PUNCT) != 0;
903 /*************************************************************************
906 * Seems to be iswcntrl
908 BOOL WINAPI SHLWAPI_32(WCHAR wc)
910 return (get_char_typeW(wc) & C1_CNTRL) != 0;
913 /*************************************************************************
916 * Seems to be iswdigit
918 BOOL WINAPI SHLWAPI_33(WCHAR wc)
920 return (get_char_typeW(wc) & C1_DIGIT) != 0;
923 /*************************************************************************
926 * Seems to be iswxdigit
928 BOOL WINAPI SHLWAPI_34(WCHAR wc)
930 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
933 /*************************************************************************
937 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
939 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
943 /*************************************************************************
947 BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
949 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
950 h1, ui2, h3, debugstr_w(p4));
951 return AppendMenuW(h1, ui2, h3, p4);
954 /*************************************************************************
957 * Get the text from a given dialog item.
959 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
961 HWND hItem = GetDlgItem(hWnd, nItem);
964 return GetWindowTextW(hItem, lpsDest, nDestLen);
966 *lpsDest = (WCHAR)'\0';
970 /*************************************************************************
972 * Function: Compare two ASCII strings for "len" bytes.
973 * Returns: *str1-*str2 (case sensitive)
975 DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
977 return strncmp( str1, str2, len );
980 /*************************************************************************
983 * Function: Compare two WIDE strings for "len" bytes.
984 * Returns: *str1-*str2 (case sensitive)
986 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
988 return strncmpW( str1, str2, len );
991 /*************************************************************************
993 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
994 * Returns: *str1-*str2 (case insensitive)
996 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
998 return strncasecmp( str1, str2, len );
1001 /*************************************************************************
1004 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
1005 * Returns: *str1-*str2 (case insensitive)
1007 DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
1009 return strncmpiW( str1, str2, len );
1012 /*************************************************************************
1015 * Case sensitive string compare (ASCII). Does not SetLastError().
1017 DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
1019 return strcmp(str1, str2);
1022 /*************************************************************************
1025 * Case sensitive string compare. Does not SetLastError().
1027 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
1029 return strcmpW( str1, str2 );
1032 /*************************************************************************
1035 * Case insensitive string compare. Does not SetLastError(). ??
1037 DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
1039 return strcmpiW( str1, str2 );
1042 /*************************************************************************
1045 * Ensure a multibyte character string doesn't end in a hanging lead byte.
1047 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
1051 LPSTR lastByte = lpStr + size - 1;
1053 while(lpStr < lastByte)
1054 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
1056 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1066 /*************************************************************************
1069 DWORD WINAPI SHLWAPI_164 (
1077 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1078 return 0x80004002; /* E_NOINTERFACE */
1081 /*************************************************************************
1084 * SetWindowLongA with mask.
1086 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1088 LONG ret = GetWindowLongA(hwnd, offset);
1089 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1091 if (newFlags != ret)
1092 ret = SetWindowLongA(hwnd, offset, newFlags);
1096 /*************************************************************************
1099 * Do IUnknown::Release on passed object.
1101 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1105 TRACE("(%p)\n",lpUnknown);
1106 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1109 TRACE("doing Release\n");
1110 return IUnknown_Release(temp);
1113 /*************************************************************************
1116 * Skip URL '//' sequence.
1118 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1120 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1125 /*************************************************************************
1127 * Get window handle of OLE object
1129 DWORD WINAPI SHLWAPI_172 (
1130 IUnknown *y, /* [in] OLE object interface */
1131 LPHWND z) /* [out] location to put window handle */
1136 TRACE("(%p %p)\n",y,z);
1137 if (!y) return E_FAIL;
1139 if ((ret = IUnknown_QueryInterface(y, &IID_IOleWindow,(LPVOID *)&pv)) < 0) {
1143 ret = IOleWindow_GetWindow((IOleWindow *)pv, z);
1144 IUnknown_Release(pv);
1145 TRACE("result hwnd=%08x\n", *z);
1149 /*************************************************************************
1152 * Seems to do call either IObjectWithSite::SetSite or
1153 * IPersistMoniker::GetClassID. But since we do not implement either
1154 * of those classes in our headers, we will fake it out.
1156 DWORD WINAPI SHLWAPI_174(
1157 IUnknown *p1, /* [in] OLE object */
1158 LPVOID *p2) /* [out] ptr to result of either GetClassID
1163 if (!p1) return E_FAIL;
1165 /* see if SetSite interface exists for IObjectWithSite object */
1166 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1167 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1170 /* see if GetClassId interface exists for IPersistMoniker object */
1171 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1172 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1173 if (ret) return ret;
1175 /* fake a GetClassId call */
1176 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1177 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1179 IUnknown_Release((IUnknown *)aa);
1182 /* fake a SetSite call */
1183 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1184 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1186 IUnknown_Release((IUnknown *)p1);
1191 /*************************************************************************
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 *z) /* [out] place to save interface pointer */
1210 if (!unk) return E_FAIL;
1211 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
1212 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
1213 if (ret) return ret;
1214 ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
1216 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
1217 IUnknown_Release((IUnknown*)aa);
1221 /*************************************************************************
1224 * Enable or disable a menu item.
1226 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1228 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1231 /*************************************************************************
1234 * Register a window class if it isn't already.
1236 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1239 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1241 return (DWORD)RegisterClassA(wndclass);
1244 /*************************************************************************
1247 DWORD WINAPI SHLWAPI_193 ()
1255 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1260 /*************************************************************************
1263 * Copy interface pointer
1265 DWORD WINAPI SHLWAPI_199 (
1266 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1267 IUnknown *src) /* [in] interface pointer */
1269 TRACE("(%p %p)\n",dest,src);
1272 IUnknown_Release(*dest);
1274 IUnknown_AddRef(src);
1281 /*************************************************************************
1284 * Some sort of memory management process - associated with _210
1286 DWORD WINAPI SHLWAPI_208 (
1293 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1298 /*************************************************************************
1301 * Some sort of memory management process - associated with _208
1303 DWORD WINAPI SHLWAPI_209 (
1306 FIXME("(%p) stub\n",
1311 /*************************************************************************
1314 * Some sort of memory management process - associated with _208
1316 DWORD WINAPI SHLWAPI_210 (
1321 FIXME("(%p 0x%08lx %p) stub\n",
1326 /*************************************************************************
1329 DWORD WINAPI SHLWAPI_211 (
1333 FIXME("(%p 0x%08lx) stub\n",
1338 /*************************************************************************
1344 DWORD WINAPI SHLWAPI_215 (
1351 len_a = lstrlenA(lpStrSrc);
1352 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1353 TRACE("%s %s %d, ret=%d\n",
1354 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1358 /*************************************************************************
1361 * WideCharToMultiByte with multi language support.
1363 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1364 LPINT lpnMultiCharCount)
1366 static HRESULT (WINAPI *pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
1367 WCHAR emptyW[] = { '\0' };
1371 if (!lpDstStr || !lpnMultiCharCount)
1379 len = strlenW(lpSrcStr) + 1;
1384 CodePage = CP_UTF8; /* Fall through... */
1385 case 0x0000C350: /* FIXME: CP_ #define */
1390 INT nWideCharCount = len - 1;
1392 GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
1393 if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1397 if (nWideCharCount < len - 1)
1399 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1403 *lpnMultiCharCount = 0;
1405 if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1407 SHLWAPI_162 (mem, *lpnMultiCharCount);
1408 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1409 return *lpnMultiCharCount + 1;
1411 HeapFree(GetProcessHeap(), 0, mem);
1412 return *lpnMultiCharCount;
1414 lpDstStr[*lpnMultiCharCount] = '\0';
1415 return *lpnMultiCharCount;
1422 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1423 *lpnMultiCharCount, NULL, NULL);
1425 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1427 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1430 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1433 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1434 reqLen, NULL, NULL);
1436 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1439 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1441 HeapFree(GetProcessHeap(), 0, mem);
1448 /*************************************************************************
1451 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1452 * --> Crash. Something wrong here.
1454 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1456 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1458 INT myint = MultiCharCount;
1460 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1463 /*************************************************************************
1466 * Seems to be "super" QueryInterface. Supplied with at table of interfaces
1467 * and an array of IIDs and offsets into the table.
1470 * error codes: E_POINTER, E_NOINTERFACE
1477 HRESULT WINAPI SHLWAPI_219 (
1478 LPVOID w, /* [in] table of interfaces */
1479 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1480 REFIID riid, /* [in] REFIID to get interface for */
1481 LPVOID *z) /* [out] location to get interface pointer */
1485 IFACE_INDEX_TBL *xmove;
1487 TRACE("(%p %p %s %p)\n",
1488 w,x,debugstr_guid(riid),z);
1491 while (xmove->refid) {
1492 TRACE("trying (indx %ld) %s\n", xmove->indx,
1493 debugstr_guid(xmove->refid));
1494 if (IsEqualIID(riid, xmove->refid)) {
1495 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1496 TRACE("matched, returning (%p)\n", a_vtbl);
1497 *z = (LPVOID)a_vtbl;
1498 IUnknown_AddRef(a_vtbl);
1504 if (IsEqualIID(riid, &IID_IUnknown)) {
1505 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1506 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1507 *z = (LPVOID)a_vtbl;
1508 IUnknown_AddRef(a_vtbl);
1512 ret = E_NOINTERFACE;
1518 /*************************************************************************
1522 * securityattributes missing
1524 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
1528 sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1529 guid->Data1, guid->Data2, guid->Data3,
1530 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1531 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1532 FIXME("(%s) stub\n", lpstrName);
1533 return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
1536 /*************************************************************************
1540 * get the count of the semaphore
1542 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
1546 FIXME("(0x%08x) stub\n",handle);
1548 ReleaseSemaphore( handle, 1, &oldCount); /* +1 */
1549 WaitForSingleObject( handle, 0 ); /* -1 */
1553 /*************************************************************************
1556 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1560 CHAR value[MAX_PATH], string[MAX_PATH];
1562 strcpy(string, "CLSID\\");
1563 strcat(string, debugstr_guid(lpUnknown));
1564 strcat(string, "\\InProcServer32");
1567 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1568 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1569 RegCloseKey(newkey);
1570 return LoadLibraryExA(value, 0, 0);
1573 /*************************************************************************
1576 * Unicode version of SHLWAPI_183.
1578 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1582 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1584 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1586 return RegisterClassW(lpWndClass);
1589 /*************************************************************************
1592 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1594 FIXME("(0x%08x %p 0x%08lx) stub\n",
1595 hInstance, p2, dw3);
1598 /* pseudo code from relay trace */
1599 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1600 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1601 /* above pair repeated for:
1602 TridentThicketUrlDlClass
1611 /*************************************************************************
1614 * Calls ASCII or Unicode WindowProc for the given window.
1616 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1618 if (IsWindowUnicode(hWnd))
1619 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1620 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1623 /*************************************************************************
1627 DWORD WINAPI SHLWAPI_241 ()
1630 return /* 0xabba1243 */ 0;
1633 /*************************************************************************
1636 * native does at least approximately:
1637 * strcpyW(newstr, x);
1638 * strcatW(newstr, "\\Restrictions");
1639 * if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1643 DWORD WINAPI SHLWAPI_266 (
1645 LPVOID x, /* [in] partial registry key */
1649 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1650 return /* 0xabba1248 */ 0;
1653 /*************************************************************************
1656 HRESULT WINAPI SHLWAPI_267 (
1659 LPVOID y, /* [???] NOTE: same as 3rd parameter of SHLWAPI_219 */
1660 LPVOID z) /* [???] NOTE: same as 4th parameter of SHLWAPI_219 */
1662 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1664 /* native seems to do:
1665 * SHLWAPI_219 ((LPVOID)(((LPSTR)x)-4), ???, (REFIID) y, (LPVOID*) z);
1668 *((LPDWORD)z) = 0xabba1200;
1669 return /* 0xabba1254 */ 0;
1672 /*************************************************************************
1675 DWORD WINAPI SHLWAPI_268 (
1679 FIXME("(%p %p)\n",w,x);
1680 return 0xabba1251; /* 0 = failure */
1683 /*************************************************************************
1686 * on first call process does following: other calls just returns 2
1687 * instance = LoadLibraryA("SHELL32.DLL");
1688 * func = GetProcAddress(instance, "DllGetVersion");
1689 * ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
1690 * ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
1691 * RegCloseKey(newkey);
1692 * FreeLibrary(instance);
1695 DWORD WINAPI SHLWAPI_276 ()
1698 return /* 0xabba1244 */ 2;
1701 /*************************************************************************
1705 HWND WINAPI SHLWAPI_278 (
1716 char * clsname = "WorkerA";
1718 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1719 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1721 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1723 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1725 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1726 wndclass.lpfnWndProc = DefWindowProcW;
1727 wndclass.cbWndExtra = 4;
1728 wndclass.hInstance = shlwapi_hInstance;
1729 wndclass.hCursor = hCursor;
1730 wndclass.hbrBackground = COLOR_BTNSHADOW;
1731 wndclass.lpszMenuName = NULL;
1732 wndclass.lpszClassName = clsname;
1733 RegisterClassA (&wndclass);
1735 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1736 hMenu,shlwapi_hInstance,0);
1737 SetWindowLongA(hwnd, 0, z);
1738 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1742 /*************************************************************************
1745 * Late bound call to winmm.PlaySoundW
1747 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1749 static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
1751 GET_FUNC(winmm, "PlaySoundW", FALSE);
1752 return pfnFunc(pszSound, hmod, fdwSound);
1755 /*************************************************************************
1758 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1761 * str1: "I" "I" pushl esp+0x20
1762 * str2: "U" "I" pushl 0x77c93810
1763 * (is "I" and "U" "integer" and "unsigned" ??)
1765 * pStr: "" "" pushl eax
1766 * some_len: 0x824 0x104 pushl 0x824
1767 * lpStr2: "%l" "%l" pushl esp+0xc
1769 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1770 * LocalAlloc(0x00, some_len) -> irrelevant_var
1771 * LocalAlloc(0x40, irrelevant_len) -> pStr
1772 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1773 * shlwapi.PathRemoveBlanksW(pStr);
1775 ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1779 /*************************************************************************
1782 * Late bound call to shell32.SHGetFileInfoW
1784 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1785 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1787 static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
1789 GET_FUNC(shell32, "SHGetFileInfoW", 0);
1790 return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1793 /*************************************************************************
1796 * Late bound call to shell32.DragQueryFileW
1798 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1800 static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
1802 GET_FUNC(shell32, "DragQueryFileW", 0);
1803 return pfnFunc(hDrop, lFile, lpszFile, lLength);
1806 /*************************************************************************
1809 * Late bound call to shell32.SHBrowseForFolderW
1811 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1813 static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
1815 GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
1816 return pfnFunc(lpBi);
1819 /*************************************************************************
1822 * Late bound call to shell32.SHGetPathFromIDListW
1824 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1826 static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
1828 GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
1829 return pfnFunc(pidl, pszPath);
1832 /*************************************************************************
1835 * Late bound call to shell32.ShellExecuteExW
1837 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1839 static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
1841 GET_FUNC(shell32, "ShellExecuteExW", FALSE);
1842 return pfnFunc(lpExecInfo);
1845 /*************************************************************************
1848 * Late bound call to shell32.SHFileOperationW.
1850 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1852 static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
1854 GET_FUNC(shell32, "SHFileOperationW", 0);
1855 return pfnFunc(lpFileOp);
1858 /*************************************************************************
1861 * Late bound call to shell32.ExtractIconExW.
1863 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1864 HICON *phiconSmall, UINT nIcons)
1866 static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
1868 GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
1869 return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1872 /*************************************************************************
1876 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
1878 return InterlockedCompareExchange(dest, xchg, compare);
1881 /*************************************************************************
1884 DWORD WINAPI SHLWAPI_346 (
1889 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1890 lstrcpynW(dest, src, len);
1891 return lstrlenW(dest)+1;
1894 /*************************************************************************
1897 * seems to be late bound call to GetFileVersionInfoSizeW
1899 DWORD WINAPI SHLWAPI_350 (
1903 static DWORD WINAPI (*pfnFunc)(LPCWSTR,LPDWORD) = NULL;
1906 GET_FUNC(version, "GetFileVersionInfoSizeW", 0);
1907 ret = pfnFunc(x, y);
1911 /*************************************************************************
1914 * seems to be late bound call to GetFileVersionInfoW
1916 BOOL WINAPI SHLWAPI_351 (
1917 LPWSTR w, /* [in] path to dll */
1918 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1919 DWORD y, /* [in] return value from .350 - assume length */
1920 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1922 static BOOL WINAPI (*pfnFunc)(LPCWSTR,DWORD,DWORD,LPVOID) = NULL;
1924 GET_FUNC(version, "GetFileVersionInfoW", 0);
1925 return pfnFunc(w, x, y-0x208, z+0x208);
1928 /*************************************************************************
1931 * seems to be late bound call to VerQueryValueW
1933 WORD WINAPI SHLWAPI_352 (
1934 LPVOID w, /* [in] buffer from _351 */
1935 LPWSTR x, /* [in] value to retrieve -
1936 converted and passed to VerQueryValueA as #2 */
1937 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1938 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1940 static WORD WINAPI (*pfnFunc)(LPVOID,LPCWSTR,LPVOID*,UINT*) = NULL;
1942 GET_FUNC(version, "VerQueryValueW", 0);
1943 return pfnFunc(w+0x208, x, y, z);
1946 /**************************************************************************
1949 * mbc - this function is undocumented, The parameters are correct and
1950 * the calls to InitializeSecurityDescriptor and
1951 * SetSecurityDescriptorDacl are correct, but apparently some
1952 * apps call this function with all zero parameters.
1955 DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str)
1965 if (!InitializeSecurityDescriptor(pSD, 1)) return 0;
1966 return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0);
1970 /*************************************************************************
1973 * Late bound call to shell32.SHGetNewLinkInfoW
1975 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
1976 BOOL *pfMustCopy, UINT uFlags)
1978 static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
1980 GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
1981 return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
1984 /*************************************************************************
1987 * Late bound call to shell32.SHDefExtractIconW
1989 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
1990 LPVOID arg5, LPVOID arg6)
1992 /* FIXME: Correct args */
1993 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
1995 GET_FUNC(shell32, "SHDefExtractIconW", 0);
1996 return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
1999 /*************************************************************************
2002 * Wrapper for lstrcpynA with src and dst swapped.
2004 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
2006 lstrcpynA(dst, src, n);
2010 /*************************************************************************
2013 * Late bound call to shell32.ExtractIconW
2015 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
2018 static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
2020 GET_FUNC(shell32, "ExtractIconW", (HICON)0);
2021 return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
2024 /*************************************************************************
2027 LANGID WINAPI SHLWAPI_376 ()
2030 /* FIXME: This should be a forward in the .spec file to the win2k function
2031 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2033 return GetUserDefaultLangID();
2036 /*************************************************************************
2039 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2041 * FIXME: Native shows calls to:
2042 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2044 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2045 * RegQueryValueExA for "LPKInstalled"
2047 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2048 * RegQueryValueExA for "ResourceLocale"
2050 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2051 * RegQueryValueExA for "Locale"
2053 * and then tests the Locale ("en" for me).
2055 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2057 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
2059 CHAR mod_path[2*MAX_PATH];
2062 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
2063 ptr = strrchr(mod_path, '\\');
2065 strcpy(ptr+1, new_mod);
2066 TRACE("loading %s\n", debugstr_a(mod_path));
2067 return (DWORD)LoadLibraryA(mod_path);
2072 /*************************************************************************
2075 * This is Unicode version of .377
2077 DWORD WINAPI SHLWAPI_378 (
2078 LPCWSTR new_mod, /* [in] new module name */
2079 HMODULE inst_hwnd, /* [in] calling module handle */
2080 LPVOID z) /* [???] 4 */
2082 WCHAR mod_path[2*MAX_PATH];
2085 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2086 ptr = strrchrW(mod_path, '\\');
2088 strcpyW(ptr+1, new_mod);
2089 TRACE("loading %s\n", debugstr_w(mod_path));
2090 return (DWORD)LoadLibraryW(mod_path);
2095 /*************************************************************************
2098 * Late bound call to comdlg32.GetSaveFileNameW
2100 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2102 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2104 GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
2105 return pfnFunc(ofn);
2108 /*************************************************************************
2111 * Late bound call to mpr.WNetRestoreConnectionW
2113 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2115 /* FIXME: Correct args */
2116 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
2118 GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
2119 return pfnFunc(arg1, arg2);
2122 /*************************************************************************
2125 * Late bound call to mpr.WNetGetLastErrorW
2127 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2130 /* FIXME: Correct args */
2131 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
2133 GET_FUNC(mpr, "WNetGetLastErrorW", 0);
2134 return pfnFunc(arg1, arg2, arg3, arg4, arg5);
2137 /*************************************************************************
2140 * Late bound call to comdlg32.PageSetupDlgW
2142 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2144 static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
2146 GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
2147 return pfnFunc(pagedlg);
2150 /*************************************************************************
2153 * Late bound call to comdlg32.PrintDlgW
2155 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2157 static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
2159 GET_FUNC(comdlg32, "PrintDlgW", FALSE);
2160 return pfnFunc(printdlg);
2163 /*************************************************************************
2166 * Late bound call to comdlg32.GetOpenFileNameW
2168 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2170 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2172 GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
2173 return pfnFunc(ofn);
2176 /* INTERNAL: Map from HLS color space to RGB */
2177 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2179 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2183 else if (wHue > 120)
2188 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2191 /* Convert to RGB and scale into RGB range (0..255) */
2192 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2194 /*************************************************************************
2195 * ColorHLSToRGB [SHLWAPI.404]
2197 * Convert from HLS color space into an RGB COLORREF.
2200 * Input HLS values are constrained to the range (0..240).
2202 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2208 WORD wGreen, wBlue, wMid1, wMid2;
2210 if (wLuminosity > 120)
2211 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2213 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2215 wMid1 = wLuminosity * 2 - wMid2;
2217 wRed = GET_RGB(wHue + 80);
2218 wGreen = GET_RGB(wHue);
2219 wBlue = GET_RGB(wHue - 80);
2221 return RGB(wRed, wGreen, wBlue);
2224 wRed = wLuminosity * 255 / 240;
2225 return RGB(wRed, wRed, wRed);
2228 /*************************************************************************
2231 * Function unknown seems to always to return 0
2233 DWORD WINAPI SHLWAPI_413 (DWORD x)
2235 FIXME("(0x%08lx)stub\n", x);
2239 /*************************************************************************
2242 * Function seems to do FreeLibrary plus other things.
2244 * FIXME native shows the following calls:
2245 * RtlEnterCriticalSection
2247 * GetProcAddress(Comctl32??, 150L)
2249 * RtlLeaveCriticalSection
2250 * followed by the FreeLibrary.
2251 * The above code may be related to .377 above.
2253 BOOL WINAPI SHLWAPI_418 (HMODULE x)
2255 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2256 return FreeLibrary(x);
2259 /*************************************************************************
2262 DWORD WINAPI SHLWAPI_431 (DWORD x)
2264 FIXME("(0x%08lx)stub\n", x);
2268 /*************************************************************************
2271 * This is really CLSIDFromString which is exported by ole32.dll,
2272 * however the native shlwapi.dll does *not* import ole32. Nor does
2273 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2274 * that MS duplicated the code for CLSIDFromString.
2276 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2277 * in dlls/ole32/compobj.c
2279 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2287 memset(s, 0, sizeof(CLSID));
2290 else { /* validate the CLSID string */
2292 if (strlenW(s) != 38)
2293 return CO_E_CLASSSTRING;
2295 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2296 return CO_E_CLASSSTRING;
2298 for (i=1; i<37; i++)
2300 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2301 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2302 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2303 ((s[i] >= L'A') && (s[i] <= L'F')))
2305 return CO_E_CLASSSTRING;
2309 TRACE("%s -> %p\n", debugstr_w(s), id);
2311 /* quick lookup table */
2312 memset(table, 0, 256*sizeof(WCHAR));
2314 for (i = 0; i < 10; i++) {
2317 for (i = 0; i < 6; i++) {
2318 table['A' + i] = i+10;
2319 table['a' + i] = i+10;
2322 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2326 s++; /* skip leading brace */
2327 for (i = 0; i < 4; i++) {
2328 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2334 for (i = 0; i < 2; i++) {
2335 p[1-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 /* these are just sequential bytes */
2349 for (i = 0; i < 2; i++) {
2350 *p++ = table[*s]<<4 | table[*(s+1)];
2355 for (i = 0; i < 6; i++) {
2356 *p++ = table[*s]<<4 | table[*(s+1)];
2363 /*************************************************************************
2367 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2368 * the registry to determine what O/S & Service Pack level is running, and
2369 * therefore which functions are available. Currently we always run as NT,
2370 * since this means that we don't need extra code to emulate Unicode calls,
2371 * they are forwarded directly to the appropriate API call instead.
2372 * Since the flags for whether to call or emulate Unicode are internal to
2373 * the dll, this function does not need a full implementation.
2375 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2377 FIXME("(0x%08lx)stub\n", functionToCall);
2378 return /* 0xabba1247 */ 0;
2381 /*************************************************************************
2382 * ColorRGBToHLS [SHLWAPI.445]
2384 * Convert from RGB COLORREF into the HLS color space.
2387 * Input HLS values are constrained to the range (0..240).
2389 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2390 LPWORD wLuminance, LPWORD pwSaturation)
2396 /*************************************************************************
2397 * SHCreateShellPalette [SHLWAPI.@]
2399 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2402 return CreateHalftonePalette(hdc);
2405 /*************************************************************************
2406 * SHGetInverseCMAP (SHLWAPI.@)
2408 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2411 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2412 *x = (LPDWORD)0xabba1249;
2415 FIXME("(%p, %#lx)stub\n", x, why);
2419 /*************************************************************************
2420 * SHIsLowMemoryMachine [SHLWAPI.@]
2422 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2424 FIXME("0x%08lx\n", x);
2428 /*************************************************************************
2429 * GetMenuPosFromID [SHLWAPI.@]
2431 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2434 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2436 while (nIter < nCount)
2439 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2446 /*************************************************************************
2447 * _SHGetInstanceExplorer@4 [SHLWAPI.@]
2449 * Late bound call to shell32.SHGetInstanceExplorer.
2451 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
2453 static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
2455 GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
2456 return pfnFunc(lpUnknown);
2459 /*************************************************************************
2460 * SHGetThreadRef [SHLWAPI.@]
2462 * Retrieves the per-thread object reference set by SHSetThreadRef
2463 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
2464 * successful or E_NOINTERFACE otherwise.
2466 HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
2468 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2469 *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
2473 /*************************************************************************
2474 * SHSetThreadRef [SHLWAPI.@]
2476 * Stores a per-thread reference to a COM object
2477 * "punk" - Pointer to the IUnknown interface of the object to
2478 * which you want to store a reference. Returns S_OK if successful
2479 * or an OLE error value.
2481 HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
2483 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2484 TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);