Changed some treeview related definitions.
[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 <stdlib.h>
8 #include <string.h>
9
10 #include "windows.h"
11 #include "wine/winuser16.h"
12 #include "winerror.h"
13 #include "heap.h"
14 #include "resource.h"
15 #include "dlgs.h"
16 #include "win.h"
17 #include "sysmetrics.h"
18 #include "debug.h"
19 #include "winreg.h"
20 #include "authors.h"
21
22 #include "shell.h"
23 #include "pidl.h"
24 #include "shlobj.h"
25 #include "shell32_main.h"
26
27 #include "shlguid.h"
28
29 /*************************************************************************
30  *                              CommandLineToArgvW      [SHELL32.7]
31  */
32 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
33 { LPWSTR  *argv,s,t;
34         int     i;
35   TRACE(shell,"\n");
36
37         /* to get writeable copy */
38         cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
39         s=cmdline;i=0;
40   while (*s)
41   { /* space */
42     if (*s==0x0020) 
43     { i++;
44                         s++;
45                         while (*s && *s==0x0020)
46                                 s++;
47                         continue;
48                 }
49                 s++;
50         }
51         argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
52         s=t=cmdline;
53         i=0;
54   while (*s)
55   { if (*s==0x0020)
56     { *s=0;
57                         argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
58                         *s=0x0020;
59                         while (*s && *s==0x0020)
60                                 s++;
61                         if (*s)
62                                 t=s+1;
63                         else
64                                 t=s;
65                         continue;
66                 }
67                 s++;
68         }
69         if (*t)
70                 argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
71         HeapFree( GetProcessHeap(), 0, cmdline );
72         argv[i]=NULL;
73         *numargs=i;
74         return argv;
75 }
76
77 /*************************************************************************
78  *                              Control_RunDLL          [SHELL32.12]
79  *
80  * Wild speculation in the following!
81  *
82  * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
83  */
84
85 void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
86 {
87     FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
88           debugstr_a(cmd), arg4);
89 }
90
91 /*************************************************************************
92  *  SHGetFileInfoA              [SHELL32.254]
93  *
94  * FIXME
95  *   
96  */
97
98 DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
99                               SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
100                               UINT32 flags )
101 {       CHAR            szTemp[MAX_PATH];
102         LPPIDLDATA      pData;
103         LPITEMIDLIST    pPidlTemp = NULL;
104         DWORD           ret=0;
105   
106         TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
107               path,dwFileAttributes,psfi,sizeofpsfi,flags);
108
109         /* translate the pidl to a path*/
110         if (flags & SHGFI_PIDL)
111         { pPidlTemp = (LPCITEMIDLIST)path;
112           SHGetPathFromIDList32A (pPidlTemp, szTemp);
113           TRACE(shell,"pidl=%p is %s\n", path, szTemp);
114         }
115         else
116         { strcpy(szTemp,path);
117           TRACE(shell,"path=%s\n", szTemp);
118         }
119
120         if (flags & SHGFI_ATTRIBUTES)
121         { if (flags & SHGFI_PIDL)
122           { pData = _ILGetDataPointer((LPCITEMIDLIST)path);
123             psfi->dwAttributes = pData->u.generic.dwSFGAO; /* fixme: no direct access*/
124             ret=TRUE;
125           }
126           else
127           { psfi->dwAttributes=SFGAO_FILESYSTEM;
128             ret=TRUE;
129           }
130           FIXME(shell,"file attributes, stub\n");           
131         }
132
133         if (flags & SHGFI_DISPLAYNAME)
134         { if (flags & SHGFI_PIDL)
135           { strcpy(psfi->szDisplayName,szTemp);
136           }
137           else
138           { strcpy(psfi->szDisplayName,path);
139           }
140           TRACE(shell,"displayname=%s\n", psfi->szDisplayName);   
141           ret=TRUE;
142         }
143   
144         if (flags & SHGFI_TYPENAME)
145         { FIXME(shell,"get the file type, stub\n");
146           strcpy(psfi->szTypeName,"FIXME: Type");
147           ret=TRUE;
148         }
149   
150   if (flags & SHGFI_ICONLOCATION)
151   { FIXME(shell,"location of icon, stub\n");
152     strcpy(psfi->szDisplayName,"");
153     ret=TRUE;
154   }
155
156   if (flags & SHGFI_EXETYPE)
157     FIXME(shell,"type of executable, stub\n");
158
159   if (flags & SHGFI_LINKOVERLAY)
160     FIXME(shell,"set icon to link, stub\n");
161
162   if (flags & SHGFI_OPENICON)
163     FIXME(shell,"set to open icon, stub\n");
164
165   if (flags & SHGFI_SELECTED)
166     FIXME(shell,"set icon to selected, stub\n");
167
168   if (flags & SHGFI_SHELLICONSIZE)
169     FIXME(shell,"set icon to shell size, stub\n");
170
171   if (flags & SHGFI_USEFILEATTRIBUTES)
172     FIXME(shell,"use the dwFileAttributes, stub\n");
173  
174   if (flags & SHGFI_ICON)
175   { FIXME(shell,"icon handle\n");
176     if (flags & SHGFI_SMALLICON)
177      { TRACE(shell,"set to small icon\n"); 
178        psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL);
179        ret = (DWORD) ShellSmallIconList;
180      }
181      else
182      { TRACE(shell,"set to big icon\n");
183        psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL);
184        ret = (DWORD) ShellBigIconList;
185      }      
186   }
187
188         if (flags & SHGFI_SYSICONINDEX)
189         { if (!pPidlTemp)
190           { pPidlTemp = ILCreateFromPath (szTemp);
191           }
192           psfi->iIcon = SHMapPIDLToSystemImageListIndex (NULL, pPidlTemp, 0);
193           TRACE(shell,"-- SYSICONINDEX %i\n", psfi->iIcon);
194
195           if (flags & SHGFI_SMALLICON)
196           { TRACE(shell,"set to small icon\n"); 
197             ret = (DWORD) ShellSmallIconList;
198           }
199           else        
200           { TRACE(shell,"set to big icon\n");
201             ret = (DWORD) ShellBigIconList;
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   } else {
381     lpclf = IClassFactory_Constructor();
382     /* fixme: the buildin IClassFactory_Constructor is at the moment only 
383                 for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/
384     if(lpclf) {
385       hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
386       IClassFactory_Release(lpclf);
387           }  
388   }
389         
390   if (pdesktopfolder) {
391     *shellfolder = pdesktopfolder;
392     pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder);
393   } else {
394     *shellfolder=NULL;
395         }
396
397   TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
398         return hres;
399 }
400
401 /*************************************************************************
402  *                       SHGetPathFromIDList            [SHELL32.221][NT 4.0: SHELL32.219]
403  */
404 BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath)     
405 { TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
406   return SHGetPathFromIDList32A(pidl,pszPath);
407 }
408
409 /*************************************************************************
410  *                       SHGetSpecialFolderLocation     [SHELL32.223]
411  * gets the folder locations from the registry and creates a pidl
412  * creates missing reg keys and directorys
413  * 
414  * PARAMS
415  *   hwndOwner [I]
416  *   nFolder   [I] CSIDL_xxxxx
417  *   ppidl     [O] PIDL of a special folder
418  *
419  * RETURNS
420  *    HResult
421  *
422  * FIXME
423  *   - look for "User Shell Folder" first
424  *
425  */
426 HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl)
427 { LPSHELLFOLDER shellfolder;
428   DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res;
429   CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH];
430   LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
431   HKEY key;
432
433         enum 
434         { FT_UNKNOWN= 0x00000000,
435           FT_DIR=     0x00000001, 
436           FT_DESKTOP= 0x00000002,
437           FT_SPECIAL= 0x00000003
438         } tFolder; 
439
440         TRACE(shell,"(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
441
442         strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
443
444         res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
445         if (res)
446         { ERR(shell,"Could not create key %s %08lx \n",buffer,res);
447           return E_OUTOFMEMORY;
448         }
449
450         tFolder=FT_DIR; 
451         switch (nFolder)
452         { case CSIDL_BITBUCKET:
453             strcpy (buffer,"xxx");                      /*not in the registry*/
454             TRACE (shell,"looking for Recycler\n");
455             tFolder=FT_UNKNOWN;
456             break;
457           case CSIDL_CONTROLS:
458             strcpy (buffer,"xxx");                      /*virtual folder*/
459             TRACE (shell,"looking for Control\n");
460             tFolder=FT_UNKNOWN;
461             break;
462           case CSIDL_DESKTOP:
463             strcpy (buffer,"xxx");                      /*virtual folder*/
464             TRACE (shell,"looking for Desktop\n");
465             tFolder=FT_DESKTOP;                 
466             break;
467           case CSIDL_DESKTOPDIRECTORY:
468           case CSIDL_COMMON_DESKTOPDIRECTORY:
469             strcpy (buffer,"Desktop");
470             break;
471           case CSIDL_DRIVES:
472             strcpy (buffer,"xxx");                      /*virtual folder*/
473             TRACE (shell,"looking for Drives\n");
474             tFolder=FT_SPECIAL;
475             break;
476           case CSIDL_FONTS:
477             strcpy (buffer,"Fonts");                    
478             break;
479           case CSIDL_NETHOOD:
480             strcpy (buffer,"NetHood");                  
481             break;
482           case CSIDL_PRINTHOOD:
483             strcpy (buffer,"PrintHood");                        
484             break;
485           case CSIDL_NETWORK:
486             strcpy (buffer,"xxx");                              /*virtual folder*/
487             TRACE (shell,"looking for Network\n");
488             tFolder=FT_UNKNOWN;
489             break;
490           case CSIDL_APPDATA:
491             strcpy (buffer,"Appdata");                  
492             break;
493           case CSIDL_PERSONAL:
494             strcpy (buffer,"Personal");                 
495             break;
496           case CSIDL_FAVORITES:
497             strcpy (buffer,"Favorites");                        
498             break;
499           case CSIDL_PRINTERS:
500             strcpy (buffer,"PrintHood");
501             break;
502           case CSIDL_COMMON_PROGRAMS:
503           case CSIDL_PROGRAMS:
504             strcpy (buffer,"Programs");                 
505             break;
506           case CSIDL_RECENT:
507             strcpy (buffer,"Recent");
508             break;
509           case CSIDL_SENDTO:
510             strcpy (buffer,"SendTo");
511             break;
512           case CSIDL_COMMON_STARTMENU:
513           case CSIDL_STARTMENU:
514             strcpy (buffer,"Start Menu");
515             break;
516           case CSIDL_COMMON_STARTUP:  
517           case CSIDL_STARTUP:
518             strcpy (buffer,"Startup");                  
519             break;
520           case CSIDL_TEMPLATES:
521             strcpy (buffer,"Templates");                        
522             break;
523           default:
524             ERR (shell,"unknown CSIDL 0x%08x\n", nFolder);
525             tFolder=FT_UNKNOWN;                 
526             break;
527         }
528
529         TRACE(shell,"Key=%s\n",buffer);
530
531         type=REG_SZ;
532
533         switch (tFolder)
534         { case FT_DIR:
535             /* Directory: get the value from the registry, if its not there 
536                         create it and the directory*/
537             if (RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
538             { GetWindowsDirectory32A(npath,MAX_PATH);
539               PathAddBackslash32A(npath);
540               switch (nFolder)
541               { case CSIDL_DESKTOPDIRECTORY:
542                 case CSIDL_COMMON_DESKTOPDIRECTORY:
543                   strcat (npath,"Desktop");
544                   break;
545                 case CSIDL_FONTS:
546                   strcat (npath,"Fonts");                       
547                   break;
548                 case CSIDL_NETHOOD:
549                   strcat (npath,"NetHood");                     
550                   break;
551                 case CSIDL_PRINTHOOD:
552                   strcat (npath,"PrintHood");                   
553                   break;
554                 case CSIDL_APPDATA:
555                   strcat (npath,"Appdata");                     
556                   break;
557                 case CSIDL_PERSONAL:
558                   strcpy (npath,"C:\\Personal");                        
559                   break;
560                 case CSIDL_FAVORITES:
561                   strcat (npath,"Favorites");                   
562                   break;
563                 case CSIDL_PRINTERS:
564                   strcat (npath,"PrintHood");                   
565                   break;
566                 case CSIDL_COMMON_PROGRAMS:
567                 case CSIDL_PROGRAMS:
568                   strcat (npath,"Start Menu");                  
569                   CreateDirectory32A(npath,NULL);
570                   strcat (npath,"\\Programs");                  
571                   break;
572                 case CSIDL_RECENT:
573                   strcat (npath,"Recent");
574                   break;
575                 case CSIDL_SENDTO:
576                   strcat (npath,"SendTo");
577                   break;
578                 case CSIDL_COMMON_STARTMENU:
579                 case CSIDL_STARTMENU:
580                   strcat (npath,"Start Menu");
581                   break;
582                 case CSIDL_COMMON_STARTUP:  
583                 case CSIDL_STARTUP:
584                   strcat (npath,"Start Menu");                  
585                   CreateDirectory32A(npath,NULL);
586                   strcat (npath,"\\Startup");                   
587                   break;
588                 case CSIDL_TEMPLATES:
589                   strcat (npath,"Templates");                   
590                   break;
591                 default:
592                   RegCloseKey(key);
593                   return E_OUTOFMEMORY;
594               }
595               if (RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)npath,sizeof(npath)+1))
596               { ERR(shell,"could not create value %s\n",buffer);
597                 RegCloseKey(key);
598                 return E_OUTOFMEMORY;
599               }
600               TRACE(shell,"value %s=%s created\n",buffer,npath);
601               CreateDirectory32A(npath,NULL);
602               strcpy(tpath,npath);
603             }
604             break;
605           case FT_DESKTOP:
606             strcpy (tpath,"Desktop");
607             break;
608           case FT_SPECIAL:
609             if (nFolder==CSIDL_DRIVES)
610             strcpy (tpath,"My Computer");
611             break;
612           default:
613             RegCloseKey(key);
614             return E_OUTOFMEMORY;
615         }
616
617         RegCloseKey(key);
618
619         TRACE(shell,"Value=%s\n",tpath);
620         LocalToWideChar32(lpszDisplayName, tpath, 256);
621   
622         if (SHGetDesktopFolder(&shellfolder)==S_OK)
623         { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
624           shellfolder->lpvtbl->fnRelease(shellfolder);
625         }
626
627         TRACE(shell, "-- (new pidl %p)\n",*ppidl);
628         return NOERROR;
629 }
630 /*************************************************************************
631  * SHHelpShortcuts_RunDLL [SHELL32.224]
632  *
633  */
634 DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
635 { FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
636         dwArg1, dwArg2, dwArg3, dwArg4);
637
638   return 0;
639 }
640
641 /*************************************************************************
642  * SHLoadInProc [SHELL32.225]
643  *
644  */
645
646 DWORD WINAPI SHLoadInProc (DWORD dwArg1)
647 { FIXME (shell, "(%lx) empty stub!\n", dwArg1);
648     return 0;
649 }
650
651 /*************************************************************************
652  *             ShellExecute32A   (SHELL32.245)
653  */
654 HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
655                                     LPCSTR lpFile, LPCSTR lpParameters,
656                                     LPCSTR lpDirectory, INT32 iShowCmd )
657 {   TRACE(shell,"\n");
658     return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
659                            lpDirectory, iShowCmd );
660 }
661
662 /*************************************************************************
663  * ShellExecute32W [SHELL32.294]
664  * from shellapi.h
665  * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, 
666  * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);   
667  */
668 HINSTANCE32 WINAPI 
669 ShellExecute32W(
670        HWND32 hwnd, 
671        LPCWSTR lpOperation, 
672        LPCWSTR lpFile, 
673        LPCWSTR lpParameters, 
674        LPCWSTR lpDirectory, 
675        INT32 nShowCmd) {
676
677        FIXME(shell,": stub\n");
678        return 0;
679 }
680
681
682
683
684
685
686 /*************************************************************************
687  *             AboutDlgProc32  (not an exported API function)
688  */
689 BOOL32 WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam,
690                               LPARAM lParam )
691 {   HWND32 hWndCtl;
692     char Template[512], AppTitle[512];
693
694     TRACE(shell,"\n");
695
696     switch(msg)
697     { case WM_INITDIALOG:
698       { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
699             if (info)
700         { const char* const *pstr = SHELL_People;
701                 SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
702                 GetWindowText32A( hWnd, Template, sizeof(Template) );
703                 sprintf( AppTitle, Template, info->szApp );
704                 SetWindowText32A( hWnd, AppTitle );
705                 SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT),
706                                   info->szOtherStuff );
707                 hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
708                 SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 );
709                 SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
710                 while (*pstr)
711           { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr );
712                     pstr++;
713                 }
714                 SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 );
715             }
716         }
717         return 1;
718
719     case WM_PAINT:
720       { RECT32 rect;
721             PAINTSTRUCT32 ps;
722             HDC32 hDC = BeginPaint32( hWnd, &ps );
723
724             if( __get_dropline( hWnd, &rect ) ) {
725                 SelectObject32( hDC, GetStockObject32( BLACK_PEN ) );
726                 MoveToEx32( hDC, rect.left, rect.top, NULL );
727                 LineTo32( hDC, rect.right, rect.bottom );
728             }
729             EndPaint32( hWnd, &ps );
730         }
731         break;
732
733     case WM_LBTRACKPOINT:
734         hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
735         if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
736       { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) )
737         { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 );
738                 if( idx != -1 )
739           { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 );
740                     HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
741                     char* pstr = (char*)GlobalLock16( hMemObj );
742
743                     if( pstr )
744             { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
745                         SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
746                         SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
747                         UpdateWindow32( hWndCtl );
748                         if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
749                             SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr );
750                     }
751             if( hMemObj )
752               GlobalFree16( hMemObj );
753                 }
754             }
755         }
756         break;
757
758     case WM_QUERYDROPOBJECT:
759         if( wParam == 0 )
760       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
761             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
762         { RECT32 rect;
763                 if( __get_dropline( hWnd, &rect ) )
764           { POINT32 pt;
765             pt.x=lpDragInfo->pt.x;
766             pt.x=lpDragInfo->pt.y;
767                     rect.bottom += DROP_FIELD_HEIGHT;
768                     if( PtInRect32( &rect, pt ) )
769             { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
770                         return TRUE;
771                     }
772                 }
773             }
774         }
775         break;
776
777     case WM_DROPOBJECT:
778         if( wParam == hWnd )
779       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
780             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
781         { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
782                 if( pstr )
783           { static char __appendix_str[] = " with";
784
785                     hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT );
786                     SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
787                     if( !lstrncmp32A( Template, "WINE", 4 ) )
788                         SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template );
789                     else
790           { char* pch = Template + strlen(Template) - strlen(__appendix_str);
791                         *pch = '\0';
792                         SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, 
793                                         (WPARAM32)-1, (LPARAM)Template );
794                     }
795
796                     lstrcpy32A( Template, pstr );
797                     lstrcat32A( Template, __appendix_str );
798                     SetWindowText32A( hWndCtl, Template );
799                     SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
800                     return TRUE;
801                 }
802             }
803         }
804         break;
805
806     case WM_COMMAND:
807         if (wParam == IDOK)
808     {  EndDialog32(hWnd, TRUE);
809             return TRUE;
810         }
811         break;
812     }
813     return 0;
814 }
815
816
817 /*************************************************************************
818  *             ShellAbout32A   (SHELL32.243)
819  */
820 BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
821                              HICON32 hIcon )
822 {   ABOUT_INFO info;
823     TRACE(shell,"\n");
824     info.szApp        = szApp;
825     info.szOtherStuff = szOtherStuff;
826     info.hIcon        = hIcon;
827     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
828     return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
829                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
830                                       hWnd, AboutDlgProc32, (LPARAM)&info );
831 }
832
833
834 /*************************************************************************
835  *             ShellAbout32W   (SHELL32.244)
836  */
837 BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
838                              HICON32 hIcon )
839 {   BOOL32 ret;
840     ABOUT_INFO info;
841
842     TRACE(shell,"\n");
843     
844     info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
845     info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
846     info.hIcon        = hIcon;
847     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
848     ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
849                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
850                                       hWnd, AboutDlgProc32, (LPARAM)&info );
851     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
852     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
853     return ret;
854 }
855
856 /*************************************************************************
857  *                              Shell_NotifyIcon        [SHELL32.296]
858  *      FIXME
859  *      This function is supposed to deal with the systray.
860  *      Any ideas on how this is to be implimented?
861  */
862 BOOL32 WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid )
863 {   TRACE(shell,"\n");
864     return FALSE;
865 }
866
867 /*************************************************************************
868  *                              Shell_NotifyIcon        [SHELL32.297]
869  *      FIXME
870  *      This function is supposed to deal with the systray.
871  *      Any ideas on how this is to be implimented?
872  */
873 BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATA pnid )
874 {   TRACE(shell,"\n");
875     return FALSE;
876 }
877
878 /*************************************************************************
879  * FreeIconList
880  */
881 void WINAPI FreeIconList( DWORD dw )
882 { FIXME(shell, "(%lx): stub\n",dw);
883 }
884
885 /*************************************************************************
886  * SHGetPathFromIDList32A        [SHELL32.261][NT 4.0: SHELL32.220]
887  *
888  * PARAMETERS
889  *  pidl,   [IN] pidl 
890  *  pszPath [OUT] path
891  *
892  * RETURNS 
893  *  path from a passed PIDL.
894  *
895  * NOTES
896  *     exported by name
897  *
898  * FIXME
899  *  fnGetDisplayNameOf can return different types of OLEString
900  */
901 DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath)
902 {       STRRET lpName;
903         LPSHELLFOLDER shellfolder;
904         CHAR  buffer[MAX_PATH],tpath[MAX_PATH];
905         DWORD type,tpathlen=MAX_PATH,dwdisp;
906         HKEY  key;
907
908         TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
909
910   if (!pidl)
911   {  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
912
913      if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
914      { return E_OUTOFMEMORY;
915      }
916      type=REG_SZ;    
917      strcpy (buffer,"Desktop");                                 /*registry name*/
918      if ( RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
919      { GetWindowsDirectory32A(tpath,MAX_PATH);
920        PathAddBackslash32A(tpath);
921        strcat (tpath,"Desktop");                                /*folder name*/
922        RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)tpath,tpathlen);
923        CreateDirectory32A(tpath,NULL);
924      }
925      RegCloseKey(key);
926      strcpy(pszPath,tpath);
927   }
928   else
929   { if (SHGetDesktopFolder(&shellfolder)==S_OK)
930         { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
931           shellfolder->lpvtbl->fnRelease(shellfolder);
932         }
933   /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/
934         strcpy(pszPath,lpName.u.cStr);
935         /* fixme free the olestring*/
936   }
937         TRACE(shell,"-- (%s)\n",pszPath);
938         return NOERROR;
939 }
940 /*************************************************************************
941  * SHGetPathFromIDList32W [SHELL32.262]
942  */
943 DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath)
944 {       char sTemp[MAX_PATH];
945
946         TRACE (shell,"(pidl=%p)\n", pidl);
947
948         SHGetPathFromIDList32A (pidl, sTemp);
949         lstrcpyAtoW(pszPath, sTemp);
950
951         TRACE(shell,"-- (%s)\n",debugstr_w(pszPath));
952
953         return NOERROR;
954 }
955
956 /*************************************************************************
957  * global variables of the shell32.dll
958  *
959  */
960 void    (WINAPI* pDLLInitComctl)(LPVOID);
961 INT32   (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon);
962 INT32   (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32);
963 HIMAGELIST (WINAPI * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32);
964 HICON32 (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32);
965 INT32   (WINAPI* pImageList_GetImageCount)(HIMAGELIST);
966
967 LPVOID  (WINAPI* pCOMCTL32_Alloc) (INT32);  
968 BOOL32  (WINAPI* pCOMCTL32_Free) (LPVOID);  
969
970 HDPA    (WINAPI* pDPA_Create) (INT32);  
971 INT32   (WINAPI* pDPA_InsertPtr) (const HDPA, INT32, LPVOID); 
972 BOOL32  (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); 
973 LPVOID  (WINAPI* pDPA_GetPtr) (const HDPA, INT32);   
974 BOOL32  (WINAPI* pDPA_Destroy) (const HDPA); 
975 INT32   (WINAPI *pDPA_Search) (const HDPA, LPVOID, INT32, PFNDPACOMPARE, LPARAM, UINT32);
976
977 /* user32 */
978 HICON32* (WINAPI *pLookupIconIdFromDirectoryEx32)(LPBYTE dir, BOOL32 bIcon, INT32 width, INT32 height, UINT32 cFlag);
979 HICON32* (WINAPI *pCreateIconFromResourceEx32)(LPBYTE bits,UINT32 cbSize, BOOL32 bIcon, DWORD dwVersion, INT32 width, INT32 height,UINT32 cFlag);
980
981 static BOOL32           bShell32IsInitialized = 0;
982 static HINSTANCE32      hComctl32;
983 static INT32            shell32_RefCount = 0;
984
985 INT32           shell32_ObjCount = 0;
986 HINSTANCE32     shell32_hInstance; 
987 /*************************************************************************
988  * SHELL32 LibMain
989  *
990  */
991
992 BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
993 {       HMODULE32 hUser32;
994
995         TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
996
997         shell32_hInstance = hinstDLL;
998   
999         switch (fdwReason)
1000         { case DLL_PROCESS_ATTACH:
1001             if (!bShell32IsInitialized)
1002             { hComctl32 = LoadLibrary32A("COMCTL32.DLL");       
1003               hUser32 = GetModuleHandle32A("USER32");
1004               if (hComctl32 && hUser32)
1005               { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx");
1006                 if (pDLLInitComctl)
1007                 { pDLLInitComctl(NULL);
1008                 }
1009                 pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create");
1010                 pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon");
1011                 pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon");
1012                 pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon");
1013                 pImageList_GetImageCount=GetProcAddress32(hComctl32,"ImageList_GetImageCount");
1014
1015                 /* imports by ordinal, pray that it works*/
1016                 pCOMCTL32_Alloc=GetProcAddress32(hComctl32, (LPCSTR)71L);
1017                 pCOMCTL32_Free=GetProcAddress32(hComctl32, (LPCSTR)73L);
1018                 pDPA_Create=GetProcAddress32(hComctl32, (LPCSTR)328L);
1019                 pDPA_Destroy=GetProcAddress32(hComctl32, (LPCSTR)329L);
1020                 pDPA_GetPtr=GetProcAddress32(hComctl32, (LPCSTR)332L);
1021                 pDPA_InsertPtr=GetProcAddress32(hComctl32, (LPCSTR)334L);
1022                 pDPA_Sort=GetProcAddress32(hComctl32, (LPCSTR)338L);
1023                 pDPA_Search=GetProcAddress32(hComctl32, (LPCSTR)339L);
1024                 /* user32 */
1025                 pLookupIconIdFromDirectoryEx32=GetProcAddress32(hUser32,"LookupIconIdFromDirectoryEx");
1026                 pCreateIconFromResourceEx32=GetProcAddress32(hUser32,"CreateIconFromResourceEx");
1027               }
1028               else
1029               { ERR(shell,"P A N I C SHELL32 loading failed\n");
1030                 return FALSE;
1031               }
1032               SIC_Initialize();
1033               bShell32IsInitialized = TRUE;
1034             }
1035             shell32_RefCount++;
1036             break;
1037
1038           case DLL_THREAD_ATTACH:
1039             shell32_RefCount++;
1040             break;
1041
1042           case DLL_THREAD_DETACH:
1043             shell32_RefCount--;
1044             break;
1045
1046           case DLL_PROCESS_DETACH:
1047             shell32_RefCount--;
1048             if ( !shell32_RefCount )
1049             { FreeLibrary32(hComctl32);
1050               bShell32IsInitialized = FALSE;
1051
1052               if (pdesktopfolder) 
1053               { pdesktopfolder->lpvtbl->fnRelease(pdesktopfolder);
1054               }
1055
1056               /* this one is here ot check if AddRef/Release is balanced */
1057               if (shell32_ObjCount)
1058               { FIXME(shell,"%u objects left\n", shell32_ObjCount);
1059               }
1060             }
1061             TRACE(shell, "refcount=%u objcount=%u \n", shell32_RefCount, shell32_ObjCount);
1062             break;            
1063         }
1064
1065         return TRUE;
1066 }