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"},
117 /* Macro to get function pointer for a module*/
118 #define GET_FUNC(module, name, fail) \
119 if (!SHLWAPI_h##module) SHLWAPI_h##module = LoadLibraryA(#module ".dll"); \
120 if (!SHLWAPI_h##module) return fail; \
121 if (!pfnFunc) pfnFunc = (void*)GetProcAddress(SHLWAPI_h##module, name); \
122 if (!pfnFunc) return fail
125 NOTES: Most functions exported by ordinal seem to be superflous.
126 The reason for these functions to be there is to provide a wraper
127 for unicode functions to provide these functions on systems without
128 unicode functions eg. win95/win98. Since we have such functions we just
129 call these. If running Wine with native DLL's, some late bound calls may
130 fail. However, its better to implement the functions in the forward DLL
131 and recommend the builtin rather than reimplementing the calls here!
134 /*************************************************************************
137 * Identifies the Internet "scheme" in the passed string. ASCII based.
138 * Also determines start and length of item after the ':'
140 DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
143 const SHL_2_inet_scheme *inet_pro;
145 if (y->size != 0x18) return E_INVALIDARG;
146 /* FIXME: leading white space generates error of 0x80041001 which
149 if (*x <= ' ') return 0x80041001;
164 /* check for no scheme in string start */
165 /* (apparently schemes *must* be larger than a single character) */
166 if ((*x == '\0') || (y->sizep1 <= 1)) {
171 /* found scheme, set length of remainder */
172 y->sizep2 = lstrlenA(y->ap2);
174 /* see if known scheme and return indicator number */
175 y->fcncde = URL_SCHEME_UNKNOWN;
176 inet_pro = shlwapi_schemes;
177 while (inet_pro->scheme_name) {
178 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
179 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
180 y->fcncde = inet_pro->scheme_number;
188 /*************************************************************************
191 * Identifies the Internet "scheme" in the passed string. UNICODE based.
192 * Also determines start and length of item after the ':'
194 DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
197 const SHL_2_inet_scheme *inet_pro;
201 if (y->size != 0x18) return E_INVALIDARG;
202 /* FIXME: leading white space generates error of 0x80041001 which
205 if (*x <= L' ') return 0x80041001;
220 /* check for no scheme in string start */
221 /* (apparently schemes *must* be larger than a single character) */
222 if ((*x == L'\0') || (y->sizep1 <= 1)) {
227 /* found scheme, set length of remainder */
228 y->sizep2 = lstrlenW(y->ap2);
230 /* see if known scheme and return indicator number */
231 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
232 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
233 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
234 y->fcncde = URL_SCHEME_UNKNOWN;
235 inet_pro = shlwapi_schemes;
236 while (inet_pro->scheme_name) {
237 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
238 min(len, lstrlenA(inet_pro->scheme_name)))) {
239 y->fcncde = inet_pro->scheme_number;
244 HeapFree(GetProcessHeap(), 0, cmpstr);
248 /*************************************************************************
249 * SHLWAPI_DupSharedHandle
251 * Internal implemetation of SHLWAPI_11.
254 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
255 DWORD dwSrcProcId, DWORD dwAccess,
259 DWORD dwMyProcId = GetCurrentProcessId();
260 HSHARED hRet = (HSHARED)NULL;
262 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
263 dwAccess, dwOptions);
265 /* Get dest process handle */
266 if (dwDstProcId == dwMyProcId)
267 hDst = GetCurrentProcess();
269 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
273 /* Get src process handle */
274 if (dwSrcProcId == dwMyProcId)
275 hSrc = GetCurrentProcess();
277 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
281 /* Make handle available to dest process */
282 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
283 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
284 hRet = (HSHARED)NULL;
286 if (dwSrcProcId != dwMyProcId)
290 if (dwDstProcId != dwMyProcId)
294 TRACE("Returning handle %p\n", (PVOID)hRet);
298 /*************************************************************************
301 * Create a block of sharable memory and initialise it with data.
304 * dwProcId [I] ID of process owning data
305 * lpvData [I] Pointer to data to write
306 * dwSize [I] Size of data
309 * Success: A shared memory handle
313 * Ordinals 7-11 provide a set of calls to create shared memory between a
314 * group of processes. The shared memory is treated opaquely in that its size
315 * is not exposed to clients who map it. This is accomplished by storing
316 * the size of the map as the first DWORD of mapped data, and then offsetting
317 * the view pointer returned by this size.
319 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
320 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
321 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
323 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
327 HSHARED hRet = (HSHARED)NULL;
329 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
331 /* Create file mapping of the correct length */
332 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
333 dwSize + sizeof(dwSize), NULL);
337 /* Get a view in our process address space */
338 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
342 /* Write size of data, followed by the data, to the view */
343 *((DWORD*)pMapped) = dwSize;
345 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
347 /* Release view. All further views mapped will be opaque */
348 UnmapViewOfFile(pMapped);
349 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
350 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
351 DUPLICATE_SAME_ACCESS);
358 /*************************************************************************
361 * Get a pointer to a block of shared memory from a shared memory handle.
364 * hShared [I] Shared memory handle
365 * dwProcId [I] ID of process owning hShared
368 * Success: A pointer to the shared memory
374 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
379 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
381 /* Get handle to shared memory for current process */
382 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
383 FILE_MAP_ALL_ACCESS, 0);
385 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
389 return (char *) pMapped + sizeof(DWORD); /* Hide size */
393 /*************************************************************************
396 * Release a pointer to a block of shared memory.
399 * lpView [I] Shared memory pointer
408 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
410 TRACE("(%p)\n", lpView);
411 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
414 /*************************************************************************
417 * Destroy a block of sharable memory.
420 * hShared [I] Shared memory handle
421 * dwProcId [I] ID of process owning hShared
430 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
434 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
436 /* Get a copy of the handle for our process, closing the source handle */
437 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
438 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
439 /* Close local copy */
440 return CloseHandle((HANDLE)hClose);
443 /*************************************************************************
446 * Copy a sharable memory handle from one process to another.
449 * hShared [I] Shared memory handle to duplicate
450 * dwDstProcId [I] ID of the process wanting the duplicated handle
451 * dwSrcProcId [I] ID of the process owning hShared
452 * dwAccess [I] Desired DuplicateHandle access
453 * dwOptions [I] Desired DuplicateHandle options
456 * Success: A handle suitable for use by the dwDstProcId process.
457 * Failure: A NULL handle.
462 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
463 DWORD dwAccess, DWORD dwOptions)
467 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
468 dwAccess, dwOptions);
472 /*************************************************************************
474 * (Used by IE4 during startup)
476 HRESULT WINAPI SHLWAPI_13 (
480 FIXME("(%p %p)stub\n",w,x);
483 /* pseudo code extracted from relay trace */
484 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Aceepted Documents", &newkey);
489 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
493 b1 = LocalAlloc(0x40, size);
497 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
498 RegisterClipBoardFormatA(a4);
501 hwnd1 = GetModuleHandleA("URLMON.DLL");
502 proc = GetProcAddress(hwnd1, "CreateFormatEnumerator");
503 HeapAlloc(??, 0, 0x14);
504 HeapAlloc(??, 0, 0x50);
505 LocalAlloc(0x40, 0x78);
506 /* FIXME: bad string below */
507 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
508 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
511 IsBadReadPtr(c1 = 0x403fd210,4);
512 InterlockedIncrement(c1+4);
515 IsBadReadPtr(c1 = 0x403fd210,4);
516 InterlockedIncrement(c1+4);
518 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
519 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
520 hwnd1 = GetModuleHandleA("URLMON.DLL");
521 proc = GetProcAddress(hwnd1, "RegisterFormatEnumerator");
522 /* 0x1a40c88c is in URLMON.DLL just before above proc
523 * content is L"_EnumFORMATETC_"
526 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
529 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
530 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
531 InterlockedIncrement(d2+4);
532 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
533 InterlockedDecrement(d2+4);
534 IsBadReadPtr(c1,00000004);
535 InterlockedDecrement(c1+4);
536 IsBadReadPtr(c1,00000004);
537 InterlockedDecrement(c1+4);
542 /*************************************************************************
546 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
549 HRESULT WINAPI SHLWAPI_14 (
554 DWORD mystrlen, mytype;
558 mystrlen = (*buflen > 6) ? *buflen : 6;
559 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
560 HEAP_ZERO_MEMORY, mystrlen);
561 RegOpenKeyA(HKEY_CURRENT_USER,
562 "Software\\Microsoft\\Internet Explorer\\International",
564 if (RegQueryValueExA(mykey, "AcceptLanguage",
565 0, &mytype, mystr, &mystrlen)) {
566 /* Did not find value */
567 mylcid = GetUserDefaultLCID();
568 /* somehow the mylcid translates into "en-us"
569 * this is similar to "LOCALE_SABBREVLANGNAME"
570 * which could be gotten via GetLocaleInfo.
571 * The only problem is LOCALE_SABBREVLANGUAGE" is
572 * a 3 char string (first 2 are country code and third is
573 * letter for "sublanguage", which does not come close to
576 lstrcpyA(mystr, "en-us");
577 mystrlen = lstrlenA(mystr);
580 /* handle returned string */
581 FIXME("missing code\n");
583 if (mystrlen > *buflen)
584 lstrcpynA(langbuf, mystr, *buflen);
586 lstrcpyA(langbuf, mystr);
587 *buflen = lstrlenA(langbuf);
590 HeapFree(GetProcessHeap(), 0, mystr);
591 TRACE("language is %s\n", debugstr_a(langbuf));
595 /*************************************************************************
599 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
602 HRESULT WINAPI SHLWAPI_15 (
607 DWORD mystrlen, mytype;
611 mystrlen = (*buflen > 6) ? *buflen : 6;
612 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
613 HEAP_ZERO_MEMORY, mystrlen);
614 RegOpenKeyA(HKEY_CURRENT_USER,
615 "Software\\Microsoft\\Internet Explorer\\International",
617 if (RegQueryValueExA(mykey, "AcceptLanguage",
618 0, &mytype, mystr, &mystrlen)) {
619 /* Did not find value */
620 mylcid = GetUserDefaultLCID();
621 /* somehow the mylcid translates into "en-us"
622 * this is similar to "LOCALE_SABBREVLANGNAME"
623 * which could be gotten via GetLocaleInfo.
624 * The only problem is LOCALE_SABBREVLANGUAGE" is
625 * a 3 char string (first 2 are country code and third is
626 * letter for "sublanguage", which does not come close to
629 lstrcpyA(mystr, "en-us");
630 mystrlen = lstrlenA(mystr);
633 /* handle returned string */
634 FIXME("missing code\n");
637 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
638 HeapFree(GetProcessHeap(), 0, mystr);
639 TRACE("language is %s\n", debugstr_w(langbuf));
643 /*************************************************************************
646 HRESULT WINAPI SHLWAPI_16 (
652 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
656 /*************************************************************************
659 * w is pointer to address of callback routine
660 * x is pointer to LPVOID to receive address of locally allocated
662 * return is 0 (unless out of memory???)
664 * related to _19, _21 and _22 below
665 * only seen invoked by SHDOCVW
667 LONG WINAPI SHLWAPI_18 (
671 FIXME("(%p %p)stub\n",w,x);
676 /*************************************************************************
679 * w is address of allocated memory from _21
680 * return is 0 (unless out of memory???)
682 * related to _18, _21 and _22 below
683 * only seen invoked by SHDOCVW
685 LONG WINAPI SHLWAPI_19 (
688 FIXME("(%p) stub\n",w);
692 /*************************************************************************
695 * w points to space allocated via .18 above
696 * LocalSize is done on it (retrieves 18)
697 * LocalReAlloc is done on it to size 8 with LMEM_MOVEABLE & LMEM_ZEROINIT
698 * x values seen 0xa0000005
701 * relates to _18, _19 and _22 above and below
702 * only seen invoked by SHDOCVW
704 LONG WINAPI SHLWAPI_21 (
708 FIXME("(%p %lx)stub\n",w,x);
712 /*************************************************************************
715 * return is 'w' value seen in x is 0xa0000005
717 * relates to _18, _19 and _21 above
718 * only seen invoked by SHDOCVW
720 LPVOID WINAPI SHLWAPI_22 (
724 FIXME("(%p %lx)stub\n",w,x);
728 /*************************************************************************
732 * converts a guid to a string
733 * returns strlen(str)
735 DWORD WINAPI SHLWAPI_23 (
736 REFGUID guid, /* [in] clsid */
737 LPSTR str, /* [out] buffer */
738 INT cmax) /* [in] size of buffer */
742 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
743 guid->Data1, guid->Data2, guid->Data3,
744 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
745 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
746 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
747 if (strlen(xguid)>=cmax) return 0;
749 return strlen(xguid) + 1;
752 /*************************************************************************
756 * converts a guid to a string
757 * returns strlen(str)
759 DWORD WINAPI SHLWAPI_24 (
760 REFGUID guid, /* [in] clsid */
761 LPWSTR str, /* [out] buffer */
762 INT cmax) /* [in] size of buffer */
766 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
767 guid->Data1, guid->Data2, guid->Data3,
768 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
769 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
770 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
773 /*************************************************************************
776 * Seems to be iswalpha
778 BOOL WINAPI SHLWAPI_25(WCHAR wc)
780 return (get_char_typeW(wc) & C1_ALPHA) != 0;
783 /*************************************************************************
786 * Seems to be iswupper
788 BOOL WINAPI SHLWAPI_26(WCHAR wc)
790 return (get_char_typeW(wc) & C1_UPPER) != 0;
793 /*************************************************************************
796 * Seems to be iswlower
798 BOOL WINAPI SHLWAPI_27(WCHAR wc)
800 return (get_char_typeW(wc) & C1_LOWER) != 0;
803 /*************************************************************************
806 * Seems to be iswalnum
808 BOOL WINAPI SHLWAPI_28(WCHAR wc)
810 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
813 /*************************************************************************
816 * Seems to be iswspace
818 BOOL WINAPI SHLWAPI_29(WCHAR wc)
820 return (get_char_typeW(wc) & C1_SPACE) != 0;
823 /*************************************************************************
826 * Seems to be iswblank
828 BOOL WINAPI SHLWAPI_30(WCHAR wc)
830 return (get_char_typeW(wc) & C1_BLANK) != 0;
833 /*************************************************************************
836 * Seems to be iswpunct
838 BOOL WINAPI SHLWAPI_31(WCHAR wc)
840 return (get_char_typeW(wc) & C1_PUNCT) != 0;
843 /*************************************************************************
846 * Seems to be iswcntrl
848 BOOL WINAPI SHLWAPI_32(WCHAR wc)
850 return (get_char_typeW(wc) & C1_CNTRL) != 0;
853 /*************************************************************************
856 * Seems to be iswdigit
858 BOOL WINAPI SHLWAPI_33(WCHAR wc)
860 return (get_char_typeW(wc) & C1_DIGIT) != 0;
863 /*************************************************************************
866 * Seems to be iswxdigit
868 BOOL WINAPI SHLWAPI_34(WCHAR wc)
870 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
873 /*************************************************************************
877 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
879 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
883 /*************************************************************************
887 BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
889 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
890 h1, ui2, h3, debugstr_w(p4));
891 return AppendMenuW(h1, ui2, h3, p4);
894 /*************************************************************************
897 * Get the text from a given dialog item.
899 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
901 HWND hItem = GetDlgItem(hWnd, nItem);
904 return GetWindowTextW(hItem, lpsDest, nDestLen);
906 *lpsDest = (WCHAR)'\0';
910 /*************************************************************************
912 * Function: Compare two ASCII strings for "len" bytes.
913 * Returns: *str1-*str2 (case sensitive)
915 DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
917 return strncmp( str1, str2, len );
920 /*************************************************************************
923 * Function: Compare two WIDE strings for "len" bytes.
924 * Returns: *str1-*str2 (case sensitive)
926 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
928 return strncmpW( str1, str2, len );
931 /*************************************************************************
933 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
934 * Returns: *str1-*str2 (case insensitive)
936 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
938 return strncasecmp( str1, str2, len );
941 /*************************************************************************
944 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
945 * Returns: *str1-*str2 (case insensitive)
947 DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
949 return strncmpiW( str1, str2, len );
952 /*************************************************************************
955 * Case sensitive string compare (ASCII). Does not SetLastError().
957 DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
959 return strcmp(str1, str2);
962 /*************************************************************************
965 * Case sensitive string compare. Does not SetLastError().
967 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
969 return strcmpW( str1, str2 );
972 /*************************************************************************
975 * Case insensitive string compare. Does not SetLastError(). ??
977 DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
979 return strcmpiW( str1, str2 );
982 /*************************************************************************
985 * Ensure a multibyte character string doesn't end in a hanging lead byte.
987 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
991 LPSTR lastByte = lpStr + size - 1;
993 while(lpStr < lastByte)
994 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
996 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1006 /*************************************************************************
1009 DWORD WINAPI SHLWAPI_164 (
1017 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1018 return 0x80004002; /* E_NOINTERFACE */
1021 /*************************************************************************
1024 * SetWindowLongA with mask.
1026 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1028 LONG ret = GetWindowLongA(hwnd, offset);
1029 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1031 if (newFlags != ret)
1032 ret = SetWindowLongA(hwnd, offset, newFlags);
1036 /*************************************************************************
1039 * Do IUnknown::Release on passed object.
1041 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1045 TRACE("(%p)\n",lpUnknown);
1046 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1049 TRACE("doing Release\n");
1050 return IUnknown_Release(temp);
1053 /*************************************************************************
1056 * Skip URL '//' sequence.
1058 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1060 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1065 /*************************************************************************
1067 * Get window handle of OLE object
1069 DWORD WINAPI SHLWAPI_172 (
1070 IUnknown *y, /* [in] OLE object interface */
1071 LPHWND z) /* [out] location to put window handle */
1076 TRACE("(%p %p)\n",y,z);
1077 if (!y) return E_FAIL;
1079 if ((ret = IUnknown_QueryInterface(y, &IID_IOleWindow,(LPVOID *)&pv)) < 0) {
1083 ret = IOleWindow_GetWindow((IOleWindow *)pv, z);
1084 IUnknown_Release(pv);
1085 TRACE("result hwnd=%08x\n", *z);
1089 /*************************************************************************
1092 * Seems to do call either IObjectWithSite::SetSite or
1093 * IPersistMoniker::GetClassID. But since we do not implement either
1094 * of those classes in our headers, we will fake it out.
1096 DWORD WINAPI SHLWAPI_174(
1097 IUnknown *p1, /* [in] OLE object */
1098 LPVOID *p2) /* [out] ptr to result of either GetClassID
1103 if (!p1) return E_FAIL;
1105 /* see if SetSite interface exists for IObjectWithSite object */
1106 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1107 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1110 /* see if GetClassId interface exists for IPersistMoniker object */
1111 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1112 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1113 if (ret) return ret;
1115 /* fake a GetClassId call */
1116 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1117 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1119 IUnknown_Release((IUnknown *)aa);
1122 /* fake a SetSite call */
1123 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1124 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1126 IUnknown_Release((IUnknown *)p1);
1131 /*************************************************************************
1134 * Function appears to be interface to IServiceProvider::QueryService
1137 * returns E_NOINTERFACE
1139 * S_OK if _219 called successfully
1141 DWORD WINAPI SHLWAPI_176 (
1142 IUnknown* unk, /* [in] object to give Service Provider */
1143 REFGUID sid, /* [in] Service ID */
1144 REFIID riid, /* [in] Function requested */
1145 LPVOID *z) /* [out] place to save interface pointer */
1150 if (!unk) return E_FAIL;
1151 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
1152 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
1153 if (ret) return ret;
1154 ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
1156 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
1157 IUnknown_Release((IUnknown*)aa);
1161 /*************************************************************************
1164 * Enable or disable a menu item.
1166 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1168 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1171 /*************************************************************************
1174 * Register a window class if it isn't already.
1176 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1179 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1181 return (DWORD)RegisterClassA(wndclass);
1184 /*************************************************************************
1187 DWORD WINAPI SHLWAPI_193 ()
1195 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1200 /*************************************************************************
1203 * Copy interface pointer
1205 DWORD WINAPI SHLWAPI_199 (
1206 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1207 IUnknown *src) /* [in] interface pointer */
1209 TRACE("(%p %p)\n",dest,src);
1212 IUnknown_Release(*dest);
1214 IUnknown_AddRef(src);
1221 /*************************************************************************
1224 * Some sort of memory management process - associated with _210
1226 DWORD WINAPI SHLWAPI_208 (
1233 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1238 /*************************************************************************
1241 * Some sort of memory management process - associated with _208
1243 DWORD WINAPI SHLWAPI_209 (
1246 FIXME("(%p) stub\n",
1251 /*************************************************************************
1254 * Some sort of memory management process - associated with _208
1256 DWORD WINAPI SHLWAPI_210 (
1261 FIXME("(%p 0x%08lx %p) stub\n",
1266 /*************************************************************************
1269 DWORD WINAPI SHLWAPI_211 (
1273 FIXME("(%p 0x%08lx) stub\n",
1278 /*************************************************************************
1284 DWORD WINAPI SHLWAPI_215 (
1291 len_a = lstrlenA(lpStrSrc);
1292 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1293 TRACE("%s %s %d, ret=%d\n",
1294 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1298 /*************************************************************************
1301 * WideCharToMultiByte with multi language support.
1303 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1304 LPINT lpnMultiCharCount)
1306 static HRESULT (WINAPI *pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
1307 WCHAR emptyW[] = { '\0' };
1311 if (!lpDstStr || !lpnMultiCharCount)
1319 len = strlenW(lpSrcStr) + 1;
1324 CodePage = CP_UTF8; /* Fall through... */
1325 case 0x0000C350: /* FIXME: CP_ #define */
1330 INT nWideCharCount = len - 1;
1332 GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
1333 if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1337 if (nWideCharCount < len - 1)
1339 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1343 *lpnMultiCharCount = 0;
1345 if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1347 SHLWAPI_162 (mem, *lpnMultiCharCount);
1348 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1349 return *lpnMultiCharCount + 1;
1351 HeapFree(GetProcessHeap(), 0, mem);
1352 return *lpnMultiCharCount;
1354 lpDstStr[*lpnMultiCharCount] = '\0';
1355 return *lpnMultiCharCount;
1362 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1363 *lpnMultiCharCount, NULL, NULL);
1365 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1367 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1370 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1373 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1374 reqLen, NULL, NULL);
1376 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1379 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1381 HeapFree(GetProcessHeap(), 0, mem);
1388 /*************************************************************************
1391 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1392 * --> Crash. Something wrong here.
1394 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1396 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1398 INT myint = MultiCharCount;
1400 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1403 /*************************************************************************
1406 * Seems to be "super" QueryInterface. Supplied with at table of interfaces
1407 * and an array of IIDs and offsets into the table.
1410 * error codes: E_POINTER, E_NOINTERFACE
1417 HRESULT WINAPI SHLWAPI_219 (
1418 LPVOID w, /* [in] table of interfaces */
1419 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1420 REFIID riid, /* [in] REFIID to get interface for */
1421 LPVOID *z) /* [out] location to get interface pointer */
1425 IFACE_INDEX_TBL *xmove;
1427 TRACE("(%p %p %s %p)\n",
1428 w,x,debugstr_guid(riid),z);
1431 while (xmove->refid) {
1432 TRACE("trying (indx %ld) %s\n", xmove->indx,
1433 debugstr_guid(xmove->refid));
1434 if (IsEqualIID(riid, xmove->refid)) {
1435 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1436 TRACE("matched, returning (%p)\n", a_vtbl);
1437 *z = (LPVOID)a_vtbl;
1438 IUnknown_AddRef(a_vtbl);
1444 if (IsEqualIID(riid, &IID_IUnknown)) {
1445 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1446 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1447 *z = (LPVOID)a_vtbl;
1448 IUnknown_AddRef(a_vtbl);
1452 ret = E_NOINTERFACE;
1458 /*************************************************************************
1462 * securityattributes missing
1464 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
1468 sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1469 guid->Data1, guid->Data2, guid->Data3,
1470 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1471 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1472 FIXME("(%s) stub\n", lpstrName);
1473 return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
1476 /*************************************************************************
1480 * get the count of the semaphore
1482 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
1486 FIXME("(0x%08x) stub\n",handle);
1488 ReleaseSemaphore( handle, 1, &oldCount); /* +1 */
1489 WaitForSingleObject( handle, 0 ); /* -1 */
1493 /*************************************************************************
1496 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1500 CHAR value[MAX_PATH], string[MAX_PATH];
1502 strcpy(string, "CLSID\\");
1503 strcat(string, debugstr_guid(lpUnknown));
1504 strcat(string, "\\InProcServer32");
1507 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1508 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1509 RegCloseKey(newkey);
1510 return LoadLibraryExA(value, 0, 0);
1513 /*************************************************************************
1516 * Unicode version of SHLWAPI_183.
1518 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1522 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1524 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1526 return RegisterClassW(lpWndClass);
1529 /*************************************************************************
1532 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1534 FIXME("(0x%08x %p 0x%08lx) stub\n",
1535 hInstance, p2, dw3);
1538 /* pseudo code from relay trace */
1539 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1540 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1541 /* above pair repeated for:
1542 TridentThicketUrlDlClass
1551 /*************************************************************************
1554 * Calls ASCII or Unicode WindowProc for the given window.
1556 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1558 if (IsWindowUnicode(hWnd))
1559 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1560 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1563 /*************************************************************************
1567 DWORD WINAPI SHLWAPI_241 ()
1570 return /* 0xabba1243 */ 0;
1573 /*************************************************************************
1576 DWORD WINAPI SHLWAPI_266 (
1582 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1586 /*************************************************************************
1589 HRESULT WINAPI SHLWAPI_267 (
1590 LPVOID w, /* [???] NOTE: same as 1th parameter of SHLWAPI_219 */
1591 LPVOID x, /* [???] NOTE: same as 2nd parameter of SHLWAPI_219 */
1595 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1596 *((LPDWORD)z) = 0xabba1200;
1600 /*************************************************************************
1603 DWORD WINAPI SHLWAPI_268 (
1607 FIXME("(%p %p)\n",w,x);
1608 return 0xabba1251; /* 0 = failure */
1611 /*************************************************************************
1615 DWORD WINAPI SHLWAPI_276 ()
1618 return /* 0xabba1244 */ 0;
1621 /*************************************************************************
1625 HWND WINAPI SHLWAPI_278 (
1636 char * clsname = "WorkerA";
1638 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1639 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1641 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1643 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1645 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1646 wndclass.lpfnWndProc = DefWindowProcW;
1647 wndclass.cbWndExtra = 4;
1648 wndclass.hInstance = shlwapi_hInstance;
1649 wndclass.hCursor = hCursor;
1650 wndclass.hbrBackground = COLOR_BTNSHADOW;
1651 wndclass.lpszMenuName = NULL;
1652 wndclass.lpszClassName = clsname;
1653 RegisterClassA (&wndclass);
1655 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1656 hMenu,shlwapi_hInstance,0);
1657 SetWindowLongA(hwnd, 0, z);
1658 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1662 /*************************************************************************
1665 * Late bound call to winmm.PlaySoundW
1667 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1669 static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
1671 GET_FUNC(winmm, "PlaySoundW", FALSE);
1672 return pfnFunc(pszSound, hmod, fdwSound);
1675 /*************************************************************************
1678 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1681 * str1: "I" "I" pushl esp+0x20
1682 * str2: "U" "I" pushl 0x77c93810
1683 * (is "I" and "U" "integer" and "unsigned" ??)
1685 * pStr: "" "" pushl eax
1686 * some_len: 0x824 0x104 pushl 0x824
1687 * lpStr2: "%l" "%l" pushl esp+0xc
1689 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1690 * LocalAlloc(0x00, some_len) -> irrelevant_var
1691 * LocalAlloc(0x40, irrelevant_len) -> pStr
1692 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1693 * shlwapi.PathRemoveBlanksW(pStr);
1695 ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1699 /*************************************************************************
1702 * Late bound call to shell32.SHGetFileInfoW
1704 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1705 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1707 static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
1709 GET_FUNC(shell32, "SHGetFileInfoW", 0);
1710 return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1713 /*************************************************************************
1716 * Late bound call to shell32.DragQueryFileW
1718 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1720 static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
1722 GET_FUNC(shell32, "DragQueryFileW", 0);
1723 return pfnFunc(hDrop, lFile, lpszFile, lLength);
1726 /*************************************************************************
1729 * Late bound call to shell32.SHBrowseForFolderW
1731 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1733 static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
1735 GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
1736 return pfnFunc(lpBi);
1739 /*************************************************************************
1742 * Late bound call to shell32.SHGetPathFromIDListW
1744 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1746 static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
1748 GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
1749 return pfnFunc(pidl, pszPath);
1752 /*************************************************************************
1755 * Late bound call to shell32.ShellExecuteExW
1757 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1759 static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
1761 GET_FUNC(shell32, "ShellExecuteExW", FALSE);
1762 return pfnFunc(lpExecInfo);
1765 /*************************************************************************
1768 * Late bound call to shell32.SHFileOperationW.
1770 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1772 static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
1774 GET_FUNC(shell32, "SHFileOperationW", 0);
1775 return pfnFunc(lpFileOp);
1778 /*************************************************************************
1781 * Late bound call to shell32.ExtractIconExW.
1783 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1784 HICON *phiconSmall, UINT nIcons)
1786 static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
1788 GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
1789 return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1792 /*************************************************************************
1796 LONG WINAPI SHLWAPI_342( PLONG dest, LONG xchg, LONG compare)
1798 return InterlockedCompareExchange(dest, xchg, compare);
1801 /*************************************************************************
1804 DWORD WINAPI SHLWAPI_346 (
1809 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1810 lstrcpynW(dest, src, len);
1811 return lstrlenW(dest)+1;
1814 /*************************************************************************
1817 * seems to be W interface to GetFileVersionInfoSizeA
1819 DWORD WINAPI SHLWAPI_350 (
1823 static DWORD WINAPI (*pfnFunc)(LPCSTR,LPDWORD) = NULL;
1824 CHAR mbpath[MAX_PATH];
1827 GET_FUNC(version, "GetFileVersionInfoSizeA", 0);
1828 WideCharToMultiByte(0, 0, x, -1, mbpath, MAX_PATH, 0, 0);
1829 ret = pfnFunc(mbpath, y);
1833 /*************************************************************************
1836 * seems to be W interface to GetFileVersionInfoA
1838 BOOL WINAPI SHLWAPI_351 (
1839 LPWSTR w, /* [in] path to dll */
1840 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1841 DWORD y, /* [in] return value from .350 - assume length */
1842 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1844 static BOOL WINAPI (*pfnFunc)(LPCSTR,DWORD,DWORD,LPVOID) = NULL;
1845 CHAR mbpath[MAX_PATH];
1847 GET_FUNC(version, "GetFileVersionInfoA", 0);
1848 WideCharToMultiByte(0, 0, w, -1, mbpath, MAX_PATH, 0, 0);
1849 return pfnFunc(mbpath , x, y-0x208, z+0x208);
1852 /*************************************************************************
1855 * seems to be W interface to VerQueryValueA
1857 WORD WINAPI SHLWAPI_352 (
1858 LPVOID w, /* [in] buffer from _351 */
1859 LPWSTR x, /* [in] value to retrieve -
1860 converted and passed to VerQueryValueA as #2 */
1861 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1862 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1864 static WORD WINAPI (*pfnFunc)(LPVOID,LPCSTR,LPVOID*,UINT*) = NULL;
1865 CHAR buf1[MAX_PATH];
1868 GET_FUNC(version, "VerQueryValueA", 0);
1869 WideCharToMultiByte(0, 0, x, lstrlenW(x)+1, buf1, MAX_PATH, 0, 0);
1870 ret = pfnFunc(w+0x208, buf1, y, z);
1871 if (CompareStringA(GetThreadLocale(), NORM_IGNORECASE, buf1, 1,
1872 "\\StringFileInfo", 15) == 2 /* CSTR_EQUAL */) {
1873 ERR("Need to translate back to wide - should fail now\n");
1878 /**************************************************************************
1881 * mbc - this function is undocumented, The parameters are correct and
1882 * the calls to InitializeSecurityDescriptor and
1883 * SetSecurityDescriptorDacl are correct, but apparently some
1884 * apps call this function with all zero parameters.
1887 DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str)
1897 if (!InitializeSecurityDescriptor(pSD, 1)) return 0;
1898 return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0);
1902 /*************************************************************************
1905 * Late bound call to shell32.SHGetNewLinkInfoW
1907 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
1908 BOOL *pfMustCopy, UINT uFlags)
1910 static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
1912 GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
1913 return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
1916 /*************************************************************************
1919 * Late bound call to shell32.SHDefExtractIconW
1921 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
1922 LPVOID arg5, LPVOID arg6)
1924 /* FIXME: Correct args */
1925 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
1927 GET_FUNC(shell32, "SHDefExtractIconW", 0);
1928 return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
1931 /*************************************************************************
1934 * Wrapper for lstrcpynA with src and dst swapped.
1936 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
1938 lstrcpynA(dst, src, n);
1942 /*************************************************************************
1945 * Late bound call to shell32.ExtractIconW
1947 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
1950 static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
1952 GET_FUNC(shell32, "ExtractIconW", (HICON)0);
1953 return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
1956 /*************************************************************************
1959 LANGID WINAPI SHLWAPI_376 ()
1962 /* FIXME: This should be a forward in the .spec file to the win2k function
1963 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
1965 return GetUserDefaultLangID();
1968 /*************************************************************************
1971 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
1973 * FIXME: Native shows calls to:
1974 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
1976 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
1977 * RegQueryValueExA for "LPKInstalled"
1979 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
1980 * RegQueryValueExA for "ResourceLocale"
1982 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
1983 * RegQueryValueExA for "Locale"
1985 * and then tests the Locale ("en" for me).
1987 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
1989 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
1991 CHAR mod_path[2*MAX_PATH];
1994 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
1995 ptr = strrchr(mod_path, '\\');
1997 strcpy(ptr+1, new_mod);
1998 TRACE("loading %s\n", debugstr_a(mod_path));
1999 return (DWORD)LoadLibraryA(mod_path);
2004 /*************************************************************************
2007 * This is Unicode version of .377
2009 DWORD WINAPI SHLWAPI_378 (
2010 LPCWSTR new_mod, /* [in] new module name */
2011 HMODULE inst_hwnd, /* [in] calling module handle */
2012 LPVOID z) /* [???] 4 */
2014 WCHAR mod_path[2*MAX_PATH];
2017 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2018 ptr = strrchrW(mod_path, '\\');
2020 strcpyW(ptr+1, new_mod);
2021 TRACE("loading %s\n", debugstr_w(mod_path));
2022 return (DWORD)LoadLibraryW(mod_path);
2027 /*************************************************************************
2030 * Late bound call to comdlg32.GetSaveFileNameW
2032 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2034 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2036 GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
2037 return pfnFunc(ofn);
2040 /*************************************************************************
2043 * Late bound call to mpr.WNetRestoreConnectionW
2045 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2047 /* FIXME: Correct args */
2048 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
2050 GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
2051 return pfnFunc(arg1, arg2);
2054 /*************************************************************************
2057 * Late bound call to mpr.WNetGetLastErrorW
2059 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2062 /* FIXME: Correct args */
2063 static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
2065 GET_FUNC(mpr, "WNetGetLastErrorW", 0);
2066 return pfnFunc(arg1, arg2, arg3, arg4, arg5);
2069 /*************************************************************************
2072 * Late bound call to comdlg32.PageSetupDlgW
2074 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2076 static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
2078 GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
2079 return pfnFunc(pagedlg);
2082 /*************************************************************************
2085 * Late bound call to comdlg32.PrintDlgW
2087 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2089 static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
2091 GET_FUNC(comdlg32, "PrintDlgW", FALSE);
2092 return pfnFunc(printdlg);
2095 /*************************************************************************
2098 * Late bound call to comdlg32.GetOpenFileNameW
2100 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2102 static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
2104 GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
2105 return pfnFunc(ofn);
2108 /* INTERNAL: Map from HLS color space to RGB */
2109 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2111 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2115 else if (wHue > 120)
2120 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2123 /* Convert to RGB and scale into RGB range (0..255) */
2124 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2126 /*************************************************************************
2127 * ColorHLSToRGB [SHLWAPI.404]
2129 * Convert from HLS color space into an RGB COLORREF.
2132 * Input HLS values are constrained to the range (0..240).
2134 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2140 WORD wGreen, wBlue, wMid1, wMid2;
2142 if (wLuminosity > 120)
2143 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2145 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2147 wMid1 = wLuminosity * 2 - wMid2;
2149 wRed = GET_RGB(wHue + 80);
2150 wGreen = GET_RGB(wHue);
2151 wBlue = GET_RGB(wHue - 80);
2153 return RGB(wRed, wGreen, wBlue);
2156 wRed = wLuminosity * 255 / 240;
2157 return RGB(wRed, wRed, wRed);
2160 /*************************************************************************
2163 * Function unknown seems to always to return 0
2165 DWORD WINAPI SHLWAPI_413 (DWORD x)
2167 FIXME("(0x%08lx)stub\n", x);
2171 /*************************************************************************
2174 * Function seems to do FreeLibrary plus other things.
2176 * FIXME native shows the following calls:
2177 * RtlEnterCriticalSection
2179 * GetProcAddress(Comctl32??, 150L)
2181 * RtlLeaveCriticalSection
2182 * followed by the FreeLibrary.
2183 * The above code may be related to .377 above.
2185 BOOL WINAPI SHLWAPI_418 (HMODULE x)
2187 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2188 return FreeLibrary(x);
2191 /*************************************************************************
2194 DWORD WINAPI SHLWAPI_431 (DWORD x)
2196 FIXME("(0x%08lx)stub\n", x);
2200 /*************************************************************************
2203 * This is really CLSIDFromString which is exported by ole32.dll,
2204 * however the native shlwapi.dll does *not* import ole32. Nor does
2205 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2206 * that MS duplicated the code for CLSIDFromString.
2208 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2209 * in dlls/ole32/compobj.c
2211 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2219 memset(s, 0, sizeof(CLSID));
2222 else { /* validate the CLSID string */
2224 if (strlenW(s) != 38)
2225 return CO_E_CLASSSTRING;
2227 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2228 return CO_E_CLASSSTRING;
2230 for (i=1; i<37; i++)
2232 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2233 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2234 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2235 ((s[i] >= L'A') && (s[i] <= L'F')))
2237 return CO_E_CLASSSTRING;
2241 TRACE("%s -> %p\n", debugstr_w(s), id);
2243 /* quick lookup table */
2244 memset(table, 0, 256*sizeof(WCHAR));
2246 for (i = 0; i < 10; i++) {
2249 for (i = 0; i < 6; i++) {
2250 table['A' + i] = i+10;
2251 table['a' + i] = i+10;
2254 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2258 s++; /* skip leading brace */
2259 for (i = 0; i < 4; i++) {
2260 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2266 for (i = 0; i < 2; i++) {
2267 p[1-i] = table[*s]<<4 | table[*(s+1)];
2273 for (i = 0; i < 2; i++) {
2274 p[1-i] = table[*s]<<4 | table[*(s+1)];
2280 /* these are just sequential bytes */
2281 for (i = 0; i < 2; i++) {
2282 *p++ = table[*s]<<4 | table[*(s+1)];
2287 for (i = 0; i < 6; i++) {
2288 *p++ = table[*s]<<4 | table[*(s+1)];
2295 /*************************************************************************
2299 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2300 * the registry to determine what O/S & Service Pack level is running, and
2301 * therefore which functions are available. Currently we always run as NT,
2302 * since this means that we don't need extra code to emulate Unicode calls,
2303 * they are forwarded directly to the appropriate API call instead.
2304 * Since the flags for whether to call or emulate Unicode are internal to
2305 * the dll, this function does not need a full implementation.
2307 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2309 FIXME("(0x%08lx)stub\n", functionToCall);
2310 return /* 0xabba1247 */ 0;
2313 /*************************************************************************
2314 * ColorRGBToHLS [SHLWAPI.445]
2316 * Convert from RGB COLORREF into the HLS color space.
2319 * Input HLS values are constrained to the range (0..240).
2321 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2322 LPWORD wLuminance, LPWORD pwSaturation)
2328 /*************************************************************************
2329 * SHCreateShellPalette [SHLWAPI.@]
2331 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2334 return CreateHalftonePalette(hdc);
2337 /*************************************************************************
2338 * SHGetInverseCMAP (SHLWAPI.@)
2340 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2343 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2344 *x = (LPDWORD)0xabba1249;
2347 FIXME("(%p, %#lx)stub\n", x, why);
2351 /*************************************************************************
2352 * SHIsLowMemoryMachine [SHLWAPI.@]
2354 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2356 FIXME("0x%08lx\n", x);
2360 /*************************************************************************
2361 * GetMenuPosFromID [SHLWAPI.@]
2363 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2366 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2368 while (nIter < nCount)
2371 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2378 /*************************************************************************
2379 * _SHGetInstanceExplorer@4 [SHLWAPI.@]
2381 * Late bound call to shell32.SHGetInstanceExplorer.
2383 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
2385 static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
2387 GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
2388 return pfnFunc(lpUnknown);
2391 /*************************************************************************
2392 * SHGetThreadRef [SHLWAPI.@]
2394 * Retrieves the per-thread object reference set by SHSetThreadRef
2395 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
2396 * successful or E_NOINTERFACE otherwise.
2398 HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
2400 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2401 *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
2405 /*************************************************************************
2406 * SHSetThreadRef [SHLWAPI.@]
2408 * Stores a per-thread reference to a COM object
2409 * "punk" - Pointer to the IUnknown interface of the object to
2410 * which you want to store a reference. Returns S_OK if successful
2411 * or an OLE error value.
2413 HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
2415 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2416 TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);