/* * Shell basics * * 1998 Marcus Meissner * 1998 Juergen Schmied (jsch) * */ #include #include #include #include #include #include "windows.h" #include "winerror.h" #include "file.h" #include "shell.h" #include "heap.h" #include "module.h" #include "neexe.h" #include "resource.h" #include "dlgs.h" #include "win.h" #include "graphics.h" #include "cursoricon.h" #include "interfaces.h" #include "sysmetrics.h" #include "shlobj.h" #include "debug.h" #include "winreg.h" #include "imagelist.h" #include "commctrl.h" #include "authors.h" #include "pidl.h" #include "shell32_main.h" /************************************************************************* * CommandLineToArgvW [SHELL32.7] */ LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs) { LPWSTR *argv,s,t; int i; TRACE(shell,"\n"); /* to get writeable copy */ cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline); s=cmdline;i=0; while (*s) { /* space */ if (*s==0x0020) { i++; s++; while (*s && *s==0x0020) s++; continue; } s++; } argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) ); s=t=cmdline; i=0; while (*s) { if (*s==0x0020) { *s=0; argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t ); *s=0x0020; while (*s && *s==0x0020) s++; if (*s) t=s+1; else t=s; continue; } s++; } if (*t) argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t ); HeapFree( GetProcessHeap(), 0, cmdline ); argv[i]=NULL; *numargs=i; return argv; } /************************************************************************* * Control_RunDLL [SHELL32.12] * * Wild speculation in the following! * * http://premium.microsoft.com/msdn/library/techart/msdn193.htm */ void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 ) { FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code, debugstr_a(cmd), arg4); } /************************************************************************* * Shell_GetImageList [SHELL32.71] * * PARAMETERS * imglist[1|2] [OUT] pointer which recive imagelist handles * * NOTES * undocumented * I don't know, which pointer is which. They may have to be * exchanged. (jsch) */ BOOL32 WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2) { WARN(shell,"(%p,%p):semi-stub.\n",imglist1,imglist2); if (imglist1) { *imglist1=ShellSmallIconList; } if (imglist2) { *imglist2=ShellBigIconList; } return TRUE; } /************************************************************************* * SHGetFileInfoA [SHELL32.218] * * FIXME * */ HIMAGELIST ShellSmallIconList = 0; HIMAGELIST ShellBigIconList = 0; DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes, SHFILEINFO32A *psfi, UINT32 sizeofpsfi, UINT32 flags ) { CHAR szTemp[MAX_PATH]; LPPIDLDATA pData; DWORD ret=0; TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n", path,dwFileAttributes,psfi,sizeofpsfi,flags); /* translate the pidl to a path*/ if (flags & SHGFI_PIDL) { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp); TRACE(shell,"pidl=%p is %s\n",path,szTemp); } else { TRACE(shell,"path=%p\n",path); } if (flags & SHGFI_ATTRIBUTES) { if (flags & SHGFI_PIDL) { pData = _ILGetDataPointer((LPCITEMIDLIST)path); psfi->dwAttributes = pData->u.generic.dwSFGAO; /* fixme: no direct access*/ ret=TRUE; } else { psfi->dwAttributes=SFGAO_FILESYSTEM; ret=TRUE; } FIXME(shell,"file attributes, stub\n"); } if (flags & SHGFI_DISPLAYNAME) { if (flags & SHGFI_PIDL) { strcpy(psfi->szDisplayName,szTemp); } else { strcpy(psfi->szDisplayName,path); } TRACE(shell,"displayname=%s\n", psfi->szDisplayName); ret=TRUE; } if (flags & SHGFI_TYPENAME) { FIXME(shell,"get the file type, stub\n"); strcpy(psfi->szTypeName,"FIXME: Type"); ret=TRUE; } if (flags & SHGFI_ICONLOCATION) { FIXME(shell,"location of icon, stub\n"); strcpy(psfi->szDisplayName,""); ret=TRUE; } if (flags & SHGFI_EXETYPE) FIXME(shell,"type of executable, stub\n"); if (flags & SHGFI_LINKOVERLAY) FIXME(shell,"set icon to link, stub\n"); if (flags & SHGFI_OPENICON) FIXME(shell,"set to open icon, stub\n"); if (flags & SHGFI_SELECTED) FIXME(shell,"set icon to selected, stub\n"); if (flags & SHGFI_SHELLICONSIZE) FIXME(shell,"set icon to shell size, stub\n"); if (flags & SHGFI_USEFILEATTRIBUTES) FIXME(shell,"use the dwFileAttributes, stub\n"); if (flags & SHGFI_ICON) { FIXME(shell,"icon handle\n"); if (flags & SHGFI_SMALLICON) { TRACE(shell,"set to small icon\n"); psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL); ret = (DWORD) ShellSmallIconList; } else { TRACE(shell,"set to big icon\n"); psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL); ret = (DWORD) ShellBigIconList; } } if (flags & SHGFI_SYSICONINDEX) { FIXME(shell,"get the SYSICONINDEX\n"); psfi->iIcon=32; if (flags & SHGFI_SMALLICON) { TRACE(shell,"set to small icon\n"); ret = (DWORD) ShellSmallIconList; } else { TRACE(shell,"set to big icon\n"); ret = (DWORD) ShellBigIconList; } } return ret; } /************************************************************************* * ExtractIcon32A (SHELL32.133) */ HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName, UINT32 nIconIndex ) { HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1); TRACE(shell,"\n"); if( handle ) { HICON16* ptr = (HICON16*)GlobalLock16(handle); HICON16 hIcon = *ptr; GlobalFree16(handle); return hIcon; } return 0; } /************************************************************************* * ExtractIcon32W (SHELL32.180) */ HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName, UINT32 nIconIndex ) { LPSTR exefn; HICON32 ret; TRACE(shell,"\n"); exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName); ret = ExtractIcon32A(hInstance,exefn,nIconIndex); HeapFree(GetProcessHeap(),0,exefn); return ret; } /************************************************************************* * FindExecutable32A (SHELL32.184) */ HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult ) { HINSTANCE32 retval=31; /* default - 'No association was found' */ char old_dir[1024]; TRACE(shell, "File %s, Dir %s\n", (lpFile != NULL?lpFile:"-"), (lpDirectory != NULL?lpDirectory:"-")); lpResult[0]='\0'; /* Start off with an empty return string */ /* trap NULL parameters on entry */ if (( lpFile == NULL ) || ( lpResult == NULL )) { /* FIXME - should throw a warning, perhaps! */ return 2; /* File not found. Close enough, I guess. */ } if (lpDirectory) { GetCurrentDirectory32A( sizeof(old_dir), old_dir ); SetCurrentDirectory32A( lpDirectory ); } retval = SHELL_FindExecutable( lpFile, "open", lpResult ); TRACE(shell, "returning %s\n", lpResult); if (lpDirectory) SetCurrentDirectory32A( old_dir ); return retval; } typedef struct { LPCSTR szApp; LPCSTR szOtherStuff; HICON32 hIcon; } ABOUT_INFO; #define IDC_STATIC_TEXT 100 #define IDC_LISTBOX 99 #define IDC_WINE_TEXT 98 #define DROP_FIELD_TOP (-15) #define DROP_FIELD_HEIGHT 15 extern HICON32 hIconTitleFont; static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect ) { HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT); if( hWndCtl ) { GetWindowRect32( hWndCtl, lprect ); MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 ); lprect->bottom = (lprect->top += DROP_FIELD_TOP); return TRUE; } return FALSE; } /************************************************************************* * SHAppBarMessage32 [SHELL32.207] */ UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data) { FIXME(shell,"(0x%08lx,%p): stub\n", msg, data); #if 0 switch (msg) { case ABM_ACTIVATE: case ABM_GETAUTOHIDEBAR: case ABM_GETSTATE: case ABM_GETTASKBARPOS: case ABM_NEW: case ABM_QUERYPOS: case ABM_REMOVE: case ABM_SETAUTOHIDEBAR: case ABM_SETPOS: case ABM_WINDOWPOSCHANGED: ; } #endif return 0; } /************************************************************************* * SHBrowseForFolderA [SHELL32.209] * */ LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi) { FIXME (shell, "(0x%lx,%s): stub\n", (DWORD)lpbi, debugstr_a(lpbi->lpszTitle)); return NULL; } /************************************************************************* * SHGetDesktopFolder [SHELL32.216] * * SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with * CLSID_ShellDesktop * CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf); * * RETURNS * the interface to the shell desktop folder. * * FIXME * the pdesktopfolder has to be released at the end (at dll unloading???) */ LPSHELLFOLDER pdesktopfolder=NULL; DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) { HRESULT hres = E_OUTOFMEMORY; LPCLASSFACTORY lpclf; TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder); if (pdesktopfolder) { hres = NOERROR; } else { lpclf = IClassFactory_Constructor(); /* fixme: the buildin IClassFactory_Constructor is at the moment only for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/ if(lpclf) { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); lpclf->lpvtbl->fnRelease(lpclf); } } if (pdesktopfolder) { *shellfolder = pdesktopfolder; pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder); } else { *shellfolder=NULL; } TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder); return hres; } /************************************************************************* * SHGetPathFromIDList [SHELL32.221][NT 4.0: SHELL32.219] */ BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath) { TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); return SHGetPathFromIDList32A(pidl,pszPath); } /************************************************************************* * SHGetSpecialFolderLocation [SHELL32.223] * gets the folder locations from the registry and creates a pidl * creates missing reg keys and directorys * * PARAMS * hwndOwner [I] * nFolder [I] CSIDL_xxxxx * ppidl [O] PIDL of a special folder * * RETURNS * HResult * * FIXME * - look for "User Shell Folder" first * */ HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl) { LPSHELLFOLDER shellfolder; DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res; CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH]; LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0]; HKEY key; enum { FT_UNKNOWN= 0x00000000, FT_DIR= 0x00000001, FT_DESKTOP= 0x00000002 } tFolder; TRACE(shell,"(%04x,%d,%p)\n", hwndOwner,nFolder,ppidl); strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp); if (res) { ERR(shell,"Could not create key %s %08lx \n",buffer,res); return E_OUTOFMEMORY; } tFolder=FT_DIR; switch (nFolder) { case CSIDL_BITBUCKET: strcpy (buffer,"xxx"); /*not in the registry*/ TRACE (shell,"looking for Recycler\n"); tFolder=FT_UNKNOWN; break; case CSIDL_CONTROLS: strcpy (buffer,"xxx"); /*virtual folder*/ TRACE (shell,"looking for Control\n"); tFolder=FT_UNKNOWN; break; case CSIDL_DESKTOP: strcpy (buffer,"xxx"); /*virtual folder*/ TRACE (shell,"looking for Desktop\n"); tFolder=FT_DESKTOP; break; case CSIDL_DESKTOPDIRECTORY: strcpy (buffer,"Desktop"); break; case CSIDL_DRIVES: strcpy (buffer,"xxx"); /*virtual folder*/ TRACE (shell,"looking for Drives\n"); tFolder=FT_UNKNOWN; break; case CSIDL_FONTS: strcpy (buffer,"Fonts"); break; case CSIDL_NETHOOD: strcpy (buffer,"NetHood"); break; case CSIDL_NETWORK: strcpy (buffer,"xxx"); /*virtual folder*/ TRACE (shell,"looking for Network\n"); tFolder=FT_UNKNOWN; break; case CSIDL_PERSONAL: strcpy (buffer,"Personal"); break; case CSIDL_FAVORITES: strcpy (buffer,"Favorites"); break; case CSIDL_PRINTERS: strcpy (buffer,"PrintHood"); break; case CSIDL_PROGRAMS: strcpy (buffer,"Programs"); break; case CSIDL_RECENT: strcpy (buffer,"Recent"); break; case CSIDL_SENDTO: strcpy (buffer,"SendTo"); break; case CSIDL_STARTMENU: strcpy (buffer,"Start Menu"); break; case CSIDL_STARTUP: strcpy (buffer,"Startup"); break; case CSIDL_TEMPLATES: strcpy (buffer,"Templates"); break; default: ERR (shell,"unknown CSIDL\n"); tFolder=FT_UNKNOWN; break; } TRACE(shell,"Key=%s\n",buffer); type=REG_SZ; switch (tFolder) { case FT_DIR: /* Directory: get the value from the registry, if its not there create it and the directory*/ if (RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) { GetWindowsDirectory32A(npath,MAX_PATH); PathAddBackslash(npath); switch (nFolder) { case CSIDL_DESKTOPDIRECTORY: strcat (npath,"Desktop"); break; case CSIDL_FONTS: strcat (npath,"Fonts"); break; case CSIDL_NETHOOD: strcat (npath,"NetHood"); break; case CSIDL_PERSONAL: strcpy (npath,"C:\\Personal"); break; case CSIDL_FAVORITES: strcat (npath,"Favorites"); break; case CSIDL_PRINTERS: strcat (npath,"PrintHood"); break; case CSIDL_PROGRAMS: strcat (npath,"Start Menu"); CreateDirectory32A(npath,NULL); strcat (npath,"\\Programs"); break; case CSIDL_RECENT: strcat (npath,"Recent"); break; case CSIDL_SENDTO: strcat (npath,"SendTo"); break; case CSIDL_STARTMENU: strcat (npath,"Start Menu"); break; case CSIDL_STARTUP: strcat (npath,"Start Menu"); CreateDirectory32A(npath,NULL); strcat (npath,"\\Startup"); break; case CSIDL_TEMPLATES: strcat (npath,"Templates"); break; default: RegCloseKey(key); return E_OUTOFMEMORY; } if (RegSetValueEx32A(key,buffer,0,REG_SZ,npath,sizeof(npath)+1)) { ERR(shell,"could not create value %s\n",buffer); RegCloseKey(key); return E_OUTOFMEMORY; } TRACE(shell,"value %s=%s created\n",buffer,npath); CreateDirectory32A(npath,NULL); strcpy(tpath,npath); } break; case FT_DESKTOP: strcpy (tpath,"Desktop"); break; default: RegCloseKey(key); return E_OUTOFMEMORY; break; } RegCloseKey(key); TRACE(shell,"Value=%s\n",tpath); LocalToWideChar32(lpszDisplayName, tpath, 256); if (SHGetDesktopFolder(&shellfolder)==S_OK) { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL); shellfolder->lpvtbl->fnRelease(shellfolder); } TRACE(shell, "-- (new pidl %p)\n",*ppidl); return NOERROR; } /************************************************************************* * SHHelpShortcuts_RunDLL [SHELL32.224] * */ DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4) { FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n", dwArg1, dwArg2, dwArg3, dwArg4); return 0; } /************************************************************************* * SHLoadInProc [SHELL32.225] * */ DWORD WINAPI SHLoadInProc (DWORD dwArg1) { FIXME (shell, "(%lx) empty stub!\n", dwArg1); return 0; } /************************************************************************* * ShellExecute32A (SHELL32.245) */ HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT32 iShowCmd ) { TRACE(shell,"\n"); return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters, lpDirectory, iShowCmd ); } /************************************************************************* * AboutDlgProc32 (not an exported API function) */ LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam ) { HWND32 hWndCtl; char Template[512], AppTitle[512]; TRACE(shell,"\n"); switch(msg) { case WM_INITDIALOG: { ABOUT_INFO *info = (ABOUT_INFO *)lParam; if (info) { const char* const *pstr = SHELL_People; SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0); GetWindowText32A( hWnd, Template, sizeof(Template) ); sprintf( AppTitle, Template, info->szApp ); SetWindowText32A( hWnd, AppTitle ); SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), info->szOtherStuff ); hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 ); SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 ); while (*pstr) { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr ); pstr++; } SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 ); } } return 1; case WM_PAINT: { RECT32 rect; PAINTSTRUCT32 ps; HDC32 hDC = BeginPaint32( hWnd, &ps ); if( __get_dropline( hWnd, &rect ) ) GRAPH_DrawLines( hDC, (LPPOINT32)&rect, 1, GetStockObject32( BLACK_PEN ) ); EndPaint32( hWnd, &ps ); } break; case WM_LBTRACKPOINT: hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); if( (INT16)GetKeyState16( VK_CONTROL ) < 0 ) { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) ) { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 ); if( idx != -1 ) { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 ); HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 ); char* pstr = (char*)GlobalLock16( hMemObj ); if( pstr ) { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) ); SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr ); SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 ); UpdateWindow32( hWndCtl ); if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) ) SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr ); } if( hMemObj ) GlobalFree16( hMemObj ); } } } break; case WM_QUERYDROPOBJECT: if( wParam == 0 ) { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA ) { RECT32 rect; if( __get_dropline( hWnd, &rect ) ) { POINT32 pt = { lpDragInfo->pt.x, lpDragInfo->pt.y }; rect.bottom += DROP_FIELD_HEIGHT; if( PtInRect32( &rect, pt ) ) { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); return TRUE; } } } } break; case WM_DROPOBJECT: if( wParam == hWnd ) { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList ) { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) ); if( pstr ) { static char __appendix_str[] = " with"; hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT ); SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template ); if( !lstrncmp32A( Template, "WINE", 4 ) ) SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template ); else { char* pch = Template + strlen(Template) - strlen(__appendix_str); *pch = '\0'; SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)Template ); } lstrcpy32A( Template, pstr ); lstrcat32A( Template, __appendix_str ); SetWindowText32A( hWndCtl, Template ); SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); return TRUE; } } } break; case WM_COMMAND: if (wParam == IDOK) { EndDialog32(hWnd, TRUE); return TRUE; } break; } return 0; } /************************************************************************* * ShellAbout32A (SHELL32.243) */ BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON32 hIcon ) { ABOUT_INFO info; TRACE(shell,"\n"); info.szApp = szApp; info.szOtherStuff = szOtherStuff; info.hIcon = hIcon; if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), hWnd, AboutDlgProc32, (LPARAM)&info ); } /************************************************************************* * ShellAbout32W (SHELL32.244) */ BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, HICON32 hIcon ) { BOOL32 ret; ABOUT_INFO info; TRACE(shell,"\n"); info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp ); info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff ); info.hIcon = hIcon; if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), hWnd, AboutDlgProc32, (LPARAM)&info ); HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp ); HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff ); return ret; } /************************************************************************* * Shell_NotifyIcon [SHELL32.296] * FIXME * This function is supposed to deal with the systray. * Any ideas on how this is to be implimented? */ BOOL32 WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid ) { TRACE(shell,"\n"); return FALSE; } /************************************************************************* * Shell_NotifyIcon [SHELL32.297] * FIXME * This function is supposed to deal with the systray. * Any ideas on how this is to be implimented? */ BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATA pnid ) { TRACE(shell,"\n"); return FALSE; } /************************************************************************* * FreeIconList */ void WINAPI FreeIconList( DWORD dw ) { FIXME(shell, "(%lx): stub\n",dw); } /************************************************************************* * SHGetPathFromIDList32A [SHELL32.261][NT 4.0: SHELL32.220] * * PARAMETERS * pidl, [IN] pidl * pszPath [OUT] path * * RETURNS * path from a passed PIDL. * * NOTES * exported by name * * FIXME * fnGetDisplayNameOf can return different types of OLEString */ DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath) { STRRET lpName; LPSHELLFOLDER shellfolder; CHAR buffer[MAX_PATH],tpath[MAX_PATH]; DWORD type,tpathlen=MAX_PATH,dwdisp; HKEY key; TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); if (!pidl) { strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp)) { return E_OUTOFMEMORY; } type=REG_SZ; strcpy (buffer,"Desktop"); /*registry name*/ if ( RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) { GetWindowsDirectory32A(tpath,MAX_PATH); PathAddBackslash(tpath); strcat (tpath,"Desktop"); /*folder name*/ RegSetValueEx32A(key,buffer,0,REG_SZ,tpath,tpathlen); CreateDirectory32A(tpath,NULL); } RegCloseKey(key); strcpy(pszPath,tpath); } else { if (SHGetDesktopFolder(&shellfolder)==S_OK) { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName); shellfolder->lpvtbl->fnRelease(shellfolder); } /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/ strcpy(pszPath,lpName.u.cStr); /* fixme free the olestring*/ } TRACE(shell,"-- (%s)\n",pszPath); return NOERROR; } /************************************************************************* * SHGetPathFromIDList32W [SHELL32.262] */ DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath) { FIXME (shell,"(pidl=%p %s):stub.\n", pidl, debugstr_w(pszPath)); return 0; } void (CALLBACK* pDLLInitComctl)(); INT32 (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon); INT32(CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32); HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32); HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32); /************************************************************************* * SHELL32 LibMain * * FIXME * at the moment the icons are extracted from shell32.dll * free the imagelists */ HINSTANCE32 shell32_hInstance; BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { HICON32 htmpIcon; UINT32 iiconindex; UINT32 index; CHAR szShellPath[MAX_PATH]; HINSTANCE32 hComctl32; TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved); shell32_hInstance = hinstDLL; GetWindowsDirectory32A(szShellPath,MAX_PATH); PathAddBackslash(szShellPath); strcat(szShellPath,"system\\shell32.dll"); if (fdwReason==DLL_PROCESS_ATTACH) { hComctl32 = LoadLibrary32A("COMCTL32.DLL"); if (hComctl32) { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx"); if (pDLLInitComctl) { pDLLInitComctl(); } pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create"); pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon"); pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon"); pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon"); FreeLibrary32(hComctl32); } else { /* panic, imediately exit wine*/ ERR(shell,"P A N I C error getting functionpointers\n"); exit (1); } if ( ! ShellSmallIconList ) { if ( (ShellSmallIconList = pImageList_Create(sysMetrics[SM_CXSMICON],sysMetrics[SM_CYSMICON],ILC_COLORDDB | ILC_MASK,0,0x20)) ) { for (index=0;index < 40; index++) { if ( ! ( htmpIcon = ExtractIcon32A(hinstDLL, szShellPath, index)) || ( -1 == (iiconindex = pImageList_AddIcon (ShellSmallIconList, htmpIcon))) ) { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); break; } } } } if ( ! ShellBigIconList ) { if ( (ShellBigIconList = pImageList_Create(SYSMETRICS_CXSMICON, SYSMETRICS_CYSMICON,ILC_COLORDDB | ILC_MASK,0,0x20)) ) { for (index=0;index < 40; index++) { if ( ! (htmpIcon = ExtractIcon32A( hinstDLL, szShellPath, index)) || (-1 == (iiconindex = pImageList_AddIcon (ShellBigIconList, htmpIcon))) ) { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); break; } } } } TRACE(shell,"hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); } return TRUE; }