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