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