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

Windows Kernel

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #ifdef POSTSPLIT
  4. //#include "sdspatch.h"
  5. //#include "..ids.h"
  6. //#include "dutil.h"
  7. //#include <shsemip.h>
  8. // This is the implementation for the Shell Application level IDispatch
  9. // Currently we will try to maintain only one object per process.
  10. // BUGBUG:: The following defines must be equal to the stuff in cabinet.h...
  11. #define IDM_SYSBUTTON   300
  12. #define IDM_FINDBUTTON  301
  13. #define IDM_HELPBUTTON  302
  14. #define IDM_FILERUN                 401
  15. #define IDM_CASCADE                 403
  16. #define IDM_HORIZTILE               404
  17. #define IDM_VERTTILE                405
  18. #define IDM_DESKTOPARRANGEGRID      406
  19. #define IDM_ARRANGEMINIMIZEDWINDOWS 407
  20. #define IDM_SETTIME                 408
  21. #define IDM_SUSPEND                 409
  22. #define IDM_EJECTPC                 410
  23. #define IDM_TASKLIST                412
  24. #define IDM_TRAYPROPERTIES          413
  25. #define IDM_EDITSTARTMENU           414
  26. #define IDM_MINIMIZEALL             415
  27. #define IDM_UNDO                    416
  28. #define IDM_RETURN                  417
  29. #define IDM_PRINTNOTIFY_FOLDER      418
  30. #define IDM_MINIMIZEALLHOTKEY       419
  31. #define IDM_SHOWTASKMAN             420
  32. #define IDM_RECENT              501
  33. #define IDM_FIND                502
  34. #define IDM_PROGRAMS            504
  35. #define IDM_CONTROLS            505
  36. #define IDM_EXITWIN             506
  37. // #define IDM_FONTS            509
  38. #define IDM_PRINTERS            510
  39. #define IDM_STARTMENU           511
  40. #define IDM_MYCOMPUTER          512
  41. #define IDM_PROGRAMSINIT        513
  42. #define IDM_RECENTINIT          514
  43. #define IDM_MENU_FIND           520
  44. #define TRAY_IDM_FINDFIRST      521  // this range
  45. #define TRAY_IDM_FINDLAST       550  // is reserved for find command
  46. #define IDM_RECENTLIST          650
  47. #define IDM_QUICKTIPS   800
  48. #define IDM_HELPCONT    801
  49. #define IDM_WIZARDS     802
  50. #define IDM_USEHELP     803             // REVIEW: probably won't be used
  51. #define IDM_TUTORIAL    804
  52. #define IDM_ABOUT       805
  53. #define IDM_LAST_MENU_ITEM   IDM_ABOUT
  54. #define FCIDM_FIRST             FCIDM_GLOBALFIRST
  55. #define FCIDM_LAST              FCIDM_BROWSERLAST
  56. //#define FCIDM_FINDFILES         (FCIDM_BROWSER_TOOLS+0x0005)
  57. #define FCIDM_FINDCOMPUTER      (FCIDM_BROWSER_TOOLS+0x0006)
  58. //============================================================================
  59. class CShellDispatch : public IShellDispatch, 
  60.                        public CObjectSafety,
  61.                        protected CImpIDispatch,
  62.                        public CObjectWithSite
  63. {
  64.    friend class CAdviseRouter;
  65.    friend HRESULT GetApplicationObject(DWORD dwSafetyOptions, IUnknown *punkSite, IDispatch **ppid);
  66.     public:
  67.         //Non-delegating object IUnknown
  68.         STDMETHODIMP         QueryInterface(REFIID, LPVOID*);
  69.         STDMETHODIMP_(ULONG) AddRef(void);
  70.         STDMETHODIMP_(ULONG) Release(void);
  71.         //IDispatch members
  72.         virtual STDMETHODIMP GetTypeInfoCount(UINT * pctinfo)
  73.             { return CImpIDispatch::GetTypeInfoCount(pctinfo); }
  74.         virtual STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
  75.             { return CImpIDispatch::GetTypeInfo(itinfo, lcid, pptinfo); }
  76.         virtual STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid)
  77.             { return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); }
  78.         virtual STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
  79.             { return CImpIDispatch::Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); }
  80.         //IShellDispatch functions
  81.         STDMETHODIMP get_Application(IDispatch **ppid);
  82.         STDMETHODIMP get_Parent (IDispatch **ppid);
  83.         STDMETHOD(Open)(THIS_ VARIANT vDir);
  84.         STDMETHOD(Explore)(THIS_ VARIANT vDir);
  85.         STDMETHOD(NameSpace)(THIS_ VARIANT vDir, Folder **ppsdf);
  86.         STDMETHODIMP BrowseForFolder(long Hwnd, BSTR Title, long Options, VARIANT RootFolder, Folder **ppsdf);
  87.         STDMETHODIMP ControlPanelItem(BSTR szDir);
  88.         STDMETHODIMP MinimizeAll(void);
  89.         STDMETHODIMP UndoMinimizeALL(void);
  90.         STDMETHODIMP FileRun(void);
  91.         STDMETHODIMP CascadeWindows(void);
  92.         STDMETHODIMP TileVertically(void);
  93.         STDMETHODIMP TileHorizontally(void);
  94.         STDMETHODIMP ShutdownWindows(void);
  95.         STDMETHODIMP Suspend(void);
  96.         STDMETHODIMP EjectPC(void);
  97.         STDMETHODIMP SetTime(void);
  98.         STDMETHODIMP TrayProperties(void);
  99.         STDMETHODIMP Help(void);
  100.         STDMETHODIMP FindFiles(void);
  101.         STDMETHODIMP FindComputer(void);
  102.         STDMETHODIMP RefreshMenu(void);
  103.         STDMETHODIMP Windows(IDispatch **ppid);
  104.         STDMETHODIMP get_ObjectCount(int *pcObjs);
  105.         // Constructor and the like.. 
  106.         CShellDispatch(void);
  107.     protected:
  108.             ULONG           m_cRef;             //Object reference count
  109.     
  110.         ~CShellDispatch(void);
  111.         BOOL            FAllowUserToDoAnything(void);   // Check if we are in paranoid mode...
  112.         HRESULT         _TrayCommand(UINT idCmd);
  113.         HRESULT         ExecuteFolder(VARIANT vDir, LPCTSTR pszVerb);
  114. };
  115. STDAPI CShellDispatch_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppvOut)
  116. {
  117.     HRESULT hr = E_OUTOFMEMORY;
  118.     *ppvOut = NULL;
  119.     TraceMsg(DM_TRACE, "CSD_CreateInstance called");
  120.     // aggregation checking is handled in class factory
  121.     CShellDispatch * pshd = new CShellDispatch();
  122.     if (pshd)
  123.     {
  124.         hr = pshd->QueryInterface(riid, ppvOut);
  125.         pshd->Release();   // g_pCShellDispatch doesn't want a ref.
  126.     }
  127.     return hr;
  128. }
  129. HRESULT GetApplicationObject(DWORD dwSafetyOptions, IUnknown *punkSite, IDispatch **ppid)
  130. {
  131.     *ppid = NULL;   // Handle failure cases.
  132.     if (dwSafetyOptions && (!punkSite || LocalZoneCheck(punkSite) != S_OK))
  133.         return E_ACCESSDENIED;
  134.     HRESULT hres = CShellDispatch_CreateInstance(NULL, IID_IDispatch, (LPVOID *) ppid);
  135.     if (SUCCEEDED(hres))
  136.     {
  137.         if (punkSite)
  138.             IUnknown_SetSite(*ppid, punkSite);
  139.         if (dwSafetyOptions && SUCCEEDED(hres))
  140.             hres = MakeSafeForScripting((IUnknown**)ppid);
  141.     }
  142.     return hres;
  143. }
  144. CShellDispatch::CShellDispatch(void) :
  145.         m_cRef(1), 
  146.         CImpIDispatch(&LIBID_Shell32, 1, 0, &IID_IShellDispatch)
  147. {
  148.     DllAddRef();
  149.     TraceMsg(DM_TRACE, "CShellDispatch::CShellDispatch called");
  150. }
  151. CShellDispatch::~CShellDispatch(void)
  152. {
  153.     TraceMsg(DM_TRACE, "CShellDispatch::~CShellDispatch called");
  154.     DllRelease();
  155. }
  156. BOOL  CShellDispatch::FAllowUserToDoAnything(void)
  157. {
  158.     
  159.     if (!_dwSafetyOptions)
  160.         return TRUE;   // We are not running in safe mode so say everything is OK...   
  161.     if (!_punkSite)
  162.         return FALSE;   // We are in safe but don't have anyway to know where we are...
  163.     return (LocalZoneCheck(_punkSite) == S_OK);
  164. }
  165. STDMETHODIMP CShellDispatch::QueryInterface(REFIID riid, LPVOID* ppv)
  166. {
  167.     TraceMsg(DM_TRACE, "CShellDispatch::QueryInterface called");
  168.     static const QITAB qit[] = {
  169.         QITABENT(CShellDispatch, IShellDispatch),
  170.         QITABENTMULTI(CShellDispatch, IDispatch, IShellDispatch),
  171.         QITABENT(CShellDispatch, IObjectSafety),
  172.         QITABENT(CShellDispatch, IObjectWithSite),
  173.         { 0 },
  174.     };
  175.     return QISearch(this, qit, riid, ppv);
  176. }
  177. STDMETHODIMP_(ULONG) CShellDispatch::AddRef(void)
  178. {
  179.     TraceMsg(DM_TRACE, "CShellDispatch::AddRef called");
  180.     return ++m_cRef;
  181. }
  182. STDMETHODIMP_(ULONG) CShellDispatch::Release(void)
  183. {
  184.     TraceMsg(DM_TRACE, "CShellDispatch::Release called");
  185.     if (0L!=--m_cRef)
  186.         return m_cRef;
  187.     delete this;
  188.     return 0L;
  189. }
  190. // Helper function to process commands to the tray.
  191. HRESULT CShellDispatch::_TrayCommand(UINT idCmd)
  192. {
  193.     if (!FAllowUserToDoAnything())
  194.         return E_ACCESSDENIED;
  195.     HWND hwndTray = FindWindowA(WNDCLASS_TRAYNOTIFY, NULL);
  196.     if (hwndTray)
  197.         PostMessage(hwndTray, WM_COMMAND, idCmd, 0);
  198.     return NOERROR;
  199. }
  200. STDMETHODIMP CShellDispatch::get_Application(IDispatch **ppid)
  201. {
  202.     // Simply return ourself
  203.     return QueryInterface(IID_IDispatch, (PVOID*)ppid);
  204. }
  205. STDMETHODIMP CShellDispatch::get_Parent(IDispatch **ppid)
  206. {
  207.     return QueryInterface(IID_IDispatch, (PVOID*)ppid);
  208. }
  209. HRESULT CShellDispatch::ExecuteFolder(VARIANT vDir, LPCTSTR pszVerb)
  210. {
  211.     SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)};  
  212.     // Check to see if we allow the user to do this...
  213.     if (!FAllowUserToDoAnything())
  214.         return E_ACCESSDENIED;
  215.     sei.lpIDList = (LPVOID)VariantToIDList(&vDir);
  216.     if (sei.lpIDList)
  217.     {
  218.         // Everything should have been initialize to 0
  219.         // BUGBUG:: Should be invoke idlist but that is failing when
  220.         // explore
  221.         sei.fMask = SEE_MASK_IDLIST;
  222.         sei.nShow = SW_SHOWNORMAL;
  223.         sei.lpVerb = pszVerb;
  224.         //TraceMsg(DM_TRACE, "CShellDispatch::Open(%s) called", szParam);
  225.         HRESULT hres = ShellExecuteEx(&sei) ? NOERROR : S_FALSE;
  226.         ILFree((LPITEMIDLIST)sei.lpIDList);
  227.         return hres;
  228.     }
  229.     return S_FALSE; // bad dir
  230. }
  231. STDMETHODIMP CShellDispatch::Open(VARIANT vDir)
  232. {
  233.     return ExecuteFolder(vDir, NULL);
  234. }
  235. STDMETHODIMP CShellDispatch::Explore(VARIANT vDir)
  236. {
  237.     return ExecuteFolder(vDir, TEXT("explore"));
  238. }
  239. STDMETHODIMP CShellDispatch::NameSpace(VARIANT vDir, Folder **ppsdf)
  240. {
  241.     *ppsdf = NULL;
  242.     if (!FAllowUserToDoAnything())
  243.         return E_ACCESSDENIED;
  244.     LPITEMIDLIST pidl = VariantToIDList(&vDir);
  245.     if (pidl)
  246.     {
  247.         CSDFolder *psdf;
  248.         HRESULT hres = CSDFolder_Create(NULL, pidl, NULL, &psdf);
  249.         if (SUCCEEDED(hres))
  250.         {
  251.             hres = psdf->QueryInterface(IID_Folder, (LPVOID *)ppsdf);
  252.             psdf->Release();
  253.         }
  254.         ILFree(pidl);
  255.         return hres;
  256.     }
  257.     return S_FALSE; // bad dir
  258. }
  259. STDMETHODIMP CShellDispatch::BrowseForFolder(long Hwnd, BSTR Title, long Options, 
  260.         VARIANT RootFolder, Folder **ppsdf)
  261. {
  262.     // BUGBUG:: Not all of the arguments are being processed yet...
  263.     TCHAR szTitle[MAX_PATH];      // hopefully long enough...
  264.     BROWSEINFO browse;
  265.     LPITEMIDLIST pidl;
  266.     HRESULT hres;
  267.     if (!FAllowUserToDoAnything())
  268.         return E_ACCESSDENIED;
  269.     SHUnicodeToTCharCP(CP_ACP, Title, szTitle, ARRAYSIZE(szTitle));
  270.     browse.lpszTitle = szTitle;
  271.     browse.pszDisplayName = NULL;
  272.     browse.hwndOwner = (HWND)Hwnd;
  273.     browse.ulFlags = (ULONG)Options;
  274.     browse.lpfn = NULL;
  275.     browse.lParam = 0;
  276.     browse.iImage = 0;
  277.     browse.pidlRoot = VariantToIDList(&RootFolder);
  278.     pidl = SHBrowseForFolder(&browse);
  279.     if (browse.pidlRoot)
  280.         ILFree((LPITEMIDLIST)browse.pidlRoot);
  281.     *ppsdf = NULL;
  282.     if (!pidl)
  283.         return S_FALSE;     // Not a strong error...
  284.     CSDFolder *psdf;
  285.     hres = CSDFolder_Create(NULL, pidl, NULL, &psdf);
  286.     if (SUCCEEDED (hres))
  287.     {
  288.         hres = psdf->QueryInterface(IID_Folder, (LPVOID *)ppsdf);
  289.         psdf->Release();
  290.     }
  291.     ILFree(pidl);
  292.     return hres;
  293. }
  294. STDMETHODIMP CShellDispatch::ControlPanelItem(BSTR bszDir)
  295. {
  296.     if (!FAllowUserToDoAnything())
  297.         return E_ACCESSDENIED;
  298. #ifdef UNICODE
  299.     SHRunControlPanel(bszDir, NULL);
  300. #else // UNICODE
  301.     TCHAR szParam[MAX_PATH];
  302.     SHUnicodeToAnsiCP(CP_ACP, bszDir, szParam, ARRAYSIZE(szParam));
  303.     SHRunControlPanel(szParam, NULL);
  304.     TraceMsg(DM_TRACE, "CShellDispatch::ControlPanelItem(%s) called", szParam);
  305. #endif // UNICODE
  306.     return NOERROR;
  307. }
  308. STDMETHODIMP CShellDispatch::MinimizeAll(void)
  309. {
  310.     return _TrayCommand(IDM_MINIMIZEALL);
  311. }
  312. STDMETHODIMP CShellDispatch::UndoMinimizeALL(void)
  313. {
  314.     return _TrayCommand(IDM_UNDO);
  315. }
  316. STDMETHODIMP CShellDispatch::FileRun(void)
  317. {
  318.     return _TrayCommand(IDM_FILERUN);
  319. }
  320. STDMETHODIMP CShellDispatch::CascadeWindows(void)
  321. {
  322.     return _TrayCommand(IDM_CASCADE);
  323. }
  324. STDMETHODIMP CShellDispatch::TileVertically(void)
  325. {
  326.     return _TrayCommand(IDM_VERTTILE);
  327. }
  328. STDMETHODIMP CShellDispatch::TileHorizontally(void)
  329. {
  330.     return _TrayCommand(IDM_HORIZTILE);
  331. }
  332. STDMETHODIMP CShellDispatch::ShutdownWindows(void)
  333. {
  334.     return _TrayCommand(IDM_EXITWIN);
  335. }
  336. STDMETHODIMP CShellDispatch::Suspend(void)
  337. {
  338.     return _TrayCommand(IDM_SUSPEND);
  339. }
  340. STDMETHODIMP CShellDispatch::EjectPC(void)
  341. {
  342.     return _TrayCommand(IDM_EJECTPC);
  343. }
  344. STDMETHODIMP CShellDispatch::SetTime(void)
  345. {
  346.     return _TrayCommand(IDM_SETTIME);
  347. }
  348. STDMETHODIMP CShellDispatch::TrayProperties(void)
  349. {
  350.     return _TrayCommand(IDM_TRAYPROPERTIES);
  351. }
  352. STDMETHODIMP CShellDispatch::Help(void)
  353. {
  354.     return _TrayCommand(DVIDM_HELPSEARCH);
  355. }
  356. STDMETHODIMP CShellDispatch::FindFiles(void)
  357. {
  358.     return _TrayCommand(FCIDM_FINDFILES);
  359. }
  360. STDMETHODIMP CShellDispatch::FindComputer(void)
  361. {
  362.     return _TrayCommand(FCIDM_FINDCOMPUTER);
  363. }
  364. STDMETHODIMP CShellDispatch::RefreshMenu(void)
  365. {
  366.     return _TrayCommand(FCIDM_REFRESH);
  367. }
  368. STDMETHODIMP CShellDispatch::Windows(IDispatch **ppid)
  369. {
  370.     if (!FAllowUserToDoAnything())
  371.         return E_ACCESSDENIED;
  372.     return CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (LPVOID*)ppid);
  373. }
  374. #endif // POSTSPLIT