Built-in dlls now have resources attached via the PE-header like
[wine.git] / dlls / shell32 / shell32_main.c
blobc8023e34b10bd97dd95dba48ce8183b73fe398be
1 /*
2 * Shell basics
4 * 1998 Marcus Meissner
5 * 1998 Juergen Schmied (jsch) * <juergen.schmied@metronet.de>
6 */
7 #include <stdlib.h>
8 #include <string.h>
10 #include "wine/winuser16.h"
11 #include "winerror.h"
12 #include "heap.h"
13 #include "resource.h"
14 #include "dlgs.h"
15 #include "win.h"
16 #include "sysmetrics.h"
17 #include "debug.h"
18 #include "winreg.h"
19 #include "authors.h"
20 #include "winversion.h"
22 #include "shellapi.h"
23 #include "pidl.h"
24 #include "shlobj.h"
25 #include "shell32_main.h"
27 #include "shlguid.h"
29 DECLARE_DEBUG_CHANNEL(exec)
30 DECLARE_DEBUG_CHANNEL(shell)
32 /*************************************************************************
33 * CommandLineToArgvW [SHELL32.7]
35 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
36 { LPWSTR *argv,s,t;
37 int i;
38 TRACE(shell,"\n");
40 /* to get writeable copy */
41 cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
42 s=cmdline;i=0;
43 while (*s)
44 { /* space */
45 if (*s==0x0020)
46 { i++;
47 s++;
48 while (*s && *s==0x0020)
49 s++;
50 continue;
52 s++;
54 argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
55 s=t=cmdline;
56 i=0;
57 while (*s)
58 { if (*s==0x0020)
59 { *s=0;
60 argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
61 *s=0x0020;
62 while (*s && *s==0x0020)
63 s++;
64 if (*s)
65 t=s+1;
66 else
67 t=s;
68 continue;
70 s++;
72 if (*t)
73 argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
75 HeapFree( GetProcessHeap(), 0, cmdline );
76 argv[i]=NULL;
77 *numargs=i;
78 return argv;
81 /*************************************************************************
82 * Control_RunDLL [SHELL32.12]
84 * Wild speculation in the following!
86 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
89 void WINAPI Control_RunDLL( HWND hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
91 FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
92 debugstr_a(cmd), arg4);
95 /*************************************************************************
96 * SHGetFileInfoA [SHELL32.254]
99 DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes,
100 SHFILEINFOA *psfi, UINT sizeofpsfi,
101 UINT flags )
102 { CHAR szTemp[MAX_PATH];
103 LPPIDLDATA pData;
104 LPITEMIDLIST pPidlTemp = NULL;
105 DWORD ret=0, dwfa = dwFileAttributes;
107 TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
108 path,dwFileAttributes,psfi,sizeofpsfi,flags);
110 /* translate the pidl to a path*/
111 if (flags & SHGFI_PIDL)
112 { pPidlTemp = (LPCITEMIDLIST)path;
113 SHGetPathFromIDListA (pPidlTemp, szTemp);
114 TRACE(shell,"pidl=%p is %s\n", path, szTemp);
116 else
117 { strcpy(szTemp,path);
118 TRACE(shell,"path=%s\n", szTemp);
121 if (flags & SHGFI_ATTRIBUTES)
122 { if (flags & SHGFI_PIDL)
125 * We have to test for the desktop folder first because ILGetDataPointer returns
126 * NULL on the desktop folder.
128 if (_ILIsDesktop((LPCITEMIDLIST)path))
129 { psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK;
130 ret = TRUE;
132 else
133 { pData = _ILGetDataPointer((LPCITEMIDLIST)path);
135 switch (pData->type)
136 { case PT_DESKTOP:
137 psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK;
138 case PT_MYCOMP:
139 psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
140 SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK ;
141 case PT_SPECIAL:
142 psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CAPABILITYMASK;
143 case PT_DRIVE:
144 psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
145 SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK;
146 case PT_FOLDER:
147 psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_CAPABILITYMASK;
148 case PT_VALUE:
149 psfi->dwAttributes = SFGAO_FILESYSTEM | SFGAO_CAPABILITYMASK;
151 ret=TRUE;
154 else
155 { if (! (flags & SHGFI_USEFILEATTRIBUTES))
156 dwfa = GetFileAttributesA (szTemp);
158 psfi->dwAttributes = SFGAO_FILESYSTEM;
159 if (dwfa == FILE_ATTRIBUTE_DIRECTORY)
160 psfi->dwAttributes |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
161 ret=TRUE;
163 WARN(shell,"file attributes, semi-stub\n");
166 if (flags & SHGFI_DISPLAYNAME)
167 { if (flags & SHGFI_PIDL)
168 { strcpy(psfi->szDisplayName,szTemp);
170 else
171 { strcpy(psfi->szDisplayName,path);
173 TRACE(shell,"displayname=%s\n", psfi->szDisplayName);
174 ret=TRUE;
177 if (flags & SHGFI_TYPENAME)
178 { FIXME(shell,"get the file type, stub\n");
179 strcpy(psfi->szTypeName,"FIXME: Type");
180 ret=TRUE;
183 if (flags & SHGFI_ICONLOCATION)
184 { FIXME(shell,"location of icon, stub\n");
185 strcpy(psfi->szDisplayName,"");
186 ret=TRUE;
189 if (flags & SHGFI_EXETYPE)
190 FIXME(shell,"type of executable, stub\n");
192 if (flags & SHGFI_LINKOVERLAY)
193 FIXME(shell,"set icon to link, stub\n");
195 if (flags & SHGFI_OPENICON)
196 FIXME(shell,"set to open icon, stub\n");
198 if (flags & SHGFI_SELECTED)
199 FIXME(shell,"set icon to selected, stub\n");
201 if (flags & SHGFI_SHELLICONSIZE)
202 FIXME(shell,"set icon to shell size, stub\n");
204 if (flags & SHGFI_USEFILEATTRIBUTES)
205 FIXME(shell,"use the dwFileAttributes, stub\n");
207 if (flags & (SHGFI_UNKNOWN1 | SHGFI_UNKNOWN2 | SHGFI_UNKNOWN3))
208 FIXME(shell,"unknown attribute!\n");
210 if (flags & SHGFI_ICON)
211 { FIXME(shell,"icon handle\n");
212 if (flags & SHGFI_SMALLICON)
213 { TRACE(shell,"set to small icon\n");
214 psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL);
215 ret = (DWORD) ShellSmallIconList;
217 else
218 { TRACE(shell,"set to big icon\n");
219 psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL);
220 ret = (DWORD) ShellBigIconList;
224 if (flags & SHGFI_SYSICONINDEX)
225 { IShellFolder * sf;
226 if (!pPidlTemp)
227 { pPidlTemp = ILCreateFromPathA (szTemp);
229 if (SUCCEEDED (SHGetDesktopFolder (&sf)))
230 { psfi->iIcon = SHMapPIDLToSystemImageListIndex (sf, pPidlTemp, 0);
231 IShellFolder_Release(sf);
233 TRACE(shell,"-- SYSICONINDEX %i\n", psfi->iIcon);
235 if (flags & SHGFI_SMALLICON)
236 { TRACE(shell,"set to small icon\n");
237 ret = (DWORD) ShellSmallIconList;
239 else
240 { TRACE(shell,"set to big icon\n");
241 ret = (DWORD) ShellBigIconList;
245 return ret;
248 /*************************************************************************
249 * SHGetFileInfoW [SHELL32.255]
252 DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
253 SHFILEINFOW *psfi, UINT sizeofpsfi,
254 UINT flags )
255 { FIXME(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
256 debugstr_w(path),dwFileAttributes,psfi,sizeofpsfi,flags);
257 return 0;
260 /*************************************************************************
261 * ExtractIconA [SHELL32.133]
263 HICON WINAPI ExtractIconA( HINSTANCE hInstance, LPCSTR lpszExeFileName,
264 UINT nIconIndex )
265 { HGLOBAL16 handle = InternalExtractIcon16(hInstance,lpszExeFileName,nIconIndex, 1);
266 TRACE(shell,"\n");
267 if( handle )
269 HICON16* ptr = (HICON16*)GlobalLock16(handle);
270 HICON16 hIcon = *ptr;
272 GlobalFree16(handle);
273 return hIcon;
275 return 0;
278 /*************************************************************************
279 * ExtractIconW [SHELL32.180]
281 HICON WINAPI ExtractIconW( HINSTANCE hInstance, LPCWSTR lpszExeFileName,
282 UINT nIconIndex )
283 { LPSTR exefn;
284 HICON ret;
285 TRACE(shell,"\n");
287 exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
288 ret = ExtractIconA(hInstance,exefn,nIconIndex);
290 HeapFree(GetProcessHeap(),0,exefn);
291 return ret;
294 /*************************************************************************
295 * FindExecutableA [SHELL32.184]
297 HINSTANCE WINAPI FindExecutableA( LPCSTR lpFile, LPCSTR lpDirectory,
298 LPSTR lpResult )
299 { HINSTANCE retval=31; /* default - 'No association was found' */
300 char old_dir[1024];
302 TRACE(shell, "File %s, Dir %s\n",
303 (lpFile != NULL?lpFile:"-"),
304 (lpDirectory != NULL?lpDirectory:"-"));
306 lpResult[0]='\0'; /* Start off with an empty return string */
308 /* trap NULL parameters on entry */
309 if (( lpFile == NULL ) || ( lpResult == NULL ))
310 { /* FIXME - should throw a warning, perhaps! */
311 return 2; /* File not found. Close enough, I guess. */
314 if (lpDirectory)
315 { GetCurrentDirectoryA( sizeof(old_dir), old_dir );
316 SetCurrentDirectoryA( lpDirectory );
319 retval = SHELL_FindExecutable( lpFile, "open", lpResult );
321 TRACE(shell, "returning %s\n", lpResult);
322 if (lpDirectory)
323 SetCurrentDirectoryA( old_dir );
324 return retval;
327 /*************************************************************************
328 * FindExecutableW [SHELL32.219]
330 HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory,
331 LPWSTR lpResult)
333 FIXME(shell, "(%p,%p,%p): stub\n", lpFile, lpDirectory, lpResult);
334 return 31; /* default - 'No association was found' */
337 typedef struct
338 { LPCSTR szApp;
339 LPCSTR szOtherStuff;
340 HICON hIcon;
341 } ABOUT_INFO;
343 #define IDC_STATIC_TEXT 100
344 #define IDC_LISTBOX 99
345 #define IDC_WINE_TEXT 98
347 #define DROP_FIELD_TOP (-15)
348 #define DROP_FIELD_HEIGHT 15
350 extern HICON hIconTitleFont;
352 static BOOL __get_dropline( HWND hWnd, LPRECT lprect )
353 { HWND hWndCtl = GetDlgItem(hWnd, IDC_WINE_TEXT);
354 if( hWndCtl )
355 { GetWindowRect( hWndCtl, lprect );
356 MapWindowPoints( 0, hWnd, (LPPOINT)lprect, 2 );
357 lprect->bottom = (lprect->top += DROP_FIELD_TOP);
358 return TRUE;
360 return FALSE;
363 /*************************************************************************
364 * SHAppBarMessage32 [SHELL32.207]
366 UINT WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
368 FIXME(shell,"(0x%08lx,%p hwnd=0x%08x): stub\n", msg, data, data->hWnd);
370 switch (msg)
371 { case ABM_GETSTATE:
372 return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
373 case ABM_GETTASKBARPOS:
374 /* fake a taskbar on the bottom of the desktop */
375 { RECT rec;
376 GetWindowRect(GetDesktopWindow(), &rec);
377 rec.left = 0;
378 rec.top = rec.bottom - 2;
380 return TRUE;
381 case ABM_ACTIVATE:
382 case ABM_GETAUTOHIDEBAR:
383 case ABM_NEW:
384 case ABM_QUERYPOS:
385 case ABM_REMOVE:
386 case ABM_SETAUTOHIDEBAR:
387 case ABM_SETPOS:
388 case ABM_WINDOWPOSCHANGED:
389 return FALSE;
391 return 0;
395 /*************************************************************************
396 * SHGetDesktopFolder [SHELL32.216]
398 * SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
399 * CLSID_ShellDesktop
400 * CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf);
402 * RETURNS
403 * the interface to the shell desktop folder.
405 * FIXME
406 * the pdesktopfolder has to be released at the end (at dll unloading???)
408 LPSHELLFOLDER pdesktopfolder=NULL;
410 DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder)
411 { HRESULT hres = E_OUTOFMEMORY;
412 LPCLASSFACTORY lpclf;
413 TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder);
415 if (pdesktopfolder)
416 { hres = NOERROR;
418 else
419 { lpclf = IClassFactory_Constructor();
420 if(lpclf)
421 { hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
422 IClassFactory_Release(lpclf);
426 if (pdesktopfolder)
427 { *shellfolder = pdesktopfolder;
428 IShellFolder_AddRef(pdesktopfolder);
430 else
431 { *shellfolder=NULL;
434 TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
435 return hres;
438 /*************************************************************************
439 * SHGetSpecialFolderLocation [SHELL32.223]
441 * gets the folder locations from the registry and creates a pidl
442 * creates missing reg keys and directorys
444 * PARAMS
445 * hwndOwner [I]
446 * nFolder [I] CSIDL_xxxxx
447 * ppidl [O] PIDL of a special folder
449 * RETURNS
450 * HResult
452 * FIXME
453 * - look for "User Shell Folder" first
456 HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST * ppidl)
457 { LPSHELLFOLDER shellfolder;
458 DWORD pchEaten, tpathlen=MAX_PATH, type, dwdisp, res, dwLastError;
459 CHAR pszTemp[256], buffer[256], tpath[MAX_PATH], npath[MAX_PATH];
460 LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
461 HKEY key;
463 enum
464 { FT_UNKNOWN= 0x00000000,
465 FT_DIR= 0x00000001,
466 FT_DESKTOP= 0x00000002,
467 FT_SPECIAL= 0x00000003
468 } tFolder;
470 TRACE(shell,"(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
472 strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
474 res=RegCreateKeyExA(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
475 if (res)
476 { ERR(shell,"Could not create key %s %08lx \n",buffer,res);
477 return E_OUTOFMEMORY;
480 tFolder=FT_DIR;
481 switch (nFolder)
482 { case CSIDL_BITBUCKET:
483 strcpy (buffer,"xxx"); /*not in the registry*/
484 TRACE (shell,"looking for Recycler\n");
485 tFolder=FT_UNKNOWN;
486 break;
487 case CSIDL_CONTROLS:
488 strcpy (buffer,"xxx"); /*virtual folder*/
489 TRACE (shell,"looking for Control\n");
490 tFolder=FT_UNKNOWN;
491 break;
492 case CSIDL_DESKTOP:
493 strcpy (buffer,"xxx"); /*virtual folder*/
494 TRACE (shell,"looking for Desktop\n");
495 tFolder=FT_DESKTOP;
496 break;
497 case CSIDL_DESKTOPDIRECTORY:
498 case CSIDL_COMMON_DESKTOPDIRECTORY:
499 strcpy (buffer,"Desktop");
500 break;
501 case CSIDL_DRIVES:
502 strcpy (buffer,"xxx"); /*virtual folder*/
503 TRACE (shell,"looking for Drives\n");
504 tFolder=FT_SPECIAL;
505 break;
506 case CSIDL_FONTS:
507 strcpy (buffer,"Fonts");
508 break;
509 case CSIDL_NETHOOD:
510 strcpy (buffer,"NetHood");
511 break;
512 case CSIDL_PRINTHOOD:
513 strcpy (buffer,"PrintHood");
514 break;
515 case CSIDL_NETWORK:
516 strcpy (buffer,"xxx"); /*virtual folder*/
517 TRACE (shell,"looking for Network\n");
518 tFolder=FT_UNKNOWN;
519 break;
520 case CSIDL_APPDATA:
521 strcpy (buffer,"Appdata");
522 break;
523 case CSIDL_PERSONAL:
524 strcpy (buffer,"Personal");
525 break;
526 case CSIDL_FAVORITES:
527 strcpy (buffer,"Favorites");
528 break;
529 case CSIDL_PRINTERS:
530 strcpy (buffer,"PrintHood");
531 break;
532 case CSIDL_COMMON_PROGRAMS:
533 case CSIDL_PROGRAMS:
534 strcpy (buffer,"Programs");
535 break;
536 case CSIDL_RECENT:
537 strcpy (buffer,"Recent");
538 break;
539 case CSIDL_SENDTO:
540 strcpy (buffer,"SendTo");
541 break;
542 case CSIDL_COMMON_STARTMENU:
543 case CSIDL_STARTMENU:
544 strcpy (buffer,"Start Menu");
545 break;
546 case CSIDL_COMMON_STARTUP:
547 case CSIDL_STARTUP:
548 strcpy (buffer,"Startup");
549 break;
550 case CSIDL_TEMPLATES:
551 strcpy (buffer,"Templates");
552 break;
553 case CSIDL_INTERNET_CACHE:
554 strcpy (buffer,"Cache");
555 break;
556 case CSIDL_HISTORY:
557 strcpy (buffer,"History");
558 break;
559 case CSIDL_COOKIES:
560 strcpy(buffer,"Cookies");
561 break;
562 default:
563 ERR (shell,"unknown CSIDL 0x%08x\n", nFolder);
564 tFolder=FT_UNKNOWN;
565 break;
568 TRACE(shell,"Key=%s\n",buffer);
570 type=REG_SZ;
572 switch (tFolder)
573 { case FT_DIR:
574 /* Directory: get the value from the registry, if its not there
575 create it and the directory*/
576 if (RegQueryValueExA(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
577 { GetWindowsDirectoryA(npath,MAX_PATH);
578 PathAddBackslashA(npath);
579 switch (nFolder)
580 { case CSIDL_DESKTOPDIRECTORY:
581 case CSIDL_COMMON_DESKTOPDIRECTORY:
582 strcat (npath,"Desktop");
583 break;
584 case CSIDL_FONTS:
585 strcat (npath,"Fonts");
586 break;
587 case CSIDL_NETHOOD:
588 strcat (npath,"NetHood");
589 break;
590 case CSIDL_PRINTHOOD:
591 strcat (npath,"PrintHood");
592 break;
593 case CSIDL_APPDATA:
594 strcat (npath,"Appdata");
595 break;
596 case CSIDL_PERSONAL:
597 strcpy (npath,"C:\\Personal");
598 break;
599 case CSIDL_FAVORITES:
600 strcat (npath,"Favorites");
601 break;
602 case CSIDL_PRINTERS:
603 strcat (npath,"PrintHood");
604 break;
605 case CSIDL_COMMON_PROGRAMS:
606 case CSIDL_PROGRAMS:
607 strcat (npath,"Start Menu");
608 CreateDirectoryA(npath,NULL);
609 strcat (npath,"\\Programs");
610 break;
611 case CSIDL_RECENT:
612 strcat (npath,"Recent");
613 break;
614 case CSIDL_SENDTO:
615 strcat (npath,"SendTo");
616 break;
617 case CSIDL_COMMON_STARTMENU:
618 case CSIDL_STARTMENU:
619 strcat (npath,"Start Menu");
620 break;
621 case CSIDL_COMMON_STARTUP:
622 case CSIDL_STARTUP:
623 strcat (npath,"Start Menu");
624 CreateDirectoryA(npath,NULL);
625 strcat (npath,"\\Startup");
626 break;
627 case CSIDL_TEMPLATES:
628 strcat (npath,"Templates");
629 break;
630 case CSIDL_INTERNET_CACHE:
631 strcat(npath,"Temporary Internet Files");
632 break;
633 case CSIDL_HISTORY:
634 strcat (npath,"History");
635 break;
636 case CSIDL_COOKIES:
637 strcat (npath,"Cookies");
638 break;
639 default:
640 RegCloseKey(key);
641 return E_OUTOFMEMORY;
643 if (RegSetValueExA(key,buffer,0,REG_SZ,(LPBYTE)npath,sizeof(npath)+1))
644 { ERR(shell,"could not create value %s\n",buffer);
645 RegCloseKey(key);
646 return E_OUTOFMEMORY;
648 TRACE(shell,"value %s=%s created\n",buffer,npath);
649 dwLastError = GetLastError();
650 CreateDirectoryA(npath,NULL);
651 SetLastError (dwLastError);
652 strcpy(tpath,npath);
654 break;
655 case FT_DESKTOP:
656 strcpy (tpath,"Desktop");
657 break;
658 case FT_SPECIAL:
659 if (nFolder==CSIDL_DRIVES)
660 strcpy (tpath,"My Computer");
661 break;
662 default:
663 RegCloseKey(key);
664 return E_OUTOFMEMORY;
667 RegCloseKey(key);
669 TRACE(shell,"Value=%s\n",tpath);
670 LocalToWideChar(lpszDisplayName, tpath, 256);
672 if (SHGetDesktopFolder(&shellfolder)==S_OK)
673 { IShellFolder_ParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
674 IShellFolder_Release(shellfolder);
677 TRACE(shell, "-- (new pidl %p)\n",*ppidl);
678 return NOERROR;
680 /*************************************************************************
681 * SHHelpShortcuts_RunDLL [SHELL32.224]
684 DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
685 { FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
686 dwArg1, dwArg2, dwArg3, dwArg4);
688 return 0;
691 /*************************************************************************
692 * SHLoadInProc [SHELL32.225]
696 DWORD WINAPI SHLoadInProc (DWORD dwArg1)
697 { FIXME (shell, "(%lx) empty stub!\n", dwArg1);
698 return 0;
701 /*************************************************************************
702 * ShellExecuteA [SHELL32.245]
704 HINSTANCE WINAPI ShellExecuteA( HWND hWnd, LPCSTR lpOperation,
705 LPCSTR lpFile, LPCSTR lpParameters,
706 LPCSTR lpDirectory, INT iShowCmd )
707 { TRACE(shell,"\n");
708 return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
709 lpDirectory, iShowCmd );
712 /*************************************************************************
713 * ShellExecuteW [SHELL32.294]
714 * from shellapi.h
715 * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation,
716 * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
718 HINSTANCE WINAPI
719 ShellExecuteW(
720 HWND hwnd,
721 LPCWSTR lpOperation,
722 LPCWSTR lpFile,
723 LPCWSTR lpParameters,
724 LPCWSTR lpDirectory,
725 INT nShowCmd) {
727 FIXME(shell,": stub\n");
728 return 0;
731 /*************************************************************************
732 * AboutDlgProc32 (internal)
734 BOOL WINAPI AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
735 LPARAM lParam )
736 { HWND hWndCtl;
737 char Template[512], AppTitle[512];
739 TRACE(shell,"\n");
741 switch(msg)
742 { case WM_INITDIALOG:
743 { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
744 if (info)
745 { const char* const *pstr = SHELL_People;
746 SendDlgItemMessageA(hWnd, stc1, STM_SETICON,info->hIcon, 0);
747 GetWindowTextA( hWnd, Template, sizeof(Template) );
748 sprintf( AppTitle, Template, info->szApp );
749 SetWindowTextA( hWnd, AppTitle );
750 SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT),
751 info->szOtherStuff );
752 hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX);
753 SendMessageA( hWndCtl, WM_SETREDRAW, 0, 0 );
754 SendMessageA( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
755 while (*pstr)
756 { SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)*pstr );
757 pstr++;
759 SendMessageA( hWndCtl, WM_SETREDRAW, 1, 0 );
762 return 1;
764 case WM_PAINT:
765 { RECT rect;
766 PAINTSTRUCT ps;
767 HDC hDC = BeginPaint( hWnd, &ps );
769 if( __get_dropline( hWnd, &rect ) ) {
770 SelectObject( hDC, GetStockObject( BLACK_PEN ) );
771 MoveToEx( hDC, rect.left, rect.top, NULL );
772 LineTo( hDC, rect.right, rect.bottom );
774 EndPaint( hWnd, &ps );
776 break;
778 case WM_LBTRACKPOINT:
779 hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX);
780 if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
781 { if( DragDetect( hWndCtl, *((LPPOINT)&lParam) ) )
782 { INT idx = SendMessageA( hWndCtl, LB_GETCURSEL, 0, 0 );
783 if( idx != -1 )
784 { INT length = SendMessageA( hWndCtl, LB_GETTEXTLEN, (WPARAM)idx, 0 );
785 HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
786 char* pstr = (char*)GlobalLock16( hMemObj );
788 if( pstr )
789 { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
790 SendMessageA( hWndCtl, LB_GETTEXT, (WPARAM)idx, (LPARAM)pstr );
791 SendMessageA( hWndCtl, LB_DELETESTRING, (WPARAM)idx, 0 );
792 UpdateWindow( hWndCtl );
793 if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
794 SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)pstr );
796 if( hMemObj )
797 GlobalFree16( hMemObj );
801 break;
803 case WM_QUERYDROPOBJECT:
804 if( wParam == 0 )
805 { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
806 if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
807 { RECT rect;
808 if( __get_dropline( hWnd, &rect ) )
809 { POINT pt;
810 pt.x=lpDragInfo->pt.x;
811 pt.x=lpDragInfo->pt.y;
812 rect.bottom += DROP_FIELD_HEIGHT;
813 if( PtInRect( &rect, pt ) )
814 { SetWindowLongA( hWnd, DWL_MSGRESULT, 1 );
815 return TRUE;
820 break;
822 case WM_DROPOBJECT:
823 if( wParam == hWnd )
824 { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
825 if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
826 { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
827 if( pstr )
828 { static char __appendix_str[] = " with";
830 hWndCtl = GetDlgItem( hWnd, IDC_WINE_TEXT );
831 SendMessageA( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
832 if( !lstrncmpA( Template, "WINE", 4 ) )
833 SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT), Template );
834 else
835 { char* pch = Template + strlen(Template) - strlen(__appendix_str);
836 *pch = '\0';
837 SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING,
838 (WPARAM)-1, (LPARAM)Template );
841 lstrcpyA( Template, pstr );
842 lstrcatA( Template, __appendix_str );
843 SetWindowTextA( hWndCtl, Template );
844 SetWindowLongA( hWnd, DWL_MSGRESULT, 1 );
845 return TRUE;
849 break;
851 case WM_COMMAND:
852 if (wParam == IDOK)
853 { EndDialog(hWnd, TRUE);
854 return TRUE;
856 break;
858 return 0;
862 /*************************************************************************
863 * ShellAboutA [SHELL32.243]
865 BOOL WINAPI ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
866 HICON hIcon )
867 { ABOUT_INFO info;
868 HRSRC hRes;
869 LPVOID template;
870 TRACE(shell,"\n");
872 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA)))
873 return FALSE;
874 if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes)))
875 return FALSE;
877 info.szApp = szApp;
878 info.szOtherStuff = szOtherStuff;
879 info.hIcon = hIcon;
880 if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
881 return DialogBoxIndirectParamA( WIN_GetWindowInstance( hWnd ),
882 template, hWnd, AboutDlgProc, (LPARAM)&info );
886 /*************************************************************************
887 * ShellAboutW [SHELL32.244]
889 BOOL WINAPI ShellAboutW( HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
890 HICON hIcon )
891 { BOOL ret;
892 ABOUT_INFO info;
893 HRSRC hRes;
894 LPVOID template;
896 TRACE(shell,"\n");
898 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA)))
899 return FALSE;
900 if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes)))
901 return FALSE;
903 info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
904 info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
905 info.hIcon = hIcon;
906 if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
907 ret = DialogBoxIndirectParamA( WIN_GetWindowInstance( hWnd ),
908 template, hWnd, AboutDlgProc, (LPARAM)&info );
909 HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
910 HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
911 return ret;
914 /*************************************************************************
915 * Shell_NotifyIcon [SHELL32.296]
916 * FIXME
917 * This function is supposed to deal with the systray.
918 * Any ideas on how this is to be implimented?
920 BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATAA pnid )
921 { TRACE(shell,"\n");
922 return FALSE;
925 /*************************************************************************
926 * Shell_NotifyIcon [SHELL32.297]
927 * FIXME
928 * This function is supposed to deal with the systray.
929 * Any ideas on how this is to be implimented?
931 BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
932 { TRACE(shell,"\n");
933 return FALSE;
936 /*************************************************************************
937 * FreeIconList
939 void WINAPI FreeIconList( DWORD dw )
940 { FIXME(shell, "(%lx): stub\n",dw);
943 /*************************************************************************
944 * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220]
946 * PARAMETERS
947 * pidl, [IN] pidl
948 * pszPath [OUT] path
950 * RETURNS
951 * path from a passed PIDL.
953 * NOTES
954 * exported by name
956 * FIXME
957 * fnGetDisplayNameOf can return different types of OLEString
959 DWORD WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath)
960 { STRRET lpName;
961 LPSHELLFOLDER shellfolder;
962 CHAR buffer[MAX_PATH],tpath[MAX_PATH];
963 DWORD type,tpathlen=MAX_PATH,dwdisp;
964 HKEY key;
966 TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
968 if (!pidl)
969 { strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
971 if (RegCreateKeyExA(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
972 { return E_OUTOFMEMORY;
974 type=REG_SZ;
975 strcpy (buffer,"Desktop"); /*registry name*/
976 if ( RegQueryValueExA(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
977 { GetWindowsDirectoryA(tpath,MAX_PATH);
978 PathAddBackslashA(tpath);
979 strcat (tpath,"Desktop"); /*folder name*/
980 RegSetValueExA(key,buffer,0,REG_SZ,(LPBYTE)tpath,tpathlen);
981 CreateDirectoryA(tpath,NULL);
983 RegCloseKey(key);
984 strcpy(pszPath,tpath);
986 else
987 { if (SHGetDesktopFolder(&shellfolder)==S_OK)
988 { IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
989 IShellFolder_Release(shellfolder);
991 strcpy(pszPath,lpName.u.cStr);
993 TRACE(shell,"-- (%s)\n",pszPath);
995 return TRUE;
997 /*************************************************************************
998 * SHGetPathFromIDListW [SHELL32.262]
1000 DWORD WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath)
1001 { char sTemp[MAX_PATH];
1003 TRACE (shell,"(pidl=%p)\n", pidl);
1005 SHGetPathFromIDListA (pidl, sTemp);
1006 lstrcpyAtoW(pszPath, sTemp);
1008 TRACE(shell,"-- (%s)\n",debugstr_w(pszPath));
1010 return TRUE;
1013 /*************************************************************************
1014 * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219]
1016 BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath)
1018 TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
1020 if (VERSION_OsIsUnicode())
1021 return SHGetPathFromIDListW(pidl,pszPath);
1022 return SHGetPathFromIDListA(pidl,pszPath);
1025 /***********************************************************************
1026 * DllGetVersion [COMCTL32.25]
1028 * Retrieves version information of the 'SHELL32.DLL'
1030 * PARAMS
1031 * pdvi [O] pointer to version information structure.
1033 * RETURNS
1034 * Success: S_OK
1035 * Failure: E_INVALIDARG
1037 * NOTES
1038 * Returns version of a shell32.dll from IE4.01 SP1.
1041 HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi)
1043 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1044 { WARN (shell, "wrong DLLVERSIONINFO size from app");
1045 return E_INVALIDARG;
1048 pdvi->dwMajorVersion = 4;
1049 pdvi->dwMinorVersion = 72;
1050 pdvi->dwBuildNumber = 3110;
1051 pdvi->dwPlatformID = 1;
1053 TRACE (shell, "%lu.%lu.%lu.%lu\n",
1054 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
1055 pdvi->dwBuildNumber, pdvi->dwPlatformID);
1057 return S_OK;
1059 /*************************************************************************
1060 * global variables of the shell32.dll
1063 void (WINAPI* pDLLInitComctl)(LPVOID);
1064 INT (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON hIcon);
1065 INT (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT, HICON);
1066 HIMAGELIST (WINAPI * pImageList_Create) (INT,INT,UINT,INT,INT);
1067 BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
1068 HICON (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT, UINT);
1069 INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST);
1071 LPVOID (WINAPI* pCOMCTL32_Alloc) (INT);
1072 BOOL (WINAPI* pCOMCTL32_Free) (LPVOID);
1074 HDPA (WINAPI* pDPA_Create) (INT);
1075 INT (WINAPI* pDPA_InsertPtr) (const HDPA, INT, LPVOID);
1076 BOOL (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM);
1077 LPVOID (WINAPI* pDPA_GetPtr) (const HDPA, INT);
1078 BOOL (WINAPI* pDPA_Destroy) (const HDPA);
1079 INT (WINAPI *pDPA_Search) (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT);
1080 LPVOID (WINAPI *pDPA_DeletePtr) (const HDPA hdpa, INT i);
1082 /* user32 */
1083 HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag);
1084 HICON (WINAPI *pCreateIconFromResourceEx)(LPBYTE bits,UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height,UINT cFlag);
1086 static BOOL bShell32IsInitialized = 0;
1087 static HINSTANCE hComctl32;
1088 static INT shell32_RefCount = 0;
1090 INT shell32_ObjCount = 0;
1091 HINSTANCE shell32_hInstance;
1092 /*************************************************************************
1093 * SHELL32 LibMain
1097 BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
1098 { HMODULE hUser32;
1100 TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
1102 shell32_hInstance = hinstDLL;
1104 switch (fdwReason)
1105 { case DLL_PROCESS_ATTACH:
1106 if (!bShell32IsInitialized)
1107 { hComctl32 = LoadLibraryA("COMCTL32.DLL");
1108 hUser32 = GetModuleHandleA("USER32");
1109 if (hComctl32 && hUser32)
1110 { pDLLInitComctl=(void*)GetProcAddress(hComctl32,"InitCommonControlsEx");
1111 if (pDLLInitComctl)
1112 { pDLLInitComctl(NULL);
1114 pImageList_Create=(void*)GetProcAddress(hComctl32,"ImageList_Create");
1115 pImageList_AddIcon=(void*)GetProcAddress(hComctl32,"ImageList_AddIcon");
1116 pImageList_ReplaceIcon=(void*)GetProcAddress(hComctl32,"ImageList_ReplaceIcon");
1117 pImageList_GetIcon=(void*)GetProcAddress(hComctl32,"ImageList_GetIcon");
1118 pImageList_GetImageCount=(void*)GetProcAddress(hComctl32,"ImageList_GetImageCount");
1119 pImageList_Draw=(void*)GetProcAddress(hComctl32,"ImageList_Draw");
1121 /* imports by ordinal, pray that it works*/
1122 pCOMCTL32_Alloc=(void*)GetProcAddress(hComctl32, (LPCSTR)71L);
1123 pCOMCTL32_Free=(void*)GetProcAddress(hComctl32, (LPCSTR)73L);
1124 pDPA_Create=(void*)GetProcAddress(hComctl32, (LPCSTR)328L);
1125 pDPA_Destroy=(void*)GetProcAddress(hComctl32, (LPCSTR)329L);
1126 pDPA_GetPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)332L);
1127 pDPA_InsertPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)334L);
1128 pDPA_DeletePtr=(void*)GetProcAddress(hComctl32, (LPCSTR)336L);
1129 pDPA_Sort=(void*)GetProcAddress(hComctl32, (LPCSTR)338L);
1130 pDPA_Search=(void*)GetProcAddress(hComctl32, (LPCSTR)339L);
1131 /* user32 */
1132 pLookupIconIdFromDirectoryEx=(void*)GetProcAddress(hUser32,"LookupIconIdFromDirectoryEx");
1133 pCreateIconFromResourceEx=(void*)GetProcAddress(hUser32,"CreateIconFromResourceEx");
1135 else
1136 { ERR(shell,"P A N I C SHELL32 loading failed\n");
1137 return FALSE;
1139 SIC_Initialize();
1140 bShell32IsInitialized = TRUE;
1142 shell32_RefCount++;
1143 break;
1145 case DLL_THREAD_ATTACH:
1146 shell32_RefCount++;
1147 break;
1149 case DLL_THREAD_DETACH:
1150 shell32_RefCount--;
1151 break;
1153 case DLL_PROCESS_DETACH:
1154 shell32_RefCount--;
1155 if ( !shell32_RefCount )
1157 bShell32IsInitialized = FALSE;
1159 if (pdesktopfolder)
1160 { IShellFolder_Release(pdesktopfolder);
1163 SIC_Destroy();
1164 FreeLibrary(hComctl32);
1166 /* this one is here to check if AddRef/Release is balanced */
1167 if (shell32_ObjCount)
1168 { WARN(shell,"leaving with %u objects left (memory leak)\n", shell32_ObjCount);
1171 TRACE(shell, "refcount=%u objcount=%u \n", shell32_RefCount, shell32_ObjCount);
1172 break;
1175 return TRUE;