cmdfile.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // this file implements shell command files.
  2. // .scf
  3. // when executed, they run a shell internal command.
  4. // they can have stream storage, or whatnot in them
  5. //
  6. // file format is *PURPOSELY* text so that folks can create and modify by hand
  7. #include "stdafx.h"
  8. #pragma hdrstop
  9. #define SZDESKBAR TEXT("DeskBar")
  10. LPBYTE GetProfileData(LPCTSTR pszSection, LPCTSTR pszSizeValue, LPCTSTR pszDataValue, LPCTSTR pszFile, UINT *puSize)
  11. {
  12.     LPBYTE p = NULL;
  13.     
  14.     if (!pszSizeValue)
  15.         pszSizeValue = TEXT("size");
  16.     
  17.     UINT uSize = GetPrivateProfileInt(pszSection, pszSizeValue, 0, pszFile);
  18.     if (uSize) {
  19.         // use LocalAlloc so that we can strictly pass it to CreateStreamOnHLocal
  20.         p = (LPBYTE)LocalAlloc(LPTR, uSize);
  21.         
  22.         if (!GetPrivateProfileStruct(pszSection, pszDataValue, p, uSize, pszFile)) {
  23.             LocalFree(p);
  24.             p = NULL;
  25.         }
  26.     }    
  27.     
  28.     if (puSize)
  29.         *puSize = uSize;
  30.     return p;
  31. }
  32. IStream* GetProfileStream(LPCTSTR pszSection, LPCTSTR pszSizeValue, LPCTSTR pszDataValue, LPCTSTR pszFile)
  33. {   
  34.     UINT uSize;
  35.     LPBYTE p = GetProfileData(pszSection, pszSizeValue, pszDataValue, pszFile, &uSize);
  36.     IStream* pstm = NULL;
  37.     if (p) {
  38.         pstm = SHCreateMemStream(p, uSize);
  39.         LocalFree(p);
  40.     }
  41.     return pstm;
  42. }
  43. HWND GetInProcDesktop()
  44. {
  45.     HWND hwndDesktop = GetShellWindow();    // This is the "normal" desktop
  46.     
  47.     if (IsDesktopWindow(hwndDesktop))
  48.     {
  49.         DWORD dwProcID;
  50.         
  51.         GetWindowThreadProcessId(hwndDesktop, &dwProcID);
  52.         if (GetCurrentProcessId() == dwProcID) {
  53.             return hwndDesktop;
  54.         }
  55.     }
  56.     
  57.     return NULL;
  58. }
  59. IUnknown* CreateBandFromFile(LPCTSTR pszFile)
  60. {
  61.     TCHAR szClass[80];
  62.     IUnknown* punk = NULL;
  63.     if (!GetPrivateProfileString(SZDESKBAR, TEXT("CLSID"), TEXT(""), szClass, ARRAYSIZE(szClass), pszFile)) {
  64.         
  65.         // if not found, get the stream and do OleLoadFromStream
  66.         IStream* pstm = GetProfileStream(SZDESKBAR, NULL, TEXT("Stream"), pszFile);
  67.         
  68.         if (pstm) {
  69.             OleLoadFromStream(pstm, IID_IUnknown, (LPVOID*)&punk);
  70.             pstm->Release();
  71.         }
  72.     } else {
  73.         CLSID clsid;
  74.         
  75.         if (SHCLSIDFromString(szClass, &clsid))
  76.         {
  77.             if (SUCCEEDED(CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&punk))) {
  78.                 IStream* pstm = GetProfileStream(SZDESKBAR, NULL, TEXT("Stream"), pszFile);
  79.                 if (pstm) {
  80.                     IPersistStream *ppstm;
  81.                     punk->QueryInterface(IID_IPersistStream, (LPVOID*)&ppstm);
  82.                     if (ppstm) {
  83.                         ppstm->Load(pstm);
  84.                         ppstm->Release();
  85.                     }
  86.                     pstm->Release();
  87.                 }
  88.             }
  89.         }
  90.         
  91.     }
  92.     
  93.     return punk;
  94. }
  95. void SFC_IECommand(LPCTSTR pszFile)
  96. {
  97.     // ANSI!
  98.     TCHAR szCommand[40];
  99.     
  100.     if (GetPrivateProfileString(TEXT("IE"), TEXT("Command"), TEXT(""), szCommand, ARRAYSIZE(szCommand), pszFile)) {
  101.         if (!lstrcmpi(szCommand, TEXT("Channels"))
  102.             && !SHRestricted2W(REST_NoChannelUI, NULL, 0))
  103.         {
  104.             Channel_QuickLaunch();
  105.         }
  106.     }
  107. }
  108.    
  109. void SFC_BandFile(LPCTSTR pszFile)
  110. {
  111.     HWND hwndDesktop = GetInProcDesktop();
  112.     
  113.     if (!hwndDesktop) 
  114.         return;
  115.     
  116.     LPTSTR psz = StrDup(pszFile);
  117.     if (!PostMessage(hwndDesktop, DTM_BANDFILE, 0, (LPARAM)psz))
  118.         LocalFree(psz);
  119. }
  120. #if 0
  121. void SFC_DesktopCommand(LPCTSTR pszFile)
  122. {
  123.     UINT uID = GetPrivateProfileInt(TEXT("Desktop"), TEXT("Command"), 0, pszFile);
  124.     if (uID) {
  125.         HWND hwndDesktop = GetInProcDesktop();
  126.         PostMessage(hwndDesktop, uID, 0, 0);
  127.     }
  128. }
  129. #endif
  130. extern HWND g_hwndTray; // desktop.cpp
  131. void SFC_TrayCommand(LPCTSTR pszFile)
  132. {
  133.     // ANSI!
  134.     TCHAR szCommand[40];
  135.     ASSERT(g_hwndTray);
  136.     if (GetPrivateProfileString(TEXT("Taskbar"), TEXT("Command"), TEXT(""), szCommand, ARRAYSIZE(szCommand), pszFile)) {
  137.         char szAnsiCommand[40];
  138.         SHTCharToAnsi(szCommand, szAnsiCommand, ARRAYSIZE(szAnsiCommand));
  139.         LPSTR psz = StrDupA(szAnsiCommand);
  140.         if (psz) {
  141.             if(!PostMessage(g_hwndTray, TM_PRIVATECOMMAND, 0, (LPARAM)psz))
  142.                 LocalFree(psz);
  143.         }
  144.     }
  145. }
  146. enum {
  147.     SCFIDM_NOCOMMAND      = 0,
  148.     SCFIDM_BANDFILE       = 1,
  149.     SCFIDM_TRAYCOMMAND    = 2,
  150.     SCFIDM_IE             = 3,
  151. };
  152. typedef void (*SFCCOMMAND)(LPCTSTR lpszBuf);
  153. typedef struct _EXECCOMMADNINFO
  154. {
  155.     UINT id;
  156.     SFCCOMMAND pfn;
  157. } EXECCOMMANDINFO;
  158. EXECCOMMANDINFO const c_sCmdInfo[] = 
  159. {
  160.     
  161.     { SCFIDM_BANDFILE, SFC_BandFile},
  162.     { SCFIDM_TRAYCOMMAND, SFC_TrayCommand},
  163.     { SCFIDM_IE, SFC_IECommand},
  164. };
  165. void ShellExecCommandFile(LPITEMIDLIST pidl)
  166. {
  167.     TCHAR szFile[MAX_PATH];
  168.     if (SHGetPathFromIDList(pidl, szFile)) {
  169.         UINT uID;
  170.         
  171.         uID = GetPrivateProfileInt(TEXT("Shell"), TEXT("Command"), 0, szFile);
  172.         
  173.         if (uID) {
  174.             int i;
  175.             
  176.             for ( i = 0; i < ARRAYSIZE(c_sCmdInfo); i++) {
  177.                 if (uID == c_sCmdInfo[i].id) {
  178.                     c_sCmdInfo[i].pfn(szFile);
  179.                     break;
  180.                 }
  181.             }
  182.         }
  183.     }
  184. }
  185. class CCmdFileIcon : public IExtractIconA, public IExtractIconW, public IPersistFile
  186. {
  187. public:
  188.     // *** IUnknown methods ***
  189.     STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj);
  190.     STDMETHOD_(ULONG,AddRef) () ;
  191.     STDMETHOD_(ULONG,Release) ();
  192.     // *** IExtractIconA methods ***
  193.     STDMETHOD(GetIconLocation)(
  194.                          UINT   uFlags,
  195.                          LPSTR  szIconFile,
  196.                          UINT   cchMax,
  197.                          int   * piIndex,
  198.                          UINT  * pwFlags);
  199.     STDMETHOD(Extract)(
  200.                            LPCSTR pszFile,
  201.                            UINT   nIconIndex,
  202.                            HICON   *phiconLarge,
  203.                            HICON   *phiconSmall,
  204.                            UINT    nIconSize) {return S_FALSE;};
  205.     // *** IExtractIconW methods ***
  206.     STDMETHOD(GetIconLocation)(
  207.                          UINT   uFlags,
  208.                          LPWSTR  szIconFile,
  209.                          UINT   cchMax,
  210.                          int   * piIndex,
  211.                          UINT  * pwFlags);
  212.     STDMETHOD(Extract)(
  213.                            LPCWSTR pszFile,
  214.                            UINT   nIconIndex,
  215.                            HICON   *phiconLarge,
  216.                            HICON   *phiconSmall,
  217.                            UINT    nIconSize) {return S_FALSE;};
  218.     // IPersist methods
  219.     STDMETHODIMP GetClassID(CLSID *pclsid) { *pclsid = CLSID_CmdFileIcon; return S_OK;};
  220.     
  221.     // IPersistFile methods
  222.     STDMETHODIMP IsDirty(void) {return S_FALSE;};
  223.     STDMETHODIMP Save(LPCOLESTR pcwszFileName, BOOL bRemember) {return S_OK;};
  224.     STDMETHODIMP SaveCompleted(LPCOLESTR pcwszFileName){return S_OK;};
  225.     STDMETHODIMP Load(LPCOLESTR pcwszFileName, DWORD dwMode);
  226.     STDMETHODIMP GetCurFile(LPOLESTR *ppwszFileName);
  227.     
  228.     CCmdFileIcon() { _cRef = 1; DllAddRef(); };
  229.     ~CCmdFileIcon() { DllRelease(); };
  230. protected:
  231.     UINT  _cRef;
  232.     TCHAR _szFile[MAX_PATH];
  233. };
  234. ULONG CCmdFileIcon::AddRef()
  235. {
  236.     _cRef++;
  237.     return _cRef;
  238. }
  239. ULONG CCmdFileIcon::Release()
  240. {
  241.     ASSERT(_cRef > 0);
  242.     _cRef--;
  243.     if (_cRef > 0)
  244.         return _cRef;
  245.     delete this;
  246.     return 0;
  247. }
  248. HRESULT CCmdFileIcon::GetIconLocation( UINT   uFlags,
  249.                                     LPTSTR  szIconFile,
  250.                                     UINT    cchMax,
  251.                                     int   * piIndex,
  252.                                     UINT  * pwFlags)
  253. {
  254.     TCHAR szData[MAX_PATH + 80];
  255.     if (_szFile[0]) {
  256.         *pwFlags = 0;
  257.         *piIndex = 0;
  258.         szIconFile[0] = 0;
  259.         GetPrivateProfileString(TEXT("Shell"), TEXT("IconFile"), TEXT(""), szData, ARRAYSIZE(szData), _szFile);
  260.         
  261.         *piIndex = PathParseIconLocation(szData);
  262.         lstrcpyn(szIconFile, szData, cchMax);
  263.         return S_OK;
  264.     }
  265.     
  266.     return E_FAIL;
  267. }
  268. #ifdef UNICODE
  269. HRESULT CCmdFileIcon::GetIconLocation( UINT   uFlags,
  270.                                     LPSTR  szIconFile,
  271.                                     UINT   cchMax,
  272.                                     int   * piIndex,
  273.                                     UINT  * pwFlags)
  274. {
  275.     WCHAR szAnsiIconPath[MAX_PATH];
  276.     HRESULT hres;
  277.     
  278.     if (SUCCEEDED(hres = GetIconLocation(uFlags, szAnsiIconPath, MAX_PATH, piIndex, pwFlags)))
  279.     {
  280.         SHUnicodeToAnsi(szAnsiIconPath, szIconFile, cchMax);
  281.     }
  282.     
  283.     return hres;
  284. }
  285. #else
  286. HRESULT CCmdFileIcon::GetIconLocation( UINT   uFlags,
  287.                                     LPWSTR  szIconFile,
  288.                                     UINT   cchMax,
  289.                                     int   * piIndex,
  290.                                     UINT  * pwFlags)
  291. {
  292.     CHAR szAnsiIconPath[MAX_PATH];
  293.     HRESULT hres;
  294.     
  295.     if (SUCCEEDED(hres = GetIconLocation(uFlags, szAnsiIconPath, MAX_PATH, piIndex, pwFlags)))
  296.     {
  297.         SHAnsiToUnicode(szAnsiIconPath, szIconFile, cchMax);
  298.     }
  299.     
  300.     return hres;
  301. }
  302. #endif
  303. // IPersistFile::Load handler for Intshcut 
  304. STDMETHODIMP CCmdFileIcon::Load(LPCOLESTR pwszFile, DWORD dwMode)
  305. {
  306.     SHUnicodeToTChar(pwszFile, _szFile, ARRAYSIZE(_szFile));
  307.     return S_OK;
  308. }
  309. STDMETHODIMP CCmdFileIcon::GetCurFile(LPOLESTR *ppwszFileName)
  310. {
  311.     SHTCharToUnicode(_szFile, *ppwszFileName, MAX_PATH);
  312.     return S_OK;
  313. }
  314. HRESULT CCmdFileIcon::QueryInterface(REFIID riid, void **ppvObj)
  315. {
  316.     if (IsEqualIID(riid, IID_IUnknown) || 
  317.         IsEqualIID(riid, IID_IExtractIconA))
  318.     {
  319.         *ppvObj = SAFECAST(this, IExtractIconA*);
  320.     } 
  321.     else if (IsEqualIID(riid, IID_IExtractIconW))
  322.     {
  323.         *ppvObj = SAFECAST(this, IExtractIconW*);
  324.     } 
  325.     else if (IsEqualIID(riid, IID_IPersistFile) ||
  326.             IsEqualIID(riid, IID_IPersist))
  327.     {
  328.         *ppvObj = SAFECAST(this, IPersistFile*);
  329.     }
  330.     else
  331.     {
  332.         *ppvObj = NULL;
  333.         return E_NOINTERFACE;
  334.     }
  335.     AddRef();
  336.     return S_OK;
  337. }
  338. HRESULT CCmdFileIcon_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppunk)
  339. {
  340.     HRESULT hres;
  341.     IUnknown* pObj;
  342.     pObj = (IExtractIcon*)new CCmdFileIcon();
  343.     if (pObj)
  344.     {
  345.         hres = pObj->QueryInterface(riid, ppunk);
  346.         pObj->Release();
  347.     }
  348.     else
  349.     {
  350.         *ppunk = NULL;
  351.         hres = E_OUTOFMEMORY;
  352.     }
  353.     return hres;
  354. }