- add stubs SHLWAPI_294, UrlApplySchemeW
[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
9 #include <stdio.h>
10 #include <string.h>
11
12 #include "windef.h"
13 #include "winnls.h"
14 #include "winbase.h"
15 #include "ddeml.h"
16 #include "shlobj.h"
17 #include "shellapi.h"
18 #include "commdlg.h"
19 #include "wine/unicode.h"
20 #include "wine/obj_base.h"
21 #include "wingdi.h"
22 #include "winuser.h"
23 #include "debugtools.h"
24
25 DEFAULT_DEBUG_CHANNEL(shell);
26
27 extern HINSTANCE shlwapi_hInstance;
28 extern HMODULE SHLWAPI_hshell32;
29 extern HMODULE SHLWAPI_hwinmm;
30 extern HMODULE SHLWAPI_hcomdlg32;
31 extern HMODULE SHLWAPI_hmpr;
32 extern HMODULE SHLWAPI_hmlang;
33
34 /* Macro to get function pointer for a module*/
35 #define GET_FUNC(module, name, fail) \
36   if (!SHLWAPI_h##module) SHLWAPI_h##module = LoadLibraryA(#module ".dll"); \
37   if (!SHLWAPI_h##module) return fail; \
38   if (!pfnFunc) pfnFunc = (void*)GetProcAddress(SHLWAPI_h##module, name); \
39   if (!pfnFunc) return fail
40
41 /*
42  NOTES: Most functions exported by ordinal seem to be superflous.
43  The reason for these functions to be there is to provide a wraper
44  for unicode functions to provide these functions on systems without
45  unicode functions eg. win95/win98. Since we have such functions we just
46  call these. If running Wine with native DLL's, some late bound calls may
47  fail. However, its better to implement the functions in the forward DLL
48  and recommend the builtin rather than reimplementing the calls here!
49 */
50
51 /*************************************************************************
52  *      SHLWAPI_1       [SHLWAPI.1]
53  */
54 DWORD WINAPI SHLWAPI_1 (
55         LPSTR lpStr,
56         LPVOID x)
57 {
58         FIXME("(%p %s %p %s)\n",lpStr, debugstr_a(lpStr),x, debugstr_a(x));
59         return 0;
60 }
61
62 /*************************************************************************
63  *      SHLWAPI_2       [SHLWAPI.2]
64  */
65 DWORD WINAPI SHLWAPI_2 (LPCWSTR x,LPVOID y)
66 {
67         FIXME("(%s,%p)\n",debugstr_w(x),y);
68         return 0;
69 }
70
71 /*************************************************************************
72  *      SHLWAPI_16      [SHLWAPI.16]
73  */
74 HRESULT WINAPI SHLWAPI_16 (
75         LPVOID w,
76         LPVOID x,
77         LPVOID y,
78         LPWSTR z)
79 {
80         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
81         return 0xabba1252;
82 }
83
84 /*************************************************************************
85  *      SHLWAPI_23      [SHLWAPI.23]
86  *
87  * NOTES
88  *      converts a guid to a string
89  *      returns strlen(str)
90  */
91 DWORD WINAPI SHLWAPI_23 (
92         REFGUID guid,   /* [in]  clsid */
93         LPSTR str,      /* [out] buffer */
94         INT cmax)       /* [in]  size of buffer */
95 {
96         char xguid[40];
97
98         sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
99                  guid->Data1, guid->Data2, guid->Data3,
100                  guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
101                  guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
102         TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
103         if (strlen(xguid)>=cmax) return 0;
104         strcpy(str,xguid);
105         return strlen(xguid) + 1;
106 }
107
108 /*************************************************************************
109  *      SHLWAPI_24      [SHLWAPI.24]
110  *
111  * NOTES
112  *      converts a guid to a string
113  *      returns strlen(str)
114  */
115 DWORD WINAPI SHLWAPI_24 (
116         REFGUID guid,   /* [in]  clsid */
117         LPWSTR str,     /* [out] buffer */
118         INT cmax)       /* [in]  size of buffer */
119 {
120     char xguid[40];
121
122     sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
123              guid->Data1, guid->Data2, guid->Data3,
124              guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
125              guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
126     return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
127 }
128
129 /*************************************************************************
130  *      SHLWAPI_30      [SHLWAPI.30]
131  *
132  * Seems to be an isspaceW.
133  */
134 BOOL WINAPI SHLWAPI_30(LPWSTR lpcChar)
135 {
136   switch (*lpcChar)
137   {
138   case (WCHAR)'\t':
139   case (WCHAR)' ':
140   case 160:
141   case 12288:
142   case 65279:
143     return TRUE;
144   }
145   return FALSE;
146 }
147
148 /*************************************************************************
149  *      SHLWAPI_32      [SHLWAPI.32]
150  */
151 BOOL WINAPI SHLWAPI_32(LPCWSTR lpcChar)
152 {
153  if (*lpcChar < (WCHAR)' ')
154    return TRUE;
155
156  /* This is probably a shlwapi bug, but we do it the same for compatability */
157  if (((DWORD)lpcChar & 0xffff) - 127 <= (WCHAR)' ')
158    return TRUE;
159  return FALSE;
160 }
161
162 /*************************************************************************
163  *      SHLWAPI_40      [SHLWAPI.40]
164  *
165  * Get pointer to next Unicode character.
166  */
167 LPCWSTR WINAPI SHLWAPI_40(LPCWSTR str)
168 {
169   return *str ? str + 1 : str;
170 }
171
172 /*************************************************************************
173  *      SHLWAPI_74      [SHLWAPI.74]
174  *
175  * Get the text from a given dialog item.
176  */
177 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
178 {
179   HWND hItem = GetDlgItem(hWnd, nItem);
180
181   if (hItem)
182     return GetWindowTextW(hItem, lpsDest, nDestLen);
183   if (nDestLen)
184     *lpsDest = (WCHAR)'\0';
185   return 0;
186 }
187
188 /*************************************************************************
189  *      SHLWAPI_151     [SHLWAPI.151]
190  *
191  *      pStr "HTTP/1.1", dw1 0x5
192  */
193 DWORD WINAPI SHLWAPI_151(LPSTR pStr, LPVOID ptr, DWORD dw1)
194 {
195   FIXME("('%s', %p, %08lx): stub\n", pStr, ptr, dw1);
196   return 0;
197 }
198
199 /*************************************************************************
200  *      SHLWAPI_152     [SHLWAPI.152]
201  */
202 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
203 {
204   if (!len)
205     return 0;
206
207   while (--len && *str1 && *str1 == *str2)
208   {
209     str1++;
210     str2++;
211   }
212   return *str1 - *str2;
213 }
214
215 /*************************************************************************
216  *      SHLWAPI_153     [SHLWAPI.153]
217  */
218 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD dw3)
219 {
220     FIXME("'%s' '%s' %08lx - stub\n", str1, str2, dw3);
221     return 0;
222 }
223
224 /*************************************************************************
225  *      SHLWAPI_156     [SHLWAPI.156]
226  *
227  *      Case sensitive string compare. Does not SetLastError().
228  */
229 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
230 {
231   while (*str1 && (*str1 == *str2)) { str1++; str2++; }
232   return (INT)(*str1 - *str2);
233 }
234
235 /*************************************************************************
236  *      SHLWAPI_162     [SHLWAPI.162]
237  *
238  * Ensure a multibyte character string doesn't end in a hanging lead byte.
239  */
240 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
241 {
242   if (lpStr && size)
243   {
244     LPSTR lastByte = lpStr + size - 1;
245
246     while(lpStr < lastByte)
247       lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
248
249     if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
250     {
251       *lpStr = '\0';
252       size--;
253     }
254     return size;
255   }
256   return 0;
257 }
258
259 /*************************************************************************
260  *      SHLWAPI_165     [SHLWAPI.165]
261  *
262  * SetWindowLongA with mask.
263  */
264 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
265 {
266   LONG ret = GetWindowLongA(hwnd, offset);
267   UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
268
269   if (newFlags != ret)
270     ret = SetWindowLongA(hwnd, offset, newFlags);
271   return ret;
272 }
273
274 /*************************************************************************
275  *      SHLWAPI_169     [SHLWAPI.169]
276  */
277 DWORD WINAPI SHLWAPI_169 (IUnknown * lpUnknown)
278 {
279         TRACE("(%p)\n",lpUnknown);
280 #if 0
281         if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
282         return IUnknown_Release(lpUnknown);
283 #endif
284         return 0;
285 }
286
287 /*************************************************************************
288  *      SHLWAPI_170     [SHLWAPI.170]
289  *
290  * Skip URL '//' sequence.
291  */
292 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
293 {
294   if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
295     lpszSrc += 2;
296   return lpszSrc;
297 }
298
299 /*************************************************************************
300  *      SHLWAPI_181     [SHLWAPI.181]
301  *
302  *      Enable or disable a menu item.
303  */
304 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
305 {
306   return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
307 }
308
309 /*************************************************************************
310  *      SHLWAPI_183     [SHLWAPI.183]
311  *
312  * Register a window class if it isn't already.
313  */
314 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
315 {
316   WNDCLASSA wca;
317   if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
318     return TRUE;
319   return (DWORD)RegisterClassA(wndclass);
320 }
321
322 /*************************************************************************
323  *      SHLWAPI_193     [SHLWAPI.193]
324  */
325 DWORD WINAPI SHLWAPI_193 ()
326 {
327         HDC hdc;
328         DWORD ret;
329
330         TRACE("()\n");
331
332         hdc = GetDC(0);
333         ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
334         ReleaseDC(0, hdc);
335         return ret;
336 }
337
338 /*************************************************************************
339  *      SHLWAPI_215     [SHLWAPI.215]
340  *
341  * NOTES
342  *  check me!
343  */
344 LPWSTR WINAPI SHLWAPI_215 (
345         LPWSTR lpStrSrc,
346         LPVOID lpwStrDest,
347         int len)
348 {
349         WARN("(%p %p %u)\n",lpStrSrc,lpwStrDest,len);
350         return strncpyW(lpwStrDest, lpStrSrc, len);
351 }
352
353 /*************************************************************************
354  *      SHLWAPI_218     [SHLWAPI.218]
355  *
356  * WideCharToMultiByte with multi language support.
357  */
358 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
359                        LPINT lpnMultiCharCount)
360 {
361   static HRESULT (WINAPI *pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
362   WCHAR emptyW[] = { '\0' };
363   int len , reqLen;
364   LPSTR mem;
365
366   if (!lpDstStr || !lpnMultiCharCount)
367     return 0;
368
369   if (!lpSrcStr)
370     lpSrcStr = emptyW;
371
372   *lpDstStr = '\0';
373
374   len = strlenW(lpSrcStr) + 1;
375
376   switch (CodePage)
377   {
378   case CP_WINUNICODE:
379     CodePage = CP_UTF8; /* Fall through... */
380   case 0x0000C350: /* FIXME: CP_ #define */
381   case CP_UTF7:
382   case CP_UTF8:
383     {
384       DWORD dwMode = 0;
385       INT nWideCharCount = len - 1;
386
387       GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
388       if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
389                    lpnMultiCharCount))
390         return 0;
391
392       if (nWideCharCount < len - 1)
393       {
394         mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
395         if (!mem)
396           return 0;
397
398         *lpnMultiCharCount = 0;
399
400         if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
401         {
402           SHLWAPI_162 (mem, *lpnMultiCharCount);
403           lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
404           return *lpnMultiCharCount + 1;
405         }
406         HeapFree(GetProcessHeap(), 0, mem);
407         return *lpnMultiCharCount;
408       }
409       lpDstStr[*lpnMultiCharCount] = '\0';
410       return *lpnMultiCharCount;
411     }
412     break;
413   default:
414     break;
415   }
416
417   reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
418                                *lpnMultiCharCount, NULL, NULL);
419
420   if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
421   {
422     reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
423     if (reqLen)
424     {
425       mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
426       if (mem)
427       {
428         reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
429                                      reqLen, NULL, NULL);
430
431         reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
432         reqLen++;
433
434         lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
435
436         HeapFree(GetProcessHeap(), 0, mem);
437       }
438     }
439   }
440   return reqLen;
441 }
442
443 /*************************************************************************
444  *      SHLWAPI_217     [SHLWAPI.217]
445  *
446  */
447 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, LPINT lpnMultiCharCount)
448 {
449   return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, lpnMultiCharCount);
450 }
451
452 /*************************************************************************
453  *      SHLWAPI_219     [SHLWAPI.219]
454  *
455  * NOTES
456  *  error codes: E_POINTER, E_NOINTERFACE
457  */
458 HRESULT WINAPI SHLWAPI_219 (
459         LPVOID w, /* [???] NOTE: returned by LocalAlloc, 0x450 bytes, iface */
460         LPVOID x,
461         REFIID riid, /* e.g. IWebBrowser2 */
462         LPWSTR z) /* [???] NOTE: OUT: path */
463 {
464         FIXME("(%p %s %s %p)stub\n",w,debugstr_a(x),debugstr_guid(riid),z);
465         return 0xabba1252;
466 }
467
468 /*************************************************************************
469  *      SHLWAPI_222     [SHLWAPI.222]
470  *
471  * NOTES
472  *  securityattributes missing
473  */
474 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
475 {
476         char lpstrName[80];
477
478         sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
479                  guid->Data1, guid->Data2, guid->Data3,
480                  guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
481                  guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
482         FIXME("(%s) stub\n", lpstrName);
483         return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
484 }
485
486 /*************************************************************************
487  *      SHLWAPI_223     [SHLWAPI.223]
488  *
489  * NOTES
490  *  get the count of the semaphore
491  */
492 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
493 {
494         DWORD oldCount;
495
496         FIXME("(0x%08x) stub\n",handle);
497
498         ReleaseSemaphore( handle, 1, &oldCount);        /* +1 */
499         WaitForSingleObject( handle, 0 );               /* -1 */
500         return oldCount;
501 }
502
503 /*************************************************************************
504  *      SHLWAPI_237     [SHLWAPI.237]
505  *
506  * Unicode version of SHLWAPI_183.
507  */
508 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
509 {
510         WNDCLASSW WndClass;
511
512         TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
513
514         if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
515                 return TRUE;
516         return RegisterClassW(lpWndClass);
517 }
518
519 /*************************************************************************
520  *      SHLWAPI_240     [SHLWAPI.240]
521  *
522  *      Calls ASCII or Unicode WindowProc for the given window.
523  */
524 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
525 {
526         if (IsWindowUnicode(hWnd))
527                 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
528         return DefWindowProcA(hWnd, uMessage, wParam, lParam);
529 }
530
531 /*************************************************************************
532  *      SHLWAPI_241     [SHLWAPI.241]
533  *
534  */
535 DWORD WINAPI SHLWAPI_241 ()
536 {
537         FIXME("()stub\n");
538         return 0xabba1243;
539 }
540
541 /*************************************************************************
542  *      SHLWAPI_266     [SHLWAPI.266]
543  */
544 DWORD WINAPI SHLWAPI_266 (
545         LPVOID w,
546         LPVOID x,
547         LPVOID y,
548         LPVOID z)
549 {
550         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
551         return 0xabba1248;
552 }
553
554 /*************************************************************************
555  *      SHLWAPI_267     [SHLWAPI.267]
556  */
557 HRESULT WINAPI SHLWAPI_267 (
558         LPVOID w, /* [???] NOTE: same as 1th parameter of SHLWAPI_219 */
559         LPVOID x, /* [???] NOTE: same as 2nd parameter of SHLWAPI_219 */
560         LPVOID y,
561         LPVOID z)
562 {
563         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
564         *((LPDWORD)z) = 0xabba1200;
565         return 0xabba1254;
566 }
567
568 /*************************************************************************
569  *      SHLWAPI_268     [SHLWAPI.268]
570  */
571 DWORD WINAPI SHLWAPI_268 (
572         LPVOID w,
573         LPVOID x)
574 {
575         FIXME("(%p %p)\n",w,x);
576         return 0xabba1251; /* 0 = failure */
577 }
578
579 /*************************************************************************
580  *      SHLWAPI_276     [SHLWAPI.276]
581  *
582  */
583 DWORD WINAPI SHLWAPI_276 ()
584 {
585         FIXME("()stub\n");
586         return 0xabba1244;
587 }
588
589 /*************************************************************************
590  *      SHLWAPI_278     [SHLWAPI.278]
591  *
592  */
593 DWORD WINAPI SHLWAPI_278 (
594         LONG wndProc,
595         HWND hWndParent,
596         DWORD dwExStyle,
597         DWORD dwStyle,
598         HMENU hMenu,
599         LONG z)
600 {
601         WNDCLASSA wndclass;
602         HWND hwnd;
603         HCURSOR hCursor;
604         char * clsname = "WorkerA";
605
606         FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx)stub\n",
607           wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
608
609         hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
610
611         if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
612         {
613           RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
614           wndclass.lpfnWndProc = DefWindowProcW;
615           wndclass.cbWndExtra = 4;
616           wndclass.hInstance = shlwapi_hInstance;
617           wndclass.hCursor = hCursor;
618           wndclass.hbrBackground = COLOR_BTNSHADOW;
619           wndclass.lpszMenuName = NULL;
620           wndclass.lpszClassName = clsname;
621           RegisterClassA (&wndclass);
622         }
623         hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
624                 hMenu,shlwapi_hInstance,0);
625         SetWindowLongA(hwnd, 0, z);
626         SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
627         return hwnd;
628 }
629
630 /*************************************************************************
631  *      SHLWAPI_289     [SHLWAPI.289]
632  *
633  * Late bound call to winmm.PlaySoundW
634  */
635 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
636 {
637   static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
638
639   GET_FUNC(winmm, "PlaySoundW", FALSE);
640   return pfnFunc(pszSound, hmod, fdwSound);
641 }
642
643 /*************************************************************************
644  *      SHLWAPI_294     [SHLWAPI.294]
645  */
646 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len,  LPCSTR lpStr2)
647 {
648     /*
649      * str1:            "I"     "I"     pushl esp+0x20
650      * str2:            "U"     "I"     pushl 0x77c93810
651      * (is "I" and "U" "integer" and "unsigned" ??)
652      *
653      * pStr:            ""      ""      pushl eax
654      * some_len:        0x824   0x104   pushl 0x824
655      * lpStr2:          "%l"    "%l"    pushl esp+0xc
656      *
657      * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
658      * LocalAlloc(0x00, some_len) -> irrelevant_var
659      * LocalAlloc(0x40, irrelevant_len) -> pStr
660      * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
661      * shlwapi.PathRemoveBlanksW(pStr);
662      */
663     ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
664     return TRUE;
665 }
666
667 /*************************************************************************
668  *      SHLWAPI_313     [SHLWAPI.313]
669  *
670  * Late bound call to shell32.SHGetFileInfoW
671  */
672 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
673                          SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
674 {
675   static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
676
677   GET_FUNC(shell32, "SHGetFileInfoW", 0);
678   return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
679 }
680
681 /*************************************************************************
682  *      SHLWAPI_318     [SHLWAPI.318]
683  *
684  * Late bound call to shell32.DragQueryFileW
685  */
686 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
687 {
688   static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
689
690   GET_FUNC(shell32, "DragQueryFileW", 0);
691   return pfnFunc(hDrop, lFile, lpszFile, lLength);
692 }
693
694 /*************************************************************************
695  *      SHLWAPI_333     [SHLWAPI.333]
696  *
697  * Late bound call to shell32.SHBrowseForFolderW
698  */
699 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
700 {
701   static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
702
703   GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
704   return pfnFunc(lpBi);
705 }
706
707 /*************************************************************************
708  *      SHLWAPI_334     [SHLWAPI.334]
709  *
710  * Late bound call to shell32.SHGetPathFromIDListW
711  */
712 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
713 {
714   static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
715
716   GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
717   return pfnFunc(pidl, pszPath);
718 }
719
720 /*************************************************************************
721  *      SHLWAPI_335     [SHLWAPI.335]
722  *
723  * Late bound call to shell32.ShellExecuteExW
724  */
725 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
726 {
727   static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
728
729   GET_FUNC(shell32, "ShellExecuteExW", FALSE);
730   return pfnFunc(lpExecInfo);
731 }
732
733 /*************************************************************************
734  *      SHLWAPI_336     [SHLWAPI.336]
735  *
736  * Late bound call to shell32.SHFileOperationW.
737  */
738 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
739 {
740   static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
741
742   GET_FUNC(shell32, "SHFileOperationW", 0);
743   return pfnFunc(lpFileOp);
744 }
745
746 /*************************************************************************
747  *      SHLWAPI_337     [SHLWAPI.337]
748  *
749  * Late bound call to shell32.ExtractIconExW.
750  */
751 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
752                          HICON *phiconSmall, UINT nIcons)
753 {
754   static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
755
756   GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
757   return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
758 }
759
760 /*************************************************************************
761  *      SHLWAPI_342     [SHLWAPI.342]
762  *
763  */
764 DWORD WINAPI SHLWAPI_342 (
765         LPVOID w,
766         LPVOID x,
767         LPVOID y,
768         LPVOID z)
769 {
770         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
771         return 0xabba1249;
772 }
773
774 /*************************************************************************
775  *      SHLWAPI_346     [SHLWAPI.346]
776  */
777 DWORD WINAPI SHLWAPI_346 (
778         LPCWSTR src,
779         LPWSTR dest,
780         int len)
781 {
782         FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
783         lstrcpynW(dest, src, len);
784         return lstrlenW(dest)+1;
785 }
786
787 /*************************************************************************
788  *      SHLWAPI_357     [SHLWAPI.357]
789  *
790  * Late bound call to shell32.SHGetNewLinkInfoW
791  */
792 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
793                         BOOL *pfMustCopy, UINT uFlags)
794 {
795   static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
796
797   GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
798   return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
799 }
800
801 /*************************************************************************
802  *      SHLWAPI_358     [SHLWAPI.358]
803  *
804  * Late bound call to shell32.SHDefExtractIconW
805  */
806 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
807                          LPVOID arg5, LPVOID arg6)
808 {
809   /* FIXME: Correct args */
810   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
811
812   GET_FUNC(shell32, "SHDefExtractIconW", 0);
813   return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
814 }
815
816 /*************************************************************************
817  *      SHLWAPI_364     [SHLWAPI.364]
818  *
819  * Wrapper for lstrcpynA with src and dst swapped.
820  */
821 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
822 {
823   lstrcpynA(dst, src, n);
824   return TRUE;
825 }
826
827 /*************************************************************************
828  *      SHLWAPI_370     [SHLWAPI.370]
829  *
830  * Late bound call to shell32.ExtractIconW
831  */
832 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
833                          UINT nIconIndex)
834 {
835   static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
836
837   GET_FUNC(shell32, "ExtractIconW", (HICON)0);
838   return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
839 }
840
841 /*************************************************************************
842  *      SHLWAPI_376     [SHLWAPI.376]
843  */
844 DWORD WINAPI SHLWAPI_376 (LONG x)
845 {
846         FIXME("(0x%08lx)stub\n", x );
847   /* FIXME: This should be a forward in the .spec file to the win2k function
848    * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
849    */
850   return 0xabba1245;
851 }
852
853 /*************************************************************************
854  *      SHLWAPI_377     [SHLWAPI.377]
855  */
856 DWORD WINAPI SHLWAPI_377 (LPVOID x, LPVOID y, LPVOID z)
857 {
858         FIXME("(%p %p %p)stub\n", x,y,z);
859         return 0xabba1246;
860 }
861
862 /*************************************************************************
863  *      SHLWAPI_378     [SHLWAPI.378]
864  */
865 DWORD WINAPI SHLWAPI_378 (
866         LPSTR x,
867         LPVOID y, /* [???] 0x50000000 */
868         LPVOID z) /* [???] 4 */
869 {
870         FIXME("(%s %p %p)stub\n", x,y,z);
871         return LoadLibraryA(x);
872 }
873
874 /*************************************************************************
875  *      SHLWAPI_389     [SHLWAPI.389]
876  *
877  * Late bound call to comdlg32.GetSaveFileNameW
878  */
879 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
880 {
881   static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
882
883   GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
884   return pfnFunc(ofn);
885 }
886
887 /*************************************************************************
888  *      SHLWAPI_390     [SHLWAPI.390]
889  *
890  * Late bound call to mpr.WNetRestoreConnectionW
891  */
892 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
893 {
894   /* FIXME: Correct args */
895   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
896
897   GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
898   return pfnFunc(arg1, arg2);
899 }
900
901 /*************************************************************************
902  *      SHLWAPI_391     [SHLWAPI.391]
903  *
904  * Late bound call to mpr.WNetGetLastErrorW
905  */
906 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
907                          LPVOID arg5)
908 {
909   /* FIXME: Correct args */
910   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
911
912   GET_FUNC(mpr, "WNetGetLastErrorW", 0);
913   return pfnFunc(arg1, arg2, arg3, arg4, arg5);
914 }
915
916 /*************************************************************************
917  *      SHLWAPI_401     [SHLWAPI.401]
918  *
919  * Late bound call to comdlg32.PageSetupDlgW
920  */
921 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
922 {
923   static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
924
925   GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
926   return pfnFunc(pagedlg);
927 }
928
929 /*************************************************************************
930  *      SHLWAPI_402     [SHLWAPI.402]
931  *
932  * Late bound call to comdlg32.PrintDlgW
933  */
934 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
935 {
936   static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
937
938   GET_FUNC(comdlg32, "PrintDlgW", FALSE);
939   return pfnFunc(printdlg);
940 }
941
942 /*************************************************************************
943  *      SHLWAPI_403     [SHLWAPI.403]
944  *
945  * Late bound call to comdlg32.GetOpenFileNameW
946  */
947 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
948 {
949   static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
950
951   GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
952   return pfnFunc(ofn);
953 }
954
955 /* INTERNAL: Map from HLS color space to RGB */
956 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
957 {
958   wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
959
960   if (wHue > 160)
961     return wMid1;
962   else if (wHue > 120)
963     wHue = 160 - wHue;
964   else if (wHue > 40)
965     return wMid2;
966
967   return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
968 }
969
970 /* Convert to RGB and scale into RGB range (0..255) */
971 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
972
973 /*************************************************************************
974  *      ColorHLSToRGB   [SHLWAPI.404]
975  *
976  * Convert from HLS color space into an RGB COLORREF.
977  *
978  * NOTES
979  * Input HLS values are constrained to the range (0..240).
980  */
981 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
982 {
983   WORD wRed;
984
985   if (wSaturation)
986   {
987     WORD wGreen, wBlue, wMid1, wMid2;
988
989     if (wLuminosity > 120)
990       wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
991     else
992       wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
993
994     wMid1 = wLuminosity * 2 - wMid2;
995
996     wRed   = GET_RGB(wHue + 80);
997     wGreen = GET_RGB(wHue);
998     wBlue  = GET_RGB(wHue - 80);
999
1000     return RGB(wRed, wGreen, wBlue);
1001   }
1002
1003   wRed = wLuminosity * 255 / 240;
1004   return RGB(wRed, wRed, wRed);
1005 }
1006
1007 /*************************************************************************
1008  *      SHLWAPI_431     [SHLWAPI.431]
1009  */
1010 DWORD WINAPI SHLWAPI_431 (DWORD x)
1011 {
1012         FIXME("(0x%08lx)stub\n", x);
1013         return 0xabba1247;
1014 }
1015
1016 /*************************************************************************
1017  *      SHLWAPI_437     [SHLWAPI.437]
1018  *
1019  * NOTES
1020  *  In the real shlwapi, One time initialisation calls GetVersionEx and reads
1021  *  the registry to determine what O/S & Service Pack level is running, and
1022  *  therefore which functions are available. Currently we always run as NT,
1023  *  since this means that we don't need extra code to emulate Unicode calls,
1024  *  they are forwarded directly to the appropriate API call instead.
1025  *  Since the flags for whether to call or emulate Unicode are internal to
1026  *  the dll, this function does not need a full implementation.
1027  */
1028 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
1029 {
1030         FIXME("(0x%08lx)stub\n", functionToCall);
1031         return 0xabba1247;
1032 }
1033
1034 /*************************************************************************
1035  *      SHCreateShellPalette    [SHLWAPI.@]
1036  */
1037 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
1038 {
1039         FIXME("stub\n");
1040         return CreateHalftonePalette(hdc);
1041 }
1042
1043 /*************************************************************************
1044  *      SHGetInverseCMAP
1045  */
1046 DWORD WINAPI SHGetInverseCMAP (LPVOID x, DWORD why)
1047 {
1048         FIXME("(%p, %#lx)stub\n", x, why);
1049         return 0;
1050 }
1051
1052 /*************************************************************************
1053  *      SHIsLowMemoryMachine    [SHLWAPI.@]
1054  */
1055 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
1056 {
1057         FIXME("0x%08lx\n", x);
1058         return 0;
1059 }
1060
1061 /*************************************************************************
1062  *      GetMenuPosFromID        [SHLWAPI.@]
1063  */
1064 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
1065 {
1066  MENUITEMINFOA mi;
1067  INT nCount = GetMenuItemCount(hMenu), nIter = 0;
1068
1069  while (nIter < nCount)
1070  {
1071    mi.wID = 0;
1072    if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
1073      return nIter;
1074    nIter++;
1075  }
1076  return -1;
1077 }
1078
1079 /*************************************************************************
1080  *      _SHGetInstanceExplorer  [SHLWAPI.@]
1081  *
1082  * Late bound call to shell32.SHGetInstanceExplorer.
1083  */
1084 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
1085 {
1086   static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
1087
1088   GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
1089   return pfnFunc(lpUnknown);
1090 }