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