Started implementation of ShellExecuteEx32A.
[wine] / dlls / shell32 / shell32_main.c
1 /*
2  *                              Shell basics
3  *
4  *  1998 Marcus Meissner
5  *  1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
6  */
7 #include <assert.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <ctype.h>
12 #include "windows.h"
13 #include "winerror.h"
14 #include "file.h"
15 #include "shell.h"
16 #include "heap.h"
17 #include "module.h"
18 #include "neexe.h"
19 #include "resource.h"
20 #include "dlgs.h"
21 #include "win.h"
22 #include "cursoricon.h"
23 #include "interfaces.h"
24 #include "sysmetrics.h"
25 #include "shlobj.h"
26 #include "debug.h"
27 #include "winreg.h"
28 #include "imagelist.h"
29 #include "sysmetrics.h"
30 #include "commctrl.h"
31 #include "authors.h"
32 #include "pidl.h"
33 #include "shell32_main.h"
34
35 /*************************************************************************
36  *                              CommandLineToArgvW      [SHELL32.7]
37  */
38 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
39 { LPWSTR  *argv,s,t;
40         int     i;
41   TRACE(shell,"\n");
42
43         /* to get writeable copy */
44         cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
45         s=cmdline;i=0;
46   while (*s)
47   { /* space */
48     if (*s==0x0020) 
49     { i++;
50                         s++;
51                         while (*s && *s==0x0020)
52                                 s++;
53                         continue;
54                 }
55                 s++;
56         }
57         argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
58         s=t=cmdline;
59         i=0;
60   while (*s)
61   { if (*s==0x0020)
62     { *s=0;
63                         argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
64                         *s=0x0020;
65                         while (*s && *s==0x0020)
66                                 s++;
67                         if (*s)
68                                 t=s+1;
69                         else
70                                 t=s;
71                         continue;
72                 }
73                 s++;
74         }
75         if (*t)
76                 argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
77         HeapFree( GetProcessHeap(), 0, cmdline );
78         argv[i]=NULL;
79         *numargs=i;
80         return argv;
81 }
82
83 /*************************************************************************
84  *                              Control_RunDLL          [SHELL32.12]
85  *
86  * Wild speculation in the following!
87  *
88  * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
89  */
90
91 void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
92 {
93     FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
94           debugstr_a(cmd), arg4);
95 }
96
97 /*************************************************************************
98  *  SHGetFileInfoA              [SHELL32.254]
99  *
100  * FIXME
101  *   
102  */
103
104 DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
105                               SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
106                               UINT32 flags )
107 {       CHAR szTemp[MAX_PATH];
108         LPPIDLDATA      pData;
109         DWORD ret=0;
110   
111         TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
112               path,dwFileAttributes,psfi,sizeofpsfi,flags);
113
114         /* translate the pidl to a path*/
115         if (flags & SHGFI_PIDL)
116         { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp);
117           TRACE(shell,"pidl=%p is %s\n",path,szTemp);
118         }
119         else
120         { TRACE(shell,"path=%p\n",path);
121         }
122
123         if (flags & SHGFI_ATTRIBUTES)
124         { if (flags & SHGFI_PIDL)
125           { pData = _ILGetDataPointer((LPCITEMIDLIST)path);
126             psfi->dwAttributes = pData->u.generic.dwSFGAO; /* fixme: no direct access*/
127             ret=TRUE;
128           }
129           else
130           { psfi->dwAttributes=SFGAO_FILESYSTEM;
131             ret=TRUE;
132           }
133           FIXME(shell,"file attributes, stub\n");           
134         }
135
136         if (flags & SHGFI_DISPLAYNAME)
137         { if (flags & SHGFI_PIDL)
138           { strcpy(psfi->szDisplayName,szTemp);
139           }
140           else
141           { strcpy(psfi->szDisplayName,path);
142           }
143           TRACE(shell,"displayname=%s\n", psfi->szDisplayName);   
144           ret=TRUE;
145         }
146   
147         if (flags & SHGFI_TYPENAME)
148         { FIXME(shell,"get the file type, stub\n");
149           strcpy(psfi->szTypeName,"FIXME: Type");
150           ret=TRUE;
151         }
152   
153   if (flags & SHGFI_ICONLOCATION)
154   { FIXME(shell,"location of icon, stub\n");
155     strcpy(psfi->szDisplayName,"");
156     ret=TRUE;
157   }
158
159   if (flags & SHGFI_EXETYPE)
160     FIXME(shell,"type of executable, stub\n");
161
162   if (flags & SHGFI_LINKOVERLAY)
163     FIXME(shell,"set icon to link, stub\n");
164
165   if (flags & SHGFI_OPENICON)
166     FIXME(shell,"set to open icon, stub\n");
167
168   if (flags & SHGFI_SELECTED)
169     FIXME(shell,"set icon to selected, stub\n");
170
171   if (flags & SHGFI_SHELLICONSIZE)
172     FIXME(shell,"set icon to shell size, stub\n");
173
174   if (flags & SHGFI_USEFILEATTRIBUTES)
175     FIXME(shell,"use the dwFileAttributes, stub\n");
176  
177   if (flags & SHGFI_ICON)
178   { FIXME(shell,"icon handle\n");
179     if (flags & SHGFI_SMALLICON)
180      { TRACE(shell,"set to small icon\n"); 
181        psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL);
182        ret = (DWORD) ShellSmallIconList;
183      }
184      else
185      { TRACE(shell,"set to big icon\n");
186        psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL);
187        ret = (DWORD) ShellBigIconList;
188      }      
189   }
190
191   if (flags & SHGFI_SYSICONINDEX)
192   {  FIXME(shell,"get the SYSICONINDEX\n");
193      psfi->iIcon=32;
194      if (flags & SHGFI_SMALLICON)
195      { TRACE(shell,"set to small icon\n"); 
196        ret = (DWORD) ShellSmallIconList;
197      }
198      else        
199      { TRACE(shell,"set to big icon\n");
200        ret = (DWORD) ShellBigIconList;
201      }
202   }
203
204  
205   return ret;
206 }
207
208 /*************************************************************************
209  *  SHGetFileInfo32W            [SHELL32.255]
210  *
211  * FIXME
212  *   
213  */
214
215 DWORD WINAPI SHGetFileInfo32W(LPCWSTR path,DWORD dwFileAttributes,
216                               SHFILEINFO32W *psfi, UINT32 sizeofpsfi,
217                               UINT32 flags )
218 {       FIXME(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
219               debugstr_w(path),dwFileAttributes,psfi,sizeofpsfi,flags);
220         return 0;
221 }
222
223 /*************************************************************************
224  *             ExtractIcon32A   (SHELL32.133)
225  */
226 HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
227         UINT32 nIconIndex )
228 {   HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
229     TRACE(shell,"\n");
230     if( handle )
231     {
232         HICON16* ptr = (HICON16*)GlobalLock16(handle);
233         HICON16  hIcon = *ptr;
234
235         GlobalFree16(handle);
236         return hIcon;
237     }
238     return 0;
239 }
240
241 /*************************************************************************
242  *             ExtractIcon32W   (SHELL32.180)
243  */
244 HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName,
245         UINT32 nIconIndex )
246 { LPSTR  exefn;
247   HICON32  ret;
248   TRACE(shell,"\n");
249
250   exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
251   ret = ExtractIcon32A(hInstance,exefn,nIconIndex);
252
253         HeapFree(GetProcessHeap(),0,exefn);
254         return ret;
255 }
256
257 /*************************************************************************
258  *             FindExecutable32A   (SHELL32.184)
259  */
260 HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory,
261                                       LPSTR lpResult )
262 { HINSTANCE32 retval=31;    /* default - 'No association was found' */
263     char old_dir[1024];
264
265   TRACE(shell, "File %s, Dir %s\n", 
266                  (lpFile != NULL?lpFile:"-"), 
267                  (lpDirectory != NULL?lpDirectory:"-"));
268
269     lpResult[0]='\0'; /* Start off with an empty return string */
270
271     /* trap NULL parameters on entry */
272     if (( lpFile == NULL ) || ( lpResult == NULL ))
273   { /* FIXME - should throw a warning, perhaps! */
274         return 2; /* File not found. Close enough, I guess. */
275     }
276
277     if (lpDirectory)
278   { GetCurrentDirectory32A( sizeof(old_dir), old_dir );
279         SetCurrentDirectory32A( lpDirectory );
280     }
281
282     retval = SHELL_FindExecutable( lpFile, "open", lpResult );
283
284   TRACE(shell, "returning %s\n", lpResult);
285   if (lpDirectory)
286     SetCurrentDirectory32A( old_dir );
287     return retval;
288 }
289
290 /*************************************************************************
291  *             FindExecutable32W   (SHELL32.219)
292  */
293 HINSTANCE32 WINAPI FindExecutable32W(LPCWSTR lpFile, LPCWSTR lpDirectory,
294                                      LPWSTR lpResult)
295 {
296   FIXME(shell, "(%p,%p,%p): stub\n", lpFile, lpDirectory, lpResult);
297   return 31;    /* default - 'No association was found' */
298 }
299
300 typedef struct
301 { LPCSTR  szApp;
302     LPCSTR  szOtherStuff;
303     HICON32 hIcon;
304 } ABOUT_INFO;
305
306 #define         IDC_STATIC_TEXT         100
307 #define         IDC_LISTBOX             99
308 #define         IDC_WINE_TEXT           98
309
310 #define         DROP_FIELD_TOP          (-15)
311 #define         DROP_FIELD_HEIGHT       15
312
313 extern HICON32 hIconTitleFont;
314
315 static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect )
316 { HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT);
317     if( hWndCtl )
318   { GetWindowRect32( hWndCtl, lprect );
319         MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 );
320         lprect->bottom = (lprect->top += DROP_FIELD_TOP);
321         return TRUE;
322     }
323     return FALSE;
324 }
325
326 /*************************************************************************
327  *                              SHAppBarMessage32       [SHELL32.207]
328  */
329 UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data)
330 { FIXME(shell,"(0x%08lx,%p): stub\n", msg, data);
331 #if 0
332   switch (msg)
333   { case ABM_ACTIVATE:
334         case ABM_GETAUTOHIDEBAR:
335         case ABM_GETSTATE:
336         case ABM_GETTASKBARPOS:
337         case ABM_NEW:
338         case ABM_QUERYPOS:
339         case ABM_REMOVE:
340         case ABM_SETAUTOHIDEBAR:
341         case ABM_SETPOS:
342         case ABM_WINDOWPOSCHANGED:
343             ;
344     }
345 #endif
346     return 0;
347 }
348
349 /*************************************************************************
350  * SHBrowseForFolderA [SHELL32.209]
351  *
352  */
353 LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
354 { FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
355   return NULL;
356 }
357
358 /*************************************************************************
359  *  SHGetDesktopFolder          [SHELL32.216]
360  * 
361  *  SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
362  *  CLSID_ShellDesktop
363  *  CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf);
364  *
365  * RETURNS
366  *   the interface to the shell desktop folder.
367  *
368  * FIXME
369  *   the pdesktopfolder has to be released at the end (at dll unloading???)
370  */
371 LPSHELLFOLDER pdesktopfolder=NULL;
372
373 DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder)
374 { HRESULT       hres = E_OUTOFMEMORY;
375   LPCLASSFACTORY lpclf;
376         TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder);
377
378   if (pdesktopfolder)
379         {       hres = NOERROR;
380         }
381         else
382   { lpclf = IClassFactory_Constructor();
383     /* fixme: the buildin IClassFactory_Constructor is at the moment only 
384                 for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/
385     if(lpclf)
386     { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
387                   lpclf->lpvtbl->fnRelease(lpclf);
388           }  
389   }
390         
391   if (pdesktopfolder)
392         { *shellfolder = pdesktopfolder;
393     pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder);
394         }
395   else
396         { *shellfolder=NULL;
397         }       
398
399   TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
400         return hres;
401 }
402 /*************************************************************************
403  *                       SHGetPathFromIDList            [SHELL32.221][NT 4.0: SHELL32.219]
404  */
405 BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath)     
406 { TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
407   return SHGetPathFromIDList32A(pidl,pszPath);
408 }
409
410 /*************************************************************************
411  *                       SHGetSpecialFolderLocation     [SHELL32.223]
412  * gets the folder locations from the registry and creates a pidl
413  * creates missing reg keys and directorys
414  * 
415  * PARAMS
416  *   hwndOwner [I]
417  *   nFolder   [I] CSIDL_xxxxx
418  *   ppidl     [O] PIDL of a special folder
419  *
420  * RETURNS
421  *    HResult
422  *
423  * FIXME
424  *   - look for "User Shell Folder" first
425  *
426  */
427 HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl)
428 { LPSHELLFOLDER shellfolder;
429   DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res;
430   CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH];
431   LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
432   HKEY key;
433
434         enum 
435         { FT_UNKNOWN= 0x00000000,
436           FT_DIR=     0x00000001, 
437           FT_DESKTOP= 0x00000002,
438           FT_SPECIAL= 0x00000003
439         } tFolder; 
440
441         TRACE(shell,"(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
442
443         strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
444
445         res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
446         if (res)
447         { ERR(shell,"Could not create key %s %08lx \n",buffer,res);
448           return E_OUTOFMEMORY;
449         }
450
451         tFolder=FT_DIR; 
452         switch (nFolder)
453         { case CSIDL_BITBUCKET:
454             strcpy (buffer,"xxx");                      /*not in the registry*/
455             TRACE (shell,"looking for Recycler\n");
456             tFolder=FT_UNKNOWN;
457             break;
458           case CSIDL_CONTROLS:
459             strcpy (buffer,"xxx");                      /*virtual folder*/
460             TRACE (shell,"looking for Control\n");
461             tFolder=FT_UNKNOWN;
462             break;
463           case CSIDL_DESKTOP:
464             strcpy (buffer,"xxx");                      /*virtual folder*/
465             TRACE (shell,"looking for Desktop\n");
466             tFolder=FT_DESKTOP;                 
467             break;
468           case CSIDL_DESKTOPDIRECTORY:
469           case CSIDL_COMMON_DESKTOPDIRECTORY:
470             strcpy (buffer,"Desktop");
471             break;
472           case CSIDL_DRIVES:
473             strcpy (buffer,"xxx");                      /*virtual folder*/
474             TRACE (shell,"looking for Drives\n");
475             tFolder=FT_SPECIAL;
476             break;
477           case CSIDL_FONTS:
478             strcpy (buffer,"Fonts");                    
479             break;
480           case CSIDL_NETHOOD:
481             strcpy (buffer,"NetHood");                  
482             break;
483           case CSIDL_PRINTHOOD:
484             strcpy (buffer,"PrintHood");                        
485             break;
486           case CSIDL_NETWORK:
487             strcpy (buffer,"xxx");                              /*virtual folder*/
488             TRACE (shell,"looking for Network\n");
489             tFolder=FT_UNKNOWN;
490             break;
491           case CSIDL_APPDATA:
492             strcpy (buffer,"Appdata");                  
493             break;
494           case CSIDL_PERSONAL:
495             strcpy (buffer,"Personal");                 
496             break;
497           case CSIDL_FAVORITES:
498             strcpy (buffer,"Favorites");                        
499             break;
500           case CSIDL_PRINTERS:
501             strcpy (buffer,"PrintHood");
502             break;
503           case CSIDL_COMMON_PROGRAMS:
504           case CSIDL_PROGRAMS:
505             strcpy (buffer,"Programs");                 
506             break;
507           case CSIDL_RECENT:
508             strcpy (buffer,"Recent");
509             break;
510           case CSIDL_SENDTO:
511             strcpy (buffer,"SendTo");
512             break;
513           case CSIDL_COMMON_STARTMENU:
514           case CSIDL_STARTMENU:
515             strcpy (buffer,"Start Menu");
516             break;
517           case CSIDL_COMMON_STARTUP:  
518           case CSIDL_STARTUP:
519             strcpy (buffer,"Startup");                  
520             break;
521           case CSIDL_TEMPLATES:
522             strcpy (buffer,"Templates");                        
523             break;
524           default:
525             ERR (shell,"unknown CSIDL 0x%08x\n", nFolder);
526             tFolder=FT_UNKNOWN;                 
527             break;
528         }
529
530         TRACE(shell,"Key=%s\n",buffer);
531
532         type=REG_SZ;
533
534         switch (tFolder)
535         { case FT_DIR:
536             /* Directory: get the value from the registry, if its not there 
537                         create it and the directory*/
538             if (RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
539             { GetWindowsDirectory32A(npath,MAX_PATH);
540               PathAddBackslash32A(npath);
541               switch (nFolder)
542               { case CSIDL_DESKTOPDIRECTORY:
543                 case CSIDL_COMMON_DESKTOPDIRECTORY:
544                   strcat (npath,"Desktop");
545                   break;
546                 case CSIDL_FONTS:
547                   strcat (npath,"Fonts");                       
548                   break;
549                 case CSIDL_NETHOOD:
550                   strcat (npath,"NetHood");                     
551                   break;
552                 case CSIDL_PRINTHOOD:
553                   strcat (npath,"PrintHood");                   
554                   break;
555                 case CSIDL_APPDATA:
556                   strcat (npath,"Appdata");                     
557                   break;
558                 case CSIDL_PERSONAL:
559                   strcpy (npath,"C:\\Personal");                        
560                   break;
561                 case CSIDL_FAVORITES:
562                   strcat (npath,"Favorites");                   
563                   break;
564                 case CSIDL_PRINTERS:
565                   strcat (npath,"PrintHood");                   
566                   break;
567                 case CSIDL_COMMON_PROGRAMS:
568                 case CSIDL_PROGRAMS:
569                   strcat (npath,"Start Menu");                  
570                   CreateDirectory32A(npath,NULL);
571                   strcat (npath,"\\Programs");                  
572                   break;
573                 case CSIDL_RECENT:
574                   strcat (npath,"Recent");
575                   break;
576                 case CSIDL_SENDTO:
577                   strcat (npath,"SendTo");
578                   break;
579                 case CSIDL_COMMON_STARTMENU:
580                 case CSIDL_STARTMENU:
581                   strcat (npath,"Start Menu");
582                   break;
583                 case CSIDL_COMMON_STARTUP:  
584                 case CSIDL_STARTUP:
585                   strcat (npath,"Start Menu");                  
586                   CreateDirectory32A(npath,NULL);
587                   strcat (npath,"\\Startup");                   
588                   break;
589                 case CSIDL_TEMPLATES:
590                   strcat (npath,"Templates");                   
591                   break;
592                 default:
593                   RegCloseKey(key);
594                   return E_OUTOFMEMORY;
595               }
596               if (RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)npath,sizeof(npath)+1))
597               { ERR(shell,"could not create value %s\n",buffer);
598                 RegCloseKey(key);
599                 return E_OUTOFMEMORY;
600               }
601               TRACE(shell,"value %s=%s created\n",buffer,npath);
602               CreateDirectory32A(npath,NULL);
603               strcpy(tpath,npath);
604             }
605             break;
606           case FT_DESKTOP:
607             strcpy (tpath,"Desktop");
608             break;
609           case FT_SPECIAL:
610             if (nFolder==CSIDL_DRIVES)
611             strcpy (tpath,"My Computer");
612             break;
613           default:
614             RegCloseKey(key);
615             return E_OUTOFMEMORY;
616         }
617
618         RegCloseKey(key);
619
620         TRACE(shell,"Value=%s\n",tpath);
621         LocalToWideChar32(lpszDisplayName, tpath, 256);
622   
623         if (SHGetDesktopFolder(&shellfolder)==S_OK)
624         { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
625           shellfolder->lpvtbl->fnRelease(shellfolder);
626         }
627
628         TRACE(shell, "-- (new pidl %p)\n",*ppidl);
629         return NOERROR;
630 }
631 /*************************************************************************
632  * SHHelpShortcuts_RunDLL [SHELL32.224]
633  *
634  */
635 DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
636 { FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
637         dwArg1, dwArg2, dwArg3, dwArg4);
638
639   return 0;
640 }
641
642 /*************************************************************************
643  * SHLoadInProc [SHELL32.225]
644  *
645  */
646
647 DWORD WINAPI SHLoadInProc (DWORD dwArg1)
648 { FIXME (shell, "(%lx) empty stub!\n", dwArg1);
649     return 0;
650 }
651
652 /*************************************************************************
653  *             ShellExecute32A   (SHELL32.245)
654  */
655 HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
656                                     LPCSTR lpFile, LPCSTR lpParameters,
657                                     LPCSTR lpDirectory, INT32 iShowCmd )
658 {   TRACE(shell,"\n");
659     return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
660                            lpDirectory, iShowCmd );
661 }
662
663 /*************************************************************************
664  * ShellExecute32W [SHELL32.294]
665  * from shellapi.h
666  * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, 
667  * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);   
668  */
669 HINSTANCE32 WINAPI 
670 ShellExecute32W(
671        HWND32 hwnd, 
672        LPCWSTR lpOperation, 
673        LPCWSTR lpFile, 
674        LPCWSTR lpParameters, 
675        LPCWSTR lpDirectory, 
676        INT32 nShowCmd) {
677
678        FIXME(shell,": stub\n");
679        return 0;
680 }
681
682
683
684
685
686
687 /*************************************************************************
688  *             AboutDlgProc32  (not an exported API function)
689  */
690 LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam,
691                                LPARAM lParam )
692 {   HWND32 hWndCtl;
693     char Template[512], AppTitle[512];
694
695     TRACE(shell,"\n");
696
697     switch(msg)
698     { case WM_INITDIALOG:
699       { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
700             if (info)
701         { const char* const *pstr = SHELL_People;
702                 SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
703                 GetWindowText32A( hWnd, Template, sizeof(Template) );
704                 sprintf( AppTitle, Template, info->szApp );
705                 SetWindowText32A( hWnd, AppTitle );
706                 SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT),
707                                   info->szOtherStuff );
708                 hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
709                 SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 );
710                 SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
711                 while (*pstr)
712           { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr );
713                     pstr++;
714                 }
715                 SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 );
716             }
717         }
718         return 1;
719
720     case WM_PAINT:
721       { RECT32 rect;
722             PAINTSTRUCT32 ps;
723             HDC32 hDC = BeginPaint32( hWnd, &ps );
724
725             if( __get_dropline( hWnd, &rect ) ) {
726                 SelectObject32( hDC, GetStockObject32( BLACK_PEN ) );
727                 MoveToEx32( hDC, rect.left, rect.top, NULL );
728                 LineTo32( hDC, rect.right, rect.bottom );
729             }
730             EndPaint32( hWnd, &ps );
731         }
732         break;
733
734     case WM_LBTRACKPOINT:
735         hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
736         if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
737       { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) )
738         { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 );
739                 if( idx != -1 )
740           { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 );
741                     HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
742                     char* pstr = (char*)GlobalLock16( hMemObj );
743
744                     if( pstr )
745             { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
746                         SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
747                         SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
748                         UpdateWindow32( hWndCtl );
749                         if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
750                             SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr );
751                     }
752             if( hMemObj )
753               GlobalFree16( hMemObj );
754                 }
755             }
756         }
757         break;
758
759     case WM_QUERYDROPOBJECT:
760         if( wParam == 0 )
761       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
762             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
763         { RECT32 rect;
764                 if( __get_dropline( hWnd, &rect ) )
765           { POINT32 pt;
766             pt.x=lpDragInfo->pt.x;
767             pt.x=lpDragInfo->pt.y;
768                     rect.bottom += DROP_FIELD_HEIGHT;
769                     if( PtInRect32( &rect, pt ) )
770             { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
771                         return TRUE;
772                     }
773                 }
774             }
775         }
776         break;
777
778     case WM_DROPOBJECT:
779         if( wParam == hWnd )
780       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
781             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
782         { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
783                 if( pstr )
784           { static char __appendix_str[] = " with";
785
786                     hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT );
787                     SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
788                     if( !lstrncmp32A( Template, "WINE", 4 ) )
789                         SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template );
790                     else
791           { char* pch = Template + strlen(Template) - strlen(__appendix_str);
792                         *pch = '\0';
793                         SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, 
794                                         (WPARAM32)-1, (LPARAM)Template );
795                     }
796
797                     lstrcpy32A( Template, pstr );
798                     lstrcat32A( Template, __appendix_str );
799                     SetWindowText32A( hWndCtl, Template );
800                     SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
801                     return TRUE;
802                 }
803             }
804         }
805         break;
806
807     case WM_COMMAND:
808         if (wParam == IDOK)
809     {  EndDialog32(hWnd, TRUE);
810             return TRUE;
811         }
812         break;
813     }
814     return 0;
815 }
816
817
818 /*************************************************************************
819  *             ShellAbout32A   (SHELL32.243)
820  */
821 BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
822                              HICON32 hIcon )
823 {   ABOUT_INFO info;
824     TRACE(shell,"\n");
825     info.szApp        = szApp;
826     info.szOtherStuff = szOtherStuff;
827     info.hIcon        = hIcon;
828     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
829     return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
830                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
831                                       hWnd, AboutDlgProc32, (LPARAM)&info );
832 }
833
834
835 /*************************************************************************
836  *             ShellAbout32W   (SHELL32.244)
837  */
838 BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
839                              HICON32 hIcon )
840 {   BOOL32 ret;
841     ABOUT_INFO info;
842
843     TRACE(shell,"\n");
844     
845     info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
846     info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
847     info.hIcon        = hIcon;
848     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
849     ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
850                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
851                                       hWnd, AboutDlgProc32, (LPARAM)&info );
852     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
853     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
854     return ret;
855 }
856
857 /*************************************************************************
858  *                              Shell_NotifyIcon        [SHELL32.296]
859  *      FIXME
860  *      This function is supposed to deal with the systray.
861  *      Any ideas on how this is to be implimented?
862  */
863 BOOL32 WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid )
864 {   TRACE(shell,"\n");
865     return FALSE;
866 }
867
868 /*************************************************************************
869  *                              Shell_NotifyIcon        [SHELL32.297]
870  *      FIXME
871  *      This function is supposed to deal with the systray.
872  *      Any ideas on how this is to be implimented?
873  */
874 BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATA pnid )
875 {   TRACE(shell,"\n");
876     return FALSE;
877 }
878
879 /*************************************************************************
880  * FreeIconList
881  */
882 void WINAPI FreeIconList( DWORD dw )
883 { FIXME(shell, "(%lx): stub\n",dw);
884 }
885
886 /*************************************************************************
887  * SHGetPathFromIDList32A        [SHELL32.261][NT 4.0: SHELL32.220]
888  *
889  * PARAMETERS
890  *  pidl,   [IN] pidl 
891  *  pszPath [OUT] path
892  *
893  * RETURNS 
894  *  path from a passed PIDL.
895  *
896  * NOTES
897  *     exported by name
898  *
899  * FIXME
900  *  fnGetDisplayNameOf can return different types of OLEString
901  */
902 DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath)
903 {       STRRET lpName;
904         LPSHELLFOLDER shellfolder;
905         CHAR  buffer[MAX_PATH],tpath[MAX_PATH];
906         DWORD type,tpathlen=MAX_PATH,dwdisp;
907         HKEY  key;
908
909         TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
910
911   if (!pidl)
912   {  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
913
914      if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
915      { return E_OUTOFMEMORY;
916      }
917      type=REG_SZ;    
918      strcpy (buffer,"Desktop");                                 /*registry name*/
919      if ( RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
920      { GetWindowsDirectory32A(tpath,MAX_PATH);
921        PathAddBackslash32A(tpath);
922        strcat (tpath,"Desktop");                                /*folder name*/
923        RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)tpath,tpathlen);
924        CreateDirectory32A(tpath,NULL);
925      }
926      RegCloseKey(key);
927      strcpy(pszPath,tpath);
928   }
929   else
930   { if (SHGetDesktopFolder(&shellfolder)==S_OK)
931         { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
932           shellfolder->lpvtbl->fnRelease(shellfolder);
933         }
934   /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/
935         strcpy(pszPath,lpName.u.cStr);
936         /* fixme free the olestring*/
937   }
938         TRACE(shell,"-- (%s)\n",pszPath);
939         return NOERROR;
940 }
941 /*************************************************************************
942  * SHGetPathFromIDList32W [SHELL32.262]
943  */
944 DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath)
945 {       char sTemp[MAX_PATH];
946
947         TRACE (shell,"(pidl=%p)\n", pidl);
948
949         SHGetPathFromIDList32A (pidl, sTemp);
950         lstrcpyAtoW(pszPath, sTemp);
951
952         TRACE(shell,"-- (%s)\n",debugstr_w(pszPath));
953
954         return NOERROR;
955 }
956
957
958 void    (CALLBACK* pDLLInitComctl)(void);
959 INT32   (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon);
960 INT32   (CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32);
961 HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32);
962 HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32);
963 INT32   (CALLBACK* pImageList_GetImageCount)(HIMAGELIST);
964
965 LPVOID  (CALLBACK* pCOMCTL32_Alloc) (INT32);  
966 BOOL32  (CALLBACK* pCOMCTL32_Free) (LPVOID);  
967
968 HDPA    (CALLBACK* pDPA_Create) (INT32);  
969 INT32   (CALLBACK* pDPA_InsertPtr) (const HDPA, INT32, LPVOID); 
970 BOOL32  (CALLBACK* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); 
971 LPVOID  (CALLBACK* pDPA_GetPtr) (const HDPA, INT32);   
972 BOOL32  (CALLBACK* pDPA_Destroy) (const HDPA); 
973 INT32   (CALLBACK *pDPA_Search) (const HDPA, LPVOID, INT32, PFNDPACOMPARE, LPARAM, UINT32);
974 static BOOL32 bShell32IsInitialized=0;
975 /*************************************************************************
976  * SHELL32 LibMain
977  *
978  * FIXME
979  *  at the moment the icons are extracted from shell32.dll
980  *  free the imagelists
981  */
982 HINSTANCE32 shell32_hInstance; 
983
984 BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
985 { HINSTANCE32 hComctl32;
986
987   TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved);
988
989   shell32_hInstance = hinstDLL;
990   
991   if (fdwReason==DLL_PROCESS_ATTACH && !bShell32IsInitialized)
992   { hComctl32 = LoadLibrary32A("COMCTL32.DLL"); 
993     if (hComctl32)
994     { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx");
995       if (pDLLInitComctl)
996       { pDLLInitComctl();
997       }
998       pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create");
999       pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon");
1000       pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon");
1001       pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon");
1002       pImageList_GetImageCount=GetProcAddress32(hComctl32,"ImageList_GetImageCount");
1003
1004       /* imports by ordinal, pray that it works*/
1005       pCOMCTL32_Alloc=GetProcAddress32(hComctl32, (LPCSTR)71L);
1006       pCOMCTL32_Free=GetProcAddress32(hComctl32, (LPCSTR)73L);
1007       pDPA_Create=GetProcAddress32(hComctl32, (LPCSTR)328L);
1008       pDPA_Destroy=GetProcAddress32(hComctl32, (LPCSTR)329L);
1009       pDPA_GetPtr=GetProcAddress32(hComctl32, (LPCSTR)332L);
1010       pDPA_InsertPtr=GetProcAddress32(hComctl32, (LPCSTR)334L);
1011       pDPA_Sort=GetProcAddress32(hComctl32, (LPCSTR)338L);
1012       pDPA_Search=GetProcAddress32(hComctl32, (LPCSTR)339L);
1013
1014       FreeLibrary32(hComctl32);
1015     }
1016     else
1017     { /* panic, imediately exit wine*/
1018       ERR(shell,"P A N I C error getting functionpointers\n");
1019       exit (1);
1020     }
1021     SIC_Initialize();
1022     bShell32IsInitialized = TRUE;
1023   }
1024   return TRUE;
1025 }