- Added some missing WINELIB_NAME_AW definitions, types and messages
[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 "heap.h"
15
16 #include "shellapi.h"
17 #include "shlguid.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 (SHELL_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     strcpy(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)
113 {
114         HKEY    hKey;
115         DWORD   dwData;
116         DWORD   dwDataSize = sizeof (DWORD);
117
118         TRACE("(%p 0x%08lx)\n",lpsfs,dwMask);
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 (SHELL_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 BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
505 {       CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20];
506         LPSTR pos;
507         int gap, len;
508         STARTUPINFOA  startup;
509         PROCESS_INFORMATION info;
510                         
511         WARN("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s incomplete\n",
512                 sei->fMask, sei->hwnd, sei->lpVerb, sei->lpFile,
513                 sei->lpParameters, sei->lpDirectory, sei->nShow, 
514                 (sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass : "not used");
515
516         ZeroMemory(szApplicationName,MAX_PATH);
517         if (sei->lpFile)
518           strcpy(szApplicationName, sei->lpFile);
519         
520         ZeroMemory(szCommandline,MAX_PATH);
521         if (sei->lpParameters)
522           strcpy(szCommandline, sei->lpParameters);
523                         
524         if (sei->fMask & (SEE_MASK_CLASSKEY | SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
525                           SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
526                           SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE | 
527                           SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
528         {
529           FIXME("flags ignored: 0x%08lx\n", sei->fMask);
530         }
531         
532         /* launch a document by fileclass like 'Wordpad.Document.1' */
533         if (sei->fMask & SEE_MASK_CLASSNAME)
534         {
535           /* the commandline contains 'c:\Path\wordpad.exe "%1"' */
536           HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, 256);
537           /* fixme: get the extension of lpFile, check if it fits to the lpClass */
538           TRACE("SEE_MASK_CLASSNAME->'%s'\n", szCommandline);
539         }
540
541         /* process the IDList */
542         if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
543         {
544           SHGetPathFromIDListA (sei->lpIDList,szApplicationName);
545           TRACE("-- idlist=%p (%s)\n", sei->lpIDList, szApplicationName);
546         }
547         else
548         {
549           if (sei->fMask & SEE_MASK_IDLIST )
550           {
551             pos = strstr(szCommandline, "%I");
552             if (pos)
553             {
554               LPVOID pv;
555               HGLOBAL hmem = SHAllocShared ( sei->lpIDList, ILGetSize(sei->lpIDList), 0);
556               pv = SHLockShared(hmem,0);
557               sprintf(szPidl,":%p",pv );
558               SHUnlockShared(pv);
559             
560               gap = strlen(szPidl);
561               len = strlen(pos)-2;
562               memmove(pos+gap,pos+2,len);
563               memcpy(pos,szPidl,gap);
564
565             }
566           }
567         }
568
569         TRACE("execute:'%s','%s'\n",szApplicationName, szCommandline);
570
571         strcat(szApplicationName, " ");
572         strcat(szApplicationName, szCommandline);
573
574         ZeroMemory(&startup,sizeof(STARTUPINFOA));
575         startup.cb = sizeof(STARTUPINFOA);
576
577         if (! CreateProcessA(NULL, szApplicationName,
578                          NULL, NULL, FALSE, 0, 
579                          NULL, NULL, &startup, &info))
580         {
581           sei->hInstApp = GetLastError();
582           return FALSE;
583         }
584
585         sei->hInstApp = 33;
586         
587         /* Give 30 seconds to the app to come up */
588         if ( WaitForInputIdle ( info.hProcess, 30000 ) ==  0xFFFFFFFF )
589           ERR("WaitForInputIdle failed: Error %ld\n", GetLastError() );
590  
591         if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
592           sei->hProcess = info.hProcess;          
593         else
594           CloseHandle( info.hProcess );
595         CloseHandle( info.hThread );
596         return TRUE;
597 }
598 /*************************************************************************
599  * ShellExecuteExW                              [SHELL32.293]
600  *
601  */
602 BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
603 {       SHELLEXECUTEINFOA seiA;
604         DWORD ret;
605
606         TRACE("%p\n", sei);
607
608         memcpy(&seiA, sei, sizeof(SHELLEXECUTEINFOA));
609         
610         if (sei->lpVerb)
611           seiA.lpVerb = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpVerb);
612
613         if (sei->lpFile)
614           seiA.lpFile = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpFile);
615
616         if (sei->lpParameters)
617           seiA.lpParameters = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpParameters);
618
619         if (sei->lpDirectory)
620           seiA.lpDirectory = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpDirectory);
621
622         if ((sei->fMask & SEE_MASK_CLASSNAME) && sei->lpClass)
623           seiA.lpClass = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpClass);
624         else
625           seiA.lpClass = NULL;
626                   
627         ret = ShellExecuteExA(&seiA);
628
629         if (seiA.lpVerb)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpVerb );
630         if (seiA.lpFile)        HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpFile );
631         if (seiA.lpParameters)  HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpParameters );
632         if (seiA.lpDirectory)   HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpDirectory );
633         if (seiA.lpClass)       HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpClass );
634
635         return ret;
636 }
637
638 static LPUNKNOWN SHELL32_IExplorerInterface=0;
639 /*************************************************************************
640  * SHSetInstanceExplorer                        [SHELL32.176]
641  *
642  * NOTES
643  *  Sets the interface
644  */
645 HRESULT WINAPI SHSetInstanceExplorer (LPUNKNOWN lpUnknown)
646 {       TRACE("%p\n", lpUnknown);
647         SHELL32_IExplorerInterface = lpUnknown;
648         return (HRESULT) lpUnknown;
649 }
650 /*************************************************************************
651  * SHGetInstanceExplorer                        [SHELL32.256]
652  *
653  * NOTES
654  *  gets the interface pointer of the explorer and a reference
655  */
656 HRESULT WINAPI SHGetInstanceExplorer (LPUNKNOWN * lpUnknown)
657 {       TRACE("%p\n", lpUnknown);
658
659         *lpUnknown = SHELL32_IExplorerInterface;
660
661         if (!SHELL32_IExplorerInterface)
662           return E_FAIL;
663
664         IUnknown_AddRef(SHELL32_IExplorerInterface);
665         return NOERROR;
666 }
667 /*************************************************************************
668  * SHFreeUnusedLibraries                        [SHELL32.123]
669  *
670  * NOTES
671  *  exported by name
672  */
673 void WINAPI SHFreeUnusedLibraries (void)
674 {
675         FIXME("stub\n");
676 }
677 /*************************************************************************
678  * DAD_SetDragImage                             [SHELL32.136]
679  *
680  * NOTES
681  *  exported by name
682  */
683 BOOL WINAPI DAD_SetDragImage(
684         HIMAGELIST himlTrack,
685         LPPOINT lppt)
686 {
687         FIXME("%p %p stub\n",himlTrack, lppt);
688   return 0;
689 }
690 /*************************************************************************
691  * DAD_ShowDragImage                            [SHELL32.137]
692  *
693  * NOTES
694  *  exported by name
695  */
696 BOOL WINAPI DAD_ShowDragImage(BOOL bShow)
697 {
698         FIXME("0x%08x stub\n",bShow);
699         return 0;
700 }
701 /*************************************************************************
702  * ReadCabinetState                             [NT 4.0:SHELL32.651]
703  *
704  */
705 HRESULT WINAPI ReadCabinetState(DWORD u, DWORD v)
706 {       FIXME("0x%04lx 0x%04lx stub\n",u,v);
707         return 0;
708 }
709 /*************************************************************************
710  * WriteCabinetState                            [NT 4.0:SHELL32.652]
711  *
712  */
713 HRESULT WINAPI WriteCabinetState(DWORD u)
714 {       FIXME("0x%04lx stub\n",u);
715         return 0;
716 }
717 /*************************************************************************
718  * FileIconInit                                 [SHELL32.660]
719  *
720  */
721 BOOL WINAPI FileIconInit(BOOL bFullInit)
722 {       FIXME("(%s)\n", bFullInit ? "true" : "false");
723         return 0;
724 }
725 /*************************************************************************
726  * IsUserAdmin                                  [NT 4.0:SHELL32.680]
727  *
728  */
729 HRESULT WINAPI IsUserAdmin(void)
730 {       FIXME("stub\n");
731         return TRUE;
732 }
733
734 /*************************************************************************
735  * SHAllocShared                                [SHELL32.520]
736  *
737  * NOTES
738  *  parameter1 is return value from HeapAlloc
739  *  parameter2 is equal to the size allocated with HeapAlloc
740  *  parameter3 is return value from GetCurrentProcessId
741  *
742  *  the return value is posted as lParam with 0x402 (WM_USER+2) to somewhere
743  *  WM_USER+2 could be the undocumented CWM_SETPATH
744  *  the allocated memory contains a pidl
745  */
746 HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID)
747 {       HGLOBAL hmem;
748         LPVOID pmem;
749         
750         TRACE("ptr=%p size=0x%04lx procID=0x%04lx\n",psrc,size,procID);
751         hmem = GlobalAlloc(GMEM_FIXED, size);
752         if (!hmem)
753           return 0;
754         
755         pmem =  GlobalLock (hmem);
756
757         if (! pmem)
758           return 0;
759           
760         memcpy (pmem, psrc, size);
761         GlobalUnlock(hmem); 
762         return hmem;
763 }
764 /*************************************************************************
765  * SHLockShared                                 [SHELL32.521]
766  *
767  * NOTES
768  *  parameter1 is return value from SHAllocShared
769  *  parameter2 is return value from GetCurrentProcessId
770  *  the receiver of (WM_USER+2) trys to lock the HANDLE (?) 
771  *  the returnvalue seems to be a memoryadress
772  */
773 LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID)
774 {       TRACE("handle=0x%04x procID=0x%04lx\n",hmem,procID);
775         return GlobalLock(hmem);
776 }
777 /*************************************************************************
778  * SHUnlockShared                               [SHELL32.522]
779  *
780  * NOTES
781  *  parameter1 is return value from SHLockShared
782  */
783 BOOL WINAPI SHUnlockShared(LPVOID pv)
784 {
785         TRACE("%p\n",pv);
786         return GlobalUnlock((HANDLE)pv); 
787 }
788 /*************************************************************************
789  * SHFreeShared                                 [SHELL32.523]
790  *
791  * NOTES
792  *  parameter1 is return value from SHAllocShared
793  *  parameter2 is return value from GetCurrentProcessId
794  */
795 BOOL WINAPI SHFreeShared(
796         HANDLE hMem,
797         DWORD pid)
798 {
799         TRACE("handle=0x%04x 0x%04lx\n",hMem,pid);
800         return GlobalFree(hMem);
801 }
802
803 /*************************************************************************
804  * SetAppStartingCursor                         [SHELL32.99]
805  */
806 HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v)
807 {       FIXME("hwnd=0x%04x 0x%04lx stub\n",u,v );
808         return 0;
809 }
810 /*************************************************************************
811  * SHLoadOLE                                    [SHELL32.151]
812  *
813  */
814 HRESULT WINAPI SHLoadOLE(DWORD u)
815 {       FIXME("0x%04lx stub\n",u);
816         return S_OK;
817 }
818 /*************************************************************************
819  * DriveType                                    [SHELL32.64]
820  *
821  */
822 HRESULT WINAPI DriveType(DWORD u)
823 {       FIXME("0x%04lx stub\n",u);
824         return 0;
825 }
826 /*************************************************************************
827  * SHAbortInvokeCommand                         [SHELL32.198]
828  *
829  */
830 HRESULT WINAPI SHAbortInvokeCommand(void)
831 {       FIXME("stub\n");
832         return 1;
833 }
834 /*************************************************************************
835  * SHOutOfMemoryMessageBox                      [SHELL32.126]
836  *
837  */
838 int WINAPI SHOutOfMemoryMessageBox(
839         HWND hwndOwner,
840         LPCSTR lpCaption,
841         UINT uType)
842 {
843         FIXME("0x%04x %s 0x%08x stub\n",hwndOwner, lpCaption, uType);
844         return 0;
845 }
846 /*************************************************************************
847  * SHFlushClipboard                             [SHELL32.121]
848  *
849  */
850 HRESULT WINAPI SHFlushClipboard(void)
851 {       FIXME("stub\n");
852         return 1;
853 }
854
855 /*************************************************************************
856  * SHWaitForFileToOpen                          [SHELL32.97]
857  *
858  */
859 BOOL WINAPI SHWaitForFileToOpen(
860         LPCITEMIDLIST pidl, 
861         DWORD dwFlags,
862         DWORD dwTimeout)
863 {
864         FIXME("%p 0x%08lx 0x%08lx stub\n", pidl, dwFlags, dwTimeout);
865         return 0;
866 }
867 /*************************************************************************
868  * Control_FillCache_RunDLL                     [SHELL32.8]
869  *
870  */
871 HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
872 {       FIXME("0x%04x 0x%04x 0x%04lx 0x%04lx stub\n",hWnd, hModule,w,x);
873         return 0;
874 }
875 /*************************************************************************
876  * RunDLL_CallEntry16                           [SHELL32.122]
877  * the name is propably wrong
878  */
879 HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
880 {       FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
881         return 0;
882 }
883
884 /************************************************************************
885  *      shell32_654                             [SHELL32.654]
886  *
887  * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
888  * second one could be a size (0x0c). The size is the same as the structure saved to
889  * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
890  * I'm (js) guessing: this one is just ReadCabinetState ;-)
891  */
892 HRESULT WINAPI shell32_654 (DWORD x, DWORD y)
893 {       FIXME("0x%08lx 0x%08lx stub\n",x,y);
894         return 0;
895 }
896
897 /************************************************************************
898  *      RLBuildListOfPaths                      [SHELL32.146]
899  *
900  * NOTES
901  *   builds a DPA
902  */
903 DWORD WINAPI RLBuildListOfPaths (void)
904 {       FIXME("stub\n");
905         return 0;
906 }
907 /************************************************************************
908  *      SHValidateUNC                           [SHELL32.173]
909  *
910  */
911 HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
912 {
913         FIXME("0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
914         return 0;
915 }
916
917 /************************************************************************
918  *      DoEnvironmentSubstA                     [SHELL32.1222]
919  *
920  */
921 HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y)
922 {
923         FIXME("(%s, %s) stub\n", debugstr_a(x), debugstr_a(y));
924         return 0;
925 }
926
927 /************************************************************************
928  *      DoEnvironmentSubstW                     [SHELL32.1223]
929  *
930  */
931 HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y)
932 {
933         FIXME("(%s, %s): stub\n", debugstr_w(x), debugstr_w(y));
934         return 0;
935 }
936
937 /************************************************************************
938  *      DoEnvironmentSubst                      [SHELL32.53]
939  *
940  */
941 HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y)
942 {
943         if (SHELL_OsIsUnicode())
944           return DoEnvironmentSubstW(x, y);
945         return DoEnvironmentSubstA(x, y);
946 }
947
948 /*************************************************************************
949  *      shell32_243                             [SHELL32.243]
950  * 
951  * Win98+ by-ordinal routine.  In Win98 this routine returns zero and
952  * does nothing else.  Possibly this does something in NT or SHELL32 5.0?
953  *
954  */
955
956 BOOL WINAPI shell32_243(DWORD a, DWORD b) 
957
958   return FALSE; 
959 }
960
961 /*************************************************************************
962  *      SHELL32_714     [SHELL32]
963  */
964 DWORD WINAPI SHELL32_714(LPVOID x)
965 {
966         FIXME("(%s)stub\n", debugstr_w(x));
967         return 0;
968 }