POSIX threads emulation, tricks glibc into being threadsafe.
[wine] / dlls / shell32 / shellord.c
1 /*
2  * The parameters of many functions changes between different OS versions
3  * (NT uses Unicode strings, 95 uses ASCII strings)
4  * 
5  * Copyright 1997 Marcus Meissner
6  *           1998 Jürgen Schmied
7  */
8 #include <string.h>
9 #include <stdio.h>
10 #include "winerror.h"
11 #include "winreg.h"
12 #include "debugtools.h"
13 #include "winnls.h"
14 #include "winversion.h"
15 #include "heap.h"
16 #include "crtdll.h"
17
18 #include "shellapi.h"
19 #include "shlobj.h"
20 #include "shell32_main.h"
21 #include "wine/undocshell.h"
22 #include "shpolicy.h"
23
24 DEFAULT_DEBUG_CHANNEL(shell);
25
26 /*************************************************************************
27  * ParseFieldA                                  [SHELL32.58]
28  *
29  * copys a field from a ',' delimited string
30  * 
31  * first field is nField = 1
32  */
33 DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len) 
34 {
35         WARN("('%s',0x%08lx,%p,%ld) semi-stub.\n",src,nField,dst,len);
36
37         if (!src || !src[0] || !dst || !len)
38           return 0;
39
40         /* skip n fields delimited by ',' */
41         while (nField > 1)
42         {
43           if (*src=='\0') return FALSE;
44           if (*(src++)==',') nField--;
45         }
46
47         /* copy part till the next ',' to dst */
48         while ( *src!='\0' && *src!=',' && (len--)>0 ) *(dst++)=*(src++);
49         
50         /* finalize the string */
51         *dst=0x0;
52         
53         return TRUE;
54 }
55
56 /*************************************************************************
57  * PickIconDlg                                  [SHELL32.62]
58  * 
59  */
60 DWORD WINAPI PickIconDlg(DWORD x,DWORD y,DWORD z,DWORD a) 
61 {       FIXME("(%08lx,%08lx,%08lx,%08lx):stub.\n",x,y,z,a);
62         return 0xffffffff;
63 }
64
65 /*************************************************************************
66  * GetFileNameFromBrowse                        [SHELL32.63]
67  * 
68  */
69 DWORD WINAPI GetFileNameFromBrowse(HWND howner, LPSTR targetbuf, DWORD len, DWORD x, LPCSTR suffix, LPCSTR y, LPCSTR cmd) 
70 {       FIXME("(%04x,%p,%ld,%08lx,%s,%s,%s):stub.\n",
71             howner,targetbuf,len,x,suffix,y,cmd);
72     /* puts up a Open Dialog and requests input into targetbuf */
73     /* OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_FILEMUSTEXIST|OFN_unknown */
74     lstrcpyA(targetbuf,"x:\\dummy.exe");
75     return 1;
76 }
77
78 /*************************************************************************
79  * SHGetSettings                                [SHELL32.68]
80  * 
81  * NOTES
82  *  the registry path are for win98 (tested)
83  *  and possibly are the same in nt40
84  */
85 void WINAPI SHGetSettings(LPSHELLFLAGSTATE lpsfs, DWORD dwMask, DWORD dwx)
86 {
87         HKEY    hKey;
88         DWORD   dwData;
89         DWORD   dwDataSize = sizeof (DWORD);
90
91         TRACE("(%p 0x%08lx 0x%08lx)\n",lpsfs,dwMask, dwx);
92         
93         if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
94                                  0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
95           return;
96         
97         if ( (SSF_SHOWEXTENSIONS & dwMask) && !RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
98           lpsfs->fShowExtensions  = ((dwData == 0) ?  0 : 1);
99
100         if ( (SSF_SHOWINFOTIP & dwMask) && !RegQueryValueExA(hKey, "ShowInfoTip", 0, 0, (LPBYTE)&dwData, &dwDataSize))
101           lpsfs->fShowInfoTip  = ((dwData == 0) ?  0 : 1);
102
103         if ( (SSF_DONTPRETTYPATH & dwMask) && !RegQueryValueExA(hKey, "DontPrettyPath", 0, 0, (LPBYTE)&dwData, &dwDataSize))
104           lpsfs->fDontPrettyPath  = ((dwData == 0) ?  0 : 1);
105
106         if ( (SSF_HIDEICONS & dwMask) && !RegQueryValueExA(hKey, "HideIcons", 0, 0, (LPBYTE)&dwData, &dwDataSize))
107           lpsfs->fHideIcons  = ((dwData == 0) ?  0 : 1);
108
109         if ( (SSF_MAPNETDRVBUTTON & dwMask) && !RegQueryValueExA(hKey, "MapNetDrvBtn", 0, 0, (LPBYTE)&dwData, &dwDataSize))
110           lpsfs->fMapNetDrvBtn  = ((dwData == 0) ?  0 : 1);
111
112         if ( (SSF_SHOWATTRIBCOL & dwMask) && !RegQueryValueExA(hKey, "ShowAttribCol", 0, 0, (LPBYTE)&dwData, &dwDataSize))
113           lpsfs->fShowAttribCol  = ((dwData == 0) ?  0 : 1);
114
115         if (((SSF_SHOWALLOBJECTS | SSF_SHOWSYSFILES) & dwMask) && !RegQueryValueExA(hKey, "Hidden", 0, 0, (LPBYTE)&dwData, &dwDataSize))
116         { if (dwData == 0)
117           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 0;
118             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 0;
119           }
120           else if (dwData == 1)
121           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 1;
122             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 0;
123           }
124           else if (dwData == 2)
125           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 0;
126             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 1;
127           }
128         }
129         RegCloseKey (hKey);
130
131         TRACE("-- 0x%04x\n", *(WORD*)lpsfs);
132 }
133
134 /*************************************************************************
135  * SHShellFolderView_Message                    [SHELL32.73]
136  *
137  * PARAMETERS
138  *  hwndCabinet defines the explorer cabinet window that contains the 
139  *              shellview you need to communicate with
140  *  uMsg        identifying the SFVM enum to perform
141  *  lParam
142  *
143  * NOTES
144  *  Message SFVM_REARRANGE = 1
145  *    This message gets sent when a column gets clicked to instruct the
146  *    shell view to re-sort the item list. lParam identifies the column
147  *    that was clicked.
148  */
149 int WINAPI SHShellFolderView_Message(HWND hwndCabinet,UINT uMsg,LPARAM lParam)
150 { FIXME("%04x %08ux %08lx stub\n",hwndCabinet,uMsg,lParam);
151   return 0;
152 }
153
154 /*************************************************************************
155  * OleStrToStrN                                 [SHELL32.78]
156  */
157 BOOL WINAPI OleStrToStrNA (LPSTR lpStr, INT nStr, LPCWSTR lpOle, INT nOle) 
158 {
159         TRACE("(%p, %x, %s, %x)\n", lpStr, nStr, debugstr_wn(lpOle,nOle), nOle);
160         return WideCharToMultiByte (0, 0, lpOle, nOle, lpStr, nStr, NULL, NULL);
161 }
162
163 BOOL WINAPI OleStrToStrNW (LPWSTR lpwStr, INT nwStr, LPCWSTR lpOle, INT nOle) 
164 {
165         TRACE("(%p, %x, %s, %x)\n", lpwStr, nwStr, debugstr_wn(lpOle,nOle), nOle);
166
167         if (lstrcpynW ( lpwStr, lpOle, nwStr))
168         { return lstrlenW (lpwStr);
169         }
170         return 0;
171 }
172
173 BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn) 
174 {
175         if (VERSION_OsIsUnicode())
176           return OleStrToStrNW (lpOut, nOut, lpIn, nIn);
177         return OleStrToStrNA (lpOut, nOut, lpIn, nIn);
178 }
179
180 /*************************************************************************
181  * StrToOleStrN                                 [SHELL32.79]
182  *  lpMulti, nMulti, nWide [IN]
183  *  lpWide [OUT]
184  */
185 BOOL WINAPI StrToOleStrNA (LPWSTR lpWide, INT nWide, LPCSTR lpStrA, INT nStr) 
186 {
187         TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_an(lpStrA,nStr), nStr);
188         return MultiByteToWideChar (0, 0, lpStrA, nStr, lpWide, nWide);
189 }
190 BOOL WINAPI StrToOleStrNW (LPWSTR lpWide, INT nWide, LPCWSTR lpStrW, INT nStr) 
191 {
192         TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_wn(lpStrW, nStr), nStr);
193
194         if (lstrcpynW (lpWide, lpStrW, nWide))
195         { return lstrlenW (lpWide);
196         }
197         return 0;
198 }
199
200 BOOL WINAPI StrToOleStrNAW (LPWSTR lpWide, INT nWide, LPCVOID lpStr, INT nStr) 
201 {
202         if (VERSION_OsIsUnicode())
203           return StrToOleStrNW (lpWide, nWide, lpStr, nStr);
204         return StrToOleStrNA (lpWide, nWide, lpStr, nStr);
205 }
206
207 /*************************************************************************
208  * RegisterShellHook                            [SHELL32.181]
209  *
210  * PARAMS
211  *      hwnd [I]  window handle
212  *      y    [I]  flag ????
213  * 
214  * NOTES
215  *     exported by ordinal
216  */
217 void WINAPI RegisterShellHook(HWND hwnd, DWORD y) {
218     FIXME("(0x%08x,0x%08lx):stub.\n",hwnd,y);
219 }
220 /*************************************************************************
221  * ShellMessageBoxW                             [SHELL32.182]
222  *
223  * Format and output errormessage.
224  *
225  * idText       resource ID of title or LPSTR
226  * idTitle      resource ID of title or LPSTR
227  *
228  * NOTES
229  *     exported by ordinal
230  */
231 INT __cdecl
232 ShellMessageBoxW(HMODULE hmod,HWND hwnd,DWORD idText,DWORD idTitle,DWORD uType,LPCVOID arglist) 
233 {       WCHAR   szText[100],szTitle[100],szTemp[256];
234         LPWSTR   pszText = &szText[0], pszTitle = &szTitle[0];
235         LPVOID  args = &arglist;
236
237         TRACE("(%08lx,%08lx,%08lx,%08lx,%08lx,%p)\n",(DWORD)hmod,(DWORD)hwnd,idText,idTitle,uType,arglist);
238
239         if (!HIWORD (idTitle))
240           LoadStringW(hmod,idTitle,pszTitle,100);
241         else
242           pszTitle = (LPWSTR)idTitle;
243
244         if (! HIWORD (idText))
245           LoadStringW(hmod,idText,pszText,100);
246         else
247           pszText = (LPWSTR)idText;
248
249         FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY ,szText,0,0,szTemp,256,args);
250         return MessageBoxW(hwnd,szTemp,szTitle,uType);
251 }
252
253 /*************************************************************************
254  * ShellMessageBoxA                             [SHELL32.183]
255  */
256 INT __cdecl
257 ShellMessageBoxA(HMODULE hmod,HWND hwnd,DWORD idText,DWORD idTitle,DWORD uType,LPCVOID arglist) 
258 {       char    szText[100],szTitle[100],szTemp[256];
259         LPSTR   pszText = &szText[0], pszTitle = &szTitle[0];
260         LPVOID  args = &arglist;
261
262         TRACE("(%08lx,%08lx,%08lx,%08lx,%08lx,%p)\n", (DWORD)hmod,(DWORD)hwnd,idText,idTitle,uType,arglist);
263
264         if (!HIWORD (idTitle))
265           LoadStringA(hmod,idTitle,pszTitle,100);
266         else
267           pszTitle = (LPSTR)idTitle;
268
269         if (! HIWORD (idText))
270           LoadStringA(hmod,idText,pszText,100);
271         else
272           pszText = (LPSTR)idText;
273
274         FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY ,pszText,0,0,szTemp,256,args);
275         return MessageBoxA(hwnd,szTemp,pszTitle,uType);
276 }
277
278 /*************************************************************************
279  * SHRestricted                         [SHELL32.100]
280  *
281  * walks through policy table, queries <app> key, <type> value, returns 
282  * queried (DWORD) value, and caches it between called to SHInitRestricted
283  * to prevent unnecessary registry access.
284  *
285  * NOTES
286  *     exported by ordinal
287  *
288  * REFERENCES: 
289  *     MS System Policy Editor
290  *     98Lite 2.0 (which uses many of these policy keys) http://www.98lite.net/
291  *     "The Windows 95 Registry", by John Woram, 1996 MIS: Press
292  */
293 DWORD WINAPI SHRestricted (DWORD pol) {
294         char regstr[256];
295         HKEY    xhkey;
296         DWORD   retval, polidx, i, datsize = 4;
297
298         TRACE("(%08lx)\n",pol);
299
300         polidx = -1;
301
302         /* scan to see if we know this policy ID */
303         for (i = 0; i < SHELL_MAX_POLICIES; i++)
304         {
305              if (pol == sh32_policy_table[i].polflags)
306              {
307                  polidx = i;
308                  break;
309              }
310         }
311
312         if (polidx == -1)
313         {
314             /* we don't know this policy, return 0 */
315             TRACE("unknown policy: (%08lx)\n", pol);
316                 return 0;
317         }
318
319         /* we have a known policy */
320         lstrcpyA(regstr, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\");
321         lstrcatA(regstr, sh32_policy_table[polidx].appstr);
322
323         /* first check if this policy has been cached, return it if so */
324         if (sh32_policy_table[polidx].cache != SHELL_NO_POLICY)
325         {
326             return sh32_policy_table[polidx].cache;
327         }
328
329         /* return 0 and don't set the cache if any registry errors occur */
330         retval = 0;
331         if (RegOpenKeyA(HKEY_CURRENT_USER, regstr, &xhkey) == ERROR_SUCCESS)
332         {
333             if (RegQueryValueExA(xhkey, sh32_policy_table[polidx].keystr, NULL, NULL, (LPBYTE)&retval, &datsize) == ERROR_SUCCESS)
334             {
335                 sh32_policy_table[polidx].cache = retval;
336             }
337
338         RegCloseKey(xhkey);
339 }
340
341         return retval;
342 }
343
344 /*************************************************************************
345  *      SHInitRestricted                         [SHELL32.244]
346  *
347  * Win98+ by-ordinal only routine called by Explorer and MSIE 4 and 5.
348  * Inits the policy cache used by SHRestricted to avoid excess
349  * registry access.
350  *
351  * INPUTS
352  * Two inputs: one is a string or NULL.  If non-NULL the pointer
353  * should point to a string containing the following exact text:
354  * "Software\Microsoft\Windows\CurrentVersion\Policies".
355  * The other input is unused.
356  *
357  * NOTES
358  * If the input is non-NULL and does not point to a string containing
359  * that exact text the routine will do nothing.
360  *
361  * If the text does match or the pointer is NULL, then the routine
362  * will init SHRestricted()'s policy cache to all 0xffffffff and
363  * returns 0xffffffff as well.
364  *
365  * I haven't yet run into anything calling this with inputs other than
366  * (NULL, NULL), so I may have the inputs reversed.
367  */
368
369 BOOL WINAPI SHInitRestricted(LPSTR inpRegKey, LPSTR parm2)
370 {
371      int i;
372
373      TRACE("(%p, %p)\n", inpRegKey, parm2);
374
375      /* first check - if input is non-NULL and points to the secret
376         key string, then pass.  Otherwise return 0.
377      */
378
379      if (inpRegKey != (LPSTR)NULL)
380      {
381          if (lstrcmpiA(inpRegKey, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies"))
382          {
383              /* doesn't match, fail */
384              return 0;
385          }
386      }                               
387
388      /* check passed, init all policy cache entries with SHELL_NO_POLICY */
389      for (i = 0; i < SHELL_MAX_POLICIES; i++)
390      {
391           sh32_policy_table[i].cache = SHELL_NO_POLICY;
392      }
393
394      return SHELL_NO_POLICY;
395 }
396
397 /*************************************************************************
398  * SHFree                                       [SHELL32.195]
399  *
400  * NOTES
401  *     free_ptr() - frees memory using IMalloc
402  *     exported by ordinal
403  */
404 #define MEM_DEBUG 1
405 DWORD WINAPI SHFree(LPVOID x) 
406 {
407 #if MEM_DEBUG
408         WORD len = *(LPWORD)((LPBYTE)x-2);
409
410         if ( *(LPWORD)((LPBYTE)x+len) != 0x7384)
411           ERR("MAGIC2!\n");
412
413         if ( (*(LPWORD)((LPBYTE)x-4)) != 0x8271)
414           ERR("MAGIC1!\n");
415         else
416           memset((LPBYTE)x-4, 0xde, len+6);
417
418         TRACE("%p len=%u\n",x, len);
419
420         x = (LPBYTE) x - 4;
421 #else
422         TRACE("%p\n",x);
423 #endif
424         return HeapFree(GetProcessHeap(), 0, x);
425 }
426
427 /*************************************************************************
428  * SHAlloc                                      [SHELL32.196]
429  *
430  * NOTES
431  *     void *task_alloc(DWORD len), uses SHMalloc allocator
432  *     exported by ordinal
433  */
434 LPVOID WINAPI SHAlloc(DWORD len) 
435 {
436         LPBYTE ret;
437
438 #if MEM_DEBUG
439         ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len+6);
440 #else
441         ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len);
442 #endif
443
444 #if MEM_DEBUG
445         *(LPWORD)(ret) = 0x8271;
446         *(LPWORD)(ret+2) = (WORD)len;
447         *(LPWORD)(ret+4+len) = 0x7384;
448         ret += 4;
449         memset(ret, 0xdf, len);
450 #endif
451         TRACE("%lu bytes at %p\n",len, ret);
452         return (LPVOID)ret;
453 }
454
455 /*************************************************************************
456  * SHRegisterDragDrop                           [SHELL32.86]
457  *
458  * NOTES
459  *     exported by ordinal
460  */
461 DWORD WINAPI SHRegisterDragDrop(HWND hWnd,IDropTarget * pDropTarget) 
462 {
463         FIXME("(0x%08x,%p):stub.\n", hWnd, pDropTarget);
464         return     RegisterDragDrop(hWnd, pDropTarget);
465 }
466
467 /*************************************************************************
468  * SHRevokeDragDrop                             [SHELL32.87]
469  *
470  * NOTES
471  *     exported by ordinal
472  */
473 DWORD WINAPI SHRevokeDragDrop(DWORD x) {
474     FIXME("(0x%08lx):stub.\n",x);
475     return 0;
476 }
477
478 /*************************************************************************
479  * SHDoDragDrop                                 [SHELL32.88]
480  *
481  * NOTES
482  *     exported by ordinal
483  */
484 DWORD WINAPI SHDoDragDrop(DWORD u, DWORD v, DWORD w, DWORD x, DWORD y, DWORD z) {
485     FIXME("(0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx):stub.\n",u,v,w,x,y,z);
486     return 0;
487 }
488
489 /*************************************************************************
490  * RunFileDlg                                   [SHELL32.61]
491  *
492  * NOTES
493  *     Original name: RunFileDlg (exported by ordinal)
494  */
495 DWORD WINAPI
496 RunFileDlg (HWND hwndOwner, DWORD dwParam1, DWORD dwParam2,
497             LPSTR lpszTitle, LPSTR lpszPrompt, UINT uFlags)
498 {
499     FIXME("(0x%08x 0x%lx 0x%lx \"%s\" \"%s\" 0x%x):stub.\n",
500            hwndOwner, dwParam1, dwParam2, lpszTitle, lpszPrompt, uFlags);
501     return 0;
502 }
503
504 /*************************************************************************
505  * ExitWindowsDialog                            [SHELL32.60]
506  *
507  * NOTES
508  *     exported by ordinal
509  */
510 void WINAPI ExitWindowsDialog (HWND hWndOwner)
511 {
512         TRACE("(0x%08x)\n", hWndOwner);
513         if (MessageBoxA( hWndOwner, "Do you want to exit WINE?", "Shutdown", MB_YESNO|MB_ICONQUESTION) == IDOK)
514         { SendMessageA ( hWndOwner, WM_QUIT, 0, 0);
515         }
516 }
517
518 /*************************************************************************
519  * ArrangeWindows                               [SHELL32.184]
520  * 
521  */
522 DWORD WINAPI
523 ArrangeWindows (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3,
524                 DWORD dwParam4, DWORD dwParam5)
525 {
526     FIXME("(0x%lx 0x%lx 0x%lx 0x%lx 0x%lx):stub.\n",
527            dwParam1, dwParam2, dwParam3, dwParam4, dwParam5);
528     return 0;
529 }
530
531 /*************************************************************************
532  * SignalFileOpen                               [SHELL32.103]
533  *
534  * NOTES
535  *     exported by ordinal
536  */
537 DWORD WINAPI
538 SignalFileOpen (DWORD dwParam1)
539 {
540     FIXME("(0x%08lx):stub.\n", dwParam1);
541
542     return 0;
543 }
544
545 /*************************************************************************
546  * SHAddToRecentDocs                            [SHELL32.234]
547  *
548  * PARAMETERS
549  *   uFlags  [IN] SHARD_PATH or SHARD_PIDL
550  *   pv      [IN] string or pidl, NULL clears the list
551  *
552  * NOTES
553  *     exported by name
554  */
555 DWORD WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)   
556 { if (SHARD_PIDL==uFlags)
557   { FIXME("(0x%08x,pidl=%p):stub.\n", uFlags,pv);
558         }
559         else
560         { FIXME("(0x%08x,%s):stub.\n", uFlags,(char*)pv);
561         }
562   return 0;
563 }
564 /*************************************************************************
565  * SHCreateShellFolderViewEx                    [SHELL32.174]
566  *
567  * NOTES
568  *  see IShellFolder::CreateViewObject
569  */
570 HRESULT WINAPI SHCreateShellFolderViewEx(
571   LPSHELLVIEWDATA psvcbi, /*[in ] shelltemplate struct*/
572   LPVOID* ppv)            /*[out] IShellView pointer*/
573 {
574         IShellView * psf;
575         HRESULT hRes;
576         
577         TRACE("sf=%p pidl=%p cb=%p mode=0x%08lx parm=0x%08lx\n", 
578           psvcbi->pShellFolder, psvcbi->pidl, psvcbi->pCallBack, psvcbi->viewmode, psvcbi->dwUserParam);
579
580         psf = IShellView_Constructor(psvcbi->pShellFolder);
581         
582         if (!psf)
583           return E_OUTOFMEMORY;
584
585         IShellView_AddRef(psf);
586         hRes = IShellView_QueryInterface(psf, &IID_IShellView, (LPVOID *)ppv);
587         IShellView_Release(psf);
588
589         return hRes;
590 }
591 /*************************************************************************
592  *  SHWinHelp                                   [SHELL32.127]
593  *
594  */
595 HRESULT WINAPI SHWinHelp (DWORD v, DWORD w, DWORD x, DWORD z)
596 {       FIXME("0x%08lx 0x%08lx 0x%08lx 0x%08lx stub\n",v,w,x,z);
597         return 0;
598 }
599 /*************************************************************************
600  *  SHRunControlPanel [SHELL32.161]
601  *
602  */
603 HRESULT WINAPI SHRunControlPanel (DWORD x, DWORD z)
604 {       FIXME("0x%08lx 0x%08lx stub\n",x,z);
605         return 0;
606 }
607 /*************************************************************************
608  * ShellExecuteEx                               [SHELL32.291]
609  *
610  */
611 BOOL WINAPI ShellExecuteExAW (LPVOID sei)
612 {       if (VERSION_OsIsUnicode())
613           return ShellExecuteExW (sei);
614         return ShellExecuteExA (sei);
615 }
616 /*************************************************************************
617  * ShellExecuteExA                              [SHELL32.292]
618  *
619  * placeholder in the commandline:
620  *      %1 file
621  *      %2 printer
622  *      %3 driver
623  *      %4 port
624  *      %I adress of a global item ID (explorer switch /idlist)
625  *      %L ??? path/url/current file ???
626  *      %S ???
627  *      %* all following parameters (see batfile)
628  */
629 BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
630 {       CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20];
631         LPSTR pos;
632         int gap, len;
633         STARTUPINFOA  startup;
634         PROCESS_INFORMATION info;
635                         
636         WARN("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s incomplete\n",
637                 sei->fMask, sei->hwnd, sei->lpVerb, sei->lpFile,
638                 sei->lpParameters, sei->lpDirectory, sei->nShow, 
639                 (sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass : "not used");
640
641         ZeroMemory(szApplicationName,MAX_PATH);
642         if (sei->lpFile)
643           strcpy(szApplicationName, sei->lpFile);
644         
645         ZeroMemory(szCommandline,MAX_PATH);
646         if (sei->lpParameters)
647           strcpy(szCommandline, sei->lpParameters);
648                         
649         if (sei->fMask & (SEE_MASK_CLASSKEY | SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
650                           SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
651                           SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE | 
652                           SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
653         {
654           FIXME("flags ignored: 0x%08lx\n", sei->fMask);
655         }
656         
657         /* launch a document by fileclass like 'Wordpad.Document.1' */
658         if (sei->fMask & SEE_MASK_CLASSNAME)
659         {
660           /* the commandline contains 'c:\Path\wordpad.exe "%1"' */
661           HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, 256);
662           /* fixme: get the extension of lpFile, check if it fits to the lpClass */
663           TRACE("SEE_MASK_CLASSNAME->'%s'\n", szCommandline);
664         }
665
666         /* process the IDList */
667         if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
668         {
669           SHGetPathFromIDListA (sei->lpIDList,szApplicationName);
670           TRACE("-- idlist=%p (%s)\n", sei->lpIDList, szApplicationName);
671         }
672         else
673         {
674           if (sei->fMask & SEE_MASK_IDLIST )
675           {
676             pos = strstr(szCommandline, "%I");
677             if (pos)
678             {
679               HGLOBAL hmem = SHAllocShared ( sei->lpIDList, ILGetSize(sei->lpIDList), 0);
680               sprintf(szPidl,":%li",(DWORD)SHLockShared(hmem,0) );
681               SHUnlockShared(hmem);
682             
683               gap = strlen(szPidl);
684               len = strlen(pos)-2;
685               memmove(pos+gap,pos+2,len);
686               memcpy(pos,szPidl,gap);
687
688             }
689           }
690         }
691
692         TRACE("execute:'%s','%s'\n",szApplicationName, szCommandline);
693
694         strcat(szApplicationName, " ");
695         strcat(szApplicationName, szCommandline);
696
697         ZeroMemory(&startup,sizeof(STARTUPINFOA));
698         startup.cb = sizeof(STARTUPINFOA);
699
700         if (! CreateProcessA(NULL, szApplicationName,
701                          NULL, NULL, FALSE, 0, 
702                          NULL, NULL, &startup, &info))
703         {
704           sei->hInstApp = GetLastError();
705           return FALSE;
706         }
707
708         sei->hInstApp = 33;
709         
710         /* Give 30 seconds to the app to come up */
711         if ( WaitForInputIdle ( info.hProcess, 30000 ) ==  0xFFFFFFFF )
712           ERR("WaitForInputIdle failed: Error %ld\n", GetLastError() );
713  
714         if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
715           sei->hProcess = info.hProcess;          
716         else
717           CloseHandle( info.hProcess );
718         CloseHandle( info.hThread );
719         return TRUE;
720 }
721 /*************************************************************************
722  * ShellExecuteExW                              [SHELL32.293]
723  *
724  */
725 BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
726 {       SHELLEXECUTEINFOA seiA;
727         DWORD ret;
728
729         TRACE("%p\n", sei);
730
731         memcpy(&seiA, sei, sizeof(SHELLEXECUTEINFOA));
732         
733         if (sei->lpVerb)
734           seiA.lpVerb = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpVerb);
735
736         if (sei->lpFile)
737           seiA.lpFile = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpFile);
738
739         if (sei->lpParameters)
740           seiA.lpParameters = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpParameters);
741
742         if (sei->lpDirectory)
743           seiA.lpDirectory = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpDirectory);
744
745         if ((sei->fMask & SEE_MASK_CLASSNAME) && sei->lpClass)
746           seiA.lpClass = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpClass);
747         else
748           seiA.lpClass = NULL;
749                   
750         ret = ShellExecuteExA(&seiA);
751
752         if (seiA.lpVerb)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpVerb );
753         if (seiA.lpFile)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpFile );
754         if (seiA.lpParameters)  HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpParameters );
755         if (seiA.lpDirectory)   HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpDirectory );
756         if (seiA.lpClass)       HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpClass );
757
758         return ret;
759 }
760
761 static LPUNKNOWN SHELL32_IExplorerInterface=0;
762 /*************************************************************************
763  * SHSetInstanceExplorer                        [SHELL32.176]
764  *
765  * NOTES
766  *  Sets the interface
767  */
768 HRESULT WINAPI SHSetInstanceExplorer (LPUNKNOWN lpUnknown)
769 {       TRACE("%p\n", lpUnknown);
770         SHELL32_IExplorerInterface = lpUnknown;
771         return (HRESULT) lpUnknown;
772 }
773 /*************************************************************************
774  * SHGetInstanceExplorer                        [SHELL32.256]
775  *
776  * NOTES
777  *  gets the interface pointer of the explorer and a reference
778  */
779 HRESULT WINAPI SHGetInstanceExplorer (LPUNKNOWN * lpUnknown)
780 {       TRACE("%p\n", lpUnknown);
781
782         *lpUnknown = SHELL32_IExplorerInterface;
783
784         if (!SHELL32_IExplorerInterface)
785           return E_FAIL;
786
787         IUnknown_AddRef(SHELL32_IExplorerInterface);
788         return NOERROR;
789 }
790 /*************************************************************************
791  * SHFreeUnusedLibraries                        [SHELL32.123]
792  *
793  * NOTES
794  *  exported by name
795  */
796 HRESULT WINAPI SHFreeUnusedLibraries (void)
797 {       FIXME("stub\n");
798         return TRUE;
799 }
800 /*************************************************************************
801  * DAD_SetDragImage                             [SHELL32.136]
802  *
803  * NOTES
804  *  exported by name
805  */
806 HRESULT WINAPI DAD_SetDragImage (DWORD u, DWORD v)
807 { FIXME("0x%08lx 0x%08lx stub\n",u, v);
808   return 0;
809 }
810 /*************************************************************************
811  * DAD_ShowDragImage                            [SHELL32.137]
812  *
813  * NOTES
814  *  exported by name
815  */
816 HRESULT WINAPI DAD_ShowDragImage (DWORD u)
817 { FIXME("0x%08lx stub\n",u);
818   return 0;
819 }
820 /*************************************************************************
821  * SHRegCloseKey                        [NT4.0:SHELL32.505]
822  *
823  */
824 HRESULT WINAPI SHRegCloseKey (HKEY hkey)
825 {       TRACE("0x%04x\n",hkey);
826         return RegCloseKey( hkey );
827 }
828 /*************************************************************************
829  * SHRegOpenKeyA                                [SHELL32.506]
830  *
831  */
832 HRESULT WINAPI SHRegOpenKeyA(HKEY hKey, LPSTR lpSubKey, LPHKEY phkResult)
833 {
834         TRACE("(0x%08x, %s, %p)\n", hKey, debugstr_a(lpSubKey), phkResult);
835         return RegOpenKeyA(hKey, lpSubKey, phkResult);
836 }
837
838 /*************************************************************************
839  * SHRegOpenKeyW                                [NT4.0:SHELL32.507]
840  *
841  */
842 HRESULT WINAPI SHRegOpenKeyW (HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey)
843 {       WARN("0x%04x %s %p\n",hkey,debugstr_w(lpszSubKey),retkey);
844         return RegOpenKeyW( hkey, lpszSubKey, retkey );
845 }
846 /*************************************************************************
847  * SHRegQueryValueExA                           [SHELL32.509]
848  *
849  */
850 HRESULT WINAPI SHRegQueryValueExA(
851         HKEY hkey,
852         LPSTR lpValueName,
853         LPDWORD lpReserved,
854         LPDWORD lpType,
855         LPBYTE lpData,
856         LPDWORD lpcbData)
857 {
858         TRACE("0x%04x %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
859         return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
860 }
861 /*************************************************************************
862  * SHRegQueryValueW                             [NT4.0:SHELL32.510]
863  *
864  */
865 HRESULT WINAPI SHRegQueryValueW (HKEY hkey, LPWSTR lpszSubKey,
866                                  LPWSTR lpszData, LPDWORD lpcbData )
867 {       WARN("0x%04x %s %p %p semi-stub\n",
868                 hkey, debugstr_w(lpszSubKey), lpszData, lpcbData);
869         return RegQueryValueW( hkey, lpszSubKey, lpszData, lpcbData );
870 }
871
872 /*************************************************************************
873  * SHRegQueryValueExW                           [NT4.0:SHELL32.511]
874  *
875  * FIXME 
876  *  if the datatype REG_EXPAND_SZ then expand the string and change
877  *  *pdwType to REG_SZ. 
878  */
879 HRESULT WINAPI SHRegQueryValueExW (HKEY hkey, LPWSTR pszValue, LPDWORD pdwReserved,
880                  LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData)
881 {       DWORD ret;
882         WARN("0x%04x %s %p %p %p %p semi-stub\n",
883                 hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
884         ret = RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, pvData, pcbData);
885         return ret;
886 }
887
888 /*************************************************************************
889  * SHGetValueA
890  *
891  * Gets a value from the registry
892  */
893 DWORD WINAPI SHGetValueA(
894     HKEY     hkey,
895     LPCSTR   pSubKey,
896     LPCSTR   pValue,
897     LPDWORD  pwType,
898     LPVOID   pvData,
899     LPDWORD  pbData
900     )
901 {
902     FIXME("(%p),stub!\n", pSubKey);
903
904         return ERROR_SUCCESS;  /* return success */
905 }
906
907 /*************************************************************************
908  * SHGetValueW
909  *
910  * Gets a value from the registry
911  */
912 DWORD WINAPI SHGetValueW(
913     HKEY     hkey,
914     LPCWSTR  pSubKey,
915     LPCWSTR  pValue,
916     LPDWORD  pwType,
917     LPVOID   pvData,
918     LPDWORD  pbData
919     )
920 {
921     FIXME("(%p),stub!\n", pSubKey);
922
923         return ERROR_SUCCESS;  /* return success */
924 }
925
926 /*************************************************************************
927  * SHRegGetUSValueA
928  *
929  * Gets a user-specific registry value
930  */
931 LONG WINAPI SHRegGetUSValueA(
932     LPCSTR   pSubKey,
933     LPCSTR   pValue,
934     LPDWORD  pwType,
935     LPVOID   pvData,
936     LPDWORD  pbData,
937     BOOL     fIgnoreHKCU,
938     LPVOID   pDefaultData,
939     DWORD    wDefaultDataSize
940     )
941 {
942     FIXME("(%p),stub!\n", pSubKey);
943
944         return ERROR_SUCCESS;  /* return success */
945 }
946
947 /*************************************************************************
948  * SHRegGetUSValueW
949  *
950  * Gets a user-specific registry value
951  */
952 LONG WINAPI SHRegGetUSValueW(
953     LPCWSTR  pSubKey,
954     LPCWSTR  pValue,
955     LPDWORD  pwType,
956     LPVOID   pvData,
957     LPDWORD  pbData,
958     BOOL     flagIgnoreHKCU,
959     LPVOID   pDefaultData,
960     DWORD    wDefaultDataSize
961     )
962 {
963     FIXME("(%p),stub!\n", pSubKey);
964
965         return ERROR_SUCCESS;  /* return success */
966 }
967   
968 /*************************************************************************
969  * SHRegDeleteKeyA and SHDeleteKeyA
970  */
971 HRESULT WINAPI SHRegDeleteKeyA(HKEY hkey, LPCSTR pszSubKey)
972 {
973         FIXME("hkey=0x%08x, %s\n", hkey, debugstr_a(pszSubKey));
974         return 0;
975 }
976
977 /*************************************************************************
978  * SHRegDeleteKeyW and SHDeleteKeyA
979  */
980 HRESULT WINAPI SHRegDeleteKeyW(HKEY hkey, LPCWSTR pszSubKey)
981 {
982         FIXME("hkey=0x%08x, %s\n", hkey, debugstr_w(pszSubKey));
983         return 0;
984 }
985 /*************************************************************************
986  * ReadCabinetState                             [NT 4.0:SHELL32.651]
987  *
988  */
989 HRESULT WINAPI ReadCabinetState(DWORD u, DWORD v)
990 {       FIXME("0x%04lx 0x%04lx stub\n",u,v);
991         return 0;
992 }
993 /*************************************************************************
994  * WriteCabinetState                            [NT 4.0:SHELL32.652]
995  *
996  */
997 HRESULT WINAPI WriteCabinetState(DWORD u)
998 {       FIXME("0x%04lx stub\n",u);
999         return 0;
1000 }
1001 /*************************************************************************
1002  * FileIconInit                                 [SHELL32.660]
1003  *
1004  */
1005 BOOL WINAPI FileIconInit(BOOL bFullInit)
1006 {       FIXME("(%s)\n", bFullInit ? "true" : "false");
1007         return 0;
1008 }
1009 /*************************************************************************
1010  * IsUserAdmin                                  [NT 4.0:SHELL32.680]
1011  *
1012  */
1013 HRESULT WINAPI IsUserAdmin(void)
1014 {       FIXME("stub\n");
1015         return TRUE;
1016 }
1017
1018 /*************************************************************************
1019  * StrRetToBufA                                 [SHLWAPI.@]
1020  * 
1021  * converts a STRRET to a normal string
1022  *
1023  * NOTES
1024  *  the pidl is for STRRET OFFSET
1025  */
1026 HRESULT WINAPI StrRetToBufA (LPSTRRET src, LPITEMIDLIST pidl, LPSTR dest, DWORD len)
1027 {
1028         return StrRetToStrNA(dest, len, src, pidl);
1029 }
1030
1031 /*************************************************************************
1032  * StrRetToBufW                                 [SHLWAPI.@]
1033  * 
1034  * converts a STRRET to a normal string
1035  *
1036  * NOTES
1037  *  the pidl is for STRRET OFFSET
1038  */
1039 HRESULT WINAPI StrRetToBufW (LPSTRRET src, LPITEMIDLIST pidl, LPWSTR dest, DWORD len)
1040 {
1041         return StrRetToStrNW(dest, len, src, pidl);
1042 }
1043
1044 /*************************************************************************
1045  * StrRetToStrN                                 [SHELL32.96]
1046  * 
1047  * converts a STRRET to a normal string
1048  *
1049  * NOTES
1050  *  the pidl is for STRRET OFFSET
1051  */
1052 HRESULT WINAPI StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
1053 {
1054         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
1055
1056         switch (src->uType)
1057         {
1058           case STRRET_WSTR:
1059             WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
1060             SHFree(src->u.pOleStr);
1061             break;
1062
1063           case STRRET_CSTRA:
1064             lstrcpynA((LPSTR)dest, src->u.cStr, len);
1065             break;
1066
1067           case STRRET_OFFSETA:
1068             lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
1069             break;
1070
1071           default:
1072             FIXME("unknown type!\n");
1073             if (len)
1074             {
1075               *(LPSTR)dest = '\0';
1076             }
1077             return(FALSE);
1078         }
1079         return S_OK;
1080 }
1081
1082 HRESULT WINAPI StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
1083 {
1084         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
1085
1086         switch (src->uType)
1087         {
1088           case STRRET_WSTR:
1089             lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
1090             SHFree(src->u.pOleStr);
1091             break;
1092
1093           case STRRET_CSTRA:
1094             lstrcpynAtoW((LPWSTR)dest, src->u.cStr, len);
1095             break;
1096
1097           case STRRET_OFFSETA:
1098             if (pidl)
1099             {
1100               lstrcpynAtoW((LPWSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
1101             }
1102             break;
1103
1104           default:
1105             FIXME("unknown type!\n");
1106             if (len)
1107             { *(LPSTR)dest = '\0';
1108             }
1109             return(FALSE);
1110         }
1111         return S_OK;
1112 }
1113 HRESULT WINAPI StrRetToStrNAW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
1114 {
1115         if(VERSION_OsIsUnicode())
1116           return StrRetToStrNW (dest, len, src, pidl);
1117         return StrRetToStrNA (dest, len, src, pidl);
1118 }
1119
1120 /*************************************************************************
1121  * StrChrW                                      [NT 4.0:SHELL32.651]
1122  *
1123  */
1124 LPWSTR WINAPI StrChrW (LPWSTR str, WCHAR x )
1125 {
1126         TRACE("%s 0x%04x\n",debugstr_w(str),x);
1127         return CRTDLL_wcschr(str, x);
1128 }
1129
1130 /*************************************************************************
1131  * StrCmpNIW                                    [NT 4.0:SHELL32.*]
1132  *
1133  */
1134 INT WINAPI StrCmpNIW ( LPWSTR wstr1, LPWSTR wstr2, INT len)
1135 {
1136         TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
1137         return CRTDLL__wcsnicmp(wstr1, wstr2, len);
1138 }
1139
1140 /*************************************************************************
1141  * SHAllocShared                                [SHELL32.520]
1142  *
1143  * NOTES
1144  *  parameter1 is return value from HeapAlloc
1145  *  parameter2 is equal to the size allocated with HeapAlloc
1146  *  parameter3 is return value from GetCurrentProcessId
1147  *
1148  *  the return value is posted as lParam with 0x402 (WM_USER+2) to somewhere
1149  *  WM_USER+2 could be the undocumented CWM_SETPATH
1150  *  the allocated memory contains a pidl
1151  */
1152 HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID)
1153 {       HGLOBAL hmem;
1154         LPVOID pmem;
1155         
1156         TRACE("ptr=%p size=0x%04lx procID=0x%04lx\n",psrc,size,procID);
1157         hmem = GlobalAlloc(GMEM_FIXED, size);
1158         if (!hmem)
1159           return 0;
1160         
1161         pmem =  GlobalLock (hmem);
1162
1163         if (! pmem)
1164           return 0;
1165           
1166         memcpy (pmem, psrc, size);
1167         GlobalUnlock(hmem); 
1168         return hmem;
1169 }
1170 /*************************************************************************
1171  * SHLockShared                                 [SHELL32.521]
1172  *
1173  * NOTES
1174  *  parameter1 is return value from SHAllocShared
1175  *  parameter2 is return value from GetCurrentProcessId
1176  *  the receiver of (WM_USER+2) trys to lock the HANDLE (?) 
1177  *  the returnvalue seems to be a memoryadress
1178  */
1179 LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID)
1180 {       TRACE("handle=0x%04x procID=0x%04lx\n",hmem,procID);
1181         return GlobalLock(hmem);
1182 }
1183 /*************************************************************************
1184  * SHUnlockShared                               [SHELL32.522]
1185  *
1186  * NOTES
1187  *  parameter1 is return value from SHLockShared
1188  */
1189 BOOL WINAPI SHUnlockShared(HANDLE pmem)
1190 {       TRACE("handle=0x%04x\n",pmem);
1191         return GlobalUnlock(pmem); 
1192 }
1193 /*************************************************************************
1194  * SHFreeShared                                 [SHELL32.523]
1195  *
1196  * NOTES
1197  *  parameter1 is return value from SHAllocShared
1198  *  parameter2 is return value from GetCurrentProcessId
1199  */
1200 HANDLE WINAPI SHFreeShared(HANDLE hmem, DWORD procID)
1201 {       TRACE("handle=0x%04x 0x%04lx\n",hmem,procID);
1202         return GlobalFree(hmem);
1203 }
1204
1205 /*************************************************************************
1206  * SetAppStartingCursor                         [SHELL32.99]
1207  *
1208  */
1209 HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v)
1210 {       FIXME("hwnd=0x%04x 0x%04lx stub\n",u,v );
1211         return 0;
1212 }
1213 /*************************************************************************
1214  * SHLoadOLE                                    [SHELL32.151]
1215  *
1216  */
1217 HRESULT WINAPI SHLoadOLE(DWORD u)
1218 {       FIXME("0x%04lx stub\n",u);
1219         return S_OK;
1220 }
1221 /*************************************************************************
1222  * DriveType                                    [SHELL32.64]
1223  *
1224  */
1225 HRESULT WINAPI DriveType(DWORD u)
1226 {       FIXME("0x%04lx stub\n",u);
1227         return 0;
1228 }
1229 /*************************************************************************
1230  * SHAbortInvokeCommand                         [SHELL32.198]
1231  *
1232  */
1233 HRESULT WINAPI SHAbortInvokeCommand(void)
1234 {       FIXME("stub\n");
1235         return 1;
1236 }
1237 /*************************************************************************
1238  * SHOutOfMemoryMessageBox                      [SHELL32.126]
1239  *
1240  */
1241 HRESULT WINAPI SHOutOfMemoryMessageBox(DWORD u, DWORD v, DWORD w)
1242 {       FIXME("0x%04lx 0x%04lx 0x%04lx stub\n",u,v,w);
1243         return 0;
1244 }
1245 /*************************************************************************
1246  * SHFlushClipboard                             [SHELL32.121]
1247  *
1248  */
1249 HRESULT WINAPI SHFlushClipboard(void)
1250 {       FIXME("stub\n");
1251         return 1;
1252 }
1253
1254 /*************************************************************************
1255  * StrFormatByteSizeA                           [SHLWAPI]
1256  */
1257 LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
1258 {       char buf[64];
1259         TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
1260         if ( dw<1024L )
1261         { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
1262         }
1263         else if ( dw<1048576L)
1264         { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
1265         }
1266         else if ( dw < 1073741824L)
1267         { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
1268         }
1269         else
1270         { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
1271         }
1272         lstrcpynA (pszBuf, buf, cchBuf);
1273         return pszBuf;  
1274 }
1275
1276 /*************************************************************************
1277  * StrFormatByteSizeW                           [SHLWAPI]
1278  */
1279 LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
1280 {       char buf[64];
1281         TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
1282         if ( dw<1024L )
1283         { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
1284         }
1285         else if ( dw<1048576L)
1286         { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
1287         }
1288         else if ( dw < 1073741824L)
1289         { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
1290         }
1291         else
1292         { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
1293         }
1294         lstrcpynAtoW (pszBuf, buf, cchBuf);
1295         return pszBuf;  
1296 }
1297 /*************************************************************************
1298  * SHWaitForFileToOpen                          [SHELL32.97]
1299  *
1300  */
1301 HRESULT WINAPI SHWaitForFileToOpen(DWORD u, DWORD v, DWORD w)
1302 {       FIXME("0x%04lx 0x%04lx 0x%04lx stub\n",u,v,w);
1303         return 0;
1304 }
1305 /*************************************************************************
1306  * Control_FillCache_RunDLL                     [SHELL32.8]
1307  *
1308  */
1309 HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
1310 {       FIXME("0x%04x 0x%04x 0x%04lx 0x%04lx stub\n",hWnd, hModule,w,x);
1311         return 0;
1312 }
1313 /*************************************************************************
1314  * RunDLL_CallEntry16                           [SHELL32.122]
1315  * the name is propably wrong
1316  */
1317 HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
1318 {       FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
1319         return 0;
1320 }
1321
1322 /************************************************************************
1323  *      shell32_654                             [SHELL32.654]
1324  *
1325  * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
1326  * second one could be a size (0x0c). The size is the same as the structure saved to
1327  * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
1328  * I'm (js) guessing: this one is just ReadCabinetState ;-)
1329  */
1330 HRESULT WINAPI shell32_654 (DWORD x, DWORD y)
1331 {       FIXME("0x%08lx 0x%08lx stub\n",x,y);
1332         return 0;
1333 }
1334
1335 /************************************************************************
1336  *      RLBuildListOfPaths                      [SHELL32.146]
1337  *
1338  * NOTES
1339  *   builds a DPA
1340  */
1341 DWORD WINAPI RLBuildListOfPaths (void)
1342 {       FIXME("stub\n");
1343         return 0;
1344 }
1345 /************************************************************************
1346  *      StrToOleStr                     [SHELL32.163]
1347  *
1348  */
1349 int WINAPI StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString)
1350 {
1351         TRACE("(%p, %p %s)\n",
1352         lpWideCharStr, lpMultiByteString, debugstr_a(lpMultiByteString));
1353
1354         return MultiByteToWideChar(0, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH);
1355
1356 }
1357 int WINAPI StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString)
1358 {
1359         TRACE("(%p, %p %s)\n",
1360         lpWideCharStr, lpWString, debugstr_w(lpWString));
1361
1362         if (lstrcpyW (lpWideCharStr, lpWString ))
1363         { return lstrlenW (lpWideCharStr);
1364         }
1365         return 0;
1366 }
1367
1368 BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString)
1369 {
1370         if (VERSION_OsIsUnicode())
1371           return StrToOleStrW (lpWideCharStr, lpString);
1372         return StrToOleStrA (lpWideCharStr, lpString);
1373 }
1374
1375 /************************************************************************
1376  *      SHValidateUNC                           [SHELL32.173]
1377  *
1378  */
1379 HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
1380 {
1381         FIXME("0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
1382         return 0;
1383 }
1384
1385 /************************************************************************
1386  *      DoEnvironmentSubstA                     [SHELL32.1222]
1387  *
1388  */
1389 HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y)
1390 {
1391         FIXME("(%p %s, %p %s) stub\n", x, debugstr_a(x), y, debugstr_a(y));
1392         return 0;
1393 }
1394
1395 /************************************************************************
1396  *      DoEnvironmentSubstW                     [SHELL32.1223]
1397  *
1398  */
1399 HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y)
1400 {
1401         FIXME("(%p %s, %p %s) stub\n", x, debugstr_w(x), y, debugstr_w(y));
1402         return 0;
1403 }
1404
1405 /************************************************************************
1406  *      DoEnvironmentSubst                      [SHELL32.53]
1407  *
1408  */
1409 HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y)
1410 {
1411         if (VERSION_OsIsUnicode())
1412           return DoEnvironmentSubstW(x, y);
1413         return DoEnvironmentSubstA(x, y);
1414 }
1415
1416 /*************************************************************************
1417  *      shell32_243                             [SHELL32.243]
1418  * 
1419  * Win98+ by-ordinal routine.  In Win98 this routine returns zero and
1420  * does nothing else.  Possibly this does something in NT or SHELL32 5.0?
1421  *
1422  */
1423
1424 BOOL WINAPI shell32_243(DWORD a, DWORD b) 
1425
1426   return FALSE; 
1427 }
1428