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