2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
19 #include "wine/unicode.h"
20 #include "wine/obj_base.h"
21 #include "wine/obj_inplace.h"
22 #include "wine/obj_serviceprovider.h"
26 #include "debugtools.h"
30 DEFAULT_DEBUG_CHANNEL(shell);
32 extern HINSTANCE shlwapi_hInstance;
33 extern HMODULE SHLWAPI_hshell32;
34 extern HMODULE SHLWAPI_hwinmm;
35 extern HMODULE SHLWAPI_hcomdlg32;
36 extern HMODULE SHLWAPI_hmpr;
37 extern HMODULE SHLWAPI_hmlang;
38 extern HMODULE SHLWAPI_hversion;
40 extern DWORD SHLWAPI_ThreadRef_index;
42 typedef HANDLE HSHARED; /* Shared memory */
44 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
45 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
46 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
47 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
49 /* The following schemes were identified in the native version of
50 * SHLWAPI.DLL version 5.50
53 URL_SCHEME_INVALID = -1,
54 URL_SCHEME_UNKNOWN = 0,
69 URL_SCHEME_JAVASCRIPT,
77 URL_SCHEME scheme_number;
81 static const SHL_2_inet_scheme shlwapi_schemes[] = {
82 {URL_SCHEME_FTP, "ftp"},
83 {URL_SCHEME_HTTP, "http"},
84 {URL_SCHEME_GOPHER, "gopher"},
85 {URL_SCHEME_MAILTO, "mailto"},
86 {URL_SCHEME_NEWS, "news"},
87 {URL_SCHEME_NNTP, "nntp"},
88 {URL_SCHEME_TELNET, "telnet"},
89 {URL_SCHEME_WAIS, "wais"},
90 {URL_SCHEME_FILE, "file"},
91 {URL_SCHEME_MK, "mk"},
92 {URL_SCHEME_HTTPS, "https"},
93 {URL_SCHEME_SHELL, "shell"},
94 {URL_SCHEME_SNEWS, "snews"},
95 {URL_SCHEME_LOCAL, "local"},
96 {URL_SCHEME_JAVASCRIPT, "javascript"},
97 {URL_SCHEME_VBSCRIPT, "vbscript"},
98 {URL_SCHEME_ABOUT, "about"},
99 {URL_SCHEME_RES, "res"},
103 /* Macro to get function pointer for a module*/
104 #define GET_FUNC(module, name, fail) \
105 if (!SHLWAPI_h##module) SHLWAPI_h##module = LoadLibraryA(#module ".dll"); \
106 if (!SHLWAPI_h##module) return fail; \
107 if (!pfnFunc) pfnFunc = (void*)GetProcAddress(SHLWAPI_h##module, name); \
108 if (!pfnFunc) return fail
111 NOTES: Most functions exported by ordinal seem to be superflous.
112 The reason for these functions to be there is to provide a wraper
113 for unicode functions to provide these functions on systems without
114 unicode functions eg. win95/win98. Since we have such functions we just
115 call these. If running Wine with native DLL's, some late bound calls may
116 fail. However, its better to implement the functions in the forward DLL
117 and recommend the builtin rather than reimplementing the calls here!
120 /*************************************************************************
123 * Identifies the Internet "scheme" in the passed string. ASCII based.
124 * Also determines start and length of item after the ':'
126 DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
129 const SHL_2_inet_scheme *inet_pro;
131 if (y->size != 0x18) return E_INVALIDARG;
132 /* FIXME: leading white space generates error of 0x80041001 which
135 if (*x <= ' ') return 0x80041001;
150 /* check for no scheme in string start */
151 /* (apparently schemes *must* be larger than a single character) */
152 if ((*x == '\0') || (y->sizep1 <= 1)) {
157 /* found scheme, set length of remainder */
158 y->sizep2 = lstrlenA(y->ap2);
160 /* see if known scheme and return indicator number */
161 y->fcncde = URL_SCHEME_UNKNOWN;
162 inet_pro = shlwapi_schemes;
163 while (inet_pro->scheme_name) {
164 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
165 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
166 y->fcncde = inet_pro->scheme_number;
174 /*************************************************************************
177 * Identifies the Internet "scheme" in the passed string. UNICODE based.
178 * Also determines start and length of item after the ':'
180 DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
183 const SHL_2_inet_scheme *inet_pro;
187 if (y->size != 0x18) return E_INVALIDARG;
188 /* FIXME: leading white space generates error of 0x80041001 which
191 if (*x <= L' ') return 0x80041001;
206 /* check for no scheme in string start */
207 /* (apparently schemes *must* be larger than a single character) */
208 if ((*x == L'\0') || (y->sizep1 <= 1)) {
213 /* found scheme, set length of remainder */
214 y->sizep2 = lstrlenW(y->ap2);
216 /* see if known scheme and return indicator number */
217 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
218 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
219 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
220 y->fcncde = URL_SCHEME_UNKNOWN;
221 inet_pro = shlwapi_schemes;
222 while (inet_pro->scheme_name) {
223 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
224 min(len, lstrlenA(inet_pro->scheme_name)))) {
225 y->fcncde = inet_pro->scheme_number;
230 HeapFree(GetProcessHeap(), 0, cmpstr);
234 /*************************************************************************
235 * SHLWAPI_DupSharedHandle
237 * Internal implemetation of SHLWAPI_11.
240 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
241 DWORD dwSrcProcId, DWORD dwAccess,
245 DWORD dwMyProcId = GetCurrentProcessId();
246 HSHARED hRet = (HSHARED)NULL;
248 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
249 dwAccess, dwOptions);
251 /* Get dest process handle */
252 if (dwDstProcId == dwMyProcId)
253 hDst = GetCurrentProcess();
255 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
259 /* Get src process handle */
260 if (dwSrcProcId == dwMyProcId)
261 hSrc = GetCurrentProcess();
263 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
267 /* Make handle available to dest process */
268 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
269 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
270 hRet = (HSHARED)NULL;
272 if (dwSrcProcId != dwMyProcId)
276 if (dwDstProcId != dwMyProcId)
280 TRACE("Returning handle %p\n", (PVOID)hRet);
284 /*************************************************************************
287 * Create a block of sharable memory and initialise it with data.
290 * dwProcId [I] ID of process owning data
291 * lpvData [I] Pointer to data to write
292 * dwSize [I] Size of data
295 * Success: A shared memory handle
299 * Ordinals 7-11 provide a set of calls to create shared memory between a
300 * group of processes. The shared memory is treated opaquely in that its size
301 * is not exposed to clients who map it. This is accomplished by storing
302 * the size of the map as the first DWORD of mapped data, and then offsetting
303 * the view pointer returned by this size.
305 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
306 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
307 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
309 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
313 HSHARED hRet = (HSHARED)NULL;
315 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
317 /* Create file mapping of the correct length */
318 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
319 dwSize + sizeof(dwSize), NULL);
323 /* Get a view in our process address space */
324 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
328 /* Write size of data, followed by the data, to the view */
329 *((DWORD*)pMapped) = dwSize;
331 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
333 /* Release view. All further views mapped will be opaque */
334 UnmapViewOfFile(pMapped);
335 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
336 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
337 DUPLICATE_SAME_ACCESS);
344 /*************************************************************************
347 * Get a pointer to a block of shared memory from a shared memory handle.
350 * hShared [I] Shared memory handle
351 * dwProcId [I] ID of process owning hShared
354 * Success: A pointer to the shared memory
360 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
365 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
367 /* Get handle to shared memory for current process */
368 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
369 FILE_MAP_ALL_ACCESS, 0);
371 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
375 return (char *) pMapped + sizeof(DWORD); /* Hide size */
379 /*************************************************************************
382 * Release a pointer to a block of shared memory.
385 * lpView [I] Shared memory pointer
394 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
396 TRACE("(%p)\n", lpView);
397 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
400 /*************************************************************************
403 * Destroy a block of sharable memory.
406 * hShared [I] Shared memory handle
407 * dwProcId [I] ID of process owning hShared
416 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
420 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
422 /* Get a copy of the handle for our process, closing the source handle */
423 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
424 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
425 /* Close local copy */
426 return CloseHandle((HANDLE)hClose);
429 /*************************************************************************
432 * Copy a sharable memory handle from one process to another.
435 * hShared [I] Shared memory handle to duplicate
436 * dwDstProcId [I] ID of the process wanting the duplicated handle
437 * dwSrcProcId [I] ID of the process owning hShared
438 * dwAccess [I] Desired DuplicateHandle access
439 * dwOptions [I] Desired DuplicateHandle options
442 * Success: A handle suitable for use by the dwDstProcId process.
443 * Failure: A NULL handle.
448 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
449 DWORD dwAccess, DWORD dwOptions)
453 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
454 dwAccess, dwOptions);
458 /*************************************************************************
460 * (Used by IE4 during startup)
462 HRESULT WINAPI SHLWAPI_13 (
466 FIXME("(%p %p)stub\n",w,x);
469 /* pseudo code extracted from relay trace */
470 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Aceepted Documents", &newkey);
475 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
479 b1 = LocalAlloc(0x40, size);
483 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
484 RegisterClipBoardFormatA(a4);
487 hwnd1 = GetModuleHandleA("URLMON.DLL");
488 proc = GetProcAddress(hwnd1, "CreateFormatEnumerator");
489 HeapAlloc(??, 0, 0x14);
490 HeapAlloc(??, 0, 0x50);
491 LocalAlloc(0x40, 0x78);
492 /* FIXME: bad string below */
493 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
494 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
497 IsBadReadPtr(c1 = 0x403fd210,4);
498 InterlockedIncrement(c1+4);
501 IsBadReadPtr(c1 = 0x403fd210,4);
502 InterlockedIncrement(c1+4);
504 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
505 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
506 hwnd1 = GetModuleHandleA("URLMON.DLL");
507 proc = GetProcAddress(hwnd1, "RegisterFormatEnumerator");
508 /* 0x1a40c88c is in URLMON.DLL just before above proc
509 * content is L"_EnumFORMATETC_"
512 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
515 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
516 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
517 InterlockedIncrement(d2+4);
518 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
519 InterlockedDecrement(d2+4);
520 IsBadReadPtr(c1,00000004);
521 InterlockedDecrement(c1+4);
522 IsBadReadPtr(c1,00000004);
523 InterlockedDecrement(c1+4);
528 /*************************************************************************
532 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
535 HRESULT WINAPI SHLWAPI_14 (
540 DWORD mystrlen, mytype;
544 mystrlen = (*buflen > 6) ? *buflen : 6;
545 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
546 HEAP_ZERO_MEMORY, mystrlen);
547 RegOpenKeyA(HKEY_CURRENT_USER,
548 "Software\\Microsoft\\Internet Explorer\\International",
550 if (RegQueryValueExA(mykey, "AcceptLanguage",
551 0, &mytype, mystr, &mystrlen)) {
552 /* Did not find value */
553 mylcid = GetUserDefaultLCID();
554 /* somehow the mylcid translates into "en-us"
555 * this is similar to "LOCALE_SABBREVLANGNAME"
556 * which could be gotten via GetLocaleInfo.
557 * The only problem is LOCALE_SABBREVLANGUAGE" is
558 * a 3 char string (first 2 are country code and third is
559 * letter for "sublanguage", which does not come close to
562 lstrcpyA(mystr, "en-us");
563 mystrlen = lstrlenA(mystr);
566 /* handle returned string */
567 FIXME("missing code\n");
569 if (mystrlen > *buflen)
570 lstrcpynA(langbuf, mystr, *buflen);
572 lstrcpyA(langbuf, mystr);
573 *buflen = lstrlenA(langbuf);
576 HeapFree(GetProcessHeap(), 0, mystr);
577 TRACE("language is %s\n", debugstr_a(langbuf));
581 /*************************************************************************
585 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
588 HRESULT WINAPI SHLWAPI_15 (
593 DWORD mystrlen, mytype;
597 mystrlen = (*buflen > 6) ? *buflen : 6;
598 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
599 HEAP_ZERO_MEMORY, mystrlen);
600 RegOpenKeyA(HKEY_CURRENT_USER,
601 "Software\\Microsoft\\Internet Explorer\\International",
603 if (RegQueryValueExA(mykey, "AcceptLanguage",
604 0, &mytype, mystr, &mystrlen)) {
605 /* Did not find value */
606 mylcid = GetUserDefaultLCID();
607 /* somehow the mylcid translates into "en-us"
608 * this is similar to "LOCALE_SABBREVLANGNAME"
609 * which could be gotten via GetLocaleInfo.
610 * The only problem is LOCALE_SABBREVLANGUAGE" is
611 * a 3 char string (first 2 are country code and third is
612 * letter for "sublanguage", which does not come close to
615 lstrcpyA(mystr, "en-us");
616 mystrlen = lstrlenA(mystr);
619 /* handle returned string */
620 FIXME("missing code\n");
623 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
624 HeapFree(GetProcessHeap(), 0, mystr);
625 TRACE("language is %s\n", debugstr_w(langbuf));
629 /*************************************************************************
632 HRESULT WINAPI SHLWAPI_16 (
638 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
642 /*************************************************************************
645 * w is pointer to address of callback routine
646 * x is pointer to LPVOID to receive address of locally allocated
648 * return is 0 (unless out of memory???)
650 * related to _19, _21 and _22 below
651 * only seen invoked by SHDOCVW
653 LONG WINAPI SHLWAPI_18 (
657 FIXME("(%p %p)stub\n",w,x);
662 /*************************************************************************
665 * w is address of allocated memory from _21
666 * return is 0 (unless out of memory???)
668 * related to _18, _21 and _22 below
669 * only seen invoked by SHDOCVW
671 LONG WINAPI SHLWAPI_19 (
674 FIXME("(%p) stub\n",w);
678 /*************************************************************************
681 * w points to space allocated via .18 above
682 * LocalSize is done on it (retrieves 18)
683 * LocalReAlloc is done on it to size 8 with LMEM_MOVEABLE & LMEM_ZEROINIT
684 * x values seen 0xa0000005
687 * relates to _18, _19 and _22 above and below
688 * only seen invoked by SHDOCVW
690 LONG WINAPI SHLWAPI_21 (
694 FIXME("(%p %lx)stub\n",w,x);
698 /*************************************************************************
701 * return is 'w' value seen in x is 0xa0000005
703 * relates to _18, _19 and _21 above
704 * only seen invoked by SHDOCVW
706 LPVOID WINAPI SHLWAPI_22 (
710 FIXME("(%p %lx)stub\n",w,x);
714 /*************************************************************************
718 * converts a guid to a string
719 * returns strlen(str)
721 DWORD WINAPI SHLWAPI_23 (
722 REFGUID guid, /* [in] clsid */
723 LPSTR str, /* [out] buffer */
724 INT cmax) /* [in] size of buffer */
728 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
729 guid->Data1, guid->Data2, guid->Data3,
730 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
731 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
732 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
733 if (strlen(xguid)>=cmax) return 0;
735 return strlen(xguid) + 1;
738 /*************************************************************************
742 * converts a guid to a string
743 * returns strlen(str)
745 DWORD WINAPI SHLWAPI_24 (
746 REFGUID guid, /* [in] clsid */
747 LPWSTR str, /* [out] buffer */
748 INT cmax) /* [in] size of buffer */
752 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
753 guid->Data1, guid->Data2, guid->Data3,
754 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
755 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
756 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
759 /*************************************************************************
762 * Seems to be iswalpha
764 BOOL WINAPI SHLWAPI_25(WCHAR wc)
766 return (get_char_typeW(wc) & C1_ALPHA) != 0;
769 /*************************************************************************
772 * Seems to be iswupper
774 BOOL WINAPI SHLWAPI_26(WCHAR wc)
776 return (get_char_typeW(wc) & C1_UPPER) != 0;
779 /*************************************************************************
782 * Seems to be iswlower
784 BOOL WINAPI SHLWAPI_27(WCHAR wc)
786 return (get_char_typeW(wc) & C1_LOWER) != 0;
789 /*************************************************************************
792 * Seems to be iswalnum
794 BOOL WINAPI SHLWAPI_28(WCHAR wc)
796 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
799 /*************************************************************************
802 * Seems to be iswspace
804 BOOL WINAPI SHLWAPI_29(WCHAR wc)
806 return (get_char_typeW(wc) & C1_SPACE) != 0;
809 /*************************************************************************
812 * Seems to be iswblank
814 BOOL WINAPI SHLWAPI_30(WCHAR wc)
816 return (get_char_typeW(wc) & C1_BLANK) != 0;
819 /*************************************************************************
822 * Seems to be iswpunct
824 BOOL WINAPI SHLWAPI_31(WCHAR wc)
826 return (get_char_typeW(wc) & C1_PUNCT) != 0;
829 /*************************************************************************
832 * Seems to be iswcntrl
834 BOOL WINAPI SHLWAPI_32(WCHAR wc)
836 return (get_char_typeW(wc) & C1_CNTRL) != 0;
839 /*************************************************************************
842 * Seems to be iswdigit
844 BOOL WINAPI SHLWAPI_33(WCHAR wc)
846 return (get_char_typeW(wc) & C1_DIGIT) != 0;
849 /*************************************************************************
852 * Seems to be iswxdigit
854 BOOL WINAPI SHLWAPI_34(WCHAR wc)
856 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
859 /*************************************************************************
863 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
865 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
869 /*************************************************************************
873 BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
875 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
876 h1, ui2, h3, debugstr_w(p4));
877 return AppendMenuW(h1, ui2, h3, p4);
880 /*************************************************************************
883 * Get the text from a given dialog item.
885 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
887 HWND hItem = GetDlgItem(hWnd, nItem);
890 return GetWindowTextW(hItem, lpsDest, nDestLen);
892 *lpsDest = (WCHAR)'\0';
896 /*************************************************************************
898 * Function: Compare two ASCII strings for "len" bytes.
899 * Returns: *str1-*str2 (case sensitive)
901 DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
903 return strncmp( str1, str2, len );
906 /*************************************************************************
909 * Function: Compare two WIDE strings for "len" bytes.
910 * Returns: *str1-*str2 (case sensitive)
912 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
914 return strncmpW( str1, str2, len );
917 /*************************************************************************
919 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
920 * Returns: *str1-*str2 (case insensitive)
922 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
924 return strncasecmp( str1, str2, len );
927 /*************************************************************************
930 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
931 * Returns: *str1-*str2 (case insensitive)
933 DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
935 return strncmpiW( str1, str2, len );
938 /*************************************************************************
941 * Case sensitive string compare (ASCII). Does not SetLastError().
943 DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
945 return strcmp(str1, str2);
948 /*************************************************************************
951 * Case sensitive string compare. Does not SetLastError().
953 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
955 return strcmpW( str1, str2 );
958 /*************************************************************************
961 * Case insensitive string compare. Does not SetLastError(). ??
963 DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
965 return strcmpiW( str1, str2 );
968 /*************************************************************************
971 * Ensure a multibyte character string doesn't end in a hanging lead byte.
973 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
977 LPSTR lastByte = lpStr + size - 1;
979 while(lpStr < lastByte)
980 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
982 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
992 /*************************************************************************
995 DWORD WINAPI SHLWAPI_164 (
1003 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1004 return 0x80004002; /* E_NOINTERFACE */
1007 /*************************************************************************
1010 * SetWindowLongA with mask.
1012 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1014 LONG ret = GetWindowLongA(hwnd, offset);
1015 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1017 if (newFlags != ret)
1018 ret = SetWindowLongA(hwnd, offset, newFlags);
1022 /*************************************************************************
1025 * Do IUnknown::Release on passed object.
1027 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1031 TRACE("(%p)\n",lpUnknown);
1032 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1035 TRACE("doing Release\n");
1036 return IUnknown_Release(temp);
1039 /*************************************************************************
1042 * Skip URL '//' sequence.
1044 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1046 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1051 /*************************************************************************
1053 * Get window handle of OLE object
1055 DWORD WINAPI SHLWAPI_172 (
1056 IUnknown *y, /* [in] OLE object interface */
1057 LPHWND z) /* [out] location to put window handle */
1062 TRACE("(%p %p)\n",y,z);
1063 if (!y) return E_FAIL;
1065 if ((ret = IUnknown_QueryInterface(y, &IID_IOleWindow,(LPVOID *)&pv)) < 0) {
1069 ret = IOleWindow_GetWindow((IOleWindow *)pv, z);
1070 IUnknown_Release(pv);
1071 TRACE("result hwnd=%08x\n", *z);
1075 /*************************************************************************
1078 * Seems to do call either IObjectWithSite::SetSite or
1079 * IPersistMoniker::GetClassID. But since we do not implement either
1080 * of those classes in our headers, we will fake it out.
1082 DWORD WINAPI SHLWAPI_174(
1083 IUnknown *p1, /* [in] OLE object */
1084 LPVOID *p2) /* [out] ptr to result of either GetClassID
1089 if (!p1) return E_FAIL;
1091 /* see if SetSite interface exists for IObjectWithSite object */
1092 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1093 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1096 /* see if GetClassId interface exists for IPersistMoniker object */
1097 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1098 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1099 if (ret) return ret;
1101 /* fake a GetClassId call */
1102 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1103 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1105 IUnknown_Release((IUnknown *)aa);
1108 /* fake a SetSite call */
1109 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1110 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1112 IUnknown_Release((IUnknown *)p1);
1117 /*************************************************************************
1120 * Function appears to be interface to IServiceProvider::QueryService
1123 * returns E_NOINTERFACE
1125 * S_OK if _219 called successfully
1127 DWORD WINAPI SHLWAPI_176 (
1128 IUnknown* unk, /* [in] object to give Service Provider */
1129 REFGUID sid, /* [in] Service ID */
1130 REFIID riid, /* [in] Function requested */
1131 LPVOID *z) /* [out] place to save interface pointer */
1136 if (!unk) return E_FAIL;
1137 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
1138 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
1139 if (ret) return ret;
1140 ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
1142 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
1143 IUnknown_Release((IUnknown*)aa);
1147 /*************************************************************************
1150 * Enable or disable a menu item.
1152 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1154 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1157 /*************************************************************************
1160 * Register a window class if it isn't already.
1162 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1165 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1167 return (DWORD)RegisterClassA(wndclass);
1170 /*************************************************************************
1173 DWORD WINAPI SHLWAPI_193 ()
1181 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1186 /*************************************************************************
1189 * Copy interface pointer
1191 DWORD WINAPI SHLWAPI_199 (
1192 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1193 IUnknown *src) /* [in] interface pointer */
1195 TRACE("(%p %p)\n",dest,src);
1198 IUnknown_Release(*dest);
1200 IUnknown_AddRef(src);
1207 /*************************************************************************
1210 * Some sort of memory management process - associated with _210
1212 DWORD WINAPI SHLWAPI_208 (
1219 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1224 /*************************************************************************
1227 * Some sort of memory management process - associated with _208
1229 DWORD WINAPI SHLWAPI_209 (
1232 FIXME("(%p) stub\n",
1237 /*************************************************************************
1240 * Some sort of memory management process - associated with _208
1242 DWORD WINAPI SHLWAPI_210 (
1247 FIXME("(%p 0x%08lx %p) stub\n",
1252 /*************************************************************************
1255 DWORD WINAPI SHLWAPI_211 (
1259 FIXME("(%p 0x%08lx) stub\n",
1264 /*************************************************************************
1270 DWORD WINAPI SHLWAPI_215 (
1277 len_a = lstrlenA(lpStrSrc);
1278 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1279 TRACE("%s %s %d, ret=%d\n",
1280 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1284 /*************************************************************************
1287 * WideCharToMultiByte with multi language support.
1289 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1290 LPINT lpnMultiCharCount)
1292 static HRESULT (WINAPI *pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
1293 WCHAR emptyW[] = { '\0' };
1297 if (!lpDstStr || !lpnMultiCharCount)
1305 len = strlenW(lpSrcStr) + 1;
1310 CodePage = CP_UTF8; /* Fall through... */
1311 case 0x0000C350: /* FIXME: CP_ #define */
1316 INT nWideCharCount = len - 1;
1318 GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
1319 if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1323 if (nWideCharCount < len - 1)
1325 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1329 *lpnMultiCharCount = 0;
1331 if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1333 SHLWAPI_162 (mem, *lpnMultiCharCount);
1334 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1335 return *lpnMultiCharCount + 1;
1337 HeapFree(GetProcessHeap(), 0, mem);
1338 return *lpnMultiCharCount;
1340 lpDstStr[*lpnMultiCharCount] = '\0';
1341 return *lpnMultiCharCount;
1348 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1349 *lpnMultiCharCount, NULL, NULL);
1351 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1353 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1356 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1359 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1360 reqLen, NULL, NULL);
1362 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1365 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1367 HeapFree(GetProcessHeap(), 0, mem);
1374 /*************************************************************************
1377 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1378 * --> Crash. Something wrong here.
1380 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1382 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1384 INT myint = MultiCharCount;
1386 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1389 /*************************************************************************
1392 * Seems to be "super" QueryInterface. Supplied with at table of interfaces
1393 * and an array of IIDs and offsets into the table.
1396 * error codes: E_POINTER, E_NOINTERFACE
1403 HRESULT WINAPI SHLWAPI_219 (
1404 LPVOID w, /* [in] table of interfaces */
1405 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1406 REFIID riid, /* [in] REFIID to get interface for */
1407 LPVOID *z) /* [out] location to get interface pointer */
1411 IFACE_INDEX_TBL *xmove;
1413 TRACE("(%p %p %s %p)\n",
1414 w,x,debugstr_guid(riid),z);
1417 while (xmove->refid) {
1418 TRACE("trying (indx %ld) %s\n", xmove->indx,
1419 debugstr_guid(xmove->refid));
1420 if (IsEqualIID(riid, xmove->refid)) {
1421 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1422 TRACE("matched, returning (%p)\n", a_vtbl);
1423 *z = (LPVOID)a_vtbl;
1424 IUnknown_AddRef(a_vtbl);
1430 if (IsEqualIID(riid, &IID_IUnknown)) {
1431 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1432 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1433 *z = (LPVOID)a_vtbl;
1434 IUnknown_AddRef(a_vtbl);
1438 ret = E_NOINTERFACE;
1444 /*************************************************************************
1448 * securityattributes missing
1450 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
1454 sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1455 guid->Data1, guid->Data2, guid->Data3,
1456 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1457 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1458 FIXME("(%s) stub\n", lpstrName);
1459 return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
1462 /*************************************************************************
1466 * get the count of the semaphore
1468 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
1472 FIXME("(0x%08x) stub\n",handle);
1474 ReleaseSemaphore( handle, 1, &oldCount); /* +1 */
1475 WaitForSingleObject( handle, 0 ); /* -1 */
1479 /*************************************************************************
1482 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1486 CHAR value[MAX_PATH], string[MAX_PATH];
1488 strcpy(string, "CLSID\\");
1489 strcat(string, debugstr_guid(lpUnknown));
1490 strcat(string, "\\InProcServer32");
1493 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1494 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1495 RegCloseKey(newkey);
1496 return LoadLibraryExA(value, 0, 0);
1499 /*************************************************************************
1502 * Unicode version of SHLWAPI_183.
1504 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1508 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1510 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1512 return RegisterClassW(lpWndClass);
1515 /*************************************************************************
1518 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1520 FIXME("(0x%08x %p 0x%08lx) stub\n",
1521 hInstance, p2, dw3);
1524 /* pseudo code from relay trace */
1525 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1526 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1527 /* above pair repeated for:
1528 TridentThicketUrlDlClass
1537 /*************************************************************************
1540 * Calls ASCII or Unicode WindowProc for the given window.
1542 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1544 if (IsWindowUnicode(hWnd))
1545 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1546 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1549 /*************************************************************************
1553 DWORD WINAPI SHLWAPI_241 ()
1556 return /* 0xabba1243 */ 0;
1559 /*************************************************************************
1562 DWORD WINAPI SHLWAPI_266 (
1568 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1572 /*************************************************************************
1575 HRESULT WINAPI SHLWAPI_267 (
1576 LPVOID w, /* [???] NOTE: same as 1th parameter of SHLWAPI_219 */
1577 LPVOID x, /* [???] NOTE: same as 2nd parameter of SHLWAPI_219 */
1581 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1582 *((LPDWORD)z) = 0xabba1200;
1586 /*************************************************************************
1589 DWORD WINAPI SHLWAPI_268 (
1593 FIXME("(%p %p)\n",w,x);
1594 return 0xabba1251; /* 0 = failure */
1597 /*************************************************************************
1601 DWORD WINAPI SHLWAPI_276 ()
1604 return /* 0xabba1244 */ 0;
1607 /*************************************************************************
1611 HWND WINAPI SHLWAPI_278 (
1622 char * clsname = "WorkerA";
1624 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1625 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1627 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1629 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1631 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1632 wndclass.lpfnWndProc = DefWindowProcW;
1633 wndclass.cbWndExtra = 4;
1634 wndclass.hInstance = shlwapi_hInstance;
1635 wndclass.hCursor = hCursor;
1636 wndclass.hbrBackground = COLOR_BTNSHADOW;
1637 wndclass.lpszMenuName = NULL;
1638 wndclass.lpszClassName = clsname;
1639 RegisterClassA (&wndclass);
1641 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1642 hMenu,shlwapi_hInstance,0);
1643 SetWindowLongA(hwnd, 0, z);
1644 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1648 /*************************************************************************
1651 * Late bound call to winmm.PlaySoundW
1653 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1655 static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
1657 GET_FUNC(winmm, "PlaySoundW", FALSE);
1658 return pfnFunc(pszSound, hmod, fdwSound);
1661 /*************************************************************************
1664 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1667 * str1: "I" "I" pushl esp+0x20
1668 * str2: "U" "I" pushl 0x77c93810
1669 * (is "I" and "U" "integer" and "unsigned" ??)
1671 * pStr: "" "" pushl eax
1672 * some_len: 0x824 0x104 pushl 0x824
1673 * lpStr2: "%l" "%l" pushl esp+0xc
1675 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1676 * LocalAlloc(0x00, some_len) -> irrelevant_var
1677 * LocalAlloc(0x40, irrelevant_len) -> pStr
1678 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1679 * shlwapi.PathRemoveBlanksW(pStr);
1681 ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1685 /*************************************************************************
1688 * Late bound call to shell32.SHGetFileInfoW
1690 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1691 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1693 static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
1695 GET_FUNC(shell32, "SHGetFileInfoW", 0);
1696 return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1699 /*************************************************************************
1702 * Late bound call to shell32.DragQueryFileW
1704 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1706 static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
1708 GET_FUNC(shell32, "DragQueryFileW", 0);
1709 return pfnFunc(hDrop, lFile, lpszFile, lLength);
1712 /*************************************************************************
1715 * Late bound call to shell32.SHBrowseForFolderW
1717 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1719 static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
1721 GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
1722 return pfnFunc(lpBi);
1725 /*************************************************************************
1728 * Late bound call to shell32.SHGetPathFromIDListW
1730 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1732 static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
1734 GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
1735 return pfnFunc(pidl, pszPath);
1738 /*************************************************************************
1741 * Late bound call to shell32.ShellExecuteExW
1743 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1745 static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
1747 GET_FUNC(shell32, "ShellExecuteExW", FALSE);
1748 return pfnFunc(lpExecInfo);
1751 /*************************************************************************
1754 * Late bound call to shell32.SHFileOperationW.
1756 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1758 static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
1760 GET_FUNC(shell32, "SHFileOperationW", 0);
1761 return pfnFunc(lpFileOp);
1764 /*************************************************************************
1767 * Late bound call to shell32.ExtractIconExW.
1769 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1770 HICON *phiconSmall, UINT nIcons)
1772 static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
1774 GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
1775 return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1778 /*************************************************************************
1782 DWORD WINAPI SHLWAPI_342 (
1783 LPDWORD w, /* [out] location to put HKEY value??? */
1784 HKEY x, /* [in] appears to be HKEY_CURRENT_USER */
1787 FIXME("(%p 0x%08x %p)stub\n", w,x,y);
1789 return /* 0xabba1249 */ 0;
1792 /*************************************************************************
1795 DWORD WINAPI SHLWAPI_346 (
1800 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1801 lstrcpynW(dest, src, len);
1802 return lstrlenW(dest)+1;
1805 /*************************************************************************
1808 * seems to be W interface to GetFileVersionInfoSizeA
1810 DWORD WINAPI SHLWAPI_350 (
1814 static DWORD WINAPI (*pfnFunc)(LPCSTR,LPDWORD) = NULL;
1815 CHAR mbpath[MAX_PATH];
1818 GET_FUNC(version, "GetFileVersionInfoSizeA", 0);
1819 WideCharToMultiByte(0, 0, x, -1, mbpath, MAX_PATH, 0, 0);
1820 ret = pfnFunc(mbpath, y);
1824 /*************************************************************************
1827 * seems to be W interface to GetFileVersionInfoA
1829 BOOL WINAPI SHLWAPI_351 (
1830 LPWSTR w, /* [in] path to dll */
1831 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1832 DWORD y, /* [in] return value from .350 - assume length */
1833 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1835 static BOOL WINAPI (*pfnFunc)(LPCSTR,DWORD,DWORD,LPVOID) = NULL;
1836 CHAR mbpath[MAX_PATH];
1838 GET_FUNC(version, "GetFileVersionInfoA", 0);
1839 WideCharToMultiByte(0, 0, w, -1, mbpath, MAX_PATH, 0, 0);
1840 return pfnFunc(mbpath , x, y-0x208, z+0x208);
1843 /*************************************************************************
1846 * seems to be W interface to VerQueryValueA
1848 WORD WINAPI SHLWAPI_352 (
1849 LPVOID w, /* [in] buffer from _351 */
1850 LPWSTR x, /* [in] value to retrieve -
1851 converted and passed to VerQueryValueA as #2 */
1852 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1853 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1855 static WORD WINAPI (*pfnFunc)(LPVOID,LPCSTR,LPVOID*,UINT*) = NULL;
1856 CHAR buf1[MAX_PATH];
1859 GET_FUNC(version, "VerQueryValueA", 0);
1860 WideCharToMultiByte(0, 0, x, lstrlenW(x)+1, buf1, MAX_PATH, 0, 0);
1861 ret = pfnFunc(w+0x208, buf1, y, z);
1862 if (CompareStringA(GetThreadLocale(), NORM_IGNORECASE, buf1, 1,
1863 "\\StringFileInfo", 15) == 2 /* CSTR_EQUAL */) {
1864 ERR("Need to translate back to wide - should fail now\n");
1869 /*************************************************************************
1872 DWORD WINAPI SHLWAPI_356 (
1877 FIXME("(%p %p %p)stub\n", x,y,z);
1881 /*************************************************************************
1884 * Late bound call to shell32.SHGetNewLinkInfoW
1886 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
1887 BOOL *pfMustCopy, UINT uFlags)
1889 static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
1891 GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
1892 return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
1895 /*************************************************************************
1898 * Late bound call to shell32.SHDefExtractIconW
1900 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
1901 LPVOID arg5, LPVOID arg6)
1903 /* FIXME: Correct args */
1904 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
1906 GET_FUNC(shell32, "SHDefExtractIconW", 0);
1907 return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
1910 /*************************************************************************
1913 * Wrapper for lstrcpynA with src and dst swapped.
1915 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
1917 lstrcpynA(dst, src, n);
1921 /*************************************************************************
1924 * Late bound call to shell32.ExtractIconW
1926 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
1929 static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
1931 GET_FUNC(shell32, "ExtractIconW", (HICON)0);
1932 return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
1935 /*************************************************************************
1938 LANGID WINAPI SHLWAPI_376 ()
1941 /* FIXME: This should be a forward in the .spec file to the win2k function
1942 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
1944 return GetUserDefaultLangID();
1947 /*************************************************************************
1950 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
1952 * FIXME: Native shows calls to:
1953 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
1955 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
1956 * RegQueryValueExA for "LPKInstalled"
1958 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
1959 * RegQueryValueExA for "ResourceLocale"
1961 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
1962 * RegQueryValueExA for "Locale"
1964 * and then tests the Locale ("en" for me).
1966 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
1968 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
1970 CHAR mod_path[2*MAX_PATH];
1973 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
1974 ptr = strrchr(mod_path, '\\');
1976 strcpy(ptr+1, new_mod);
1977 TRACE("loading %s\n", debugstr_a(mod_path));
1978 return (DWORD)LoadLibraryA(mod_path);
1983 /*************************************************************************
1986 * This is Unicode version of .377
1988 DWORD WINAPI SHLWAPI_378 (
1989 LPCWSTR new_mod, /* [in] new module name */
1990 HMODULE inst_hwnd, /* [in] calling module handle */
1991 LPVOID z) /* [???] 4 */
1993 WCHAR mod_path[2*MAX_PATH];
1996 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
1997 ptr = strrchrW(mod_path, '\\');
1999 strcpyW(ptr+1, new_mod);
2000 TRACE("loading %s\n", debugstr_w(mod_path));
2001 return (DWORD)LoadLibraryW(mod_path);
2006 /*************************************************************************
2009 * Late bound call to comdlg32.GetSaveFileNameW
2011 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2013 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2015 GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
2016 return pfnFunc(ofn);
2019 /*************************************************************************
2022 * Late bound call to mpr.WNetRestoreConnectionW
2024 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2026 /* FIXME: Correct args */
2027 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
2029 GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
2030 return pfnFunc(arg1, arg2);
2033 /*************************************************************************
2036 * Late bound call to mpr.WNetGetLastErrorW
2038 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2041 /* FIXME: Correct args */
2042 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
2044 GET_FUNC(mpr, "WNetGetLastErrorW", 0);
2045 return pfnFunc(arg1, arg2, arg3, arg4, arg5);
2048 /*************************************************************************
2051 * Late bound call to comdlg32.PageSetupDlgW
2053 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2055 static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
2057 GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
2058 return pfnFunc(pagedlg);
2061 /*************************************************************************
2064 * Late bound call to comdlg32.PrintDlgW
2066 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2068 static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
2070 GET_FUNC(comdlg32, "PrintDlgW", FALSE);
2071 return pfnFunc(printdlg);
2074 /*************************************************************************
2077 * Late bound call to comdlg32.GetOpenFileNameW
2079 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2081 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2083 GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
2084 return pfnFunc(ofn);
2087 /* INTERNAL: Map from HLS color space to RGB */
2088 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2090 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2094 else if (wHue > 120)
2099 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2102 /* Convert to RGB and scale into RGB range (0..255) */
2103 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2105 /*************************************************************************
2106 * ColorHLSToRGB [SHLWAPI.404]
2108 * Convert from HLS color space into an RGB COLORREF.
2111 * Input HLS values are constrained to the range (0..240).
2113 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2119 WORD wGreen, wBlue, wMid1, wMid2;
2121 if (wLuminosity > 120)
2122 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2124 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2126 wMid1 = wLuminosity * 2 - wMid2;
2128 wRed = GET_RGB(wHue + 80);
2129 wGreen = GET_RGB(wHue);
2130 wBlue = GET_RGB(wHue - 80);
2132 return RGB(wRed, wGreen, wBlue);
2135 wRed = wLuminosity * 255 / 240;
2136 return RGB(wRed, wRed, wRed);
2139 /*************************************************************************
2142 * Function unknown seems to always to return 0
2144 DWORD WINAPI SHLWAPI_413 (DWORD x)
2146 FIXME("(0x%08lx)stub\n", x);
2150 /*************************************************************************
2153 * Function seems to do FreeLibrary plus other things.
2155 * FIXME native shows the following calls:
2156 * RtlEnterCriticalSection
2158 * GetProcAddress(Comctl32??, 150L)
2160 * RtlLeaveCriticalSection
2161 * followed by the FreeLibrary.
2162 * The above code may be related to .377 above.
2164 BOOL WINAPI SHLWAPI_418 (HMODULE x)
2166 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2167 return FreeLibrary(x);
2170 /*************************************************************************
2173 DWORD WINAPI SHLWAPI_431 (DWORD x)
2175 FIXME("(0x%08lx)stub\n", x);
2179 /*************************************************************************
2182 * This is really CLSIDFromString which is exported by ole32.dll,
2183 * however the native shlwapi.dll does *not* import ole32. Nor does
2184 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2185 * that MS duplicated the code for CLSIDFromString.
2187 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2188 * in dlls/ole32/compobj.c
2190 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2198 memset(s, 0, sizeof(CLSID));
2201 else { /* validate the CLSID string */
2203 if (strlenW(s) != 38)
2204 return CO_E_CLASSSTRING;
2206 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2207 return CO_E_CLASSSTRING;
2209 for (i=1; i<37; i++)
2211 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2212 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2213 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2214 ((s[i] >= L'A') && (s[i] <= L'F')))
2216 return CO_E_CLASSSTRING;
2220 TRACE("%s -> %p\n", debugstr_w(s), id);
2222 /* quick lookup table */
2223 memset(table, 0, 256*sizeof(WCHAR));
2225 for (i = 0; i < 10; i++) {
2228 for (i = 0; i < 6; i++) {
2229 table['A' + i] = i+10;
2230 table['a' + i] = i+10;
2233 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2237 s++; /* skip leading brace */
2238 for (i = 0; i < 4; i++) {
2239 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2245 for (i = 0; i < 2; i++) {
2246 p[1-i] = table[*s]<<4 | table[*(s+1)];
2252 for (i = 0; i < 2; i++) {
2253 p[1-i] = table[*s]<<4 | table[*(s+1)];
2259 /* these are just sequential bytes */
2260 for (i = 0; i < 2; i++) {
2261 *p++ = table[*s]<<4 | table[*(s+1)];
2266 for (i = 0; i < 6; i++) {
2267 *p++ = table[*s]<<4 | table[*(s+1)];
2274 /*************************************************************************
2278 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2279 * the registry to determine what O/S & Service Pack level is running, and
2280 * therefore which functions are available. Currently we always run as NT,
2281 * since this means that we don't need extra code to emulate Unicode calls,
2282 * they are forwarded directly to the appropriate API call instead.
2283 * Since the flags for whether to call or emulate Unicode are internal to
2284 * the dll, this function does not need a full implementation.
2286 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2288 FIXME("(0x%08lx)stub\n", functionToCall);
2289 return /* 0xabba1247 */ 0;
2292 /*************************************************************************
2293 * ColorRGBToHLS [SHLWAPI.445]
2295 * Convert from RGB COLORREF into the HLS color space.
2298 * Input HLS values are constrained to the range (0..240).
2300 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2301 LPWORD wLuminance, LPWORD pwSaturation)
2307 /*************************************************************************
2308 * SHCreateShellPalette [SHLWAPI.@]
2310 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2313 return CreateHalftonePalette(hdc);
2316 /*************************************************************************
2317 * SHGetInverseCMAP (SHLWAPI.@)
2319 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2322 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2323 *x = (LPDWORD)0xabba1249;
2326 FIXME("(%p, %#lx)stub\n", x, why);
2330 /*************************************************************************
2331 * SHIsLowMemoryMachine [SHLWAPI.@]
2333 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2335 FIXME("0x%08lx\n", x);
2339 /*************************************************************************
2340 * GetMenuPosFromID [SHLWAPI.@]
2342 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2345 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2347 while (nIter < nCount)
2350 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2357 /*************************************************************************
2358 * _SHGetInstanceExplorer@4 [SHLWAPI.@]
2360 * Late bound call to shell32.SHGetInstanceExplorer.
2362 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
2364 static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
2366 GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
2367 return pfnFunc(lpUnknown);
2370 /*************************************************************************
2371 * SHGetThreadRef [SHLWAPI.@]
2373 * Retrieves the per-thread object reference set by SHSetThreadRef
2374 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
2375 * successful or E_NOINTERFACE otherwise.
2377 HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
2379 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2380 *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
2384 /*************************************************************************
2385 * SHSetThreadRef [SHLWAPI.@]
2387 * Stores a per-thread reference to a COM object
2388 * "punk" - Pointer to the IUnknown interface of the object to
2389 * which you want to store a reference. Returns S_OK if successful
2390 * or an OLE error value.
2392 HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
2394 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2395 TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);