viewcomm.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "shellprv.h"
  2. #pragma  hdrstop
  3. #include "fstreex.h"
  4. #include "idlcomm.h"
  5. // returns SHAlloc() (COM Task Allocator) memory
  6. LPTSTR SHGetCaption(HIDA hida)
  7. {
  8.     UINT idFormat;
  9.     LPTSTR pszCaption = NULL;
  10.     LPITEMIDLIST pidl;
  11.     
  12.     switch (HIDA_GetCount(hida))
  13.     {
  14.     case 0:
  15.         return NULL;
  16.         
  17.     case 1:
  18.         idFormat = IDS_ONEFILEPROP;
  19.         break;
  20.         
  21.     default:
  22.         idFormat = IDS_MANYFILEPROP;
  23.         break;
  24.     }
  25.     
  26.     pidl = HIDA_ILClone(hida, 0);
  27.     if (pidl)
  28.     {
  29.         TCHAR szName[MAX_PATH];
  30.         if (SUCCEEDED(SHGetNameAndFlags(pidl, SHGDN_NORMAL, szName, ARRAYSIZE(szName), NULL)))
  31.         {
  32.             TCHAR szTemplate[40];
  33.             UINT uLen = LoadString(HINST_THISDLL, idFormat, szTemplate, ARRAYSIZE(szTemplate)) + lstrlen(szName) + 1;
  34.             
  35.             pszCaption = SHAlloc(uLen * SIZEOF(TCHAR));
  36.             if (pszCaption)
  37.             {
  38.                 wsprintf(pszCaption, szTemplate, (LPTSTR)szName);
  39.             }
  40.         }
  41.         ILFree(pidl);
  42.     }
  43.     return pszCaption;
  44. }
  45. // This is not folder specific, and could be used for other background
  46. // properties handlers, since all it does is bind to the parent of a full pidl
  47. // and ask for properties
  48. STDAPI SHPropertiesForPidl(HWND hwndOwner, LPCITEMIDLIST pidlFull, LPCTSTR pszParams)
  49. {
  50.     LPITEMIDLIST pidlLast;
  51.     IShellFolder *psf;
  52.     HRESULT hres;
  53.     if (SHRestricted(REST_NOVIEWCONTEXTMENU)) {
  54.         return HRESULT_FROM_WIN32(E_ACCESSDENIED);
  55.     }
  56.     
  57.     hres = SHBindToIDListParent(pidlFull, &IID_IShellFolder, &psf, &pidlLast);
  58.     if (SUCCEEDED(hres))
  59.     {
  60.         IContextMenu *pcm;
  61.         hres = psf->lpVtbl->GetUIObjectOf(psf, hwndOwner, 1, &pidlLast, &IID_IContextMenu, 0, &pcm);
  62.         if (SUCCEEDED(hres))
  63.         {
  64. #ifdef UNICODE
  65.             CHAR szParameters[MAX_PATH];
  66. #endif
  67.             CMINVOKECOMMANDINFOEX ici = {
  68.                 SIZEOF(CMINVOKECOMMANDINFOEX),
  69.                 0L,
  70.                 hwndOwner,
  71. #ifdef UNICODE
  72.                 "properties",
  73.                 szParameters,
  74. #else
  75.                 c_szProperties,
  76.                 pszParams,
  77. #endif
  78.                 NULL, SW_SHOWNORMAL
  79.             };
  80. #ifdef UNICODE
  81.             if (pszParams)
  82.                 SHUnicodeToAnsi(pszParams, szParameters, ARRAYSIZE(szParameters));
  83.             else
  84.                 ici.lpParameters = NULL;
  85.             ici.fMask |= CMIC_MASK_UNICODE;
  86.             ici.lpVerbW = c_szProperties;
  87.             ici.lpParametersW = pszParams;
  88. #endif
  89.             // record if shift or control was being held down
  90.             SetICIKeyModifiers(&ici.fMask);
  91.             hres = pcm->lpVtbl->InvokeCommand(pcm, (LPCMINVOKECOMMANDINFO)&ici);
  92.             pcm->lpVtbl->Release(pcm);
  93.         }
  94.         psf->lpVtbl->Release(psf);
  95.     }
  96.     return hres;
  97. }
  98. STDAPI Multi_GetAttributesOf(IShellFolder2 *psf, UINT cidl, LPCITEMIDLIST* apidl, ULONG *prgfInOut, PFNGAOCALLBACK pfnGAOCallback)
  99. {
  100.     HRESULT hres = NOERROR;
  101.     UINT iidl;
  102.     ULONG rgfOut = 0;
  103.     for (iidl=0; iidl<cidl ; iidl++)
  104.     {
  105.         ULONG rgfT = *prgfInOut;
  106.         hres = pfnGAOCallback(psf, apidl[iidl], &rgfT);
  107.         if (FAILED(hres))
  108.         {
  109.             rgfOut = 0;
  110.             break;
  111.         }
  112.         rgfOut |= rgfT;
  113.     }
  114.     *prgfInOut &= rgfOut;
  115.     return hres;
  116. }
  117. // REVIEW: Why do we have this function to expose global keys?
  118. // BUGBUG: HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE are substantially different cases
  119. //          one has to close the former, but never the latter
  120. HKEY SHGetExplorerHkey(HKEY hkeyRoot, BOOL bCreate)
  121. {
  122.     ASSERT(hkeyRoot == HKEY_CURRENT_USER || hkeyRoot == HKEY_LOCAL_MACHINE);
  123.     
  124.     if (hkeyRoot == HKEY_CURRENT_USER) {
  125.         HKEY hkeyExplorer = NULL;
  126.         RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER, &hkeyExplorer);
  127.         return hkeyExplorer;
  128.     }
  129.     if (hkeyRoot == HKEY_LOCAL_MACHINE)
  130.         return g_hklmExplorer;
  131.     
  132.     return NULL;
  133. }
  134. // REVIEW: Why do we have this function to wrap aroung RegCreate/Open key?
  135. // we don't save any code size...
  136. #define FULL_KEY_SIZE 400
  137. HKEY SHGetExplorerSubHkey(HKEY hkeyRoot, LPCTSTR szSubKey, BOOL bCreate)
  138. {
  139.     HKEY hkSubKey=0;
  140.     static TCHAR const szRegExplorer[] = REGSTR_PATH_EXPLORER  TEXT("\");
  141.     TCHAR szFullKey[FULL_KEY_SIZE];
  142.     lstrcpy( szFullKey, szRegExplorer);
  143.     lstrcpyn( szFullKey + ARRAYSIZE(szRegExplorer) - 1, szSubKey, FULL_KEY_SIZE - ARRAYSIZE(szRegExplorer));
  144.     ASSERT(  lstrlen( szSubKey) + ARRAYSIZE(szRegExplorer) < FULL_KEY_SIZE );
  145.     {
  146.         LONG err;
  147.         DWORD dwDisp;
  148.         err = bCreate ? RegCreateKeyEx(hkeyRoot, szFullKey, 0, NULL, REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hkSubKey, &dwDisp) : 
  149.                         RegOpenKeyEx  (hkeyRoot, szFullKey, 0, MAXIMUM_ALLOWED, &hkSubKey);
  150.         if( err == ERROR_SUCCESS) {
  151.             ASSERT( hkSubKey);
  152.         } else {
  153.             ASSERT( !hkSubKey);
  154.         }
  155.     }
  156.     return hkSubKey;
  157. }
  158. BOOL _LoadErrMsg(UINT idErrMsg, LPTSTR pszErrMsg, DWORD err)
  159. {
  160.     TCHAR szTemplate[256];
  161.     if (LoadString(HINST_THISDLL, idErrMsg, szTemplate, ARRAYSIZE(szTemplate)))
  162.     {
  163.         wsprintf(pszErrMsg, szTemplate, err);
  164.         return TRUE;
  165.     }
  166.     return FALSE;
  167. }
  168. BOOL _VarArgsFormatMessage( LPTSTR lpBuffer, UINT cchBuffer, DWORD err, ... )
  169. {
  170.     BOOL fSuccess;
  171.     va_list ArgList;
  172.     va_start(ArgList, err);
  173.     fSuccess = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  174.                 NULL, err, 0, lpBuffer, cchBuffer, &ArgList);
  175.     va_end(ArgList);
  176.     return fSuccess;
  177. }
  178. //
  179. // Paremeters:
  180. //  hwndOwner  -- owner window
  181. //  idTemplate -- specifies template (e.g., "Can't open %2%snn%1%s")
  182. //  err        -- specifies the WIN32 error code
  183. //  pszParam   -- specifies the 2nd parameter to idTemplate
  184. //  dwFlags    -- flags for MessageBox
  185. //
  186. STDAPI_(UINT) SHSysErrorMessageBox(HWND hwndOwner, LPCTSTR pszTitle, UINT idTemplate,
  187.                                    DWORD err, LPCTSTR pszParam, UINT dwFlags)
  188. {
  189.     BOOL fSuccess;
  190.     UINT idRet = IDCANCEL;
  191.     TCHAR szErrMsg[MAX_PATH * 2];
  192.     //
  193.     // FormatMessage is bogus, we don't know what to pass to it for %1,%2,%3,...
  194.     // For most messages, lets pass the path as %1 and "" as everything else
  195.     // For ERROR_MR_MID_NOT_FOUND (something nobody is ever supposed to see)
  196.     // we will pass the path as %2 and everything else as "".
  197.     //
  198.     if (err == ERROR_MR_MID_NOT_FOUND)
  199.     {
  200.         fSuccess = _VarArgsFormatMessage(szErrMsg,ARRAYSIZE(szErrMsg),
  201.                        err,c_szNULL,pszParam,c_szNULL,c_szNULL,c_szNULL);
  202.     } 
  203.     else 
  204.     {
  205.         fSuccess = _VarArgsFormatMessage(szErrMsg,ARRAYSIZE(szErrMsg),
  206.                        err,pszParam,c_szNULL,c_szNULL,c_szNULL,c_szNULL);
  207.     }
  208.     if (fSuccess || _LoadErrMsg(IDS_ENUMERR_FSGENERIC, szErrMsg, err))
  209.     {
  210.         if (idTemplate==IDS_SHLEXEC_ERROR && (pszParam == NULL || StrStr(szErrMsg, pszParam)))
  211.         {
  212.             idTemplate = IDS_SHLEXEC_ERROR2;
  213.         }
  214.         idRet = ShellMessageBox(HINST_THISDLL, hwndOwner,
  215.                 MAKEINTRESOURCE(idTemplate),
  216.                 pszTitle, dwFlags, szErrMsg, pszParam);
  217.     }
  218.     return idRet;
  219. }
  220. STDAPI_(UINT) SHEnumErrorMessageBox(HWND hwnd, UINT idTemplate, DWORD err, LPCTSTR pszParam, BOOL fNet, UINT dwFlags)
  221. {
  222.     UINT idRet = IDCANCEL;
  223.     TCHAR szErrMsg[256 + 32];
  224.     if (hwnd == NULL)
  225.         return idRet;
  226.     switch(err)
  227.     {
  228.     case WN_SUCCESS:
  229.     case WN_CANCEL:
  230.         return IDCANCEL;        // Don't retry
  231.     case ERROR_OUTOFMEMORY:
  232.         return IDABORT;         // Out of memory!
  233.     }
  234.     if (fNet)
  235.     {
  236.         TCHAR szProvider[256];  // We don't use it.
  237.         DWORD dwErrSize = ARRAYSIZE(szErrMsg);      // BUGBUG (DavePl) I expect a cch here, but no docs, could be cb
  238.         DWORD dwProvSize = ARRAYSIZE(szProvider);
  239.         szErrMsg[0] = 0;
  240.         MultinetGetErrorText(szErrMsg, &dwErrSize, szProvider, &dwProvSize);
  241.         if (szErrMsg[0] == 0)
  242.             _LoadErrMsg(IDS_ENUMERR_NETGENERIC, szErrMsg, err);
  243.         idRet = ShellMessageBox(HINST_THISDLL, hwnd, MAKEINTRESOURCE(idTemplate),
  244.                     NULL, dwFlags, szErrMsg, pszParam);
  245.     }
  246.     else
  247.     {
  248.         idRet = SHSysErrorMessageBox(hwnd, NULL, idTemplate, err, pszParam, dwFlags);
  249.     }
  250.     return idRet;
  251. }