ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

shell32_main.cpp
Go to the documentation of this file.
00001 /*
00002  *                 Shell basics
00003  *
00004  * Copyright 1998 Marcus Meissner
00005  * Copyright 1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <precomp.h>
00023 #include "shell32_version.h"
00024 #include <reactos/version.h>
00025 
00026 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00027 
00028 const char * const SHELL_Authors[] = { "Copyright 1993-"COPYRIGHT_YEAR" WINE team", "Copyright 1998-"COPYRIGHT_YEAR" ReactOS Team", 0 };
00029 
00030 #define MORE_DEBUG 1
00031 /*************************************************************************
00032  * CommandLineToArgvW            [SHELL32.@]
00033  *
00034  * We must interpret the quotes in the command line to rebuild the argv
00035  * array correctly:
00036  * - arguments are separated by spaces or tabs
00037  * - quotes serve as optional argument delimiters
00038  *   '"a b"'   -> 'a b'
00039  * - escaped quotes must be converted back to '"'
00040  *   '\"'      -> '"'
00041  * - an odd number of '\'s followed by '"' correspond to half that number
00042  *   of '\' followed by a '"' (extension of the above)
00043  *   '\\\"'    -> '\"'
00044  *   '\\\\\"'  -> '\\"'
00045  * - an even number of '\'s followed by a '"' correspond to half that number
00046  *   of '\', plus a regular quote serving as an argument delimiter (which
00047  *   means it does not appear in the result)
00048  *   'a\\"b c"'   -> 'a\b c'
00049  *   'a\\\\"b c"' -> 'a\\b c'
00050  * - '\' that are not followed by a '"' are copied literally
00051  *   'a\b'     -> 'a\b'
00052  *   'a\\b'    -> 'a\\b'
00053  *
00054  * Note:
00055  * '\t' == 0x0009
00056  * ' '  == 0x0020
00057  * '"'  == 0x0022
00058  * '\\' == 0x005c
00059  */
00060 LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
00061 {
00062     DWORD argc;
00063     LPWSTR  *argv;
00064     LPCWSTR cs;
00065     LPWSTR arg,s,d;
00066     LPWSTR cmdline;
00067     int in_quotes,bcount;
00068 
00069     if(!numargs)
00070     {
00071         SetLastError(ERROR_INVALID_PARAMETER);
00072         return NULL;
00073     }
00074 
00075     if (*lpCmdline==0)
00076     {
00077         /* Return the path to the executable */
00078         DWORD len, deslen=MAX_PATH, size;
00079 
00080         size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
00081         for (;;)
00082         {
00083             if (!(argv = (LPWSTR *)LocalAlloc(LMEM_FIXED, size))) return NULL;
00084             len = GetModuleFileNameW(0, (LPWSTR)(argv+1), deslen);
00085             if (!len)
00086             {
00087                 LocalFree(argv);
00088                 return NULL;
00089             }
00090             if (len < deslen) break;
00091             deslen*=2;
00092             size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
00093             LocalFree( argv );
00094         }
00095         argv[0]=(LPWSTR)(argv+1);
00096         *numargs=1;
00097 
00098         return argv;
00099     }
00100 
00101     /* to get a writable copy */
00102     argc=0;
00103     bcount=0;
00104     in_quotes=0;
00105     cs=lpCmdline;
00106     while (1)
00107     {
00108         if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes))
00109         {
00110             /* space */
00111             argc++;
00112             /* skip the remaining spaces */
00113             while (*cs==0x0009 || *cs==0x0020)
00114             {
00115                 cs++;
00116             }
00117             if (*cs==0)
00118                 break;
00119             bcount=0;
00120             continue;
00121         }
00122         else if (*cs==0x005c)
00123         {
00124             /* '\', count them */
00125             bcount++;
00126         }
00127         else if ((*cs==0x0022) && ((bcount & 1)==0))
00128         {
00129             /* unescaped '"' */
00130             in_quotes=!in_quotes;
00131             bcount=0;
00132         }
00133         else
00134         {
00135             /* a regular character */
00136             bcount=0;
00137         }
00138         cs++;
00139     }
00140     /* Allocate in a single lump, the string array, and the strings that go with it.
00141      * This way the caller can make a single GlobalFree call to free both, as per MSDN.
00142      */
00143     argv=(LPWSTR *)LocalAlloc(LMEM_FIXED, argc*sizeof(LPWSTR)+(wcslen(lpCmdline)+1)*sizeof(WCHAR));
00144     if (!argv)
00145         return NULL;
00146     cmdline=(LPWSTR)(argv+argc);
00147     wcscpy(cmdline, lpCmdline);
00148 
00149     argc=0;
00150     bcount=0;
00151     in_quotes=0;
00152     arg=d=s=cmdline;
00153     while (*s)
00154     {
00155         if ((*s==0x0009 || *s==0x0020) && !in_quotes)
00156         {
00157             /* Close the argument and copy it */
00158             *d=0;
00159             argv[argc++]=arg;
00160 
00161             /* skip the remaining spaces */
00162             do {
00163                 s++;
00164             } while (*s==0x0009 || *s==0x0020);
00165 
00166             /* Start with a new argument */
00167             arg=d=s;
00168             bcount=0;
00169         }
00170         else if (*s==0x005c)
00171         {
00172             /* '\\' */
00173             *d++=*s++;
00174             bcount++;
00175         }
00176         else if (*s==0x0022)
00177         {
00178             /* '"' */
00179             if ((bcount & 1)==0)
00180             {
00181                 /* Preceded by an even number of '\', this is half that
00182                  * number of '\', plus a quote which we erase.
00183                  */
00184                 d-=bcount/2;
00185                 in_quotes=!in_quotes;
00186                 s++;
00187             }
00188             else
00189             {
00190                 /* Preceded by an odd number of '\', this is half that
00191                  * number of '\' followed by a '"'
00192                  */
00193                 d=d-bcount/2-1;
00194                 *d++='"';
00195                 s++;
00196             }
00197             bcount=0;
00198         }
00199         else
00200         {
00201             /* a regular character */
00202             *d++=*s++;
00203             bcount=0;
00204         }
00205     }
00206     if (*arg)
00207     {
00208         *d='\0';
00209         argv[argc++]=arg;
00210     }
00211     *numargs=argc;
00212 
00213     return argv;
00214 }
00215 
00216 static DWORD shgfi_get_exe_type(LPCWSTR szFullPath)
00217 {
00218     BOOL status = FALSE;
00219     HANDLE hfile;
00220     DWORD BinaryType;
00221     IMAGE_DOS_HEADER mz_header;
00222     IMAGE_NT_HEADERS nt;
00223     DWORD len;
00224     char magic[4];
00225 
00226     status = GetBinaryTypeW (szFullPath, &BinaryType);
00227     if (!status)
00228         return 0;
00229     if (BinaryType == SCS_DOS_BINARY || BinaryType == SCS_PIF_BINARY)
00230         return 0x4d5a;
00231 
00232     hfile = CreateFileW( szFullPath, GENERIC_READ, FILE_SHARE_READ,
00233                          NULL, OPEN_EXISTING, 0, 0 );
00234     if ( hfile == INVALID_HANDLE_VALUE )
00235         return 0;
00236 
00237     /*
00238      * The next section is adapted from MODULE_GetBinaryType, as we need
00239      * to examine the image header to get OS and version information. We
00240      * know from calling GetBinaryTypeA that the image is valid and either
00241      * an NE or PE, so much error handling can be omitted.
00242      * Seek to the start of the file and read the header information.
00243      */
00244 
00245     SetFilePointer( hfile, 0, NULL, SEEK_SET );
00246     ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
00247 
00248     SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
00249     ReadFile( hfile, magic, sizeof(magic), &len, NULL );
00250 
00251     if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE )
00252     {
00253         SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
00254         ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
00255         CloseHandle( hfile );
00256 
00257         /* DLL files are not executable and should return 0 */
00258         if (nt.FileHeader.Characteristics & IMAGE_FILE_DLL)
00259             return 0;
00260 
00261         if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
00262         {
00263              return IMAGE_NT_SIGNATURE |
00264                    (nt.OptionalHeader.MajorSubsystemVersion << 24) |
00265                    (nt.OptionalHeader.MinorSubsystemVersion << 16);
00266         }
00267         return IMAGE_NT_SIGNATURE;
00268     }
00269     else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
00270     {
00271         IMAGE_OS2_HEADER ne;
00272         SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
00273         ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
00274         CloseHandle( hfile );
00275 
00276         if (ne.ne_exetyp == 2)
00277             return IMAGE_OS2_SIGNATURE | (ne.ne_expver << 16);
00278         return 0;
00279     }
00280     CloseHandle( hfile );
00281     return 0;
00282 }
00283 
00284 /*************************************************************************
00285  * SHELL_IsShortcut        [internal]
00286  *
00287  * Decide if an item id list points to a shell shortcut
00288  */
00289 BOOL SHELL_IsShortcut(LPCITEMIDLIST pidlLast)
00290 {
00291     char szTemp[MAX_PATH];
00292     HKEY keyCls;
00293     BOOL ret = FALSE;
00294 
00295     if (_ILGetExtension(pidlLast, szTemp, MAX_PATH) &&
00296           HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
00297     {
00298         if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
00299         {
00300           if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
00301             ret = TRUE;
00302 
00303           RegCloseKey(keyCls);
00304         }
00305     }
00306 
00307     return ret;
00308 }
00309 
00310 #define SHGFI_KNOWN_FLAGS \
00311     (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
00312      SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
00313      SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | \
00314      SHGFI_ICONLOCATION | SHGFI_EXETYPE | SHGFI_SYSICONINDEX | \
00315      SHGFI_LINKOVERLAY | SHGFI_SELECTED | SHGFI_ATTR_SPECIFIED)
00316 
00317 /*************************************************************************
00318  * SHGetFileInfoW            [SHELL32.@]
00319  *
00320  */
00321 DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
00322                                 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags )
00323 {
00324     WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH];
00325     int iIndex;
00326     DWORD_PTR ret = TRUE;
00327     DWORD dwAttributes = 0;
00328     CComPtr<IShellFolder>        psfParent;
00329     CComPtr<IExtractIconW>        pei;
00330     LPITEMIDLIST    pidlLast = NULL, pidl = NULL;
00331     HRESULT hr = S_OK;
00332     BOOL IconNotYetLoaded=TRUE;
00333     UINT uGilFlags = 0;
00334 
00335     TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n",
00336           (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes,
00337           psfi, psfi->dwAttributes, sizeofpsfi, flags);
00338 
00339     if (!path)
00340          return FALSE;
00341 
00342     /* windows initializes these values regardless of the flags */
00343     if (psfi != NULL)
00344     {
00345         psfi->szDisplayName[0] = '\0';
00346         psfi->szTypeName[0] = '\0';
00347         psfi->iIcon = 0;
00348     }
00349 
00350     if (!(flags & SHGFI_PIDL))
00351     {
00352         /* SHGetFileInfo should work with absolute and relative paths */
00353         if (PathIsRelativeW(path))
00354         {
00355             GetCurrentDirectoryW(MAX_PATH, szLocation);
00356             PathCombineW(szFullPath, szLocation, path);
00357         }
00358         else
00359         {
00360             lstrcpynW(szFullPath, path, MAX_PATH);
00361         }
00362     }
00363 
00364     if (flags & SHGFI_EXETYPE)
00365     {
00366         if (flags != SHGFI_EXETYPE)
00367             return 0;
00368         return shgfi_get_exe_type(szFullPath);
00369     }
00370 
00371     /*
00372      * psfi is NULL normally to query EXE type. If it is NULL, none of the
00373      * below makes sense anyway. Windows allows this and just returns FALSE
00374      */
00375     if (psfi == NULL)
00376         return FALSE;
00377 
00378     /*
00379      * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
00380      * is not specified.
00381      * The pidl functions fail on not existing file names
00382      */
00383 
00384     if (flags & SHGFI_PIDL)
00385     {
00386         pidl = ILClone((LPCITEMIDLIST)path);
00387     }
00388     else if (!(flags & SHGFI_USEFILEATTRIBUTES))
00389     {
00390         hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes);
00391     }
00392 
00393     if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES))
00394     {
00395         /* get the parent shellfolder */
00396         if (pidl)
00397         {
00398             hr = SHBindToParent( pidl, IID_IShellFolder, (LPVOID*)&psfParent,
00399                                 (LPCITEMIDLIST*)&pidlLast );
00400             if (SUCCEEDED(hr))
00401                 pidlLast = ILClone(pidlLast);
00402             ILFree(pidl);
00403         }
00404         else
00405         {
00406             ERR("pidl is null!\n");
00407             return FALSE;
00408         }
00409     }
00410 
00411     /* get the attributes of the child */
00412     if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES))
00413     {
00414         if (!(flags & SHGFI_ATTR_SPECIFIED))
00415         {
00416             psfi->dwAttributes = 0xffffffff;
00417         }
00418         if (psfParent != NULL)
00419             psfParent->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlLast,
00420                                       &(psfi->dwAttributes) );
00421     }
00422 
00423     /* get the displayname */
00424     if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME))
00425     {
00426         if (flags & SHGFI_USEFILEATTRIBUTES)
00427         {
00428             wcscpy (psfi->szDisplayName, PathFindFileNameW(szFullPath));
00429         }
00430         else
00431         {
00432             STRRET str;
00433             hr = psfParent->GetDisplayNameOf(pidlLast,
00434                                                 SHGDN_INFOLDER, &str);
00435             StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast);
00436         }
00437     }
00438 
00439     /* get the type name */
00440     if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME))
00441     {
00442         static const WCHAR szFile[] = { 'F','i','l','e',0 };
00443         static const WCHAR szDashFile[] = { '-','f','i','l','e',0 };
00444 
00445         if (!(flags & SHGFI_USEFILEATTRIBUTES))
00446         {
00447             char ftype[80];
00448 
00449             _ILGetFileType(pidlLast, ftype, 80);
00450             MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 );
00451         }
00452         else
00453         {
00454             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00455                 wcscat (psfi->szTypeName, szFile);
00456             else
00457             {
00458                 WCHAR sTemp[64];
00459 
00460                 wcscpy(sTemp,PathFindExtensionW(szFullPath));
00461                 if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE) &&
00462                     HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE )))
00463                 {
00464                     lstrcpynW (psfi->szTypeName, sTemp, 64);
00465                     wcscat (psfi->szTypeName, szDashFile);
00466                 }
00467             }
00468         }
00469     }
00470 
00471     /* ### icons ###*/
00472     if (flags & SHGFI_OPENICON)
00473         uGilFlags |= GIL_OPENICON;
00474 
00475     if (flags & SHGFI_LINKOVERLAY)
00476         uGilFlags |= GIL_FORSHORTCUT;
00477     else if ((flags&SHGFI_ADDOVERLAYS) ||
00478              (flags&(SHGFI_ICON|SHGFI_SMALLICON))==SHGFI_ICON)
00479     {
00480         if (SHELL_IsShortcut(pidlLast))
00481             uGilFlags |= GIL_FORSHORTCUT;
00482     }
00483 
00484     if (flags & SHGFI_OVERLAYINDEX)
00485         FIXME("SHGFI_OVERLAYINDEX unhandled\n");
00486 
00487     if (flags & SHGFI_SELECTED)
00488         FIXME("set icon to selected, stub\n");
00489 
00490     if (flags & SHGFI_SHELLICONSIZE)
00491         FIXME("set icon to shell size, stub\n");
00492 
00493     /* get the iconlocation */
00494     if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
00495     {
00496         UINT uDummy,uFlags;
00497 
00498         if (flags & SHGFI_USEFILEATTRIBUTES)
00499         {
00500             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00501             {
00502                 wcscpy(psfi->szDisplayName, swShell32Name);
00503                 psfi->iIcon = -IDI_SHELL_FOLDER;
00504             }
00505             else
00506             {
00507                 WCHAR* szExt;
00508                 static const WCHAR p1W[] = {'%','1',0};
00509                 WCHAR sTemp [MAX_PATH];
00510 
00511                 szExt = PathFindExtensionW(szFullPath);
00512                 TRACE("szExt=%s\n", debugstr_w(szExt));
00513                 if ( szExt &&
00514                      HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) &&
00515                      HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &psfi->iIcon))
00516                 {
00517                     if (lstrcmpW(p1W, sTemp))
00518                         wcscpy(psfi->szDisplayName, sTemp);
00519                     else
00520                     {
00521                         /* the icon is in the file */
00522                         wcscpy(psfi->szDisplayName, szFullPath);
00523                     }
00524                 }
00525                 else
00526                     ret = FALSE;
00527             }
00528         }
00529         else
00530         {
00531             hr = psfParent->GetUIObjectOf(0, 1,
00532                 (LPCITEMIDLIST*)&pidlLast, IID_IExtractIconW,
00533                 &uDummy, (LPVOID*)&pei);
00534             if (SUCCEEDED(hr))
00535             {
00536                 hr = pei->GetIconLocation(uGilFlags,
00537                     szLocation, MAX_PATH, &iIndex, &uFlags);
00538 
00539                 if (uFlags & GIL_NOTFILENAME)
00540                     ret = FALSE;
00541                 else
00542                 {
00543                     wcscpy (psfi->szDisplayName, szLocation);
00544                     psfi->iIcon = iIndex;
00545                 }
00546             }
00547         }
00548     }
00549 
00550     /* get icon index (or load icon)*/
00551     if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX)))
00552     {
00553         if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL))
00554         {
00555             WCHAR sTemp [MAX_PATH];
00556             WCHAR * szExt;
00557             int icon_idx=0;
00558 
00559             lstrcpynW(sTemp, szFullPath, MAX_PATH);
00560 
00561             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00562                 psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0);
00563             else
00564             {
00565                 static const WCHAR p1W[] = {'%','1',0};
00566 
00567                 psfi->iIcon = 0;
00568                 szExt = PathFindExtensionW(sTemp);
00569                 if ( szExt &&
00570                      HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) &&
00571                      HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &icon_idx))
00572                 {
00573                     if (!lstrcmpW(p1W,sTemp))            /* icon is in the file */
00574                         wcscpy(sTemp, szFullPath);
00575 
00576                     if (flags & SHGFI_SYSICONINDEX)
00577                     {
00578                         psfi->iIcon = SIC_GetIconIndex(sTemp,icon_idx,0);
00579                         if (psfi->iIcon == -1)
00580                             psfi->iIcon = 0;
00581                     }
00582                     else
00583                     {
00584                         UINT ret;
00585                         if (flags & SHGFI_SMALLICON)
00586                             ret = PrivateExtractIconsW( sTemp,icon_idx,
00587                                 GetSystemMetrics( SM_CXSMICON ),
00588                                 GetSystemMetrics( SM_CYSMICON ),
00589                                 &psfi->hIcon, 0, 1, 0);
00590                         else
00591                             ret = PrivateExtractIconsW( sTemp, icon_idx,
00592                                 GetSystemMetrics( SM_CXICON),
00593                                 GetSystemMetrics( SM_CYICON),
00594                                 &psfi->hIcon, 0, 1, 0);
00595 
00596                         if (ret != 0 && ret != 0xFFFFFFFF)
00597                         {
00598                             IconNotYetLoaded=FALSE;
00599                             psfi->iIcon = icon_idx;
00600                         }
00601                     }
00602                 }
00603             }
00604         }
00605         else
00606         {
00607             if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
00608                 uGilFlags, &(psfi->iIcon))))
00609             {
00610                 ret = FALSE;
00611             }
00612         }
00613         if (ret && (flags & SHGFI_SYSICONINDEX))
00614         {
00615             if (flags & SHGFI_SMALLICON)
00616                 ret = (DWORD_PTR) ShellSmallIconList;
00617             else
00618                 ret = (DWORD_PTR) ShellBigIconList;
00619         }
00620     }
00621 
00622     /* icon handle */
00623     if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded)
00624     {
00625         if (flags & SHGFI_SMALLICON)
00626             psfi->hIcon = ImageList_GetIcon( ShellSmallIconList, psfi->iIcon, ILD_NORMAL);
00627         else
00628             psfi->hIcon = ImageList_GetIcon( ShellBigIconList, psfi->iIcon, ILD_NORMAL);
00629     }
00630 
00631     if (flags & ~SHGFI_KNOWN_FLAGS)
00632         FIXME("unknown flags %08x\n", flags & ~SHGFI_KNOWN_FLAGS);
00633 
00634     if (hr != S_OK)
00635         ret = FALSE;
00636 
00637     SHFree(pidlLast);
00638 
00639 #ifdef MORE_DEBUG
00640     TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n",
00641            psfi->hIcon, psfi->iIcon, psfi->dwAttributes,
00642            debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret);
00643 #endif
00644 
00645     return ret;
00646 }
00647 
00648 /*************************************************************************
00649  * SHGetFileInfoA            [SHELL32.@]
00650  *
00651  * Note:
00652  *    MSVBVM60.__vbaNew2 expects this function to return a value in range
00653  *    1 .. 0x7fff when the function succeeds and flags does not contain
00654  *    SHGFI_EXETYPE or SHGFI_SYSICONINDEX (see bug 7701)
00655  */
00656 DWORD_PTR WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes,
00657                                 SHFILEINFOA *psfi, UINT sizeofpsfi,
00658                                 UINT flags )
00659 {
00660     INT len;
00661     LPWSTR temppath = NULL;
00662     LPCWSTR pathW;
00663     DWORD ret;
00664     SHFILEINFOW temppsfi;
00665 
00666     if (flags & SHGFI_PIDL)
00667     {
00668         /* path contains a pidl */
00669         pathW = (LPCWSTR)path;
00670     }
00671     else
00672     {
00673         len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
00674         temppath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
00675         MultiByteToWideChar(CP_ACP, 0, path, -1, temppath, len);
00676         pathW = temppath;
00677     }
00678 
00679     if (psfi && (flags & SHGFI_ATTR_SPECIFIED))
00680         temppsfi.dwAttributes=psfi->dwAttributes;
00681 
00682     if (psfi == NULL)
00683         ret = SHGetFileInfoW(pathW, dwFileAttributes, NULL, sizeof(temppsfi), flags);
00684     else
00685         ret = SHGetFileInfoW(pathW, dwFileAttributes, &temppsfi, sizeof(temppsfi), flags);
00686 
00687     if (psfi)
00688     {
00689         if(flags & SHGFI_ICON)
00690             psfi->hIcon=temppsfi.hIcon;
00691         if(flags & (SHGFI_SYSICONINDEX|SHGFI_ICON|SHGFI_ICONLOCATION))
00692             psfi->iIcon=temppsfi.iIcon;
00693         if(flags & SHGFI_ATTRIBUTES)
00694             psfi->dwAttributes=temppsfi.dwAttributes;
00695         if(flags & (SHGFI_DISPLAYNAME|SHGFI_ICONLOCATION))
00696         {
00697             WideCharToMultiByte(CP_ACP, 0, temppsfi.szDisplayName, -1,
00698                   psfi->szDisplayName, sizeof(psfi->szDisplayName), NULL, NULL);
00699         }
00700         if(flags & SHGFI_TYPENAME)
00701         {
00702             WideCharToMultiByte(CP_ACP, 0, temppsfi.szTypeName, -1,
00703                   psfi->szTypeName, sizeof(psfi->szTypeName), NULL, NULL);
00704         }
00705     }
00706 
00707     HeapFree(GetProcessHeap(), 0, temppath);
00708 
00709     return ret;
00710 }
00711 
00712 /*************************************************************************
00713  * DuplicateIcon            [SHELL32.@]
00714  */
00715 EXTERN_C HICON WINAPI DuplicateIcon( HINSTANCE hInstance, HICON hIcon)
00716 {
00717     ICONINFO IconInfo;
00718     HICON hDupIcon = 0;
00719 
00720     TRACE("%p %p\n", hInstance, hIcon);
00721 
00722     if (GetIconInfo(hIcon, &IconInfo))
00723     {
00724         hDupIcon = CreateIconIndirect(&IconInfo);
00725 
00726         /* clean up hbmMask and hbmColor */
00727         DeleteObject(IconInfo.hbmMask);
00728         DeleteObject(IconInfo.hbmColor);
00729     }
00730 
00731     return hDupIcon;
00732 }
00733 
00734 /*************************************************************************
00735  * ExtractIconA                [SHELL32.@]
00736  */
00737 HICON WINAPI ExtractIconA(HINSTANCE hInstance, LPCSTR lpszFile, UINT nIconIndex)
00738 {
00739     HICON ret;
00740     INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
00741     LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
00742 
00743     TRACE("%p %s %d\n", hInstance, lpszFile, nIconIndex);
00744 
00745     MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
00746     ret = ExtractIconW(hInstance, lpwstrFile, nIconIndex);
00747     HeapFree(GetProcessHeap(), 0, lpwstrFile);
00748 
00749     return ret;
00750 }
00751 
00752 /*************************************************************************
00753  * ExtractIconW                [SHELL32.@]
00754  */
00755 HICON WINAPI ExtractIconW(HINSTANCE hInstance, LPCWSTR lpszFile, UINT nIconIndex)
00756 {
00757     HICON  hIcon = NULL;
00758     UINT ret;
00759     UINT cx = GetSystemMetrics(SM_CXICON), cy = GetSystemMetrics(SM_CYICON);
00760 
00761     TRACE("%p %s %d\n", hInstance, debugstr_w(lpszFile), nIconIndex);
00762 
00763     if (nIconIndex == 0xFFFFFFFF)
00764     {
00765         ret = PrivateExtractIconsW(lpszFile, 0, cx, cy, NULL, NULL, 0, LR_DEFAULTCOLOR);
00766         if (ret != 0xFFFFFFFF && ret)
00767             return (HICON)(UINT_PTR)ret;
00768         return NULL;
00769     }
00770     else
00771         ret = PrivateExtractIconsW(lpszFile, nIconIndex, cx, cy, &hIcon, NULL, 1, LR_DEFAULTCOLOR);
00772 
00773     if (ret == 0xFFFFFFFF)
00774         return (HICON)1;
00775     else if (ret > 0 && hIcon)
00776         return hIcon;
00777 
00778     return NULL;
00779 }
00780 
00781 /*************************************************************************
00782  * Printer_LoadIconsW        [SHELL32.205]
00783  */
00784 EXTERN_C VOID WINAPI Printer_LoadIconsW(LPCWSTR wsPrinterName, HICON * pLargeIcon, HICON * pSmallIcon)
00785 {
00786     INT iconindex=IDI_SHELL_PRINTERS_FOLDER;
00787 
00788     TRACE("(%s, %p, %p)\n", debugstr_w(wsPrinterName), pLargeIcon, pSmallIcon);
00789 
00790     /* We should check if wsPrinterName is
00791        1. the Default Printer or not
00792        2. connected or not
00793        3. a Local Printer or a Network-Printer
00794        and use different Icons
00795     */
00796     if((wsPrinterName != NULL) && (wsPrinterName[0] != 0))
00797     {
00798         FIXME("(select Icon by PrinterName %s not implemented)\n", debugstr_w(wsPrinterName));
00799     }
00800 
00801     if(pLargeIcon != NULL)
00802         *pLargeIcon = (HICON)LoadImageW(shell32_hInstance,
00803                                  (LPCWSTR) MAKEINTRESOURCE(iconindex), IMAGE_ICON,
00804                                  0, 0, LR_DEFAULTCOLOR|LR_DEFAULTSIZE);
00805 
00806     if(pSmallIcon != NULL)
00807         *pSmallIcon = (HICON)LoadImageW(shell32_hInstance,
00808                                  (LPCWSTR) MAKEINTRESOURCE(iconindex), IMAGE_ICON,
00809                                  16, 16, LR_DEFAULTCOLOR);
00810 }
00811 
00812 /*************************************************************************
00813  * Printers_RegisterWindowW        [SHELL32.213]
00814  * used by "printui.dll":
00815  * find the Window of the given Type for the specific Printer and
00816  * return the already existent hwnd or open a new window
00817  */
00818 EXTERN_C BOOL WINAPI Printers_RegisterWindowW(LPCWSTR wsPrinter, DWORD dwType,
00819             HANDLE * phClassPidl, HWND * phwnd)
00820 {
00821     FIXME("(%s, %x, %p (%p), %p (%p)) stub!\n", debugstr_w(wsPrinter), dwType,
00822                 phClassPidl, (phClassPidl != NULL) ? *(phClassPidl) : NULL,
00823                 phwnd, (phwnd != NULL) ? *(phwnd) : NULL);
00824 
00825     return FALSE;
00826 }
00827 
00828 /*************************************************************************
00829  * Printers_UnregisterWindow      [SHELL32.214]
00830  */
00831 EXTERN_C VOID WINAPI Printers_UnregisterWindow(HANDLE hClassPidl, HWND hwnd)
00832 {
00833     FIXME("(%p, %p) stub!\n", hClassPidl, hwnd);
00834 }
00835 
00836 /*************************************************************************/
00837 
00838 typedef struct
00839 {
00840     LPCWSTR  szApp;
00841     LPCWSTR  szOtherStuff;
00842     HICON hIcon;
00843 } ABOUT_INFO;
00844 
00845 #define DROP_FIELD_TOP    (-15)
00846 #define DROP_FIELD_HEIGHT  15
00847 
00848 /*************************************************************************
00849  * SHAppBarMessage            [SHELL32.@]
00850  */
00851 UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
00852 {
00853     int width=data->rc.right - data->rc.left;
00854     int height=data->rc.bottom - data->rc.top;
00855     RECT rec=data->rc;
00856 
00857     TRACE("msg=%d, data={cb=%d, hwnd=%p, callback=%x, edge=%d, rc=%s, lparam=%lx}\n",
00858           msg, data->cbSize, data->hWnd, data->uCallbackMessage, data->uEdge,
00859           wine_dbgstr_rect(&data->rc), data->lParam);
00860 
00861     switch (msg)
00862     {
00863         case ABM_GETSTATE:
00864             return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
00865 
00866         case ABM_GETTASKBARPOS:
00867             GetWindowRect(data->hWnd, &rec);
00868             data->rc=rec;
00869             return TRUE;
00870 
00871         case ABM_ACTIVATE:
00872             SetActiveWindow(data->hWnd);
00873             return TRUE;
00874 
00875         case ABM_GETAUTOHIDEBAR:
00876             return 0; /* pretend there is no autohide bar */
00877 
00878         case ABM_NEW:
00879             /* cbSize, hWnd, and uCallbackMessage are used. All other ignored */
00880             SetWindowPos(data->hWnd,HWND_TOP,0,0,0,0,SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE);
00881             return TRUE;
00882 
00883         case ABM_QUERYPOS:
00884             GetWindowRect(data->hWnd, &(data->rc));
00885             return TRUE;
00886 
00887         case ABM_REMOVE:
00888             FIXME("ABM_REMOVE broken\n");
00889             /* FIXME: this is wrong; should it be DestroyWindow instead? */
00890             /*CloseHandle(data->hWnd);*/
00891             return TRUE;
00892 
00893         case ABM_SETAUTOHIDEBAR:
00894             SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top,
00895                              width,height,SWP_SHOWWINDOW);
00896             return TRUE;
00897 
00898         case ABM_SETPOS:
00899             data->uEdge=(ABE_RIGHT | ABE_LEFT);
00900             SetWindowPos(data->hWnd,HWND_TOP,data->rc.left,data->rc.top,
00901                          width,height,SWP_SHOWWINDOW);
00902             return TRUE;
00903 
00904         case ABM_WINDOWPOSCHANGED:
00905             return TRUE;
00906     }
00907 
00908     return FALSE;
00909 }
00910 
00911 /*************************************************************************
00912  * SHHelpShortcuts_RunDLLA        [SHELL32.@]
00913  *
00914  */
00915 EXTERN_C DWORD WINAPI SHHelpShortcuts_RunDLLA(DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
00916 {
00917     FIXME("(%x, %x, %x, %x) stub!\n", dwArg1, dwArg2, dwArg3, dwArg4);
00918     return 0;
00919 }
00920 
00921 /*************************************************************************
00922  * SHHelpShortcuts_RunDLLA        [SHELL32.@]
00923  *
00924  */
00925 EXTERN_C DWORD WINAPI SHHelpShortcuts_RunDLLW(DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
00926 {
00927     FIXME("(%x, %x, %x, %x) stub!\n", dwArg1, dwArg2, dwArg3, dwArg4);
00928     return 0;
00929 }
00930 
00931 /*************************************************************************
00932  * SHLoadInProc                [SHELL32.@]
00933  * Create an instance of specified object class from within
00934  * the shell process and release it immediately
00935  */
00936 EXTERN_C HRESULT WINAPI SHLoadInProc (REFCLSID rclsid)
00937 {
00938     CComPtr<IUnknown>            ptr;
00939 
00940     TRACE("%s\n", debugstr_guid(&rclsid));
00941 
00942     CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&ptr);
00943     if (ptr)
00944         return NOERROR;
00945     return DISP_E_MEMBERNOTFOUND;
00946 }
00947 
00948 static VOID SetRegTextData(HWND hWnd, HKEY hKey, LPCWSTR Value, UINT uID)
00949 {
00950     DWORD dwBufferSize;
00951     DWORD dwType;
00952     LPWSTR lpBuffer;
00953 
00954     if( RegQueryValueExW(hKey, Value, NULL, &dwType, NULL, &dwBufferSize) == ERROR_SUCCESS )
00955     {
00956         if(dwType == REG_SZ)
00957         {
00958             lpBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
00959 
00960             if(lpBuffer)
00961             {
00962                 if( RegQueryValueExW(hKey, Value, NULL, &dwType, (LPBYTE)lpBuffer, &dwBufferSize) == ERROR_SUCCESS )
00963                 {
00964                     SetDlgItemTextW(hWnd, uID, lpBuffer);
00965                 }
00966 
00967                 HeapFree(GetProcessHeap(), 0, lpBuffer);
00968             }
00969         }
00970     }
00971 }
00972 
00973 INT_PTR CALLBACK AboutAuthorsDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
00974 {
00975     switch(msg)
00976     {
00977         case WM_INITDIALOG:
00978         {
00979             const char* const *pstr = SHELL_Authors;
00980 
00981             // Add the authors to the list
00982             SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, FALSE, 0 );
00983 
00984             while (*pstr)
00985             {
00986                 WCHAR name[64];
00987 
00988                 /* authors list is in utf-8 format */
00989                 MultiByteToWideChar( CP_UTF8, 0, *pstr, -1, name, sizeof(name)/sizeof(WCHAR) );
00990                 SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, LB_ADDSTRING, (WPARAM)-1, (LPARAM)name );
00991                 pstr++;
00992             }
00993 
00994             SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, TRUE, 0 );
00995 
00996             return TRUE;
00997         }
00998     }
00999 
01000     return FALSE;
01001 }
01002 /*************************************************************************
01003  * AboutDlgProc            (internal)
01004  */
01005 INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
01006 {
01007     static DWORD   cxLogoBmp;
01008     static DWORD   cyLogoBmp;
01009     static HBITMAP hLogoBmp;
01010     static HWND    hWndAuthors;
01011 
01012     switch(msg)
01013     {
01014         case WM_INITDIALOG:
01015         {
01016             ABOUT_INFO *info = (ABOUT_INFO *)lParam;
01017 
01018             if (info)
01019             {
01020                 const WCHAR szRegKey[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
01021                 HKEY hRegKey;
01022                 MEMORYSTATUSEX MemStat;
01023                 WCHAR szAppTitle[512];
01024                 WCHAR szAppTitleTemplate[512];
01025                 WCHAR szAuthorsText[20];
01026 
01027                 // Preload the ROS bitmap
01028                 hLogoBmp = (HBITMAP)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDB_SHELL_ABOUT_LOGO_24BPP), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
01029 
01030                 if(hLogoBmp)
01031                 {
01032                     BITMAP bmpLogo;
01033 
01034                     GetObject( hLogoBmp, sizeof(BITMAP), &bmpLogo );
01035 
01036                     cxLogoBmp = bmpLogo.bmWidth;
01037                     cyLogoBmp = bmpLogo.bmHeight;
01038                 }
01039 
01040                 // Set App-specific stuff (icon, app name, szOtherStuff string)
01041                 SendDlgItemMessageW(hWnd, IDC_ABOUT_ICON, STM_SETICON, (WPARAM)info->hIcon, 0);
01042 
01043                 GetWindowTextW( hWnd, szAppTitleTemplate, sizeof(szAppTitleTemplate) / sizeof(WCHAR) );
01044                 swprintf( szAppTitle, szAppTitleTemplate, info->szApp );
01045                 SetWindowTextW( hWnd, szAppTitle );
01046 
01047                 SetDlgItemTextW( hWnd, IDC_ABOUT_APPNAME, info->szApp );
01048                 SetDlgItemTextW( hWnd, IDC_ABOUT_OTHERSTUFF, info->szOtherStuff );
01049 
01050                 // Set the registered user and organization name
01051                 if(RegOpenKeyExW( HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_QUERY_VALUE, &hRegKey ) == ERROR_SUCCESS)
01052                 {
01053                     SetRegTextData( hWnd, hRegKey, L"RegisteredOwner", IDC_ABOUT_REG_USERNAME );
01054                     SetRegTextData( hWnd, hRegKey, L"RegisteredOrganization", IDC_ABOUT_REG_ORGNAME );
01055 
01056                     RegCloseKey( hRegKey );
01057                 }
01058 
01059                 // Set the value for the installed physical memory
01060                 MemStat.dwLength = sizeof(MemStat);
01061                 if( GlobalMemoryStatusEx(&MemStat) )
01062                 {
01063                     WCHAR szBuf[12];
01064 
01065                     if (MemStat.ullTotalPhys > 1024 * 1024 * 1024)
01066                     {
01067                         double dTotalPhys;
01068                         WCHAR szDecimalSeparator[4];
01069                         WCHAR szUnits[3];
01070 
01071                         // We're dealing with GBs or more
01072                         MemStat.ullTotalPhys /= 1024 * 1024;
01073 
01074                         if (MemStat.ullTotalPhys > 1024 * 1024)
01075                         {
01076                             // We're dealing with TBs or more
01077                             MemStat.ullTotalPhys /= 1024;
01078 
01079                             if (MemStat.ullTotalPhys > 1024 * 1024)
01080                             {
01081                                 // We're dealing with PBs or more
01082                                 MemStat.ullTotalPhys /= 1024;
01083 
01084                                 dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
01085                                 wcscpy( szUnits, L"PB" );
01086                             }
01087                             else
01088                             {
01089                                 dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
01090                                 wcscpy( szUnits, L"TB" );
01091                             }
01092                         }
01093                         else
01094                         {
01095                             dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
01096                             wcscpy( szUnits, L"GB" );
01097                         }
01098 
01099                         // We need the decimal point of the current locale to display the RAM size correctly
01100                         if (GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
01101                             szDecimalSeparator,
01102                             sizeof(szDecimalSeparator) / sizeof(WCHAR)) > 0)
01103                         {
01104                             UCHAR uDecimals;
01105                             UINT uIntegral;
01106 
01107                             uIntegral = (UINT)dTotalPhys;
01108                             uDecimals = (UCHAR)((UINT)(dTotalPhys * 100) - uIntegral * 100);
01109 
01110                             // Display the RAM size with 2 decimals
01111                             swprintf(szBuf, L"%u%s%02u %s", uIntegral, szDecimalSeparator, uDecimals, szUnits);
01112                         }
01113                     }
01114                     else
01115                     {
01116                         // We're dealing with MBs, don't show any decimals
01117                         swprintf( szBuf, L"%u MB", (UINT)MemStat.ullTotalPhys / 1024 / 1024 );
01118                     }
01119 
01120                     SetDlgItemTextW( hWnd, IDC_ABOUT_PHYSMEM, szBuf);
01121                 }
01122 
01123                 // Add the Authors dialog
01124                 hWndAuthors = CreateDialogW( shell32_hInstance, MAKEINTRESOURCEW(IDD_ABOUT_AUTHORS), hWnd, AboutAuthorsDlgProc );
01125                 LoadStringW( shell32_hInstance, IDS_SHELL_ABOUT_AUTHORS, szAuthorsText, sizeof(szAuthorsText) / sizeof(WCHAR) );
01126                 SetDlgItemTextW( hWnd, IDC_ABOUT_AUTHORS, szAuthorsText );
01127             }
01128 
01129             return TRUE;
01130         }
01131 
01132         case WM_PAINT:
01133         {
01134             if(hLogoBmp)
01135             {
01136                 PAINTSTRUCT ps;
01137                 HDC hdc;
01138                 HDC hdcMem;
01139 
01140                 hdc = BeginPaint(hWnd, &ps);
01141                 hdcMem = CreateCompatibleDC(hdc);
01142 
01143                 if(hdcMem)
01144                 {
01145                     SelectObject(hdcMem, hLogoBmp);
01146                     BitBlt(hdc, 0, 0, cxLogoBmp, cyLogoBmp, hdcMem, 0, 0, SRCCOPY);
01147 
01148                     DeleteDC(hdcMem);
01149                 }
01150 
01151                 EndPaint(hWnd, &ps);
01152             }
01153         }; break;
01154 
01155         case WM_COMMAND:
01156         {
01157             switch(wParam)
01158             {
01159                 case IDOK:
01160                 case IDCANCEL:
01161                     EndDialog(hWnd, TRUE);
01162                     return TRUE;
01163 
01164                 case IDC_ABOUT_AUTHORS:
01165                 {
01166                     static BOOL bShowingAuthors = FALSE;
01167                     WCHAR szAuthorsText[20];
01168 
01169                     if(bShowingAuthors)
01170                     {
01171                         LoadStringW( shell32_hInstance, IDS_SHELL_ABOUT_AUTHORS, szAuthorsText, sizeof(szAuthorsText) / sizeof(WCHAR) );
01172                         ShowWindow( hWndAuthors, SW_HIDE );
01173                     }
01174                     else
01175                     {
01176                         LoadStringW( shell32_hInstance, IDS_SHELL_ABOUT_BACK, szAuthorsText, sizeof(szAuthorsText) / sizeof(WCHAR) );
01177                         ShowWindow( hWndAuthors, SW_SHOW );
01178                     }
01179 
01180                     SetDlgItemTextW( hWnd, IDC_ABOUT_AUTHORS, szAuthorsText );
01181                     bShowingAuthors = !bShowingAuthors;
01182                     return TRUE;
01183                 }
01184             }
01185         }; break;
01186 
01187         case WM_CLOSE:
01188             EndDialog(hWnd, TRUE);
01189             break;
01190     }
01191 
01192     return FALSE;
01193 }
01194 
01195 
01196 /*************************************************************************
01197  * ShellAboutA                [SHELL32.288]
01198  */
01199 BOOL WINAPI ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon )
01200 {
01201     BOOL ret;
01202     LPWSTR appW = NULL, otherW = NULL;
01203     int len;
01204 
01205     if (szApp)
01206     {
01207         len = MultiByteToWideChar(CP_ACP, 0, szApp, -1, NULL, 0);
01208         appW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
01209         MultiByteToWideChar(CP_ACP, 0, szApp, -1, appW, len);
01210     }
01211     if (szOtherStuff)
01212     {
01213         len = MultiByteToWideChar(CP_ACP, 0, szOtherStuff, -1, NULL, 0);
01214         otherW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
01215         MultiByteToWideChar(CP_ACP, 0, szOtherStuff, -1, otherW, len);
01216     }
01217 
01218     ret = ShellAboutW(hWnd, appW, otherW, hIcon);
01219 
01220     HeapFree(GetProcessHeap(), 0, otherW);
01221     HeapFree(GetProcessHeap(), 0, appW);
01222     return ret;
01223 }
01224 
01225 
01226 /*************************************************************************
01227  * ShellAboutW                [SHELL32.289]
01228  */
01229 BOOL WINAPI ShellAboutW( HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
01230                          HICON hIcon )
01231 {
01232     ABOUT_INFO info;
01233     HRSRC hRes;
01234     DLGTEMPLATE *DlgTemplate;
01235     BOOL bRet;
01236 
01237     TRACE("\n");
01238 
01239     // DialogBoxIndirectParamW will be called with the hInstance of the calling application, so we have to preload the dialog template
01240     hRes = FindResourceW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ABOUT), (LPWSTR)RT_DIALOG);
01241     if(!hRes)
01242         return FALSE;
01243 
01244     DlgTemplate = (DLGTEMPLATE *)LoadResource(shell32_hInstance, hRes);
01245     if(!DlgTemplate)
01246         return FALSE;
01247 
01248     info.szApp        = szApp;
01249     info.szOtherStuff = szOtherStuff;
01250     info.hIcon        = hIcon ? hIcon : LoadIconW( 0, (LPWSTR)IDI_WINLOGO );
01251 
01252     bRet = DialogBoxIndirectParamW((HINSTANCE)GetWindowLongPtrW( hWnd, GWLP_HINSTANCE ),
01253                                    DlgTemplate, hWnd, AboutDlgProc, (LPARAM)&info );
01254     return bRet;
01255 }
01256 
01257 /*************************************************************************
01258  * FreeIconList (SHELL32.@)
01259  */
01260 EXTERN_C void WINAPI FreeIconList( DWORD dw )
01261 {
01262     FIXME("%x: stub\n",dw);
01263 }
01264 
01265 /*************************************************************************
01266  * SHLoadNonloadedIconOverlayIdentifiers (SHELL32.@)
01267  */
01268 EXTERN_C HRESULT WINAPI SHLoadNonloadedIconOverlayIdentifiers(VOID)
01269 {
01270     FIXME("stub\n");
01271     return S_OK;
01272 }
01273 
01274 class CShell32Module : public CComModule
01275 {
01276 public:
01277 };
01278 
01279 
01280 BEGIN_OBJECT_MAP(ObjectMap)
01281 OBJECT_ENTRY(CLSID_ShellFSFolder, CFSFolder)
01282 OBJECT_ENTRY(CLSID_MyComputer, CDrivesFolder)
01283 OBJECT_ENTRY(CLSID_ShellDesktop, CDesktopFolder)
01284 OBJECT_ENTRY(CLSID_ShellItem, CShellItem)
01285 OBJECT_ENTRY(CLSID_ShellLink, CShellLink)
01286 OBJECT_ENTRY(CLSID_DragDropHelper, CDropTargetHelper)
01287 OBJECT_ENTRY(CLSID_ControlPanel, CControlPanelFolder)
01288 OBJECT_ENTRY(CLSID_AutoComplete, CAutoComplete)
01289 OBJECT_ENTRY(CLSID_MyDocuments, CMyDocsFolder)
01290 OBJECT_ENTRY(CLSID_NetworkPlaces, CNetFolder)
01291 OBJECT_ENTRY(CLSID_FontsFolderShortcut, CFontsFolder)
01292 OBJECT_ENTRY(CLSID_Printers, CPrinterFolder)
01293 OBJECT_ENTRY(CLSID_AdminFolderShortcut, CAdminToolsFolder)
01294 OBJECT_ENTRY(CLSID_RecycleBin, CRecycleBin)
01295 OBJECT_ENTRY(CLSID_OpenWithMenu, COpenWithMenu)
01296 OBJECT_ENTRY(CLSID_NewMenu, CNewMenu)
01297 OBJECT_ENTRY(CLSID_StartMenu, CStartMenu)
01298 OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
01299 END_OBJECT_MAP()
01300 
01301 CShell32Module                                gModule;
01302 
01303 
01304 /***********************************************************************
01305  * DllGetVersion [SHELL32.@]
01306  *
01307  * Retrieves version information of the 'SHELL32.DLL'
01308  *
01309  * PARAMS
01310  *     pdvi [O] pointer to version information structure.
01311  *
01312  * RETURNS
01313  *     Success: S_OK
01314  *     Failure: E_INVALIDARG
01315  *
01316  * NOTES
01317  *     Returns version of a shell32.dll from IE4.01 SP1.
01318  */
01319 
01320 STDAPI DllGetVersion(DLLVERSIONINFO *pdvi)
01321 {
01322     /* FIXME: shouldn't these values come from the version resource? */
01323     if (pdvi->cbSize == sizeof(DLLVERSIONINFO) ||
01324         pdvi->cbSize == sizeof(DLLVERSIONINFO2))
01325     {
01326         pdvi->dwMajorVersion = WINE_FILEVERSION_MAJOR;
01327         pdvi->dwMinorVersion = WINE_FILEVERSION_MINOR;
01328         pdvi->dwBuildNumber = WINE_FILEVERSION_BUILD;
01329         pdvi->dwPlatformID = WINE_FILEVERSION_PLATFORMID;
01330         if (pdvi->cbSize == sizeof(DLLVERSIONINFO2))
01331         {
01332             DLLVERSIONINFO2 *pdvi2 = (DLLVERSIONINFO2 *)pdvi;
01333 
01334             pdvi2->dwFlags = 0;
01335             pdvi2->ullVersion = MAKEDLLVERULL(WINE_FILEVERSION_MAJOR,
01336                                               WINE_FILEVERSION_MINOR,
01337                                               WINE_FILEVERSION_BUILD,
01338                                               WINE_FILEVERSION_PLATFORMID);
01339         }
01340         TRACE("%u.%u.%u.%u\n",
01341               pdvi->dwMajorVersion, pdvi->dwMinorVersion,
01342               pdvi->dwBuildNumber, pdvi->dwPlatformID);
01343         return S_OK;
01344     }
01345     else
01346     {
01347         WARN("wrong DLLVERSIONINFO size from app\n");
01348         return E_INVALIDARG;
01349     }
01350 }
01351 
01352 /*************************************************************************
01353  * global variables of the shell32.dll
01354  * all are once per process
01355  *
01356  */
01357 HINSTANCE    shell32_hInstance;
01358 HIMAGELIST   ShellSmallIconList = 0;
01359 HIMAGELIST   ShellBigIconList = 0;
01360 
01361 void *operator new (size_t, void *buf)
01362 {
01363     return buf;
01364 }
01365 
01366 /*************************************************************************
01367  * SHELL32 DllMain
01368  *
01369  * NOTES
01370  *  calling oleinitialize here breaks sone apps.
01371  */
01372 STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
01373 {
01374     TRACE("%p 0x%x %p\n", hInstance, dwReason, fImpLoad);
01375     if (dwReason == DLL_PROCESS_ATTACH)
01376     {
01377         /* HACK - the global constructors don't run, so I placement new them here */
01378         new (&gModule) CShell32Module;
01379         new (&_AtlWinModule) CAtlWinModule;
01380         new (&_AtlBaseModule) CAtlBaseModule;
01381         new (&_AtlComModule) CAtlComModule;
01382 
01383         shell32_hInstance = hInstance;
01384         gModule.Init(ObjectMap, hInstance, NULL);
01385 
01386         DisableThreadLibraryCalls (hInstance);
01387 
01388         /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
01389         GetModuleFileNameW(hInstance, swShell32Name, MAX_PATH);
01390         swShell32Name[MAX_PATH - 1] = '\0';
01391 
01392         InitCommonControlsEx(NULL);
01393 
01394         SIC_Initialize();
01395         InitChangeNotifications();
01396         InitIconOverlays();
01397     }
01398     else if (dwReason == DLL_PROCESS_DETACH)
01399     {
01400         shell32_hInstance = NULL;
01401         SIC_Destroy();
01402         FreeChangeNotifications();
01403         gModule.Term();
01404     }
01405     return TRUE;
01406 }
01407 
01408 /***********************************************************************
01409  *              DllCanUnloadNow (SHELL32.@)
01410  */
01411 STDAPI DllCanUnloadNow()
01412 {
01413     return gModule.DllCanUnloadNow();
01414 }
01415 
01416 /*************************************************************************
01417  *              DllGetClassObject     [SHELL32.@]
01418  *              SHDllGetClassObject   [SHELL32.128]
01419  */
01420 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
01421 {
01422     HRESULT                                hResult;
01423 
01424     TRACE("CLSID:%s,IID:%s\n", shdebugstr_guid(&rclsid), shdebugstr_guid(&riid));
01425 
01426     hResult = gModule.DllGetClassObject(rclsid, riid, ppv);
01427     TRACE("-- pointer to class factory: %p\n", *ppv);
01428     return hResult;
01429 }
01430 
01431 /***********************************************************************
01432  *              DllRegisterServer (SHELL32.@)
01433  */
01434 STDAPI DllRegisterServer()
01435 {
01436     HRESULT hr;
01437 
01438     hr = gModule.DllRegisterServer(FALSE);
01439     if (FAILED(hr))
01440         return hr;
01441 
01442     hr = gModule.UpdateRegistryFromResource(IDR_FOLDEROPTIONS, TRUE, NULL);
01443     if (FAILED(hr))
01444         return hr;
01445 
01446     hr = SHELL_RegisterShellFolders();
01447     if (FAILED(hr))
01448         return hr;
01449 
01450     return S_OK;
01451 }
01452 
01453 /***********************************************************************
01454  *              DllUnregisterServer (SHELL32.@)
01455  */
01456 STDAPI DllUnregisterServer()
01457 {
01458     HRESULT hr;
01459 
01460     hr = gModule.DllUnregisterServer(FALSE);
01461     if (FAILED(hr))
01462         return hr;
01463 
01464     hr = gModule.UpdateRegistryFromResource(IDR_FOLDEROPTIONS, FALSE, NULL);
01465     if (FAILED(hr))
01466         return hr;
01467 
01468     return S_OK;
01469 }
01470 
01471 /*************************************************************************
01472  * DllInstall         [SHELL32.@]
01473  *
01474  * PARAMETERS
01475  *
01476  *    BOOL bInstall - TRUE for install, FALSE for uninstall
01477  *    LPCWSTR pszCmdLine - command line (unused by shell32?)
01478  */
01479 
01480 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
01481 {
01482     FIXME("%s %s: stub\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
01483     return S_OK;        /* indicate success */
01484 }

Generated on Sat May 26 2012 04:25:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.