Fixed some issues found by winapi_check.
[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
17 #include "shellapi.h"
18 #include "shlobj.h"
19 #include "shell32_main.h"
20 #include "wine/undocshell.h"
21
22 DEFAULT_DEBUG_CHANNEL(shell);
23
24 /*************************************************************************
25  * ParseFieldA                                  [internal]
26  *
27  * copys a field from a ',' delimited string
28  * 
29  * first field is nField = 1
30  */
31 DWORD WINAPI ParseFieldA(
32         LPCSTR src,
33         DWORD nField,
34         LPSTR dst,
35         DWORD len) 
36 {
37         WARN("('%s',0x%08lx,%p,%ld) semi-stub.\n",src,nField,dst,len);
38
39         if (!src || !src[0] || !dst || !len)
40           return 0;
41
42         /* skip n fields delimited by ',' */
43         while (nField > 1)
44         {
45           if (*src=='\0') return FALSE;
46           if (*(src++)==',') nField--;
47         }
48
49         /* copy part till the next ',' to dst */
50         while ( *src!='\0' && *src!=',' && (len--)>0 ) *(dst++)=*(src++);
51         
52         /* finalize the string */
53         *dst=0x0;
54         
55         return TRUE;
56 }
57
58 /*************************************************************************
59  * ParseFieldW                  [internal]
60  *
61  * copys a field from a ',' delimited string
62  * 
63  * first field is nField = 1
64  */
65 DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len) 
66 {
67         FIXME("('%s',0x%08lx,%p,%ld) stub.\n",
68           debugstr_w(src), nField, dst, len);
69         return FALSE;
70 }
71
72 /*************************************************************************
73  * ParseFieldAW                 [SHELL32.58]
74  */
75 DWORD WINAPI ParseFieldAW(LPCVOID src, DWORD nField, LPVOID dst, DWORD len) 
76 {
77         if (VERSION_OsIsUnicode())
78           return ParseFieldW(src, nField, dst, len);
79         return ParseFieldA(src, nField, dst, len);
80 }
81
82 /*************************************************************************
83  * GetFileNameFromBrowse                        [SHELL32.63]
84  * 
85  */
86 BOOL WINAPI GetFileNameFromBrowse(
87         HWND hwndOwner,
88         LPSTR lpstrFile,
89         DWORD nMaxFile,
90         LPCSTR lpstrInitialDir,
91         LPCSTR lpstrDefExt,
92         LPCSTR lpstrFilter,
93         LPCSTR lpstrTitle)
94 {
95         FIXME("(%04x,%s,%ld,%s,%s,%s,%s):stub.\n",
96           hwndOwner, lpstrFile, nMaxFile, lpstrInitialDir, lpstrDefExt,
97           lpstrFilter, lpstrTitle);
98
99     /* puts up a Open Dialog and requests input into targetbuf */
100     /* OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_FILEMUSTEXIST|OFN_unknown */
101     lstrcpyA(lpstrFile,"x:\\dummy.exe");
102     return 1;
103 }
104
105 /*************************************************************************
106  * SHGetSettings                                [SHELL32.68]
107  * 
108  * NOTES
109  *  the registry path are for win98 (tested)
110  *  and possibly are the same in nt40
111  */
112 void WINAPI SHGetSettings(LPSHELLFLAGSTATE lpsfs, DWORD dwMask, DWORD dwx)
113 {
114         HKEY    hKey;
115         DWORD   dwData;
116         DWORD   dwDataSize = sizeof (DWORD);
117
118         TRACE("(%p 0x%08lx 0x%08lx)\n",lpsfs,dwMask, dwx);
119         
120         if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
121                                  0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
122           return;
123         
124         if ( (SSF_SHOWEXTENSIONS & dwMask) && !RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
125           lpsfs->fShowExtensions  = ((dwData == 0) ?  0 : 1);
126
127         if ( (SSF_SHOWINFOTIP & dwMask) && !RegQueryValueExA(hKey, "ShowInfoTip", 0, 0, (LPBYTE)&dwData, &dwDataSize))
128           lpsfs->fShowInfoTip  = ((dwData == 0) ?  0 : 1);
129
130         if ( (SSF_DONTPRETTYPATH & dwMask) && !RegQueryValueExA(hKey, "DontPrettyPath", 0, 0, (LPBYTE)&dwData, &dwDataSize))
131           lpsfs->fDontPrettyPath  = ((dwData == 0) ?  0 : 1);
132
133         if ( (SSF_HIDEICONS & dwMask) && !RegQueryValueExA(hKey, "HideIcons", 0, 0, (LPBYTE)&dwData, &dwDataSize))
134           lpsfs->fHideIcons  = ((dwData == 0) ?  0 : 1);
135
136         if ( (SSF_MAPNETDRVBUTTON & dwMask) && !RegQueryValueExA(hKey, "MapNetDrvBtn", 0, 0, (LPBYTE)&dwData, &dwDataSize))
137           lpsfs->fMapNetDrvBtn  = ((dwData == 0) ?  0 : 1);
138
139         if ( (SSF_SHOWATTRIBCOL & dwMask) && !RegQueryValueExA(hKey, "ShowAttribCol", 0, 0, (LPBYTE)&dwData, &dwDataSize))
140           lpsfs->fShowAttribCol  = ((dwData == 0) ?  0 : 1);
141
142         if (((SSF_SHOWALLOBJECTS | SSF_SHOWSYSFILES) & dwMask) && !RegQueryValueExA(hKey, "Hidden", 0, 0, (LPBYTE)&dwData, &dwDataSize))
143         { if (dwData == 0)
144           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 0;
145             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 0;
146           }
147           else if (dwData == 1)
148           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 1;
149             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 0;
150           }
151           else if (dwData == 2)
152           { if (SSF_SHOWALLOBJECTS & dwMask)    lpsfs->fShowAllObjects  = 0;
153             if (SSF_SHOWSYSFILES & dwMask)      lpsfs->fShowSysFiles  = 1;
154           }
155         }
156         RegCloseKey (hKey);
157
158         TRACE("-- 0x%04x\n", *(WORD*)lpsfs);
159 }
160
161 /*************************************************************************
162  * SHShellFolderView_Message                    [SHELL32.73]
163  *
164  * PARAMETERS
165  *  hwndCabinet defines the explorer cabinet window that contains the 
166  *              shellview you need to communicate with
167  *  uMsg        identifying the SFVM enum to perform
168  *  lParam
169  *
170  * NOTES
171  *  Message SFVM_REARRANGE = 1
172  *    This message gets sent when a column gets clicked to instruct the
173  *    shell view to re-sort the item list. lParam identifies the column
174  *    that was clicked.
175  */
176 int WINAPI SHShellFolderView_Message(
177         HWND hwndCabinet, 
178         DWORD dwMessage,
179         DWORD dwParam)
180 {
181         FIXME("%04x %08lx %08lx stub\n",hwndCabinet, dwMessage, dwParam);
182         return 0;
183 }
184
185 /*************************************************************************
186  * RegisterShellHook                            [SHELL32.181]
187  *
188  * PARAMS
189  *      hwnd [I]  window handle
190  *      y    [I]  flag ????
191  * 
192  * NOTES
193  *     exported by ordinal
194  */
195 BOOL WINAPI RegisterShellHook(
196         HWND hWnd,
197         DWORD dwType)
198 {
199         FIXME("(0x%08x,0x%08lx):stub.\n",hWnd, dwType);
200         return TRUE;
201 }
202 /*************************************************************************
203  * ShellMessageBoxW                             [SHELL32.182]
204  *
205  * Format and output errormessage.
206  *
207  * idText       resource ID of title or LPSTR
208  * idTitle      resource ID of title or LPSTR
209  *
210  * NOTES
211  *     exported by ordinal
212  */
213 int WINAPIV ShellMessageBoxW(
214         HINSTANCE hInstance,
215         HWND hWnd,
216         LPCWSTR lpText,
217         LPCWSTR lpCaption,
218         UINT uType,
219         ...)
220 {
221         WCHAR   szText[100],szTitle[100],szTemp[256];
222         LPCWSTR   pszText = szText, pszTitle = szTitle;
223         va_list args;
224         va_start(args, uType);
225         /* wvsprintfA(buf,fmt, args); */
226
227         TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
228         (DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);
229
230         if (!HIWORD(lpCaption))
231           LoadStringW(hInstance, (DWORD)lpCaption, szTitle, 100);
232         else
233           pszTitle = lpCaption;
234
235         if (!HIWORD(lpText))
236           LoadStringW(hInstance, (DWORD)lpText, szText, 100);
237         else
238           pszText = lpText;
239
240         FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
241                        szText, 0, 0, szTemp, 256, (LPDWORD) args);
242
243         va_end(args);
244
245         return MessageBoxW(hWnd,szTemp,szTitle,uType);
246 }
247
248 /*************************************************************************
249  * ShellMessageBoxA                             [SHELL32.183]
250  */
251 int WINAPIV ShellMessageBoxA(
252         HINSTANCE hInstance,
253         HWND hWnd,
254         LPCSTR lpText,
255         LPCSTR lpCaption,
256         UINT uType,
257         ...)
258 {
259         char    szText[100],szTitle[100],szTemp[256];
260         LPCSTR   pszText = szText, pszTitle = szTitle;
261         va_list args;
262         va_start(args, uType);
263         /* wvsprintfA(buf,fmt, args); */
264
265         TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
266         (DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);
267
268         if (!HIWORD(lpCaption))
269           LoadStringA(hInstance, (DWORD)lpCaption, szTitle, 100);
270         else
271           pszTitle = lpCaption;
272
273         if (!HIWORD(lpText))
274           LoadStringA(hInstance, (DWORD)lpText, szText, 100);
275         else
276           pszText = lpText;
277
278         FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
279                        szText, 0, 0, szTemp, 256, (LPDWORD) args);
280
281         va_end(args);
282
283         return MessageBoxA(hWnd,szTemp,szTitle,uType);
284 }
285
286 /*************************************************************************
287  * SHFree                                       [SHELL32.195]
288  *
289  * NOTES
290  *     free_ptr() - frees memory using IMalloc
291  *     exported by ordinal
292  */
293 #define MEM_DEBUG 0
294 void WINAPI SHFree(LPVOID x) 
295 {
296 #if MEM_DEBUG
297         WORD len = *(LPWORD)((LPBYTE)x-2);
298
299         if ( *(LPWORD)((LPBYTE)x+len) != 0x7384)
300           ERR("MAGIC2!\n");
301
302         if ( (*(LPWORD)((LPBYTE)x-4)) != 0x8271)
303           ERR("MAGIC1!\n");
304         else
305           memset((LPBYTE)x-4, 0xde, len+6);
306
307         TRACE("%p len=%u\n",x, len);
308
309         x = (LPBYTE) x - 4;
310 #else
311         TRACE("%p\n",x);
312 #endif
313         HeapFree(GetProcessHeap(), 0, x);
314 }
315
316 /*************************************************************************
317  * SHAlloc                                      [SHELL32.196]
318  *
319  * NOTES
320  *     void *task_alloc(DWORD len), uses SHMalloc allocator
321  *     exported by ordinal
322  */
323 LPVOID WINAPI SHAlloc(DWORD len) 
324 {
325         LPBYTE ret;
326
327 #if MEM_DEBUG
328         ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len+6);
329 #else
330         ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len);
331 #endif
332
333 #if MEM_DEBUG
334         *(LPWORD)(ret) = 0x8271;
335         *(LPWORD)(ret+2) = (WORD)len;
336         *(LPWORD)(ret+4+len) = 0x7384;
337         ret += 4;
338         memset(ret, 0xdf, len);
339 #endif
340         TRACE("%lu bytes at %p\n",len, ret);
341         return (LPVOID)ret;
342 }
343
344 /*************************************************************************
345  * SHRegisterDragDrop                           [SHELL32.86]
346  *
347  * NOTES
348  *     exported by ordinal
349  */
350 HRESULT WINAPI SHRegisterDragDrop(
351         HWND hWnd,
352         LPDROPTARGET pDropTarget)
353 {
354         FIXME("(0x%08x,%p):stub.\n", hWnd, pDropTarget);
355         if (GetShellOle()) return pRegisterDragDrop(hWnd, pDropTarget);
356         return 0;
357 }
358
359 /*************************************************************************
360  * SHRevokeDragDrop                             [SHELL32.87]
361  *
362  * NOTES
363  *     exported by ordinal
364  */
365 HRESULT WINAPI SHRevokeDragDrop(HWND hWnd)
366 {
367     FIXME("(0x%08x):stub.\n",hWnd);
368     return 0;
369 }
370
371 /*************************************************************************
372  * SHDoDragDrop                                 [SHELL32.88]
373  *
374  * NOTES
375  *     exported by ordinal
376  */
377 HRESULT WINAPI SHDoDragDrop(
378         HWND hWnd,
379         LPDATAOBJECT lpDataObject,
380         LPDROPSOURCE lpDropSource,
381         DWORD dwOKEffect,
382         LPDWORD pdwEffect)
383 {
384     FIXME("(0x%04x %p %p 0x%08lx %p):stub.\n",
385     hWnd, lpDataObject, lpDropSource, dwOKEffect, pdwEffect);
386     return 0;
387 }
388
389 /*************************************************************************
390  * ArrangeWindows                               [SHELL32.184]
391  * 
392  */
393 WORD WINAPI ArrangeWindows(
394         HWND hwndParent,
395         DWORD dwReserved,
396         LPCRECT lpRect,
397         WORD cKids,
398         CONST HWND * lpKids)
399 {
400     FIXME("(0x%08x 0x%08lx %p 0x%04x %p):stub.\n",
401            hwndParent, dwReserved, lpRect, cKids, lpKids);
402     return 0;
403 }
404
405 /*************************************************************************
406  * SignalFileOpen                               [SHELL32.103]
407  *
408  * NOTES
409  *     exported by ordinal
410  */
411 DWORD WINAPI
412 SignalFileOpen (DWORD dwParam1)
413 {
414     FIXME("(0x%08lx):stub.\n", dwParam1);
415
416     return 0;
417 }
418
419 /*************************************************************************
420  * SHAddToRecentDocs                            [SHELL32.234]
421  *
422  * PARAMETERS
423  *   uFlags  [IN] SHARD_PATH or SHARD_PIDL
424  *   pv      [IN] string or pidl, NULL clears the list
425  *
426  * NOTES
427  *     exported by name
428  */
429 DWORD WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)   
430 { if (SHARD_PIDL==uFlags)
431   { FIXME("(0x%08x,pidl=%p):stub.\n", uFlags,pv);
432         }
433         else
434         { FIXME("(0x%08x,%s):stub.\n", uFlags,(char*)pv);
435         }
436   return 0;
437 }
438 /*************************************************************************
439  * SHCreateShellFolderViewEx                    [SHELL32.174]
440  *
441  * NOTES
442  *  see IShellFolder::CreateViewObject
443  */
444 HRESULT WINAPI SHCreateShellFolderViewEx(
445         LPCSHELLFOLDERVIEWINFO psvcbi, /*[in ] shelltemplate struct*/
446         LPSHELLVIEW* ppv)              /*[out] IShellView pointer*/
447 {
448         IShellView * psf;
449         HRESULT hRes;
450         
451         TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=0x%08lx\n", 
452           psvcbi->pshf, psvcbi->pidlFolder, psvcbi->lpfnCallback,
453           psvcbi->uViewMode, psvcbi->dwUser);
454
455         psf = IShellView_Constructor(psvcbi->pshf);
456         
457         if (!psf)
458           return E_OUTOFMEMORY;
459
460         IShellView_AddRef(psf);
461         hRes = IShellView_QueryInterface(psf, &IID_IShellView, (LPVOID *)ppv);
462         IShellView_Release(psf);
463
464         return hRes;
465 }
466 /*************************************************************************
467  *  SHWinHelp                                   [SHELL32.127]
468  *
469  */
470 HRESULT WINAPI SHWinHelp (DWORD v, DWORD w, DWORD x, DWORD z)
471 {       FIXME("0x%08lx 0x%08lx 0x%08lx 0x%08lx stub\n",v,w,x,z);
472         return 0;
473 }
474 /*************************************************************************
475  *  SHRunControlPanel [SHELL32.161]
476  *
477  */
478 HRESULT WINAPI SHRunControlPanel (DWORD x, DWORD z)
479 {       FIXME("0x%08lx 0x%08lx stub\n",x,z);
480         return 0;
481 }
482 /*************************************************************************
483  * ShellExecuteEx                               [SHELL32.291]
484  *
485  */
486 BOOL WINAPI ShellExecuteExAW (LPVOID sei)
487 {       if (VERSION_OsIsUnicode())
488           return ShellExecuteExW (sei);
489         return ShellExecuteExA (sei);
490 }
491 /*************************************************************************
492  * ShellExecuteExA                              [SHELL32.292]
493  *
494  * placeholder in the commandline:
495  *      %1 file
496  *      %2 printer
497  *      %3 driver
498  *      %4 port
499  *      %I adress of a global item ID (explorer switch /idlist)
500  *      %L ??? path/url/current file ???
501  *      %S ???
502  *      %* all following parameters (see batfile)
503  */
504 #include "process.h" /* we can get rid of it hopefully */
505 #include "task.h"
506 BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
507 {       CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20];
508         LPSTR pos;
509         int gap, len;
510         STARTUPINFOA  startup;
511         PROCESS_INFORMATION info;
512                         
513         WARN("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s incomplete\n",
514                 sei->fMask, sei->hwnd, sei->lpVerb, sei->lpFile,
515                 sei->lpParameters, sei->lpDirectory, sei->nShow, 
516                 (sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass : "not used");
517
518         ZeroMemory(szApplicationName,MAX_PATH);
519         if (sei->lpFile)
520           strcpy(szApplicationName, sei->lpFile);
521         
522         ZeroMemory(szCommandline,MAX_PATH);
523         if (sei->lpParameters)
524           strcpy(szCommandline, sei->lpParameters);
525                         
526         if (sei->fMask & (SEE_MASK_CLASSKEY | SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
527                           SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
528                           SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE | 
529                           SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
530         {
531           FIXME("flags ignored: 0x%08lx\n", sei->fMask);
532         }
533         
534         /* launch a document by fileclass like 'Wordpad.Document.1' */
535         if (sei->fMask & SEE_MASK_CLASSNAME)
536         {
537           /* the commandline contains 'c:\Path\wordpad.exe "%1"' */
538           HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, 256);
539           /* fixme: get the extension of lpFile, check if it fits to the lpClass */
540           TRACE("SEE_MASK_CLASSNAME->'%s'\n", szCommandline);
541         }
542
543         /* process the IDList */
544         if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
545         {
546           SHGetPathFromIDListA (sei->lpIDList,szApplicationName);
547           TRACE("-- idlist=%p (%s)\n", sei->lpIDList, szApplicationName);
548         }
549         else
550         {
551           if (sei->fMask & SEE_MASK_IDLIST )
552           {
553             pos = strstr(szCommandline, "%I");
554             if (pos)
555             {
556               LPVOID pv;
557               HGLOBAL hmem = SHAllocShared ( sei->lpIDList, ILGetSize(sei->lpIDList), 0);
558               pv = SHLockShared(hmem,0);
559               sprintf(szPidl,":%p",pv );
560               SHUnlockShared(pv);
561             
562               gap = strlen(szPidl);
563               len = strlen(pos)-2;
564               memmove(pos+gap,pos+2,len);
565               memcpy(pos,szPidl,gap);
566
567             }
568           }
569         }
570
571         TRACE("execute:'%s','%s'\n",szApplicationName, szCommandline);
572
573         strcat(szApplicationName, " ");
574         strcat(szApplicationName, szCommandline);
575
576         ZeroMemory(&startup,sizeof(STARTUPINFOA));
577         startup.cb = sizeof(STARTUPINFOA);
578
579         if (! CreateProcessA(NULL, szApplicationName,
580                          NULL, NULL, FALSE, 0, 
581                          NULL, NULL, &startup, &info))
582         {
583           sei->hInstApp = GetLastError();
584           return FALSE;
585         }
586
587         sei->hInstApp = 33;
588         
589         /* Give 30 seconds to the app to come up */
590         if ( WaitForInputIdle ( info.hProcess, 30000 ) ==  0xFFFFFFFF )
591           ERR("WaitForInputIdle failed: Error %ld\n", GetLastError() );
592  
593         if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
594           sei->hProcess = info.hProcess;          
595         else
596           CloseHandle( info.hProcess );
597         CloseHandle( info.hThread );
598         return TRUE;
599 }
600 /*************************************************************************
601  * ShellExecuteExW                              [SHELL32.293]
602  *
603  */
604 BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
605 {       SHELLEXECUTEINFOA seiA;
606         DWORD ret;
607
608         TRACE("%p\n", sei);
609
610         memcpy(&seiA, sei, sizeof(SHELLEXECUTEINFOA));
611         
612         if (sei->lpVerb)
613           seiA.lpVerb = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpVerb);
614
615         if (sei->lpFile)
616           seiA.lpFile = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpFile);
617
618         if (sei->lpParameters)
619           seiA.lpParameters = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpParameters);
620
621         if (sei->lpDirectory)
622           seiA.lpDirectory = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpDirectory);
623
624         if ((sei->fMask & SEE_MASK_CLASSNAME) && sei->lpClass)
625           seiA.lpClass = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpClass);
626         else
627           seiA.lpClass = NULL;
628                   
629         ret = ShellExecuteExA(&seiA);
630
631         if (seiA.lpVerb)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpVerb );
632         if (seiA.lpFile)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpFile );
633         if (seiA.lpParameters)  HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpParameters );
634         if (seiA.lpDirectory)   HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpDirectory );
635         if (seiA.lpClass)       HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpClass );
636
637         return ret;
638 }
639
640 static LPUNKNOWN SHELL32_IExplorerInterface=0;
641 /*************************************************************************
642  * SHSetInstanceExplorer                        [SHELL32.176]
643  *
644  * NOTES
645  *  Sets the interface
646  */
647 HRESULT WINAPI SHSetInstanceExplorer (LPUNKNOWN lpUnknown)
648 {       TRACE("%p\n", lpUnknown);
649         SHELL32_IExplorerInterface = lpUnknown;
650         return (HRESULT) lpUnknown;
651 }
652 /*************************************************************************
653  * SHGetInstanceExplorer                        [SHELL32.256]
654  *
655  * NOTES
656  *  gets the interface pointer of the explorer and a reference
657  */
658 HRESULT WINAPI SHGetInstanceExplorer (LPUNKNOWN * lpUnknown)
659 {       TRACE("%p\n", lpUnknown);
660
661         *lpUnknown = SHELL32_IExplorerInterface;
662
663         if (!SHELL32_IExplorerInterface)
664           return E_FAIL;
665
666         IUnknown_AddRef(SHELL32_IExplorerInterface);
667         return NOERROR;
668 }
669 /*************************************************************************
670  * SHFreeUnusedLibraries                        [SHELL32.123]
671  *
672  * NOTES
673  *  exported by name
674  */
675 void WINAPI SHFreeUnusedLibraries (void)
676 {
677         FIXME("stub\n");
678 }
679 /*************************************************************************
680  * DAD_SetDragImage                             [SHELL32.136]
681  *
682  * NOTES
683  *  exported by name
684  */
685 BOOL WINAPI DAD_SetDragImage(
686         HIMAGELIST himlTrack,
687         LPPOINT lppt)
688 {
689         FIXME("%p %p stub\n",himlTrack, lppt);
690   return 0;
691 }
692 /*************************************************************************
693  * DAD_ShowDragImage                            [SHELL32.137]
694  *
695  * NOTES
696  *  exported by name
697  */
698 BOOL WINAPI DAD_ShowDragImage(BOOL bShow)
699 {
700         FIXME("0x%08x stub\n",bShow);
701         return 0;
702 }
703 /*************************************************************************
704  * ReadCabinetState                             [NT 4.0:SHELL32.651]
705  *
706  */
707 HRESULT WINAPI ReadCabinetState(DWORD u, DWORD v)
708 {       FIXME("0x%04lx 0x%04lx stub\n",u,v);
709         return 0;
710 }
711 /*************************************************************************
712  * WriteCabinetState                            [NT 4.0:SHELL32.652]
713  *
714  */
715 HRESULT WINAPI WriteCabinetState(DWORD u)
716 {       FIXME("0x%04lx stub\n",u);
717         return 0;
718 }
719 /*************************************************************************
720  * FileIconInit                                 [SHELL32.660]
721  *
722  */
723 BOOL WINAPI FileIconInit(BOOL bFullInit)
724 {       FIXME("(%s)\n", bFullInit ? "true" : "false");
725         return 0;
726 }
727 /*************************************************************************
728  * IsUserAdmin                                  [NT 4.0:SHELL32.680]
729  *
730  */
731 HRESULT WINAPI IsUserAdmin(void)
732 {       FIXME("stub\n");
733         return TRUE;
734 }
735
736 /*************************************************************************
737  * SHAllocShared                                [SHELL32.520]
738  *
739  * NOTES
740  *  parameter1 is return value from HeapAlloc
741  *  parameter2 is equal to the size allocated with HeapAlloc
742  *  parameter3 is return value from GetCurrentProcessId
743  *
744  *  the return value is posted as lParam with 0x402 (WM_USER+2) to somewhere
745  *  WM_USER+2 could be the undocumented CWM_SETPATH
746  *  the allocated memory contains a pidl
747  */
748 HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID)
749 {       HGLOBAL hmem;
750         LPVOID pmem;
751         
752         TRACE("ptr=%p size=0x%04lx procID=0x%04lx\n",psrc,size,procID);
753         hmem = GlobalAlloc(GMEM_FIXED, size);
754         if (!hmem)
755           return 0;
756         
757         pmem =  GlobalLock (hmem);
758
759         if (! pmem)
760           return 0;
761           
762         memcpy (pmem, psrc, size);
763         GlobalUnlock(hmem); 
764         return hmem;
765 }
766 /*************************************************************************
767  * SHLockShared                                 [SHELL32.521]
768  *
769  * NOTES
770  *  parameter1 is return value from SHAllocShared
771  *  parameter2 is return value from GetCurrentProcessId
772  *  the receiver of (WM_USER+2) trys to lock the HANDLE (?) 
773  *  the returnvalue seems to be a memoryadress
774  */
775 LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID)
776 {       TRACE("handle=0x%04x procID=0x%04lx\n",hmem,procID);
777         return GlobalLock(hmem);
778 }
779 /*************************************************************************
780  * SHUnlockShared                               [SHELL32.522]
781  *
782  * NOTES
783  *  parameter1 is return value from SHLockShared
784  */
785 BOOL WINAPI SHUnlockShared(LPVOID pv)
786 {
787         TRACE("%p\n",pv);
788         return GlobalUnlock((HANDLE)pv); 
789 }
790 /*************************************************************************
791  * SHFreeShared                                 [SHELL32.523]
792  *
793  * NOTES
794  *  parameter1 is return value from SHAllocShared
795  *  parameter2 is return value from GetCurrentProcessId
796  */
797 BOOL WINAPI SHFreeShared(
798         HANDLE hMem,
799         DWORD pid)
800 {
801         TRACE("handle=0x%04x 0x%04lx\n",hMem,pid);
802         return GlobalFree(hMem);
803 }
804
805 /*************************************************************************
806  * SetAppStartingCursor                         [SHELL32.99]
807  */
808 HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v)
809 {       FIXME("hwnd=0x%04x 0x%04lx stub\n",u,v );
810         return 0;
811 }
812 /*************************************************************************
813  * SHLoadOLE                                    [SHELL32.151]
814  *
815  */
816 HRESULT WINAPI SHLoadOLE(DWORD u)
817 {       FIXME("0x%04lx stub\n",u);
818         return S_OK;
819 }
820 /*************************************************************************
821  * DriveType                                    [SHELL32.64]
822  *
823  */
824 HRESULT WINAPI DriveType(DWORD u)
825 {       FIXME("0x%04lx stub\n",u);
826         return 0;
827 }
828 /*************************************************************************
829  * SHAbortInvokeCommand                         [SHELL32.198]
830  *
831  */
832 HRESULT WINAPI SHAbortInvokeCommand(void)
833 {       FIXME("stub\n");
834         return 1;
835 }
836 /*************************************************************************
837  * SHOutOfMemoryMessageBox                      [SHELL32.126]
838  *
839  */
840 int WINAPI SHOutOfMemoryMessageBox(
841         HWND hwndOwner,
842         LPCSTR lpCaption,
843         UINT uType)
844 {
845         FIXME("0x%04x %s 0x%08x stub\n",hwndOwner, lpCaption, uType);
846         return 0;
847 }
848 /*************************************************************************
849  * SHFlushClipboard                             [SHELL32.121]
850  *
851  */
852 HRESULT WINAPI SHFlushClipboard(void)
853 {       FIXME("stub\n");
854         return 1;
855 }
856
857 /*************************************************************************
858  * SHWaitForFileToOpen                          [SHELL32.97]
859  *
860  */
861 BOOL WINAPI SHWaitForFileToOpen(
862         LPCITEMIDLIST pidl, 
863         DWORD dwFlags,
864         DWORD dwTimeout)
865 {
866         FIXME("%p 0x%08lx 0x%08lx stub\n", pidl, dwFlags, dwTimeout);
867         return 0;
868 }
869 /*************************************************************************
870  * Control_FillCache_RunDLL                     [SHELL32.8]
871  *
872  */
873 HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
874 {       FIXME("0x%04x 0x%04x 0x%04lx 0x%04lx stub\n",hWnd, hModule,w,x);
875         return 0;
876 }
877 /*************************************************************************
878  * RunDLL_CallEntry16                           [SHELL32.122]
879  * the name is propably wrong
880  */
881 HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
882 {       FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
883         return 0;
884 }
885
886 /************************************************************************
887  *      shell32_654                             [SHELL32.654]
888  *
889  * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
890  * second one could be a size (0x0c). The size is the same as the structure saved to
891  * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
892  * I'm (js) guessing: this one is just ReadCabinetState ;-)
893  */
894 HRESULT WINAPI shell32_654 (DWORD x, DWORD y)
895 {       FIXME("0x%08lx 0x%08lx stub\n",x,y);
896         return 0;
897 }
898
899 /************************************************************************
900  *      RLBuildListOfPaths                      [SHELL32.146]
901  *
902  * NOTES
903  *   builds a DPA
904  */
905 DWORD WINAPI RLBuildListOfPaths (void)
906 {       FIXME("stub\n");
907         return 0;
908 }
909 /************************************************************************
910  *      SHValidateUNC                           [SHELL32.173]
911  *
912  */
913 HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
914 {
915         FIXME("0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
916         return 0;
917 }
918
919 /************************************************************************
920  *      DoEnvironmentSubstA                     [SHELL32.1222]
921  *
922  */
923 HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y)
924 {
925         FIXME("(%s, %s) stub\n", debugstr_a(x), debugstr_a(y));
926         return 0;
927 }
928
929 /************************************************************************
930  *      DoEnvironmentSubstW                     [SHELL32.1223]
931  *
932  */
933 HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y)
934 {
935         FIXME("(%s, %s): stub\n", debugstr_w(x), debugstr_w(y));
936         return 0;
937 }
938
939 /************************************************************************
940  *      DoEnvironmentSubst                      [SHELL32.53]
941  *
942  */
943 HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y)
944 {
945         if (VERSION_OsIsUnicode())
946           return DoEnvironmentSubstW(x, y);
947         return DoEnvironmentSubstA(x, y);
948 }
949
950 /*************************************************************************
951  *      shell32_243                             [SHELL32.243]
952  * 
953  * Win98+ by-ordinal routine.  In Win98 this routine returns zero and
954  * does nothing else.  Possibly this does something in NT or SHELL32 5.0?
955  *
956  */
957
958 BOOL WINAPI shell32_243(DWORD a, DWORD b) 
959
960   return FALSE; 
961 }
962
963 /*************************************************************************
964  *      SHCreateShellPalette
965  */
966 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
967 {
968         FIXME("stub\n");
969         return CreateHalftonePalette(hdc);
970 }
971 /*************************************************************************
972  *      wnsprintfA      [SHLWAPI]
973  */
974 int WINAPIV wnsprintfA(LPSTR lpOut, int cchLimitIn, LPCSTR lpFmt, ...)
975 {
976     va_list valist;
977     INT res;
978
979     va_start( valist, lpFmt );
980     res = wvsnprintfA( lpOut, cchLimitIn, lpFmt, valist );
981     va_end( valist );
982     return res;
983 }
984
985 /*************************************************************************
986  *      wnsprintfW      [SHLWAPI]
987  */
988 int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ...)
989 {
990     va_list valist;
991     INT res;
992
993     va_start( valist, lpFmt );
994     res = wvsnprintfW( lpOut, cchLimitIn, lpFmt, valist );
995     va_end( valist );
996     return res;
997 }
998 /*************************************************************************
999  *      UrlEscapeA      [SHLWAPI]
1000  */
1001 HRESULT WINAPI UrlEscapeA(
1002         LPCSTR pszUrl,
1003         LPSTR pszEscaped,
1004         LPDWORD pcchEscaped,
1005         DWORD dwFlags)
1006 {
1007         FIXME("(%s %p %p 0x%08lx)stub\n",debugstr_a(pszUrl),
1008           pszEscaped, pcchEscaped, dwFlags);
1009         return 0;
1010 }       
1011
1012 /*************************************************************************
1013  *      UrlEscapeW      [SHLWAPI]
1014  */
1015 HRESULT WINAPI UrlEscapeW(
1016         LPCWSTR pszUrl,
1017         LPWSTR pszEscaped,
1018         LPDWORD pcchEscaped,
1019         DWORD dwFlags)
1020 {
1021         FIXME("(%s %p %p 0x%08lx)stub\n",debugstr_w(pszUrl),
1022           pszEscaped, pcchEscaped, dwFlags);
1023         return 0;
1024 }       
1025
1026 /*************************************************************************
1027  *      SHELL32_714     [SHELL32]
1028  */
1029 DWORD WINAPI SHELL32_714(LPVOID x)
1030 {
1031         FIXME("(%s)stub\n", debugstr_w(x));
1032         return 0;
1033 }
1034
1035 /*************************************************************************
1036  *      SHIsLowMemoryMachine    [SHLWAPI.@]
1037  */
1038 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
1039 {
1040         FIXME("0x%08lx\n", x);
1041         return 0;
1042 }
1043