ok() does not support '%S'. Store the Ansi version, convert to Unicode
[wine] / dlls / shlwapi / ordinal.c
1 /*
2  * SHLWAPI ordinal functions
3  *
4  * Copyright 1997 Marcus Meissner
5  *           1998 Jürgen Schmied
6  *           2001 Jon Griffiths
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #define COM_NO_WINDOWS_H
24 #include "config.h"
25 #include "wine/port.h"
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "docobj.h"
31 #include "shlguid.h"
32 #include "windef.h"
33 #include "winnls.h"
34 #include "winbase.h"
35 #include "ddeml.h"
36 #include "shlobj.h"
37 #include "shellapi.h"
38 #include "commdlg.h"
39 #include "wine/unicode.h"
40 #include "wine/obj_serviceprovider.h"
41 #include "wine/obj_control.h"
42 #include "wine/obj_connection.h"
43 #include "wine/obj_property.h"
44 #include "wingdi.h"
45 #include "winreg.h"
46 #include "winuser.h"
47 #include "wine/debug.h"
48 #include "shlwapi.h"
49
50
51 WINE_DEFAULT_DEBUG_CHANNEL(shell);
52
53 /* Get a function pointer from a DLL handle */
54 #define GET_FUNC(func, module, name, fail) \
55   do { \
56     if (!func) { \
57       if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
58       if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
59     } \
60   } while (0)
61
62 /* DLL handles for late bound calls */
63 extern HINSTANCE shlwapi_hInstance;
64 extern HMODULE SHLWAPI_hshell32;
65 extern HMODULE SHLWAPI_hwinmm;
66 extern HMODULE SHLWAPI_hcomdlg32;
67 extern HMODULE SHLWAPI_hcomctl32;
68 extern HMODULE SHLWAPI_hmpr;
69 extern HMODULE SHLWAPI_hmlang;
70 extern HMODULE SHLWAPI_hversion;
71
72 extern DWORD SHLWAPI_ThreadRef_index;
73
74 typedef HANDLE HSHARED; /* Shared memory */
75
76 /* following is GUID for IObjectWithSite::SetSite  -- see _174           */
77 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
78 /* following is GUID for IPersistMoniker::GetClassID  -- see _174        */
79 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
80
81 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
82 static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
83 static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
84 static BOOL    (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
85 static DWORD   (WINAPI *pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
86 static UINT    (WINAPI *pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
87 static BOOL    (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
88 static BOOL    (WINAPI *pShellExecuteExW)(LPSHELLEXECUTEINFOW);
89 static HICON   (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
90 static UINT    (WINAPI *pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
91 static BOOL    (WINAPI *pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
92 static HRESULT (WINAPI *pSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
93 static HICON   (WINAPI *pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
94 static BOOL    (WINAPI *pGetSaveFileNameW)(LPOPENFILENAMEW);
95 static DWORD   (WINAPI *pWNetRestoreConnectionW)(HWND, LPWSTR);
96 static DWORD   (WINAPI *pWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
97 static BOOL    (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW);
98 static BOOL    (WINAPI *pPrintDlgW)(LPPRINTDLGW);
99 static BOOL    (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW);
100 static DWORD   (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
101 static BOOL    (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
102 static WORD    (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
103 static BOOL    (WINAPI *pCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
104 static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO*);
105
106 /*
107  NOTES: Most functions exported by ordinal seem to be superflous.
108  The reason for these functions to be there is to provide a wrapper
109  for unicode functions to provide these functions on systems without
110  unicode functions eg. win95/win98. Since we have such functions we just
111  call these. If running Wine with native DLL's, some late bound calls may
112  fail. However, its better to implement the functions in the forward DLL
113  and recommend the builtin rather than reimplementing the calls here!
114 */
115
116 /*************************************************************************
117  * SHLWAPI_DupSharedHandle
118  *
119  * Internal implemetation of SHLWAPI_11.
120  */
121 static
122 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
123                                        DWORD dwSrcProcId, DWORD dwAccess,
124                                        DWORD dwOptions)
125 {
126   HANDLE hDst, hSrc;
127   DWORD dwMyProcId = GetCurrentProcessId();
128   HSHARED hRet = (HSHARED)NULL;
129
130   TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
131         dwAccess, dwOptions);
132
133   /* Get dest process handle */
134   if (dwDstProcId == dwMyProcId)
135     hDst = GetCurrentProcess();
136   else
137     hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
138
139   if (hDst)
140   {
141     /* Get src process handle */
142     if (dwSrcProcId == dwMyProcId)
143       hSrc = GetCurrentProcess();
144     else
145       hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
146
147     if (hSrc)
148     {
149       /* Make handle available to dest process */
150       if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
151                            dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
152         hRet = (HSHARED)NULL;
153
154       if (dwSrcProcId != dwMyProcId)
155         CloseHandle(hSrc);
156     }
157
158     if (dwDstProcId != dwMyProcId)
159       CloseHandle(hDst);
160   }
161
162   TRACE("Returning handle %p\n", (PVOID)hRet);
163   return hRet;
164 }
165
166 /*************************************************************************
167  * @  [SHLWAPI.7]
168  *
169  * Create a block of sharable memory and initialise it with data.
170  *
171  * PARAMS
172  * dwProcId [I] ID of process owning data
173  * lpvData  [I] Pointer to data to write
174  * dwSize   [I] Size of data
175  *
176  * RETURNS
177  * Success: A shared memory handle
178  * Failure: NULL
179  *
180  * NOTES
181  * Ordinals 7-11 provide a set of calls to create shared memory between a
182  * group of processes. The shared memory is treated opaquely in that its size
183  * is not exposed to clients who map it. This is accomplished by storing
184  * the size of the map as the first DWORD of mapped data, and then offsetting
185  * the view pointer returned by this size.
186  *
187  * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
188  * SHLWAPI_8/SHLWAPI_9  - Get/Release a pointer to the shared data
189  * SHLWAPI_11           - Helper function; Duplicate cross-process handles
190    */
191 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
192 {
193   HANDLE hMap;
194   LPVOID pMapped;
195   HSHARED hRet = (HSHARED)NULL;
196
197   TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
198
199   /* Create file mapping of the correct length */
200   hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
201                             dwSize + sizeof(dwSize), NULL);
202   if (!hMap)
203     return hRet;
204
205   /* Get a view in our process address space */
206   pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
207
208   if (pMapped)
209   {
210     /* Write size of data, followed by the data, to the view */
211     *((DWORD*)pMapped) = dwSize;
212     if (dwSize)
213       memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
214
215     /* Release view. All further views mapped will be opaque */
216     UnmapViewOfFile(pMapped);
217     hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
218                                    GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
219                                    DUPLICATE_SAME_ACCESS);
220   }
221
222   CloseHandle(hMap);
223   return hRet;
224 }
225
226 /*************************************************************************
227  * @ [SHLWAPI.8]
228  *
229  * Get a pointer to a block of shared memory from a shared memory handle.
230  *
231  * PARAMS
232  * hShared  [I] Shared memory handle
233  * dwProcId [I] ID of process owning hShared
234  *
235  * RETURNS
236  * Success: A pointer to the shared memory
237  * Failure: NULL
238  *
239  * NOTES
240  * See SHLWAPI_7.
241    */
242 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
243   {
244   HSHARED hDup;
245   LPVOID pMapped;
246
247   TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
248
249   /* Get handle to shared memory for current process */
250   hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
251                                  FILE_MAP_ALL_ACCESS, 0);
252   /* Get View */
253   pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
254   CloseHandle(hDup);
255
256   if (pMapped)
257     return (char *) pMapped + sizeof(DWORD); /* Hide size */
258   return NULL;
259 }
260
261 /*************************************************************************
262  * @ [SHLWAPI.9]
263  *
264  * Release a pointer to a block of shared memory.
265  *
266  * PARAMS
267  * lpView [I] Shared memory pointer
268  *
269  * RETURNS
270  * Success: TRUE
271  * Failure: FALSE
272  *
273  * NOTES
274  * See SHLWAPI_7.
275  */
276 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
277 {
278   TRACE("(%p)\n", lpView);
279   return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
280 }
281
282 /*************************************************************************
283  * @ [SHLWAPI.10]
284  *
285  * Destroy a block of sharable memory.
286  *
287  * PARAMS
288  * hShared  [I] Shared memory handle
289  * dwProcId [I] ID of process owning hShared
290  *
291  * RETURNS
292  * Success: TRUE
293  * Failure: FALSE
294  *
295  * NOTES
296  * See SHLWAPI_7.
297  */
298 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
299 {
300   HSHARED hClose;
301
302   TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
303
304   /* Get a copy of the handle for our process, closing the source handle */
305   hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
306                                    FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
307   /* Close local copy */
308   return CloseHandle((HANDLE)hClose);
309 }
310
311 /*************************************************************************
312  * @   [SHLWAPI.11]
313  *
314  * Copy a sharable memory handle from one process to another.
315  *
316  * PARAMS
317  * hShared     [I] Shared memory handle to duplicate
318  * dwDstProcId [I] ID of the process wanting the duplicated handle
319  * dwSrcProcId [I] ID of the process owning hShared
320  * dwAccess    [I] Desired DuplicateHandle access
321  * dwOptions   [I] Desired DuplicateHandle options
322  *
323  * RETURNS
324  * Success: A handle suitable for use by the dwDstProcId process.
325  * Failure: A NULL handle.
326  *
327  * NOTES
328  * See SHLWAPI_7.
329  */
330 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
331                           DWORD dwAccess, DWORD dwOptions)
332 {
333   HSHARED hRet;
334
335   hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
336                                  dwAccess, dwOptions);
337   return hRet;
338 }
339
340 /*************************************************************************
341  *      @       [SHLWAPI.13]
342  *
343  * Create and register a clipboard enumerator for a web browser.
344  *
345  * PARAMS
346  *  lpBC      [I] Binding context
347  *  lpUnknown [I] An object exposing the IWebBrowserApp interface
348  *
349  * RETURNS
350  *  Success: S_OK.
351  *  Failure: An HRESULT error code.
352  *
353  * NOTES
354  *  The enumerator is stored as a property of the web browser. If it does not
355  *  yet exist, it is created and set before being registered.
356  *
357  * BUGS
358  *  Unimplemented.
359  */
360 HRESULT WINAPI SHLWAPI_13(LPBC lpBC, IUnknown *lpUnknown)
361 {
362         FIXME("(%p,%p) stub\n", lpBC, lpUnknown);
363         return 1;
364 #if 0
365         /* pseudo code extracted from relay trace */
366         RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Accepted Documents", &newkey);
367         ret = 0;
368         i = 0;
369         size = 0;
370         while(!ret) {
371             ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
372             size += ???;
373             i++;
374         }
375         b1 = LocalAlloc(0x40, size);
376         ret = 0;
377         i = 0;
378         while(!ret) {
379             ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
380             RegisterClipBoardFormatA(a4);
381             i++;
382         }
383         hmod1 = GetModuleHandleA("URLMON.DLL");
384         proc = GetProcAddress(hmod1, "CreateFormatEnumerator");
385         HeapAlloc(??, 0, 0x14);
386         HeapAlloc(??, 0, 0x50);
387         LocalAlloc(0x40, 0x78);
388         /* FIXME: bad string below */
389         lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
390         StrCpyW(a6,  L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
391
392         GetTickCount();
393         IsBadReadPtr(c1 = 0x403fd210,4);
394         InterlockedIncrement(c1+4);
395         LocalFree(b1);
396         RegCloseKey(newkey);
397         IsBadReadPtr(c1 = 0x403fd210,4);
398         InterlockedIncrement(c1+4);
399
400         HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
401         HeapAlloc(40350000,00000000,00000050) retval=403feb44;
402         hmod1 = GetModuleHandleA("URLMON.DLL");
403         proc = GetProcAddress(hmod1, "RegisterFormatEnumerator");
404         /* 0x1a40c88c is in URLMON.DLL just before above proc
405          * content is L"_EnumFORMATETC_"
406          * label is d1
407          */
408         IsBadReadPtr(d1 = 0x1a40c88c,00000002);
409         lstrlenW(d1);
410         lstrlenW(d1);
411         HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
412         IsBadReadPtr(d2 = 0x403fd0a8,00000004);
413         InterlockedIncrement(d2+4);
414         IsBadReadPtr(d2 = 0x403fd0a8,00000004);
415         InterlockedDecrement(d2+4);
416         IsBadReadPtr(c1,00000004);
417         InterlockedDecrement(c1+4);
418         IsBadReadPtr(c1,00000004);
419         InterlockedDecrement(c1+4);
420
421 #endif
422 }
423
424 /*************************************************************************
425  *      @       [SHLWAPI.14]
426  *
427  * Get Explorers "AcceptLanguage" setting.
428  *
429  * PARAMS
430  *  langbuf [O] Destination for language string
431  *  buflen  [I] Length of langbuf
432  *
433  * RETURNS
434  *  Success: S_OK.   langbuf is set to the language string found.
435  *  Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
436  *           does not contain the setting.
437  */
438 HRESULT WINAPI SHLWAPI_14 (
439         LPSTR langbuf,
440         LPDWORD buflen)
441 {
442         CHAR *mystr;
443         DWORD mystrlen, mytype;
444         HKEY mykey;
445         LCID mylcid;
446
447         mystrlen = (*buflen > 6) ? *buflen : 6;
448         mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
449                                  HEAP_ZERO_MEMORY, mystrlen);
450         RegOpenKeyA(HKEY_CURRENT_USER,
451                     "Software\\Microsoft\\Internet Explorer\\International",
452                     &mykey);
453         if (RegQueryValueExA(mykey, "AcceptLanguage",
454                               0, &mytype, mystr, &mystrlen)) {
455             /* Did not find value */
456             mylcid = GetUserDefaultLCID();
457             /* somehow the mylcid translates into "en-us"
458              *  this is similar to "LOCALE_SABBREVLANGNAME"
459              *  which could be gotten via GetLocaleInfo.
460              *  The only problem is LOCALE_SABBREVLANGUAGE" is
461              *  a 3 char string (first 2 are country code and third is
462              *  letter for "sublanguage", which does not come close to
463              *  "en-us"
464              */
465             lstrcpyA(mystr, "en-us");
466             mystrlen = lstrlenA(mystr);
467         }
468         else {
469             /* handle returned string */
470             FIXME("missing code\n");
471         }
472         if (mystrlen > *buflen)
473             lstrcpynA(langbuf, mystr, *buflen);
474         else {
475             lstrcpyA(langbuf, mystr);
476             *buflen = lstrlenA(langbuf);
477         }
478         RegCloseKey(mykey);
479         HeapFree(GetProcessHeap(), 0, mystr);
480         TRACE("language is %s\n", debugstr_a(langbuf));
481         return 0;
482 }
483
484 /*************************************************************************
485  *      @       [SHLWAPI.15]
486  *
487  * Unicode version of SHLWAPI_14.
488  */
489 HRESULT WINAPI SHLWAPI_15 (
490         LPWSTR langbuf,
491         LPDWORD buflen)
492 {
493         CHAR *mystr;
494         DWORD mystrlen, mytype;
495         HKEY mykey;
496         LCID mylcid;
497
498         mystrlen = (*buflen > 6) ? *buflen : 6;
499         mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
500                                  HEAP_ZERO_MEMORY, mystrlen);
501         RegOpenKeyA(HKEY_CURRENT_USER,
502                     "Software\\Microsoft\\Internet Explorer\\International",
503                     &mykey);
504         if (RegQueryValueExA(mykey, "AcceptLanguage",
505                               0, &mytype, mystr, &mystrlen)) {
506             /* Did not find value */
507             mylcid = GetUserDefaultLCID();
508             /* somehow the mylcid translates into "en-us"
509              *  this is similar to "LOCALE_SABBREVLANGNAME"
510              *  which could be gotten via GetLocaleInfo.
511              *  The only problem is LOCALE_SABBREVLANGUAGE" is
512              *  a 3 char string (first 2 are country code and third is
513              *  letter for "sublanguage", which does not come close to
514              *  "en-us"
515              */
516             lstrcpyA(mystr, "en-us");
517             mystrlen = lstrlenA(mystr);
518         }
519         else {
520             /* handle returned string */
521             FIXME("missing code\n");
522         }
523         RegCloseKey(mykey);
524         *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
525         HeapFree(GetProcessHeap(), 0, mystr);
526         TRACE("language is %s\n", debugstr_w(langbuf));
527         return 0;
528 }
529
530 /*************************************************************************
531  *      @       [SHLWAPI.23]
532  *
533  * NOTES
534  *      converts a guid to a string
535  *      returns strlen(str)
536  */
537 DWORD WINAPI SHLWAPI_23 (
538         REFGUID guid,   /* [in]  clsid */
539         LPSTR str,      /* [out] buffer */
540         INT cmax)       /* [in]  size of buffer */
541 {
542         char xguid[40];
543
544         sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
545                  guid->Data1, guid->Data2, guid->Data3,
546                  guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
547                  guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
548         TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
549         if (strlen(xguid)>=cmax) return 0;
550         strcpy(str,xguid);
551         return strlen(xguid) + 1;
552 }
553
554 /*************************************************************************
555  *      @       [SHLWAPI.24]
556  *
557  * NOTES
558  *      converts a guid to a string
559  *      returns strlen(str)
560  */
561 DWORD WINAPI SHLWAPI_24 (
562         REFGUID guid,   /* [in]  clsid */
563         LPWSTR str,     /* [out] buffer */
564         INT cmax)       /* [in]  size of buffer */
565 {
566     char xguid[40];
567
568     sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
569              guid->Data1, guid->Data2, guid->Data3,
570              guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
571              guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
572     return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
573 }
574
575 /*************************************************************************
576  *      @       [SHLWAPI.25]
577  *
578  * Seems to be iswalpha
579  */
580 BOOL WINAPI SHLWAPI_25(WCHAR wc)
581 {
582     return (get_char_typeW(wc) & C1_ALPHA) != 0;
583 }
584
585 /*************************************************************************
586  *      @       [SHLWAPI.26]
587  *
588  * Seems to be iswupper
589  */
590 BOOL WINAPI SHLWAPI_26(WCHAR wc)
591 {
592     return (get_char_typeW(wc) & C1_UPPER) != 0;
593 }
594
595 /*************************************************************************
596  *      @       [SHLWAPI.27]
597  *
598  * Seems to be iswlower
599  */
600 BOOL WINAPI SHLWAPI_27(WCHAR wc)
601 {
602     return (get_char_typeW(wc) & C1_LOWER) != 0;
603 }
604
605 /*************************************************************************
606  *      @       [SHLWAPI.28]
607  *
608  * Seems to be iswalnum
609  */
610 BOOL WINAPI SHLWAPI_28(WCHAR wc)
611 {
612     return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
613 }
614
615 /*************************************************************************
616  *      @       [SHLWAPI.29]
617  *
618  * Seems to be iswspace
619  */
620 BOOL WINAPI SHLWAPI_29(WCHAR wc)
621 {
622     return (get_char_typeW(wc) & C1_SPACE) != 0;
623 }
624
625 /*************************************************************************
626  *      @       [SHLWAPI.30]
627  *
628  * Seems to be iswblank
629  */
630 BOOL WINAPI SHLWAPI_30(WCHAR wc)
631 {
632     return (get_char_typeW(wc) & C1_BLANK) != 0;
633 }
634
635 /*************************************************************************
636  *      @       [SHLWAPI.31]
637  *
638  * Seems to be iswpunct
639  */
640 BOOL WINAPI SHLWAPI_31(WCHAR wc)
641 {
642     return (get_char_typeW(wc) & C1_PUNCT) != 0;
643 }
644
645 /*************************************************************************
646  *      @       [SHLWAPI.32]
647  *
648  * Seems to be iswcntrl
649  */
650 BOOL WINAPI SHLWAPI_32(WCHAR wc)
651 {
652     return (get_char_typeW(wc) & C1_CNTRL) != 0;
653 }
654
655 /*************************************************************************
656  *      @       [SHLWAPI.33]
657  *
658  * Seems to be iswdigit
659  */
660 BOOL WINAPI SHLWAPI_33(WCHAR wc)
661 {
662     return (get_char_typeW(wc) & C1_DIGIT) != 0;
663 }
664
665 /*************************************************************************
666  *      @       [SHLWAPI.34]
667  *
668  * Seems to be iswxdigit
669  */
670 BOOL WINAPI SHLWAPI_34(WCHAR wc)
671 {
672     return (get_char_typeW(wc) & C1_XDIGIT) != 0;
673 }
674
675 /*************************************************************************
676  *      @       [SHLWAPI.35]
677  *
678  */
679 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
680 {
681     FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
682     return TRUE;
683 }
684
685 /*************************************************************************
686  *      @       [SHLWAPI.36]
687  *
688  * Insert a bitmap menu item at the bottom of a menu.
689  *
690  * PARAMS
691  *  hMenu [I] Menu to insert into
692  *  flags [I] Flags for insertion
693  *  id    [I] Menu ID of the item
694  *  str   [I] Menu text for the item
695  *
696  * RETURNS
697  *  Success: TRUE,  the item is inserted into the menu
698  *  Failure: FALSE, if any parameter is invalid
699  */
700 BOOL WINAPI SHLWAPI_36(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
701 {
702     TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
703     return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
704 }
705
706 /*************************************************************************
707  *      @       [SHLWAPI.74]
708  *
709  * Get the text from a given dialog item.
710  *
711  * PARAMS
712  *  hWnd     [I] Handle of dialog
713  *  nItem    [I] Index of item
714  *  lpsDest  [O] Buffer for receiving window text
715  *  nDestLen [I] Length of buffer.
716  *
717  * RETURNS
718  *  Success: The length of the returned text.
719  *  Failure: 0.
720  */
721 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
722 {
723   HWND hItem = GetDlgItem(hWnd, nItem);
724
725   if (hItem)
726     return GetWindowTextW(hItem, lpsDest, nDestLen);
727   if (nDestLen)
728     *lpsDest = (WCHAR)'\0';
729   return 0;
730 }
731
732 /*************************************************************************
733  *      @   [SHLWAPI.138]
734  *
735  * Set the text of a given dialog item.
736  *
737  * PARAMS
738  *  hWnd     [I] Handle of dialog
739  *  iItem    [I] Index of item
740  *  lpszText [O] Text to set
741  *
742  * RETURNS
743  *  Success: TRUE.  The text of the dialog is set to lpszText.
744  *  Failure: FALSE, Otherwise.
745  */
746 BOOL WINAPI SHLWAPI_138(HWND hWnd, INT iItem, LPCWSTR lpszText)
747 {
748     HWND hWndItem = GetDlgItem(hWnd, iItem);
749     if (hWndItem)
750         return SetWindowTextW(hWndItem, lpszText);
751     return FALSE;
752 }
753
754 /*************************************************************************
755  *      @       [SHLWAPI.151]
756  * Function:  Compare two ASCII strings for "len" bytes.
757  * Returns:   *str1-*str2  (case sensitive)
758  */
759 DWORD WINAPI SHLWAPI_151(LPCSTR str1, LPCSTR str2, INT len)
760 {
761     return strncmp( str1, str2, len );
762 }
763
764 /*************************************************************************
765  *      @       [SHLWAPI.152]
766  *
767  * Function:  Compare two WIDE strings for "len" bytes.
768  * Returns:   *str1-*str2  (case sensitive)
769  */
770 DWORD WINAPI SHLWAPI_152(LPCWSTR str1, LPCWSTR str2, INT len)
771 {
772     return strncmpW( str1, str2, len );
773 }
774
775 /*************************************************************************
776  *      @       [SHLWAPI.153]
777  * Function:  Compare two ASCII strings for "len" bytes via caseless compare.
778  * Returns:   *str1-*str2  (case insensitive)
779  */
780 DWORD WINAPI SHLWAPI_153(LPCSTR str1, LPCSTR str2, DWORD len)
781 {
782     return strncasecmp( str1, str2, len );
783 }
784
785 /*************************************************************************
786  *      @       [SHLWAPI.154]
787  *
788  * Function:  Compare two WIDE strings for "len" bytes via caseless compare.
789  * Returns:   *str1-*str2  (case insensitive)
790  */
791 DWORD WINAPI SHLWAPI_154(LPCWSTR str1, LPCWSTR str2, DWORD len)
792 {
793     return strncmpiW( str1, str2, len );
794 }
795
796 /*************************************************************************
797  *      @       [SHLWAPI.155]
798  *
799  *      Case sensitive string compare (ASCII). Does not SetLastError().
800  */
801 DWORD WINAPI SHLWAPI_155(LPCSTR str1, LPCSTR str2)
802 {
803     return strcmp(str1, str2);
804 }
805
806 /*************************************************************************
807  *      @       [SHLWAPI.156]
808  *
809  *      Case sensitive string compare. Does not SetLastError().
810  */
811 DWORD WINAPI SHLWAPI_156(LPCWSTR str1, LPCWSTR str2)
812 {
813     return strcmpW( str1, str2 );
814 }
815
816 /*************************************************************************
817  *      @       [SHLWAPI.157]
818  *
819  *      Case insensitive string compare (ASCII). Does not SetLastError().
820  */
821 DWORD WINAPI SHLWAPI_157(LPCSTR str1, LPCSTR str2)
822 {
823     return strcasecmp(str1, str2);
824 }
825 /*************************************************************************
826  *      @       [SHLWAPI.158]
827  *
828  *      Case insensitive string compare. Does not SetLastError(). ??
829  */
830 DWORD WINAPI SHLWAPI_158 (LPCWSTR str1, LPCWSTR str2)
831 {
832     return strcmpiW( str1, str2 );
833 }
834
835 /*************************************************************************
836  *      @       [SHLWAPI.162]
837  *
838  * Remove a hanging lead byte from the end of a string, if present.
839  *
840  * PARAMS
841  *  lpStr [I] String to check for a hanging lead byte
842  *  size  [I] Length of lpszStr
843  *
844  * RETURNS
845  *  Success: The new size of the string. Any hanging lead bytes are removed.
846  *  Failure: 0, if any parameters are invalid.
847  */
848 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
849 {
850   if (lpStr && size)
851   {
852     LPSTR lastByte = lpStr + size - 1;
853
854     while(lpStr < lastByte)
855       lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
856
857     if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
858     {
859       *lpStr = '\0';
860       size--;
861     }
862     return size;
863   }
864   return 0;
865 }
866
867 /*************************************************************************
868  *      @       [SHLWAPI.163]
869  *
870  * Call IOleCommandTarget::QueryStatus() on an object.
871  *
872  * PARAMS
873  *  lpUnknown     [I] Object supporting the IOleCommandTarget interface
874  *  pguidCmdGroup [I] GUID for the command group
875  *  cCmds         [I]
876  *  prgCmds       [O] Commands
877  *  pCmdText      [O] Command text
878  *
879  * RETURNS
880  *  Success: S_OK.
881  *  Failure: E_FAIL, if lpUnknown is NULL.
882  *           E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
883  *           Otherwise, an error code from IOleCommandTarget::QueryStatus().
884  */
885 HRESULT WINAPI SHLWAPI_163(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
886                            ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
887 {
888   HRESULT hRet = E_FAIL;
889
890   TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
891
892   if (lpUnknown)
893   {
894     IOleCommandTarget* lpOle;
895
896     hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
897                                    (void**)&lpOle);
898
899     if (SUCCEEDED(hRet) && lpOle)
900     {
901       hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
902                                            prgCmds, pCmdText);
903       IOleCommandTarget_Release(lpOle);
904     }
905   }
906   return hRet;
907 }
908
909 /*************************************************************************
910  *      @               [SHLWAPI.164]
911  *
912  * Call IOleCommandTarget::Exec() on an object.
913  *
914  * PARAMS
915  *  lpUnknown     [I] Object supporting the IOleCommandTarget interface
916  *  pguidCmdGroup [I] GUID for the command group
917  *
918  * RETURNS
919  *  Success: S_OK.
920  *  Failure: E_FAIL, if lpUnknown is NULL.
921  *           E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
922  *           Otherwise, an error code from IOleCommandTarget::Exec().
923  */
924 HRESULT WINAPI SHLWAPI_164(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
925                            DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
926                            VARIANT* pvaOut)
927 {
928   HRESULT hRet = E_FAIL;
929
930   TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
931         nCmdexecopt, pvaIn, pvaOut);
932
933   if (lpUnknown)
934   {
935     IOleCommandTarget* lpOle;
936
937     hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
938                                    (void**)&lpOle);
939     if (SUCCEEDED(hRet) && lpOle)
940     {
941       hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
942                                     nCmdexecopt, pvaIn, pvaOut);
943       IOleCommandTarget_Release(lpOle);
944     }
945   }
946   return hRet;
947 }
948
949 /*************************************************************************
950  *      @       [SHLWAPI.165]
951  *
952  * Retrieve, modify, and re-set a value from a window.
953  *
954  * PARAMS
955  *  hWnd   [I] Windows to get value from
956  *  offset [I] Offset of value
957  *  wMask  [I] Mask for uiFlags
958  *  wFlags [I] Bits to set in window value
959  *
960  * RETURNS
961  *  The new value as it was set, or 0 if any parameter is invalid.
962  *
963  * NOTES
964  *  Any bits set in uiMask are cleared from the value, then any bits set in
965  *  uiFlags are set in the value.
966  */
967 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
968 {
969   LONG ret = GetWindowLongA(hwnd, offset);
970   UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
971
972   if (newFlags != ret)
973     ret = SetWindowLongA(hwnd, offset, newFlags);
974   return ret;
975 }
976
977 /*************************************************************************
978  *      @       [SHLWAPI.167]
979  *
980  * Change a window's parent.
981  *
982  * PARAMS
983  *  hWnd       [I] Window to change parent of
984  *  hWndParent [I] New parent window
985  *
986  * RETURNS
987  *  The old parent of hWnd.
988  *
989  * NOTES
990  *  If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
991  *  If hWndParent is NOT NULL then we set the WS_CHILD style.
992  */
993 HWND WINAPI SHLWAPI_167(HWND hWnd, HWND hWndParent)
994 {
995   TRACE("%p, %p\n", hWnd, hWndParent);
996
997   if(GetParent(hWnd) == hWndParent)
998     return 0;
999
1000   if(hWndParent)
1001     SHLWAPI_165(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1002   else
1003     SHLWAPI_165(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1004
1005   return SetParent(hWnd, hWndParent);
1006 }
1007
1008 /*************************************************************************
1009  *      @       [SHLWAPI.168]
1010  *
1011  * Locate and advise a connection point in an IConnectionPointContainer.
1012  *
1013  * PARAMS
1014  *  lpUnkSink   [I] Sink for the connection point advise call
1015  *  riid        [I] REFIID of connection point to advise
1016  *  bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1017  *  lpUnknown   [I] Object supporting the IConnectionPointContainer interface
1018  *  lpCookie    [O] Pointer to connection point cookie
1019  *  lppCP       [O] Destination for the IConnectionPoint found
1020  *
1021  * RETURNS
1022  *  Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1023  *           that was advised. The caller is responsable for releasing it.
1024  *  Failure: E_FAIL, if any arguments are invalid.
1025  *           E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1026  *           Or an HRESULT error code if any call fails.
1027  */
1028 HRESULT WINAPI SHLWAPI_168(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1029                            IUnknown* lpUnknown, LPDWORD lpCookie,
1030                            IConnectionPoint **lppCP)
1031 {
1032   HRESULT hRet;
1033   IConnectionPointContainer* lpContainer;
1034   IConnectionPoint *lpCP;
1035
1036   if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1037     return E_FAIL;
1038
1039   if(lppCP)
1040     *lppCP = NULL;
1041
1042   hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1043                                  (void**)&lpContainer);
1044   if (SUCCEEDED(hRet))
1045   {
1046     hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1047
1048     if (SUCCEEDED(hRet))
1049     {
1050       if(!bAdviseOnly)
1051         hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1052       hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1053
1054       if (FAILED(hRet))
1055         *lpCookie = 0;
1056
1057       if (lppCP && SUCCEEDED(hRet))
1058         *lppCP = lpCP; /* Caller keeps the interface */
1059       else
1060         IConnectionPoint_Release(lpCP); /* Release it */
1061     }
1062
1063     IUnknown_Release(lpContainer);
1064   }
1065   return hRet;
1066 }
1067
1068 /*************************************************************************
1069  *      @       [SHLWAPI.169]
1070  *
1071  *
1072  * Release an interface.
1073  *
1074  * PARAMS
1075  *  lpUnknown [I] Object to release
1076  *
1077  * RETURNS
1078  *  Nothing.
1079  */
1080 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1081 {
1082         IUnknown *temp;
1083
1084         TRACE("(%p)\n",lpUnknown);
1085         if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1086         temp = *lpUnknown;
1087         *lpUnknown = NULL;
1088         TRACE("doing Release\n");
1089         return IUnknown_Release(temp);
1090 }
1091
1092 /*************************************************************************
1093  *      @       [SHLWAPI.170]
1094  *
1095  * Skip '//' if present in a string.
1096  *
1097  * PARAMS
1098  *  lpszSrc [I] String to check for '//'
1099  *
1100  * RETURNS
1101  *  Success: The next character after the '//' or the string if not present
1102  *  Failure: NULL, if lpszStr is NULL.
1103  */
1104 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1105 {
1106   if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1107     lpszSrc += 2;
1108   return lpszSrc;
1109 }
1110
1111 /*************************************************************************
1112  *      @               [SHLWAPI.171]
1113  *
1114  * Check the two interfaces if they come from the same object.
1115  *
1116  * PARAMS
1117  *   lpInt1 [I]: Interface to check against lpInt2.
1118  *   lpInt2 [I]: Interface to check against lpInt1.
1119  *
1120  * RETURNS
1121  *   TRUE: Interfaces come from the same object.
1122  *   FALSE: Interfaces come from different objects.
1123  */
1124 BOOL WINAPI SHLWAPI_171(IUnknown* lpInt1, IUnknown* lpInt2)
1125 {
1126   LPVOID lpUnknown1, lpUnknown2;
1127
1128   TRACE("%p %p\n", lpInt1, lpInt2);
1129
1130   if (!lpInt1 || !lpInt2)
1131     return FALSE;
1132
1133   if (lpInt1 == lpInt2)
1134     return TRUE;
1135
1136   if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1137                                        (LPVOID *)&lpUnknown1)))
1138     return FALSE;
1139
1140   if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1141                                        (LPVOID *)&lpUnknown2)))
1142     return FALSE;
1143
1144   if (lpUnknown1 == lpUnknown2)
1145     return TRUE;
1146   
1147   return FALSE;
1148 }
1149
1150 /*************************************************************************
1151  *      @       [SHLWAPI.172]
1152  *
1153  * Get the window handle of an object.
1154  *
1155  * PARAMS
1156  *  lpUnknown [I] Object to get the window handle of
1157  *  lphWnd    [O] Destination for window handle
1158  *
1159  * RETURNS
1160  *  Success: S_OK. lphWnd contains the objects window handle.
1161  *  Failure: An HRESULT error code.
1162  *
1163  * NOTES
1164  *  lpUnknown is expected to support one of the following interfaces:
1165  *   IOleWindow
1166  *   IInternetSecurityMgrSite
1167  *   IShellView
1168  */
1169 HRESULT WINAPI SHLWAPI_172(IUnknown *lpUnknown, HWND *lphWnd)
1170 {
1171   /* FIXME: Wine has no header for this object */
1172   static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1173     0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1174   IUnknown *lpOle;
1175   HRESULT hRet = E_FAIL;
1176
1177   TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1178
1179   if (!lpUnknown)
1180     return hRet;
1181
1182   hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1183
1184   if (FAILED(hRet))
1185   {
1186     hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1187
1188     if (FAILED(hRet))
1189     {
1190       hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1191                                       (void**)&lpOle);
1192     }
1193   }
1194
1195   if (SUCCEEDED(hRet))
1196   {
1197     /* Lazyness here - Since GetWindow() is the first method for the above 3
1198      * interfaces, we use the same call for them all.
1199      */
1200     hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1201     IUnknown_Release(lpOle);
1202     if (lphWnd)
1203       TRACE("Returning HWND=%p\n", *lphWnd);
1204   }
1205
1206   return hRet;
1207 }
1208
1209 /*************************************************************************
1210  *      @       [SHLWAPI.174]
1211  *
1212  * Seems to do call either IObjectWithSite::SetSite or
1213  *   IPersistMoniker::GetClassID.  But since we do not implement either
1214  *   of those classes in our headers, we will fake it out.
1215  */
1216 DWORD WINAPI SHLWAPI_174(
1217         IUnknown *p1,     /* [in]   OLE object                          */
1218         LPVOID *p2)       /* [out]  ptr to result of either GetClassID
1219                                     or SetSite call.                    */
1220 {
1221     DWORD ret, aa;
1222
1223     if (!p1) return E_FAIL;
1224
1225     /* see if SetSite interface exists for IObjectWithSite object */
1226     ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1227     TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1228     if (ret) {
1229
1230         /* see if GetClassId interface exists for IPersistMoniker object */
1231         ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1232         TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1233         if (ret) return ret;
1234
1235         /* fake a GetClassId call */
1236         ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1237         TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1238               *(LPDWORD)p2);
1239         IUnknown_Release((IUnknown *)aa);
1240     }
1241     else {
1242         /* fake a SetSite call */
1243         ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1244         TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1245               *(LPDWORD)p2);
1246         IUnknown_Release((IUnknown *)p1);
1247     }
1248     return ret;
1249 }
1250
1251 /*************************************************************************
1252  *      @       [SHLWAPI.175]
1253  *
1254  * Call IPersist::GetClassID on an object.
1255  *
1256  * PARAMS
1257  *  lpUnknown [I] Object supporting the IPersist interface
1258  *  lpClassId [O] Destination for Class Id
1259  *
1260  * RETURNS
1261  *  Success: S_OK. lpClassId contains the Class Id requested.
1262  *  Failure: E_FAIL, If lpUnknown is NULL,
1263  *           E_NOINTERFACE If lpUnknown does not support IPersist,
1264  *           Or an HRESULT error code.
1265  */
1266 HRESULT WINAPI SHLWAPI_175 (IUnknown *lpUnknown, CLSID* lpClassId)
1267 {
1268   IPersist* lpPersist;
1269   HRESULT hRet = E_FAIL;
1270
1271   TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1272
1273   if (lpUnknown)
1274   {
1275     hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1276     if (SUCCEEDED(hRet))
1277     {
1278       IPersist_GetClassID(lpPersist, lpClassId);
1279       IPersist_Release(lpPersist);
1280     }
1281   }
1282   return hRet;
1283 }
1284
1285 /*************************************************************************
1286  *      @       [SHLWAPI.176]
1287  *
1288  * Retrieve a Service Interface from an object.
1289  *
1290  * PARAMS
1291  *  lpUnknown [I] Object to get an IServiceProvider interface from
1292  *  sid       [I] Service ID for QueryService call
1293  *  riid      [I] Function requested for QueryService call
1294  *  lppOut    [O] Destination for the service interface pointer
1295  *
1296  * Function appears to be interface to IServiceProvider::QueryService
1297  *
1298  * RETURNS
1299  *  Success: S_OK. lppOut contains an object providing the requested service
1300  *  Failure: An HRESULT error code
1301  *
1302  * NOTES
1303  *  lpUnknown is expected to support the IServiceProvider interface.
1304  */
1305 HRESULT WINAPI SHLWAPI_176(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1306                            LPVOID *lppOut)
1307 {
1308   IServiceProvider* pService = NULL;
1309   HRESULT hRet;
1310
1311   if (!lppOut)
1312     return E_FAIL;
1313
1314   *lppOut = NULL;
1315
1316   if (!lpUnknown)
1317     return E_FAIL;
1318
1319   /* Get an IServiceProvider interface from the object */
1320   hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1321                                  (LPVOID*)&pService);
1322
1323   if (!hRet && pService)
1324   {
1325     TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1326
1327     /* Get a Service interface from the object */
1328     hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1329
1330     TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1331
1332     /* Release the IServiceProvider interface */
1333     IUnknown_Release(pService);
1334   }
1335   return hRet;
1336 }
1337
1338 /*************************************************************************
1339  *      @       [SHLWAPI.180]
1340  *
1341  * Remove all sub-menus from a menu.
1342  *
1343  * PARAMS
1344  *  hMenu [I] Menu to remove sub-menus from
1345  *
1346  * RETURNS
1347  *  Success: 0.  All sub-menus under hMenu are removed
1348  *  Failure: -1, if any parameter is invalid
1349  */
1350 DWORD WINAPI SHLWAPI_180(HMENU hMenu)
1351 {
1352   int iItemCount = GetMenuItemCount(hMenu) - 1;
1353   while (iItemCount >= 0)
1354   {
1355     HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1356     if (hSubMenu)
1357       RemoveMenu(hMenu, iItemCount, 0x400);
1358     iItemCount--;
1359   }
1360   return iItemCount;
1361 }
1362
1363 /*************************************************************************
1364  *      @       [SHLWAPI.181]
1365  *
1366  * Enable or disable a menu item.
1367  *
1368  * PARAMS
1369  *  hMenu   [I] Menu holding menu item
1370  *  uID     [I] ID of menu item to enable/disable
1371  *  bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1372  *
1373  * RETURNS
1374  *  The return code from CheckMenuItem.
1375  */
1376 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1377 {
1378   return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1379 }
1380
1381 /*************************************************************************
1382  * @    [SHLWAPI.182]
1383  *
1384  * Check or uncheck a menu item.
1385  *
1386  * PARAMS
1387  *  hMenu  [I] Menu holding menu item
1388  *  uID    [I] ID of menu item to check/uncheck
1389  *  bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1390  *
1391  * RETURNS
1392  *  The return code from CheckMenuItem.
1393  */
1394 DWORD WINAPI SHLWAPI_182(HMENU hMenu, UINT uID, BOOL bCheck)
1395 {
1396   return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : 0);
1397 }
1398
1399 /*************************************************************************
1400  *      @       [SHLWAPI.183]
1401  *
1402  * Register a window class if it isn't already.
1403  *
1404  * PARAMS
1405  *  lpWndClass [I] Window class to register
1406  *
1407  * RETURNS
1408  *  The result of the RegisterClassA call.
1409  */
1410 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1411 {
1412   WNDCLASSA wca;
1413   if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1414     return TRUE;
1415   return (DWORD)RegisterClassA(wndclass);
1416 }
1417
1418 /*************************************************************************
1419  *      @       [SHLWAPI.187]
1420  *
1421  * Call IPersistPropertyBag::Load on an object.
1422  *
1423  * PARAMS
1424  *  lpUnknown [I] Object supporting the IPersistPropertyBag interface
1425  *  lpPropBag [O] Destination for loaded IPropertyBag
1426  *
1427  * RETURNS
1428  *  Success: S_OK.
1429  *  Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1430  */
1431 DWORD WINAPI SHLWAPI_187(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1432 {
1433   IPersistPropertyBag* lpPPBag;
1434   HRESULT hRet = E_FAIL;
1435
1436   TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1437
1438   if (lpUnknown)
1439   {
1440     hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1441                                    (void**)&lpPPBag);
1442     if (SUCCEEDED(hRet) && lpPPBag)
1443     {
1444       hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1445       IPersistPropertyBag_Release(lpPPBag);
1446     }
1447   }
1448   return hRet;
1449 }
1450
1451 /*************************************************************************
1452  *      @       [SHLWAPI.189]
1453  *
1454  * _IUnknown_OnFocusOCS
1455  */
1456 DWORD WINAPI SHLWAPI_189(LPVOID x, LPVOID y)
1457 {
1458         FIXME("%p %p\n", x, y);
1459         return 0;
1460 }
1461
1462 /*************************************************************************
1463  *      @       [SHLWAPI.193]
1464  *
1465  * Get the color depth of the primary display.
1466  *
1467  * PARAMS
1468  *  None.
1469  *
1470  * RETURNS
1471  *  The color depth of the primary display.
1472  */
1473 DWORD WINAPI SHLWAPI_193 ()
1474 {
1475         HDC hdc;
1476         DWORD ret;
1477
1478         TRACE("()\n");
1479
1480         hdc = GetDC(0);
1481         ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1482         ReleaseDC(0, hdc);
1483         return ret;
1484 }
1485
1486 /*************************************************************************
1487  *      @       [SHLWAPI.197]
1488  *
1489  * Blank out a region of text by drawing the background only.
1490  *
1491  * PARAMS
1492  *  hDC   [I] Device context to draw in
1493  *  pRect [I] Area to draw in
1494  *  cRef  [I] Color to draw in
1495  *
1496  * RETURNS
1497  *  Nothing.
1498  */
1499 DWORD WINAPI SHLWAPI_197(HDC hDC, LPCRECT pRect, COLORREF cRef)
1500 {
1501     COLORREF cOldColor = SetBkColor(hDC, cRef);
1502     ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
1503     SetBkColor(hDC, cOldColor);
1504     return 0;
1505 }
1506
1507 /*************************************************************************
1508  *      @       [SHLWAPI.199]
1509  *
1510  * Copy interface pointer
1511  *
1512  * PARAMS
1513  *   lppDest   [O] Destination for copy
1514  *   lpUnknown [I] Source for copy
1515  *
1516  * RETURNS
1517  *  Nothing.
1518  */
1519 VOID WINAPI SHLWAPI_199(IUnknown **lppDest, IUnknown *lpUnknown)
1520 {
1521   TRACE("(%p,%p)\n", lppDest, lpUnknown);
1522
1523   if (lppDest)
1524     SHLWAPI_169(lppDest); /* Release existing interface */
1525
1526   if (lpUnknown)
1527   {
1528     /* Copy */
1529     IUnknown_AddRef(lpUnknown);
1530     *lppDest = lpUnknown;
1531   }
1532 }
1533
1534 /*************************************************************************
1535  *      @       [SHLWAPI.201]
1536  *
1537  */
1538 HRESULT WINAPI SHLWAPI_201(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
1539                            DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1540                            VARIANT* pvaOut)
1541 {
1542   FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
1543         nCmdID, nCmdexecopt, pvaIn, pvaOut);
1544   return DRAGDROP_E_NOTREGISTERED;
1545 }
1546
1547 /*************************************************************************
1548  *      @       [SHLWAPI.202]
1549  *
1550  */
1551 HRESULT WINAPI SHLWAPI_202(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
1552 {
1553   FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
1554   return DRAGDROP_E_NOTREGISTERED;
1555 }
1556
1557 /*************************************************************************
1558  *      @       [SHLWAPI.203]
1559  *
1560  */
1561 VOID WINAPI SHLWAPI_203(LPCSTR lpszStr)
1562 {
1563   FIXME("(%s) - stub!\n", debugstr_a(lpszStr));
1564 }
1565
1566 /*************************************************************************
1567  * @    [SHLWAPI.204]
1568  *
1569  * Determine if a window is not a child of another window.
1570  *
1571  * PARAMS
1572  * hParent [I] Suspected parent window
1573  * hChild  [I] Suspected child window
1574  *
1575  * RETURNS
1576  * TRUE:  If hChild is a child window of hParent
1577  * FALSE: If hChild is not a child window of hParent, or they are equal
1578  */
1579 BOOL WINAPI SHLWAPI_204(HWND hParent, HWND hChild)
1580 {
1581   TRACE("(%p,%p)\n", hParent, hChild);
1582
1583   if (!hParent || !hChild)
1584     return TRUE;
1585   else if(hParent == hChild)
1586     return FALSE;
1587   return !IsChild(hParent, hChild);
1588 }
1589
1590 /*************************************************************************
1591  *      @       [SHLWAPI.208]
1592  *
1593  * Some sort of memory management process - associated with _210
1594  */
1595 DWORD WINAPI SHLWAPI_208 (
1596         DWORD    a,
1597         DWORD    b,
1598         LPVOID   c,
1599         LPVOID   d,
1600         DWORD    e)
1601 {
1602     FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1603           a, b, c, d, e);
1604     return 1;
1605 }
1606
1607 /*************************************************************************
1608  *      @       [SHLWAPI.209]
1609  *
1610  * Some sort of memory management process - associated with _208
1611  */
1612 DWORD WINAPI SHLWAPI_209 (
1613         LPVOID   a)
1614 {
1615     FIXME("(%p) stub\n",
1616           a);
1617     return 1;
1618 }
1619
1620 /*************************************************************************
1621  *      @       [SHLWAPI.210]
1622  *
1623  * Some sort of memory management process - associated with _208
1624  */
1625 DWORD WINAPI SHLWAPI_210 (
1626         LPVOID   a,
1627         DWORD    b,
1628         LPVOID   c)
1629 {
1630     FIXME("(%p 0x%08lx %p) stub\n",
1631           a, b, c);
1632     return 0;
1633 }
1634
1635 /*************************************************************************
1636  *      @       [SHLWAPI.211]
1637  */
1638 DWORD WINAPI SHLWAPI_211 (
1639         LPVOID   a,
1640         DWORD    b)
1641 {
1642     FIXME("(%p 0x%08lx) stub\n",
1643           a, b);
1644     return 1;
1645 }
1646
1647 /*************************************************************************
1648  *      @       [SHLWAPI.215]
1649  *
1650  * NOTES
1651  *  check me!
1652  */
1653 DWORD WINAPI SHLWAPI_215 (
1654         LPCSTR lpStrSrc,
1655         LPWSTR lpwStrDest,
1656         int len)
1657 {
1658         INT len_a, ret;
1659
1660         len_a = lstrlenA(lpStrSrc);
1661         ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1662         TRACE("%s %s %d, ret=%d\n",
1663               debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1664         return ret;
1665 }
1666
1667 /*************************************************************************
1668  *      @       [SHLWAPI.218]
1669  *
1670  * WideCharToMultiByte with multi language support.
1671  */
1672 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1673                        LPINT lpnMultiCharCount)
1674 {
1675   WCHAR emptyW[] = { '\0' };
1676   int len , reqLen;
1677   LPSTR mem;
1678
1679   if (!lpDstStr || !lpnMultiCharCount)
1680     return 0;
1681
1682   if (!lpSrcStr)
1683     lpSrcStr = emptyW;
1684
1685   *lpDstStr = '\0';
1686
1687   len = strlenW(lpSrcStr) + 1;
1688
1689   switch (CodePage)
1690   {
1691   case CP_WINUNICODE:
1692     CodePage = CP_UTF8; /* Fall through... */
1693   case 0x0000C350: /* FIXME: CP_ #define */
1694   case CP_UTF7:
1695   case CP_UTF8:
1696     {
1697       DWORD dwMode = 0;
1698       INT nWideCharCount = len - 1;
1699
1700       GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
1701       if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1702                                           lpnMultiCharCount))
1703         return 0;
1704
1705       if (nWideCharCount < len - 1)
1706       {
1707         mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1708         if (!mem)
1709           return 0;
1710
1711         *lpnMultiCharCount = 0;
1712
1713         if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1714         {
1715           SHLWAPI_162 (mem, *lpnMultiCharCount);
1716           lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1717           return *lpnMultiCharCount + 1;
1718         }
1719         HeapFree(GetProcessHeap(), 0, mem);
1720         return *lpnMultiCharCount;
1721       }
1722       lpDstStr[*lpnMultiCharCount] = '\0';
1723       return *lpnMultiCharCount;
1724     }
1725     break;
1726   default:
1727     break;
1728   }
1729
1730   reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1731                                *lpnMultiCharCount, NULL, NULL);
1732
1733   if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1734   {
1735     reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1736     if (reqLen)
1737     {
1738       mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1739       if (mem)
1740       {
1741         reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1742                                      reqLen, NULL, NULL);
1743
1744         reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1745         reqLen++;
1746
1747         lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1748
1749         HeapFree(GetProcessHeap(), 0, mem);
1750       }
1751     }
1752   }
1753   return reqLen;
1754 }
1755
1756 /*************************************************************************
1757  *      @       [SHLWAPI.217]
1758  *
1759  * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1760  * --> Crash. Something wrong here.
1761  *
1762  * It seems from OE v5 that the third param is the count. (GA 11/2001)
1763  */
1764 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1765 {
1766     INT myint = MultiCharCount;
1767
1768     return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1769 }
1770
1771 /*************************************************************************
1772  *      @       [SHLWAPI.219]
1773  *
1774  * Seems to be "super" QueryInterface. Supplied with a table of interfaces
1775  * and an array of IIDs and offsets into the table.
1776  *
1777  * NOTES
1778  *  error codes: E_POINTER, E_NOINTERFACE
1779  */
1780 typedef struct {
1781     REFIID   refid;
1782     DWORD    indx;
1783 } IFACE_INDEX_TBL;
1784
1785 HRESULT WINAPI SHLWAPI_219 (
1786         LPVOID w,           /* [in]   table of interfaces                   */
1787         IFACE_INDEX_TBL *x, /* [in]   array of REFIIDs and indexes to above */
1788         REFIID riid,        /* [in]   REFIID to get interface for           */
1789         LPVOID *ppv)          /* [out]  location to get interface pointer     */
1790 {
1791         HRESULT ret;
1792         IUnknown *a_vtbl;
1793         IFACE_INDEX_TBL *xmove;
1794
1795         TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
1796         if (ppv) {
1797             xmove = x;
1798             while (xmove->refid) {
1799                 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
1800                 if (IsEqualIID(riid, xmove->refid)) {
1801                     a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1802                     TRACE("matched, returning (%p)\n", a_vtbl);
1803                     *ppv = (LPVOID)a_vtbl;
1804                     IUnknown_AddRef(a_vtbl);
1805                     return S_OK;
1806                 }
1807                 xmove++;
1808             }
1809
1810             if (IsEqualIID(riid, &IID_IUnknown)) {
1811                 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1812                 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1813                 *ppv = (LPVOID)a_vtbl;
1814                 IUnknown_AddRef(a_vtbl);
1815                 return S_OK;
1816             }
1817             *ppv = 0;
1818             ret = E_NOINTERFACE;
1819         } else
1820             ret = E_POINTER;
1821
1822         TRACE("-- 0x%08lx\n", ret);
1823         return ret;
1824 }
1825
1826 /*************************************************************************
1827  *      @       [SHLWAPI.236]
1828  */
1829 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1830 {
1831     HKEY newkey;
1832     DWORD type, count;
1833     CHAR value[MAX_PATH], string[MAX_PATH];
1834
1835     strcpy(string, "CLSID\\");
1836     strcat(string, debugstr_guid(lpUnknown));
1837     strcat(string, "\\InProcServer32");
1838
1839     count = MAX_PATH;
1840     RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1841     RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1842     RegCloseKey(newkey);
1843     return LoadLibraryExA(value, 0, 0);
1844 }
1845
1846 /*************************************************************************
1847  *      @       [SHLWAPI.237]
1848  *
1849  * Unicode version of SHLWAPI_183.
1850  */
1851 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1852 {
1853         WNDCLASSW WndClass;
1854
1855         TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1856
1857         if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1858                 return TRUE;
1859         return RegisterClassW(lpWndClass);
1860 }
1861
1862 /*************************************************************************
1863  *      @       [SHLWAPI.239]
1864  */
1865 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1866 {
1867     FIXME("(%p %p 0x%08lx) stub\n",
1868           hInstance, p2, dw3);
1869     return 0;
1870 #if 0
1871     /* pseudo code from relay trace */
1872     WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1873     GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1874     /* above pair repeated for:
1875            TridentThicketUrlDlClass
1876            Shell Embedding
1877            CIESplashScreen
1878            Inet Notify_Hidden
1879            OCHost
1880     */
1881 #endif
1882 }
1883
1884 /*************************************************************************
1885  *      @       [SHLWAPI.240]
1886  *
1887  * Call The correct (ASCII/Unicode) default window procedure for a window.
1888  *
1889  * PARAMS
1890  *  hWnd     [I] Window to call the default proceedure for
1891  *  uMessage [I] Message ID
1892  *  wParam   [I] WPARAM of message
1893  *  lParam   [I] LPARAM of message
1894  *
1895  * RETURNS
1896  *  The result of calling the window proceedure.
1897  */
1898 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1899 {
1900         if (IsWindowUnicode(hWnd))
1901                 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1902         return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1903 }
1904
1905 /*************************************************************************
1906  *      @       [SHLWAPI.241]
1907  *
1908  */
1909 DWORD WINAPI SHLWAPI_241 ()
1910 {
1911         FIXME("()stub\n");
1912         return /* 0xabba1243 */ 0;
1913 }
1914
1915 /*************************************************************************
1916  *      @       [SHLWAPI.266]
1917  *
1918  * native does at least approximately:
1919  *     strcpyW(newstr, x);
1920  *     strcatW(newstr, "\\Restrictions");
1921  *     if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1922  *        return 0;
1923  *    *unknown*
1924  */
1925 DWORD WINAPI SHLWAPI_266 (
1926         LPVOID w,
1927         LPVOID x,   /* [in] partial registry key */
1928         LPVOID y,
1929         LPVOID z)
1930 {
1931         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1932         return /* 0xabba1248 */ 0;
1933 }
1934
1935 /*************************************************************************
1936  *      @       [SHLWAPI.267]
1937  *
1938  * NOTES:
1939  *   This QueryInterface asks the inner object for a interface. In case
1940  *   of aggregation this request would be forwarded by the inner to the
1941  *   outer object. This function asks the inner object directly for the
1942  *   interface circumventing the forwarding to the outer object.
1943  */
1944 HRESULT WINAPI SHLWAPI_267 (
1945         IUnknown * pUnk,   /* [in] outer object */
1946         IUnknown * pInner, /* [in] inner object */
1947         IID * riid,
1948         LPVOID* ppv)
1949 {
1950         HRESULT hret = E_NOINTERFACE;
1951         TRACE("(pUnk=%p pInner=%p\n\tIID:  %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
1952
1953         *ppv = NULL;
1954         if(pUnk && pInner) {
1955             hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
1956             if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
1957         }
1958         TRACE("-- 0x%08lx\n", hret);
1959         return hret;
1960 }
1961
1962 /*************************************************************************
1963  *      @       [SHLWAPI.268]
1964  *
1965  * Move a reference from one interface to another.
1966  *
1967  * PARAMS
1968  *   lpDest     [O] Destination to receive the reference
1969  *   lppUnknown [O] Source to give up the reference to lpDest
1970  *
1971  * RETURNS
1972  *  Nothing.
1973  */
1974 VOID WINAPI SHLWAPI_268(IUnknown *lpDest, IUnknown **lppUnknown)
1975 {
1976   TRACE("(%p,%p)\n", lpDest, lppUnknown);
1977
1978   if (*lppUnknown)
1979   {
1980     /* Copy Reference*/
1981     IUnknown_AddRef(lpDest);
1982     SHLWAPI_169(lppUnknown); /* Release existing interface */
1983   }
1984 }
1985
1986 /*************************************************************************
1987  *      @       [SHLWAPI.276]
1988  *
1989  * Determine if the browser is integrated into the shell, and set a registry
1990  * key accordingly.
1991  *
1992  * PARAMS
1993  *  None.
1994  *
1995  * RETURNS
1996  *  1, If the browser is not integrated.
1997  *  2, If the browser is integrated.
1998  *
1999  * NOTES
2000  *  The key HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser is
2001  *  either set to TRUE, or removed depending on whether the browser is deemed
2002  *  to be integrated.
2003  */
2004 DWORD WINAPI SHLWAPI_276()
2005 {
2006   static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2007   static DWORD dwState = 0;
2008   HKEY hKey;
2009   DWORD dwRet, dwData, dwSize;
2010
2011   if (dwState)
2012     return dwState;
2013
2014   /* If shell32 exports DllGetVersion(), the browser is integrated */
2015   GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2016   dwState = pDllGetVersion ? 2 : 1;
2017
2018   /* Set or delete the key accordinly */
2019   dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2020                         "Software\\Microsoft\\Internet Explorer", 0,
2021                          KEY_ALL_ACCESS, &hKey);
2022   if (!dwRet)
2023   {
2024     dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2025                              (LPBYTE)&dwData, &dwSize);
2026
2027     if (!dwRet && dwState == 1)
2028     {
2029       /* Value exists but browser is not integrated */
2030       RegDeleteValueA(hKey, szIntegratedBrowser);
2031     }
2032     else if (dwRet && dwState == 2)
2033     {
2034       /* Browser is integrated but value does not exist */
2035       dwData = TRUE;
2036       RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2037                      (LPBYTE)&dwData, sizeof(dwData));
2038     }
2039     RegCloseKey(hKey);
2040   }
2041   return dwState;
2042 }
2043
2044 /*************************************************************************
2045  *      @       [SHLWAPI.278]
2046  *
2047  */
2048 HWND WINAPI SHLWAPI_278 (
2049         LONG wndProc,
2050         HWND hWndParent,
2051         DWORD dwExStyle,
2052         DWORD dwStyle,
2053         HMENU hMenu,
2054         LONG z)
2055 {
2056         WNDCLASSA wndclass;
2057         HWND hwnd;
2058         HCURSOR hCursor;
2059         char * clsname = "WorkerA";
2060
2061         FIXME("(0x%08lx %p 0x%08lx 0x%08lx %p 0x%08lx) partial stub\n",
2062           wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
2063
2064         hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
2065
2066         if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
2067         {
2068           RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
2069           wndclass.lpfnWndProc = DefWindowProcW;
2070           wndclass.cbWndExtra = 4;
2071           wndclass.hInstance = shlwapi_hInstance;
2072           wndclass.hCursor = hCursor;
2073           wndclass.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2074           wndclass.lpszMenuName = NULL;
2075           wndclass.lpszClassName = clsname;
2076           RegisterClassA (&wndclass);
2077         }
2078         hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
2079                 hMenu,shlwapi_hInstance,0);
2080         SetWindowLongA(hwnd, 0, z);
2081         SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
2082         return hwnd;
2083 }
2084
2085 /*************************************************************************
2086  *      @       [SHLWAPI.281]
2087  *
2088  * _SHPackDispParamsV
2089  */
2090 HRESULT WINAPI SHLWAPI_281(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2091 {
2092         FIXME("%p %p %p %p\n",w,x,y,z);
2093         return E_FAIL;
2094 }
2095
2096 /*************************************************************************
2097  *      @       [SHLWAPI.282]
2098  *
2099  * This function seems to be a forward to SHLWAPI.281 (whatever THAT
2100  * function does...).
2101  */
2102 HRESULT WINAPI SHLWAPI_282(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2103 {
2104   FIXME("%p %p %p %p\n", w, x, y, z);
2105   return E_FAIL;
2106 }
2107
2108 /*************************************************************************
2109  *      @       [SHLWAPI.284]
2110  *
2111  * _IConnectionPoint_SimpleInvoke
2112  */
2113 DWORD WINAPI SHLWAPI_284 (
2114         LPVOID x,
2115         LPVOID y,
2116         LPVOID z)
2117 {
2118         TRACE("(%p %p %p) stub\n",x,y,z);
2119         return 0;
2120 }
2121
2122 /*************************************************************************
2123  *      @       [SHLWAPI.287]
2124  *
2125  * _IUnknown_CPContainerOnChanged
2126  */
2127 HRESULT WINAPI SHLWAPI_287(LPVOID x, LPVOID y)
2128 {
2129         FIXME("%p %p\n", x,y);
2130         return E_FAIL;
2131 }
2132
2133 /*************************************************************************
2134  *      @       [SHLWAPI.289]
2135  *
2136  * Late bound call to winmm.PlaySoundW
2137  */
2138 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2139 {
2140   GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2141   return pPlaySoundW(pszSound, hmod, fdwSound);
2142 }
2143
2144 /*************************************************************************
2145  *      @       [SHLWAPI.294]
2146  */
2147 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len,  LPCSTR lpStr2)
2148 {
2149     /*
2150      * str1:            "I"     "I"     pushl esp+0x20
2151      * str2:            "U"     "I"     pushl 0x77c93810
2152      * (is "I" and "U" "integer" and "unsigned" ??)
2153      *
2154      * pStr:            ""      ""      pushl eax
2155      * some_len:        0x824   0x104   pushl 0x824
2156      * lpStr2:          "%l"    "%l"    pushl esp+0xc
2157      *
2158      * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2159      * LocalAlloc(0x00, some_len) -> irrelevant_var
2160      * LocalAlloc(0x40, irrelevant_len) -> pStr
2161      * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2162      * shlwapi.PathRemoveBlanksW(pStr);
2163      */
2164     FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2165     return TRUE;
2166 }
2167
2168 /*************************************************************************
2169  *      @       [SHLWAPI.295]
2170  *
2171  * Called by ICQ2000b install via SHDOCVW:
2172  * str1: "InternetShortcut"
2173  * x: some unknown pointer
2174  * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2175  * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2176  *
2177  * In short: this one maybe creates a desktop link :-)
2178  */
2179 BOOL WINAPI SHLWAPI_295(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2180 {
2181     FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2182     return TRUE;
2183 }
2184
2185 /*************************************************************************
2186  *      @       [SHLWAPI.299]
2187  *
2188  * Late bound call to comctl32.417
2189  */
2190 BOOL WINAPI SHLWAPI_299(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2191                          LPCWSTR str, UINT count, const INT *lpDx)
2192 {
2193     GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2194     return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2195 }
2196
2197 /*************************************************************************
2198  *      @       [SHLWAPI.313]
2199  *
2200  * Late bound call to shell32.SHGetFileInfoW
2201  */
2202 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
2203                          SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2204 {
2205   GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2206   return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2207 }
2208
2209 /*************************************************************************
2210  *      @       [SHLWAPI.318]
2211  *
2212  * Late bound call to shell32.DragQueryFileW
2213  */
2214 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2215 {
2216   GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2217   return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2218 }
2219
2220 /*************************************************************************
2221  *      @       [SHLWAPI.333]
2222  *
2223  * Late bound call to shell32.SHBrowseForFolderW
2224  */
2225 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
2226 {
2227   GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2228   return pSHBrowseForFolderW(lpBi);
2229 }
2230
2231 /*************************************************************************
2232  *      @       [SHLWAPI.334]
2233  *
2234  * Late bound call to shell32.SHGetPathFromIDListW
2235  */
2236 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
2237 {
2238   GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2239   return pSHGetPathFromIDListW(pidl, pszPath);
2240 }
2241
2242 /*************************************************************************
2243  *      @       [SHLWAPI.335]
2244  *
2245  * Late bound call to shell32.ShellExecuteExW
2246  */
2247 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
2248 {
2249   GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2250   return pShellExecuteExW(lpExecInfo);
2251 }
2252
2253 /*************************************************************************
2254  *      @       [SHLWAPI.336]
2255  *
2256  * Late bound call to shell32.SHFileOperationW.
2257  */
2258 HICON WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
2259 {
2260   GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2261   return pSHFileOperationW(lpFileOp);
2262 }
2263
2264 /*************************************************************************
2265  *      @       [SHLWAPI.337]
2266  *
2267  * Late bound call to shell32.ExtractIconExW.
2268  */
2269 UINT WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2270                          HICON *phiconSmall, UINT nIcons)
2271 {
2272   GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2273   return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
2274 }
2275
2276 /*************************************************************************
2277  *      @       [SHLWAPI.342]
2278  *
2279  */
2280 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
2281 {
2282         return InterlockedCompareExchange(dest, xchg, compare);
2283 }
2284
2285 /*************************************************************************
2286  *      @       [SHLWAPI.346]
2287  */
2288 DWORD WINAPI SHLWAPI_346 (
2289         LPCWSTR src,
2290         LPWSTR dest,
2291         int len)
2292 {
2293         FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
2294         lstrcpynW(dest, src, len);
2295         return lstrlenW(dest)+1;
2296 }
2297
2298 /*************************************************************************
2299  *      @       [SHLWAPI.350]
2300  *
2301  * seems to be late bound call to GetFileVersionInfoSizeW
2302  */
2303 DWORD WINAPI SHLWAPI_350 (
2304         LPWSTR x,
2305         LPVOID y)
2306 {
2307         DWORD ret;
2308
2309         GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
2310         ret = pGetFileVersionInfoSizeW(x, y);
2311         return 0x208 + ret;
2312 }
2313
2314 /*************************************************************************
2315  *      @       [SHLWAPI.351]
2316  *
2317  * seems to be late bound call to GetFileVersionInfoW
2318  */
2319 BOOL  WINAPI SHLWAPI_351 (
2320         LPWSTR w,   /* [in] path to dll */
2321         DWORD  x,   /* [in] parm 2 to GetFileVersionInfoA */
2322         DWORD  y,   /* [in] return value from .350 - assume length */
2323         LPVOID z)   /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
2324 {
2325     GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
2326     return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
2327 }
2328
2329 /*************************************************************************
2330  *      @       [SHLWAPI.352]
2331  *
2332  * seems to be late bound call to VerQueryValueW
2333  */
2334 WORD WINAPI SHLWAPI_352 (
2335         LPVOID w,   /* [in] buffer from _351 */
2336         LPWSTR x,   /* [in]   value to retrieve -
2337                               converted and passed to VerQueryValueA as #2 */
2338         LPVOID y,   /* [out]  ver buffer - passed to VerQueryValueA as #3 */
2339         UINT*  z)   /* [in]   ver length - passed to VerQueryValueA as #4 */
2340 {
2341     GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
2342     return pVerQueryValueW((char*)w+0x208, x, y, z);
2343 }
2344
2345 /*************************************************************************
2346  *      @       [SHLWAPI.357]
2347  *
2348  * Late bound call to shell32.SHGetNewLinkInfoW
2349  */
2350 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
2351                         BOOL *pfMustCopy, UINT uFlags)
2352 {
2353   GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
2354   return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
2355 }
2356
2357 /*************************************************************************
2358  *      @       [SHLWAPI.358]
2359  *
2360  * Late bound call to shell32.SHDefExtractIconW
2361  */
2362 UINT WINAPI SHLWAPI_358(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
2363                          HICON* phiconSmall, UINT nIconSize)
2364 {
2365   GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
2366   return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
2367 }
2368
2369 /*************************************************************************
2370  *      @       [SHLWAPI.364]
2371  *
2372  * Wrapper for lstrcpynA with src and dst swapped.
2373  */
2374 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
2375 {
2376   lstrcpynA(dst, src, n);
2377   return TRUE;
2378 }
2379
2380 /*************************************************************************
2381  *      @       [SHLWAPI.370]
2382  *
2383  * Late bound call to shell32.ExtractIconW
2384  */
2385 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
2386                          UINT nIconIndex)
2387 {
2388   GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
2389   return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
2390 }
2391
2392 /*************************************************************************
2393  *      @       [SHLWAPI.376]
2394  */
2395 LANGID WINAPI SHLWAPI_376 ()
2396 {
2397     FIXME("() stub\n");
2398     /* FIXME: This should be a forward in the .spec file to the win2k function
2399      * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2400      */
2401     return GetUserDefaultLangID();
2402 }
2403
2404 /*************************************************************************
2405  *      @       [SHLWAPI.377]
2406  *
2407  * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2408  *        each call here.
2409  * FIXME: Native shows calls to:
2410  *  SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2411  *                      CheckVersion
2412  *  RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2413  *  RegQueryValueExA for "LPKInstalled"
2414  *  RegCloseKey
2415  *  RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2416  *  RegQueryValueExA for "ResourceLocale"
2417  *  RegCloseKey
2418  *  RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2419  *  RegQueryValueExA for "Locale"
2420  *  RegCloseKey
2421  *  and then tests the Locale ("en" for me).
2422  *     code below
2423  *  after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2424  */
2425 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
2426 {
2427     CHAR mod_path[2*MAX_PATH];
2428     LPSTR ptr;
2429
2430     GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
2431     ptr = strrchr(mod_path, '\\');
2432     if (ptr) {
2433         strcpy(ptr+1, new_mod);
2434         TRACE("loading %s\n", debugstr_a(mod_path));
2435         return (DWORD)LoadLibraryA(mod_path);
2436     }
2437     return 0;
2438 }
2439
2440 /*************************************************************************
2441  *      @       [SHLWAPI.378]
2442  *
2443  *  This is Unicode version of .377
2444  */
2445 DWORD WINAPI SHLWAPI_378 (
2446         LPCWSTR   new_mod,          /* [in] new module name        */
2447         HMODULE   inst_hwnd,        /* [in] calling module handle  */
2448         LPVOID z)                   /* [???] 4 */
2449 {
2450     WCHAR mod_path[2*MAX_PATH];
2451     LPWSTR ptr;
2452
2453     GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2454     ptr = strrchrW(mod_path, '\\');
2455     if (ptr) {
2456         strcpyW(ptr+1, new_mod);
2457         TRACE("loading %s\n", debugstr_w(mod_path));
2458         return (DWORD)LoadLibraryW(mod_path);
2459     }
2460     return 0;
2461 }
2462
2463 /*************************************************************************
2464  *      @       [SHLWAPI.389]
2465  *
2466  * Late bound call to comdlg32.GetSaveFileNameW
2467  */
2468 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2469 {
2470   GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
2471   return pGetSaveFileNameW(ofn);
2472 }
2473
2474 /*************************************************************************
2475  *      @       [SHLWAPI.390]
2476  *
2477  * Late bound call to mpr.WNetRestoreConnectionW
2478  */
2479 DWORD WINAPI SHLWAPI_390(HWND hwndOwner, LPWSTR lpszDevice)
2480 {
2481   GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
2482   return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
2483 }
2484
2485 /*************************************************************************
2486  *      @       [SHLWAPI.391]
2487  *
2488  * Late bound call to mpr.WNetGetLastErrorW
2489  */
2490 DWORD WINAPI SHLWAPI_391(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
2491                          LPWSTR lpNameBuf, DWORD nNameBufSize)
2492 {
2493   GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
2494   return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
2495 }
2496
2497 /*************************************************************************
2498  *      @       [SHLWAPI.401]
2499  *
2500  * Late bound call to comdlg32.PageSetupDlgW
2501  */
2502 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2503 {
2504   GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
2505   return pPageSetupDlgW(pagedlg);
2506 }
2507
2508 /*************************************************************************
2509  *      @       [SHLWAPI.402]
2510  *
2511  * Late bound call to comdlg32.PrintDlgW
2512  */
2513 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2514 {
2515   GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
2516   return pPrintDlgW(printdlg);
2517 }
2518
2519 /*************************************************************************
2520  *      @       [SHLWAPI.403]
2521  *
2522  * Late bound call to comdlg32.GetOpenFileNameW
2523  */
2524 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2525 {
2526   GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
2527   return pGetOpenFileNameW(ofn);
2528 }
2529
2530 /* INTERNAL: Map from HLS color space to RGB */
2531 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2532 {
2533   wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2534
2535   if (wHue > 160)
2536     return wMid1;
2537   else if (wHue > 120)
2538     wHue = 160 - wHue;
2539   else if (wHue > 40)
2540     return wMid2;
2541
2542   return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2543 }
2544
2545 /* Convert to RGB and scale into RGB range (0..255) */
2546 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2547
2548 /*************************************************************************
2549  *      ColorHLSToRGB   [SHLWAPI.404]
2550  *
2551  * Convert from HLS color space into an RGB COLORREF.
2552  *
2553  * NOTES
2554  * Input HLS values are constrained to the range (0..240).
2555  */
2556 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2557 {
2558   WORD wRed;
2559
2560   if (wSaturation)
2561   {
2562     WORD wGreen, wBlue, wMid1, wMid2;
2563
2564     if (wLuminosity > 120)
2565       wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2566     else
2567       wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2568
2569     wMid1 = wLuminosity * 2 - wMid2;
2570
2571     wRed   = GET_RGB(wHue + 80);
2572     wGreen = GET_RGB(wHue);
2573     wBlue  = GET_RGB(wHue - 80);
2574
2575     return RGB(wRed, wGreen, wBlue);
2576   }
2577
2578   wRed = wLuminosity * 255 / 240;
2579   return RGB(wRed, wRed, wRed);
2580 }
2581
2582 /*************************************************************************
2583  *      @       [SHLWAPI.406]
2584  */
2585 DWORD WINAPI SHLWAPI_406(LPVOID u, LPVOID v, LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2586 {
2587   FIXME("%p %p %p %p %p %p\n", u, v, w, x, y, z);
2588   return 0;
2589 }
2590
2591 /*************************************************************************
2592  *      @       [SHLWAPI.413]
2593  *
2594  * Function unknown seems to always to return 0
2595  * x can be 0x3.
2596  */
2597 DWORD WINAPI SHLWAPI_413 (DWORD x)
2598 {
2599         FIXME("(0x%08lx)stub\n", x);
2600         return 0;
2601 }
2602
2603 /*************************************************************************
2604  *      @       [SHLWAPI.418]
2605  *
2606  * Function seems to do FreeLibrary plus other things.
2607  *
2608  * FIXME native shows the following calls:
2609  *   RtlEnterCriticalSection
2610  *   LocalFree
2611  *   GetProcAddress(Comctl32??, 150L)
2612  *   DPA_DeletePtr
2613  *   RtlLeaveCriticalSection
2614  *  followed by the FreeLibrary.
2615  *  The above code may be related to .377 above.
2616  */
2617 BOOL  WINAPI SHLWAPI_418 (HMODULE x)
2618 {
2619         FIXME("(0x%08lx) partial stub\n", (LONG)x);
2620         return FreeLibrary(x);
2621 }
2622
2623 /*************************************************************************
2624  *      @       [SHLWAPI.430]
2625  */
2626 DWORD WINAPI SHLWAPI_430 (HINSTANCE hModule, HANDLE heap)
2627 {
2628         FIXME("(0x%08lx 0x%08lx) stub\n", (DWORD)hModule, (DWORD)heap);
2629         return E_FAIL;   /* This is what is used if shlwapi not loaded */
2630 }
2631
2632 /*************************************************************************
2633  *      @       [SHLWAPI.431]
2634  */
2635 DWORD WINAPI SHLWAPI_431 (DWORD x)
2636 {
2637         FIXME("(0x%08lx)stub\n", x);
2638         return 0xabba1247;
2639 }
2640
2641 /*************************************************************************
2642  *      @       [SHLWAPI.436]
2643  *
2644  *  This is really CLSIDFromString which is exported by ole32.dll,
2645  *  however the native shlwapi.dll does *not* import ole32. Nor does
2646  *  ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2647  *  that MS duplicated the code for CLSIDFromString.
2648  *
2649  *  This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2650  *  in dlls/ole32/compobj.c
2651  */
2652 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2653 {
2654     LPWSTR s = idstr;
2655     BYTE *p;
2656     INT i;
2657     WCHAR table[256];
2658
2659     if (!s) {
2660         memset(s, 0, sizeof(CLSID));
2661         return S_OK;
2662     }
2663     else {  /* validate the CLSID string */
2664
2665         if (strlenW(s) != 38)
2666             return CO_E_CLASSSTRING;
2667
2668         if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2669             return CO_E_CLASSSTRING;
2670
2671         for (i=1; i<37; i++)
2672             {
2673                 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2674                 if (!(((s[i] >= L'0') && (s[i] <= L'9'))  ||
2675                       ((s[i] >= L'a') && (s[i] <= L'f'))  ||
2676                       ((s[i] >= L'A') && (s[i] <= L'F')))
2677                     )
2678                     return CO_E_CLASSSTRING;
2679             }
2680     }
2681
2682     TRACE("%s -> %p\n", debugstr_w(s), id);
2683
2684   /* quick lookup table */
2685     memset(table, 0, 256*sizeof(WCHAR));
2686
2687     for (i = 0; i < 10; i++) {
2688         table['0' + i] = i;
2689     }
2690     for (i = 0; i < 6; i++) {
2691         table['A' + i] = i+10;
2692         table['a' + i] = i+10;
2693     }
2694
2695     /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2696
2697     p = (BYTE *) id;
2698
2699     s++;        /* skip leading brace  */
2700     for (i = 0; i < 4; i++) {
2701         p[3 - i] = table[*s]<<4 | table[*(s+1)];
2702         s += 2;
2703     }
2704     p += 4;
2705     s++;        /* skip - */
2706
2707     for (i = 0; i < 2; i++) {
2708         p[1-i] = table[*s]<<4 | table[*(s+1)];
2709         s += 2;
2710     }
2711     p += 2;
2712     s++;        /* skip - */
2713
2714     for (i = 0; i < 2; i++) {
2715         p[1-i] = table[*s]<<4 | table[*(s+1)];
2716         s += 2;
2717     }
2718     p += 2;
2719     s++;        /* skip - */
2720
2721     /* these are just sequential bytes */
2722     for (i = 0; i < 2; i++) {
2723         *p++ = table[*s]<<4 | table[*(s+1)];
2724         s += 2;
2725     }
2726     s++;        /* skip - */
2727
2728     for (i = 0; i < 6; i++) {
2729         *p++ = table[*s]<<4 | table[*(s+1)];
2730         s += 2;
2731     }
2732
2733     return S_OK;
2734 }
2735
2736 /*************************************************************************
2737  *      @       [SHLWAPI.437]
2738  *
2739  * Determine if the OS supports a given feature.
2740  *
2741  * PARAMS
2742  *  dwFeature [I] Feature requested (undocumented)
2743  *
2744  * RETURNS
2745  *  TRUE  If the feature is available.
2746  *  FALSE If the feature is not available.
2747  */
2748 DWORD WINAPI SHLWAPI_437 (DWORD feature)
2749 {
2750   FIXME("(0x%08lx) stub\n", feature);
2751   return FALSE;
2752 }
2753
2754 /*************************************************************************
2755  *      ColorRGBToHLS   [SHLWAPI.445]
2756  *
2757  * Convert from RGB COLORREF into the HLS color space.
2758  *
2759  * NOTES
2760  * Input HLS values are constrained to the range (0..240).
2761  */
2762 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2763                           LPWORD wLuminance, LPWORD pwSaturation)
2764 {
2765     FIXME("stub\n");
2766     return;
2767 }
2768
2769 /*************************************************************************
2770  *      SHCreateShellPalette    [SHLWAPI.@]
2771  */
2772 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2773 {
2774         FIXME("stub\n");
2775         return CreateHalftonePalette(hdc);
2776 }
2777
2778 /*************************************************************************
2779  *      SHGetInverseCMAP (SHLWAPI.@)
2780  */
2781 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2782 {
2783     if (why == 4) {
2784         FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2785         *x = (LPDWORD)0xabba1249;
2786         return 0;
2787     }
2788     FIXME("(%p, %#lx)stub\n", x, why);
2789     return 0;
2790 }
2791
2792 /*************************************************************************
2793  *      SHIsLowMemoryMachine    [SHLWAPI.@]
2794  */
2795 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2796 {
2797         FIXME("0x%08lx\n", x);
2798         return 0;
2799 }
2800
2801 /*************************************************************************
2802  *      GetMenuPosFromID        [SHLWAPI.@]
2803  */
2804 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2805 {
2806  MENUITEMINFOA mi;
2807  INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2808
2809  while (nIter < nCount)
2810  {
2811    mi.wID = 0;
2812    if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2813      return nIter;
2814    nIter++;
2815  }
2816  return -1;
2817 }
2818
2819 /*************************************************************************
2820  * SHSkipJunction       [SHLWAPI.@]
2821  *
2822  * Determine if a bind context can be bound to an object
2823  *
2824  * PARAMS
2825  *  pbc    [I] Bind context to check
2826  *  pclsid [I] CLSID of object to be bound to
2827  *
2828  * RETURNS
2829  *  TRUE: If it is safe to bind
2830  *  FALSE: If pbc is invalid or binding would not be safe
2831  *
2832  */
2833 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
2834 {
2835   static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
2836     'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
2837   BOOL bRet = FALSE;
2838
2839   if (pbc)
2840   {
2841     IUnknown* lpUnk;
2842
2843     if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
2844     {
2845       CLSID clsid;
2846
2847       if (SUCCEEDED(SHLWAPI_175(lpUnk, &clsid)) &&
2848           IsEqualGUID(pclsid, &clsid))
2849         bRet = TRUE;
2850
2851       IUnknown_Release(lpUnk);
2852     }
2853   }
2854   return bRet;
2855 }