When including 'wine/port.h', include it first.
[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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
445  *
446  * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
447  * --> Crash. Something wrong here.
448  */
449 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, LPINT lpnMultiCharCount)
450 {
451   return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, lpnMultiCharCount);
452 }
453
454 /*************************************************************************
455  *      @       [SHLWAPI.219]
456  *
457  * NOTES
458  *  error codes: E_POINTER, E_NOINTERFACE
459  */
460 HRESULT WINAPI SHLWAPI_219 (
461         LPVOID w, /* [???] NOTE: returned by LocalAlloc, 0x450 bytes, iface */
462         LPVOID x, /* [???] */
463         REFIID riid, /* [???] e.g. IWebBrowser2 */
464         LPWSTR z) /* [???] NOTE: OUT: path */
465 {
466         FIXME("(%p %s %s %p)stub\n",w,debugstr_a(x),debugstr_guid(riid),z);
467         return 0xabba1252;
468 }
469
470 /*************************************************************************
471  *      @       [SHLWAPI.222]
472  *
473  * NOTES
474  *  securityattributes missing
475  */
476 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
477 {
478         char lpstrName[80];
479
480         sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
481                  guid->Data1, guid->Data2, guid->Data3,
482                  guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
483                  guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
484         FIXME("(%s) stub\n", lpstrName);
485         return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
486 }
487
488 /*************************************************************************
489  *      @       [SHLWAPI.223]
490  *
491  * NOTES
492  *  get the count of the semaphore
493  */
494 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
495 {
496         DWORD oldCount;
497
498         FIXME("(0x%08x) stub\n",handle);
499
500         ReleaseSemaphore( handle, 1, &oldCount);        /* +1 */
501         WaitForSingleObject( handle, 0 );               /* -1 */
502         return oldCount;
503 }
504
505 /*************************************************************************
506  *      @       [SHLWAPI.237]
507  *
508  * Unicode version of SHLWAPI_183.
509  */
510 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
511 {
512         WNDCLASSW WndClass;
513
514         TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
515
516         if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
517                 return TRUE;
518         return RegisterClassW(lpWndClass);
519 }
520
521 /*************************************************************************
522  *      @       [SHLWAPI.240]
523  *
524  *      Calls ASCII or Unicode WindowProc for the given window.
525  */
526 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
527 {
528         if (IsWindowUnicode(hWnd))
529                 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
530         return DefWindowProcA(hWnd, uMessage, wParam, lParam);
531 }
532
533 /*************************************************************************
534  *      @       [SHLWAPI.241]
535  *
536  */
537 DWORD WINAPI SHLWAPI_241 ()
538 {
539         FIXME("()stub\n");
540         return 0xabba1243;
541 }
542
543 /*************************************************************************
544  *      @       [SHLWAPI.266]
545  */
546 DWORD WINAPI SHLWAPI_266 (
547         LPVOID w,
548         LPVOID x,
549         LPVOID y,
550         LPVOID z)
551 {
552         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
553         return 0xabba1248;
554 }
555
556 /*************************************************************************
557  *      @       [SHLWAPI.267]
558  */
559 HRESULT WINAPI SHLWAPI_267 (
560         LPVOID w, /* [???] NOTE: same as 1th parameter of SHLWAPI_219 */
561         LPVOID x, /* [???] NOTE: same as 2nd parameter of SHLWAPI_219 */
562         LPVOID y,
563         LPVOID z)
564 {
565         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
566         *((LPDWORD)z) = 0xabba1200;
567         return 0xabba1254;
568 }
569
570 /*************************************************************************
571  *      @       [SHLWAPI.268]
572  */
573 DWORD WINAPI SHLWAPI_268 (
574         LPVOID w,
575         LPVOID x)
576 {
577         FIXME("(%p %p)\n",w,x);
578         return 0xabba1251; /* 0 = failure */
579 }
580
581 /*************************************************************************
582  *      @       [SHLWAPI.276]
583  *
584  */
585 DWORD WINAPI SHLWAPI_276 ()
586 {
587         FIXME("()stub\n");
588         return 0xabba1244;
589 }
590
591 /*************************************************************************
592  *      @       [SHLWAPI.278]
593  *
594  */
595 HWND WINAPI SHLWAPI_278 (
596         LONG wndProc,
597         HWND hWndParent,
598         DWORD dwExStyle,
599         DWORD dwStyle,
600         HMENU hMenu,
601         LONG z)
602 {
603         WNDCLASSA wndclass;
604         HWND hwnd;
605         HCURSOR hCursor;
606         char * clsname = "WorkerA";
607
608         FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx)stub\n",
609           wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
610
611         hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
612
613         if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
614         {
615           RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
616           wndclass.lpfnWndProc = DefWindowProcW;
617           wndclass.cbWndExtra = 4;
618           wndclass.hInstance = shlwapi_hInstance;
619           wndclass.hCursor = hCursor;
620           wndclass.hbrBackground = COLOR_BTNSHADOW;
621           wndclass.lpszMenuName = NULL;
622           wndclass.lpszClassName = clsname;
623           RegisterClassA (&wndclass);
624         }
625         hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
626                 hMenu,shlwapi_hInstance,0);
627         SetWindowLongA(hwnd, 0, z);
628         SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
629         return hwnd;
630 }
631
632 /*************************************************************************
633  *      @       [SHLWAPI.289]
634  *
635  * Late bound call to winmm.PlaySoundW
636  */
637 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
638 {
639   static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
640
641   GET_FUNC(winmm, "PlaySoundW", FALSE);
642   return pfnFunc(pszSound, hmod, fdwSound);
643 }
644
645 /*************************************************************************
646  *      @       [SHLWAPI.294]
647  */
648 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len,  LPCSTR lpStr2)
649 {
650     /*
651      * str1:            "I"     "I"     pushl esp+0x20
652      * str2:            "U"     "I"     pushl 0x77c93810
653      * (is "I" and "U" "integer" and "unsigned" ??)
654      *
655      * pStr:            ""      ""      pushl eax
656      * some_len:        0x824   0x104   pushl 0x824
657      * lpStr2:          "%l"    "%l"    pushl esp+0xc
658      *
659      * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
660      * LocalAlloc(0x00, some_len) -> irrelevant_var
661      * LocalAlloc(0x40, irrelevant_len) -> pStr
662      * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
663      * shlwapi.PathRemoveBlanksW(pStr);
664      */
665     ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
666     return TRUE;
667 }
668
669 /*************************************************************************
670  *      @       [SHLWAPI.313]
671  *
672  * Late bound call to shell32.SHGetFileInfoW
673  */
674 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
675                          SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
676 {
677   static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
678
679   GET_FUNC(shell32, "SHGetFileInfoW", 0);
680   return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
681 }
682
683 /*************************************************************************
684  *      @       [SHLWAPI.318]
685  *
686  * Late bound call to shell32.DragQueryFileW
687  */
688 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
689 {
690   static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
691
692   GET_FUNC(shell32, "DragQueryFileW", 0);
693   return pfnFunc(hDrop, lFile, lpszFile, lLength);
694 }
695
696 /*************************************************************************
697  *      @       [SHLWAPI.333]
698  *
699  * Late bound call to shell32.SHBrowseForFolderW
700  */
701 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
702 {
703   static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
704
705   GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
706   return pfnFunc(lpBi);
707 }
708
709 /*************************************************************************
710  *      @       [SHLWAPI.334]
711  *
712  * Late bound call to shell32.SHGetPathFromIDListW
713  */
714 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
715 {
716   static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
717
718   GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
719   return pfnFunc(pidl, pszPath);
720 }
721
722 /*************************************************************************
723  *      @       [SHLWAPI.335]
724  *
725  * Late bound call to shell32.ShellExecuteExW
726  */
727 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
728 {
729   static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
730
731   GET_FUNC(shell32, "ShellExecuteExW", FALSE);
732   return pfnFunc(lpExecInfo);
733 }
734
735 /*************************************************************************
736  *      @       [SHLWAPI.336]
737  *
738  * Late bound call to shell32.SHFileOperationW.
739  */
740 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
741 {
742   static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
743
744   GET_FUNC(shell32, "SHFileOperationW", 0);
745   return pfnFunc(lpFileOp);
746 }
747
748 /*************************************************************************
749  *      @       [SHLWAPI.337]
750  *
751  * Late bound call to shell32.ExtractIconExW.
752  */
753 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
754                          HICON *phiconSmall, UINT nIcons)
755 {
756   static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
757
758   GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
759   return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
760 }
761
762 /*************************************************************************
763  *      @       [SHLWAPI.342]
764  *
765  */
766 DWORD WINAPI SHLWAPI_342 (
767         LPVOID w,
768         LPVOID x,
769         LPVOID y,
770         LPVOID z)
771 {
772         FIXME("(%p %p %p %p)stub\n",w,x,y,z);
773         return 0xabba1249;
774 }
775
776 /*************************************************************************
777  *      @       [SHLWAPI.346]
778  */
779 DWORD WINAPI SHLWAPI_346 (
780         LPCWSTR src,
781         LPWSTR dest,
782         int len)
783 {
784         FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
785         lstrcpynW(dest, src, len);
786         return lstrlenW(dest)+1;
787 }
788
789 /*************************************************************************
790  *      @       [SHLWAPI.357]
791  *
792  * Late bound call to shell32.SHGetNewLinkInfoW
793  */
794 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
795                         BOOL *pfMustCopy, UINT uFlags)
796 {
797   static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
798
799   GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
800   return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
801 }
802
803 /*************************************************************************
804  *      @       [SHLWAPI.358]
805  *
806  * Late bound call to shell32.SHDefExtractIconW
807  */
808 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
809                          LPVOID arg5, LPVOID arg6)
810 {
811   /* FIXME: Correct args */
812   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
813
814   GET_FUNC(shell32, "SHDefExtractIconW", 0);
815   return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
816 }
817
818 /*************************************************************************
819  *      @       [SHLWAPI.364]
820  *
821  * Wrapper for lstrcpynA with src and dst swapped.
822  */
823 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
824 {
825   lstrcpynA(dst, src, n);
826   return TRUE;
827 }
828
829 /*************************************************************************
830  *      @       [SHLWAPI.370]
831  *
832  * Late bound call to shell32.ExtractIconW
833  */
834 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
835                          UINT nIconIndex)
836 {
837   static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
838
839   GET_FUNC(shell32, "ExtractIconW", (HICON)0);
840   return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
841 }
842
843 /*************************************************************************
844  *      @       [SHLWAPI.376]
845  */
846 DWORD WINAPI SHLWAPI_376 (LONG x)
847 {
848         FIXME("(0x%08lx)stub\n", x );
849   /* FIXME: This should be a forward in the .spec file to the win2k function
850    * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
851    */
852   return 0xabba1245;
853 }
854
855 /*************************************************************************
856  *      @       [SHLWAPI.377]
857  */
858 DWORD WINAPI SHLWAPI_377 (LPVOID x, LPVOID y, LPVOID z)
859 {
860         FIXME("(%p %p %p)stub\n", x,y,z);
861         return 0xabba1246;
862 }
863
864 /*************************************************************************
865  *      @       [SHLWAPI.378]
866  */
867 DWORD WINAPI SHLWAPI_378 (
868         LPSTR x,
869         LPVOID y, /* [???] 0x50000000 */
870         LPVOID z) /* [???] 4 */
871 {
872         FIXME("(%s %p %p)stub\n", x,y,z);
873         return LoadLibraryA(x);
874 }
875
876 /*************************************************************************
877  *      @       [SHLWAPI.389]
878  *
879  * Late bound call to comdlg32.GetSaveFileNameW
880  */
881 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
882 {
883   static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
884
885   GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
886   return pfnFunc(ofn);
887 }
888
889 /*************************************************************************
890  *      @       [SHLWAPI.390]
891  *
892  * Late bound call to mpr.WNetRestoreConnectionW
893  */
894 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
895 {
896   /* FIXME: Correct args */
897   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
898
899   GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
900   return pfnFunc(arg1, arg2);
901 }
902
903 /*************************************************************************
904  *      @       [SHLWAPI.391]
905  *
906  * Late bound call to mpr.WNetGetLastErrorW
907  */
908 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
909                          LPVOID arg5)
910 {
911   /* FIXME: Correct args */
912   static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
913
914   GET_FUNC(mpr, "WNetGetLastErrorW", 0);
915   return pfnFunc(arg1, arg2, arg3, arg4, arg5);
916 }
917
918 /*************************************************************************
919  *      @       [SHLWAPI.401]
920  *
921  * Late bound call to comdlg32.PageSetupDlgW
922  */
923 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
924 {
925   static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
926
927   GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
928   return pfnFunc(pagedlg);
929 }
930
931 /*************************************************************************
932  *      @       [SHLWAPI.402]
933  *
934  * Late bound call to comdlg32.PrintDlgW
935  */
936 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
937 {
938   static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
939
940   GET_FUNC(comdlg32, "PrintDlgW", FALSE);
941   return pfnFunc(printdlg);
942 }
943
944 /*************************************************************************
945  *      @       [SHLWAPI.403]
946  *
947  * Late bound call to comdlg32.GetOpenFileNameW
948  */
949 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
950 {
951   static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
952
953   GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
954   return pfnFunc(ofn);
955 }
956
957 /* INTERNAL: Map from HLS color space to RGB */
958 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
959 {
960   wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
961
962   if (wHue > 160)
963     return wMid1;
964   else if (wHue > 120)
965     wHue = 160 - wHue;
966   else if (wHue > 40)
967     return wMid2;
968
969   return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
970 }
971
972 /* Convert to RGB and scale into RGB range (0..255) */
973 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
974
975 /*************************************************************************
976  *      ColorHLSToRGB   [SHLWAPI.404]
977  *
978  * Convert from HLS color space into an RGB COLORREF.
979  *
980  * NOTES
981  * Input HLS values are constrained to the range (0..240).
982  */
983 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
984 {
985   WORD wRed;
986
987   if (wSaturation)
988   {
989     WORD wGreen, wBlue, wMid1, wMid2;
990
991     if (wLuminosity > 120)
992       wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
993     else
994       wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
995
996     wMid1 = wLuminosity * 2 - wMid2;
997
998     wRed   = GET_RGB(wHue + 80);
999     wGreen = GET_RGB(wHue);
1000     wBlue  = GET_RGB(wHue - 80);
1001
1002     return RGB(wRed, wGreen, wBlue);
1003   }
1004
1005   wRed = wLuminosity * 255 / 240;
1006   return RGB(wRed, wRed, wRed);
1007 }
1008
1009 /*************************************************************************
1010  *      @       [SHLWAPI.431]
1011  */
1012 DWORD WINAPI SHLWAPI_431 (DWORD x)
1013 {
1014         FIXME("(0x%08lx)stub\n", x);
1015         return 0xabba1247;
1016 }
1017
1018 /*************************************************************************
1019  *      @       [SHLWAPI.437]
1020  *
1021  * NOTES
1022  *  In the real shlwapi, One time initialisation calls GetVersionEx and reads
1023  *  the registry to determine what O/S & Service Pack level is running, and
1024  *  therefore which functions are available. Currently we always run as NT,
1025  *  since this means that we don't need extra code to emulate Unicode calls,
1026  *  they are forwarded directly to the appropriate API call instead.
1027  *  Since the flags for whether to call or emulate Unicode are internal to
1028  *  the dll, this function does not need a full implementation.
1029  */
1030 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
1031 {
1032         FIXME("(0x%08lx)stub\n", functionToCall);
1033         return 0xabba1247;
1034 }
1035
1036 /*************************************************************************
1037  *      SHCreateShellPalette    [SHLWAPI.@]
1038  */
1039 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
1040 {
1041         FIXME("stub\n");
1042         return CreateHalftonePalette(hdc);
1043 }
1044
1045 /*************************************************************************
1046  *      SHGetInverseCMAP (SHLWAPI.@)
1047  */
1048 DWORD WINAPI SHGetInverseCMAP (LPVOID x, DWORD why)
1049 {
1050         FIXME("(%p, %#lx)stub\n", x, why);
1051         return 0;
1052 }
1053
1054 /*************************************************************************
1055  *      SHIsLowMemoryMachine    [SHLWAPI.@]
1056  */
1057 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
1058 {
1059         FIXME("0x%08lx\n", x);
1060         return 0;
1061 }
1062
1063 /*************************************************************************
1064  *      GetMenuPosFromID        [SHLWAPI.@]
1065  */
1066 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
1067 {
1068  MENUITEMINFOA mi;
1069  INT nCount = GetMenuItemCount(hMenu), nIter = 0;
1070
1071  while (nIter < nCount)
1072  {
1073    mi.wID = 0;
1074    if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
1075      return nIter;
1076    nIter++;
1077  }
1078  return -1;
1079 }
1080
1081 /*************************************************************************
1082  *      _SHGetInstanceExplorer@4        [SHLWAPI.@]
1083  *
1084  * Late bound call to shell32.SHGetInstanceExplorer.
1085  */
1086 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
1087 {
1088   static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
1089
1090   GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
1091   return pfnFunc(lpUnknown);
1092 }