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

Windows Kernel

Development Platform:

Visual C++

  1. #include <urlmon.h>
  2. #include "item.h"
  3. #include <webcheck.h>
  4. #include "utils.h"
  5. #include "parseinf.h"
  6. #include <mluisupp.h>
  7. extern "C" HRESULT GetControlFolderPath(LPTSTR lpszDir, ULONG ulSizeBuf);
  8. typedef HRESULT (STDAPICALLTYPE *PFNASYNCINSTALLDU)(LPCWSTR,LPCWSTR, LPCWSTR, DWORD,
  9.                                                     DWORD,LPCWSTR, IBindCtx *, LPVOID, DWORD );
  10. // registered clipboard formats
  11. //UINT g_cfFileDescriptor = 0;
  12. //UINT g_cfFileContents = 0;
  13. //UINT g_cfURL = 0;
  14. UINT g_cfPrefDropEffect = 0;
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // CControlItem methods.
  17. CControlItem::CControlItem() 
  18. {
  19.     DebugMsg(DM_TRACE, TEXT("ci - CControlItem() called."));
  20.     DllAddRef();
  21.     m_cRef = 1;
  22.     m_piciUpdate = NULL;
  23.     m_pcpidlUpdate = NULL;
  24.     m_pcdlbsc = NULL;
  25. }        
  26. CControlItem::~CControlItem()
  27. {
  28.     Assert(m_cRef == 0);                 // we should have zero ref count here
  29.     DebugMsg(DM_TRACE, TEXT("ci - ~CControlItem() called."));
  30.     LocalFree((HLOCAL)m_ppcei);
  31.     if (m_pCFolder != NULL)
  32.         m_pCFolder->Release();          // release the pointer to the sf
  33.     DllRelease();
  34. }
  35. HRESULT CControlItem::Initialize(CControlFolder *pCFolder, UINT cidl, LPCITEMIDLIST *ppidl)
  36. {
  37.     m_ppcei = (LPCONTROLPIDL*)LocalAlloc(LPTR, cidl * sizeof(LPCONTROLPIDL));
  38.     if (m_ppcei == NULL)
  39.         return E_OUTOFMEMORY;
  40.     
  41.     m_cItems = cidl;
  42.     m_pCFolder = pCFolder;
  43.     for (UINT i = 0; i < cidl; i++)
  44.         m_ppcei[i] = (LPCONTROLPIDL)(ppidl[i]);
  45.     m_pCFolder->AddRef();      // we're going to hold onto this pointer, so
  46.                                // we need to AddRef it.
  47.     return NOERROR;
  48. }        
  49. HRESULT CControlItem_CreateInstance(
  50.                                CControlFolder *pCFolder,
  51.                                UINT cidl, 
  52.                                LPCITEMIDLIST *ppidl, 
  53.                                REFIID riid, 
  54.                                void **ppvOut)
  55. {
  56.     *ppvOut = NULL;                 // null the out param
  57. //    if (!_ValidateIDListArray(cidl, ppidl))
  58. //        return E_FAIL;
  59.     CControlItem *pCItem = new CControlItem;
  60.     if (pCItem == NULL)
  61.         return E_OUTOFMEMORY;
  62.     HRESULT hr = pCItem->Initialize(pCFolder, cidl, ppidl);
  63.     if (SUCCEEDED(hr))
  64.     {
  65.         hr = pCItem->QueryInterface(riid, ppvOut);
  66.     }
  67.     pCItem->Release();
  68.     if (g_cfPrefDropEffect == 0)
  69.     {
  70. //        g_cfFileDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); // "FileContents"
  71. //        g_cfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);     // "FileDescriptor"
  72. //        g_cfURL = RegisterClipboardFormat(TEXT("UniformResourceLocator"));  // "UniformResourceLocator"
  73.         g_cfPrefDropEffect = RegisterClipboardFormat(TEXT("Preferred DropEffect"));// "Preferred DropEffect"
  74.     }
  75.     return hr;
  76. }
  77. HRESULT CControlItem::QueryInterface(REFIID iid, void **ppv)
  78. {
  79.     DebugMsg(DM_TRACE, TEXT("ci - QueryInterface() called."));
  80.     
  81.     if ((iid == IID_IUnknown) || (iid == IID_IContextMenu))
  82.     {
  83.         *ppv = (LPVOID)(IContextMenu*)this;
  84.     }
  85.     else if (iid == IID_IDataObject) 
  86.     {
  87.         *ppv = (LPVOID)(IDataObject*)this;
  88.     }
  89.     else if (iid == IID_IExtractIcon) 
  90.     {
  91.         *ppv = (LPVOID)(IExtractIcon*)this;
  92.     }
  93.     else if (iid == CLSID_ControlFolder)    // really should be CLSID_ControlFolderItem
  94.     {
  95.         *ppv = (void *)this; // for our friends
  96.     }
  97.     else
  98.     {
  99.         *ppv = NULL;     // null the out param
  100.         return E_NOINTERFACE;
  101.     }
  102.     AddRef();
  103.     return S_OK;
  104. }
  105. ULONG CControlItem::AddRef()
  106. {
  107.     return ++m_cRef;
  108. }
  109. ULONG CControlItem::Release()
  110. {
  111.     if (--m_cRef)
  112.         return m_cRef;
  113.     delete this;
  114.     return 0;   
  115. }
  116. HRESULT CControlItem::GetData(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
  117. {
  118.     HRESULT hres;
  119. #ifdef _DEBUG_
  120.     TCHAR szName[64];
  121.     if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
  122.         wsprintf(szName, "#%d", pFEIn->cfFormat);
  123.     DebugMsg(DM_TRACE, TEXT("ci - do - GetData(%s)"), szName);
  124. #endif
  125.     pSTM->hGlobal = NULL;
  126.     pSTM->pUnkForRelease = NULL;
  127.     if ((pFEIn->cfFormat == g_cfPrefDropEffect) && (pFEIn->tymed & TYMED_HGLOBAL))
  128.         hres = CreatePrefDropEffect(pSTM);
  129.     else 
  130.         hres = E_FAIL;      // FAIL WHEN YOU DON'T SUPPORT IT!!!
  131.     return hres;
  132. }
  133. HRESULT CControlItem::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  134. {
  135.     DebugMsg(DM_TRACE, TEXT("ci - do - GetDataHere() called."));
  136.     return E_NOTIMPL;
  137. }
  138. HRESULT CControlItem::QueryGetData(LPFORMATETC pFEIn)
  139. {
  140. #ifdef _DEBUG_
  141.     TCHAR szName[64];
  142.     if (!GetClipboardFormatName(pFEIn->cfFormat, szName, sizeof(szName)))
  143.         wsprintf(szName, "#%d", pFEIn->cfFormat);
  144.     DebugMsg(DM_TRACE, TEXT("ci - do - QueryGetData(%s)"), szName);
  145. #endif
  146.     if (pFEIn->cfFormat == g_cfPrefDropEffect)
  147.     {
  148.         DebugMsg(DM_TRACE, TEXT("                  format supported."));
  149.         return NOERROR;
  150.     }
  151.     return S_FALSE;
  152. }
  153. HRESULT CControlItem::GetCanonicalFormatEtc(LPFORMATETC pFEIn, LPFORMATETC pFEOut)
  154. {
  155.     DebugMsg(DM_TRACE, TEXT("ci - do - GetCanonicalFormatEtc() called."));
  156.     return DATA_S_SAMEFORMATETC;
  157. }
  158. HRESULT CControlItem::SetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM, BOOL fRelease)
  159. {
  160.     DebugMsg(DM_TRACE,TEXT("ci - do - SetData() called."));
  161.     return E_NOTIMPL;
  162. }
  163. HRESULT CControlItem::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC *ppEnum)
  164. {
  165.     FORMATETC ControlFmte[1] = {
  166.         {(CLIPFORMAT)g_cfPrefDropEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}
  167.     };
  168.     DebugMsg(DM_TRACE, TEXT("ci - do - EnumFormatEtc() called."));
  169.     return SHCreateStdEnumFmtEtc(ARRAYSIZE(ControlFmte), ControlFmte, ppEnum);
  170. }
  171. HRESULT CControlItem::DAdvise(LPFORMATETC pFE, DWORD grfAdv, LPADVISESINK pAdvSink,
  172.     LPDWORD pdwConnection)
  173. {
  174.     DebugMsg(DM_TRACE, TEXT("ci - do - DAdvise() called."));
  175.     return OLE_E_ADVISENOTSUPPORTED;
  176. }
  177. HRESULT CControlItem::DUnadvise(DWORD dwConnection)
  178. {
  179.     DebugMsg(DM_TRACE, TEXT("ci - do - DUnAdvise() called."));
  180.     return OLE_E_ADVISENOTSUPPORTED;
  181. }
  182. HRESULT CControlItem::EnumDAdvise(LPENUMSTATDATA *ppEnum)
  183. {
  184.     DebugMsg(DM_TRACE, TEXT("ci - do - EnumAdvise() called."));
  185.     return OLE_E_ADVISENOTSUPPORTED;
  186. }
  187. HRESULT CControlItem::CreatePrefDropEffect(LPSTGMEDIUM pSTM)
  188. {    
  189.     pSTM->tymed = TYMED_HGLOBAL;
  190.     pSTM->pUnkForRelease = NULL;
  191.     
  192.     pSTM->hGlobal = GlobalAlloc(GPTR, sizeof(DWORD));
  193.     if (pSTM->hGlobal)
  194.     {
  195.         *((LPDWORD)pSTM->hGlobal) = DROPEFFECT_COPY;
  196.         return S_OK;
  197.     }
  198.     return E_OUTOFMEMORY;    
  199. }
  200. HRESULT CControlItem::Remove(HWND hwnd)
  201. {
  202.     TCHAR szMsg[MESSAGE_MAXSIZE];
  203.     TCHAR szBuf[MESSAGE_MAXSIZE];
  204.     if ( !g_fAllAccess )
  205.     {
  206.         // The current user does not have the access privileges to modify the
  207.         // keys we need to tweak to remove a control, so let 'em know and bail
  208.         // out quickly.
  209.         MLLoadString(IDS_WARNING_USERNOACCESS, szMsg, ARRAYSIZE(szMsg));
  210.         MLLoadString(IDS_MBTITLE_REMOVECONTROL, szBuf, ARRAYSIZE(szBuf));
  211.         MessageBox(hwnd, szMsg, szBuf, MB_OK|MB_ICONWARNING);
  212.         return S_FALSE;
  213.     }
  214.     szMsg[0] = '';
  215.     if (m_cItems == 1)
  216.     {
  217. //        if(!PathFileExists(GetStringInfo(m_ppcei[0], SI_LOCATION)) ||
  218. //           IsModuleRemovable(GetStringInfo(m_ppcei[0], SI_LOCATION)))
  219.         {
  220.             MLLoadString(IDS_WARNING_SINGLEREMOVAL, szBuf, ARRAYSIZE(szBuf));
  221.             wsprintf(szMsg, szBuf, GetStringInfo(m_ppcei[0], SI_CONTROL));
  222.         }
  223.     }
  224.     else
  225.     {
  226.         MLLoadString(IDS_WARNING_MULTIPLEREMOVAL, szMsg, ARRAYSIZE(szMsg));
  227.     }
  228.     if (szMsg[0] != '')
  229.     {
  230.         MLLoadString(IDS_MBTITLE_REMOVECONTROL, szBuf, ARRAYSIZE(szBuf));
  231.         if (MessageBox(hwnd, szMsg, szBuf, MB_YESNO | MB_ICONWARNING) != IDYES)
  232.         {
  233.             return S_FALSE;
  234.         }
  235.     }
  236.     // set wait cursor
  237.     HRESULT hr = S_OK;
  238.     HCURSOR hCurOld = StartWaitCur();
  239.     LPCTSTR pszTypeLibId = NULL;
  240.     for (UINT i = 0; i < m_cItems; i++)
  241.     {
  242.         Assert(m_ppcei[i] != NULL);
  243.         if (m_ppcei[i] == NULL)
  244.         {
  245.             hr = E_FAIL;
  246.             break;
  247.         }
  248.         pszTypeLibId = GetStringInfo(m_ppcei[i], SI_TYPELIBID);
  249.         if (SUCCEEDED(hr = RemoveControlByName2(
  250.                                    GetStringInfo(m_ppcei[i], SI_LOCATION),
  251.                                    GetStringInfo(m_ppcei[i], SI_CLSID),
  252.                                    (pszTypeLibId[0] == '' ? NULL : pszTypeLibId),
  253.                                    TRUE, (m_ppcei[i])->ci.dwIsDistUnit, FALSE)))
  254.         {
  255.             if ( hr == S_FALSE )
  256.             {
  257.                 MLLoadString(
  258.                       IDS_ERROR_NOUNINSTALLACTION, 
  259.                       szBuf, 
  260.                       ARRAYSIZE(szBuf));
  261.                 wsprintf(szMsg, szBuf, GetStringInfo(m_ppcei[i], SI_CONTROL));
  262.                 MLLoadString(
  263.                       IDS_MBTITLE_NOUNINSTALLACTION,
  264.                       szBuf,
  265.                       ARRAYSIZE(szBuf));
  266.                 MessageBox(hwnd, szMsg, szBuf, MB_OK|MB_ICONWARNING);
  267.             }
  268.             GenerateEvent(
  269.                      SHCNE_DELETE, 
  270.                      m_pCFolder->m_pidl, 
  271.                      (LPITEMIDLIST)(m_ppcei[i]), 
  272.                      NULL);
  273.         }
  274.         else if (hr == STG_E_SHAREVIOLATION)
  275.         {
  276.             MLLoadString(
  277.                   IDS_CONTROL_INUSE, 
  278.                   szBuf, 
  279.                   ARRAYSIZE(szBuf));
  280.             wsprintf(szMsg, szBuf, GetStringInfo(m_ppcei[i], SI_CONTROL));
  281.             MLLoadString(
  282.                   IDS_MBTITLE_SHAREVIOLATION,
  283.                   szBuf,
  284.                   ARRAYSIZE(szBuf));
  285.             MessageBox(hwnd, szMsg, szBuf, MB_OK|MB_ICONSTOP);
  286.         }
  287.         else
  288.         {
  289.             MLLoadString(
  290.                   IDS_ERROR_REMOVEFAIL,
  291.                   szBuf, 
  292.                   ARRAYSIZE(szBuf));
  293.             wsprintf(szMsg, szBuf, GetStringInfo(m_ppcei[i], SI_CONTROL));
  294.             MLLoadString(
  295.                   IDS_MBTITLE_REMOVEFAIL,
  296.                   szBuf,
  297.                   ARRAYSIZE(szBuf));
  298.             MessageBox(hwnd, szMsg, szBuf, MB_OK|MB_ICONSTOP);
  299.             break;
  300.         }
  301.     }
  302.     EndWaitCur(hCurOld);
  303.     return hr;
  304. }
  305. ///////////////////////////////////////////////////////////////////////////////
  306. // IExtractIcon Methods
  307. STDMETHODIMP CControlItem::GetIconLocation(
  308.                             UINT uFlags,
  309.                             LPSTR szIconFile,
  310.                             UINT cchMax,
  311.                             int *piIndex,
  312.                             UINT *pwFlags)
  313. {
  314.     Assert(szIconFile != NULL);
  315.     Assert(m_cItems == 1);
  316.     if (szIconFile == NULL)
  317.         return S_FALSE;
  318.     *piIndex = 0;
  319.     *pwFlags = 0;
  320.     if (uFlags != GIL_FORSHELL)
  321.         return S_FALSE;
  322.     *pwFlags = GIL_NOTFILENAME|GIL_PERINSTANCE;
  323.     if (cchMax > (UINT)lstrlen(GetStringInfo(m_ppcei[0], SI_LOCATION)))
  324.     {
  325.         lstrcpy(szIconFile, GetStringInfo(m_ppcei[0], SI_LOCATION));
  326.         return NOERROR;
  327.     }
  328.     szIconFile[0] = '';
  329.     return S_FALSE;
  330. }
  331. STDMETHODIMP CControlItem::Extract(
  332.                     LPCSTR pszFile,
  333.                     UINT nIconIndex,
  334.                     HICON *phiconLarge,
  335.                     HICON *phiconSmall,
  336.                     UINT nIconSize)
  337. {
  338.     *phiconLarge = ExtractIcon(g_hInst, pszFile, nIconIndex);
  339.     if (*phiconLarge == NULL)
  340.     {   
  341.         *phiconLarge = GetDefaultOCIcon( m_ppcei[0] );
  342.         Assert(*phiconLarge != NULL);
  343.     }
  344.     *phiconSmall = *phiconLarge;
  345.     return NOERROR;
  346. }
  347. ///////////////////////////////////////////////////////////////////////////////
  348. // IContextMenu Methods
  349. const struct {
  350.     LPCTSTR pszVerb;
  351.     UINT idCmd;
  352. } rgcmds[] = {
  353.     {TEXT("Remove"), IDM_CTRL_REMOVECONTROL},
  354.     {TEXT("Properties"),  IDM_CTRL_PROPERTIES},
  355.     {TEXT("Update"), IDM_CTRL_UPDATE},
  356.     {TEXT("Delete"), IDM_CTRL_REMOVECONTROL},
  357.     {NULL, 0}  // terminator
  358. };
  359. int GetCmdID(LPCTSTR pszCmd)
  360. {
  361.     if ((DWORD_PTR)pszCmd <= 0xFFFF)
  362.         return (int)LOWORD(pszCmd);
  363.     for (int i = 0; rgcmds[i].pszVerb != NULL; i++)
  364.         if (lstrcmpi(pszCmd, rgcmds[i].pszVerb) == 0)
  365.             return rgcmds[i].idCmd;
  366.     return -1;
  367. }
  368. HMENU LoadPopupMenu(UINT id, UINT uSubOffset)
  369. {
  370.     HMENU hmParent, hmPopup;
  371.     hmParent = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(id));
  372.     if (!hmParent)
  373.         return NULL;
  374.     hmPopup = GetSubMenu(hmParent, uSubOffset);
  375.     RemoveMenu(hmParent, uSubOffset, MF_BYPOSITION);
  376.     DestroyMenu(hmParent);
  377.     return hmPopup;
  378. }
  379. UINT MergePopupMenu(
  380.                 HMENU *phMenu, 
  381.                 UINT idResource, 
  382.                 UINT uSubOffset, 
  383.                 UINT indexMenu,  
  384.                 UINT idCmdFirst, 
  385.                 UINT idCmdLast)
  386. {
  387.     HMENU hmMerge;
  388.     if (*phMenu == NULL)
  389.     {
  390.         *phMenu = CreatePopupMenu();
  391.         if (*phMenu == NULL)
  392.             return 0;
  393.         indexMenu = 0;    // at the bottom
  394.     }
  395.     hmMerge = LoadPopupMenu(idResource, uSubOffset);
  396.     if (!hmMerge)
  397.         return 0;
  398.     idCmdLast = Shell_MergeMenus(*phMenu, hmMerge, indexMenu, idCmdFirst, idCmdLast, MM_ADDSEPARATOR);
  399.     
  400.     DestroyMenu(hmMerge);
  401.     return idCmdLast;
  402. }
  403. HRESULT CControlItem::QueryContextMenu(
  404.                                   HMENU hmenu, 
  405.                                   UINT indexMenu, 
  406.                                   UINT idCmdFirst,
  407.                                   UINT idCmdLast, 
  408.                                   UINT uFlags)
  409. {
  410.     UINT idLastMerged = 0;
  411.     DebugMsg(DM_TRACE, TEXT("ci - cm - QueryContextMenu() called."));
  412.     
  413.     if (uFlags & CMF_DVFILE)
  414.     {
  415.         idLastMerged = MergePopupMenu(
  416.                             &hmenu,
  417.                             IDR_FILE_MERGE, 
  418.                             0, 
  419.                             indexMenu, 
  420.                             idCmdFirst,
  421.                             idCmdLast);
  422.         if (IsShowAllFilesEnabled()) {
  423.             CheckMenuItem(hmenu, 1, MF_BYPOSITION | MF_CHECKED);
  424.         }
  425.         else {
  426.             CheckMenuItem(hmenu, 1, MF_BYPOSITION | MF_UNCHECKED);
  427.         }
  428.     }
  429.     else if (!(uFlags & CMF_VERBSONLY))
  430.     {
  431.         DWORD                     dwState = 0;
  432.         // Must have a connection and not be working offline to be able
  433.         // to update.
  434.         if (InternetGetConnectedState(&dwState, 0) && !IsGlobalOffline()) {
  435.             idLastMerged = MergePopupMenu(
  436.                                 &hmenu,
  437.                                 IDR_POPUP_CONTROLCONTEXT, 
  438.                                 0, 
  439.                                 indexMenu, 
  440.                                 idCmdFirst,
  441.                                 idCmdLast);
  442.         }
  443.         else {
  444.             idLastMerged = MergePopupMenu(
  445.                                 &hmenu,
  446.                                 IDR_POPUP_CONTROLCONTEXT_NO_UPDATE,
  447.                                 0, 
  448.                                 indexMenu, 
  449.                                 idCmdFirst,
  450.                                 idCmdLast);
  451.         }
  452.         SetMenuDefaultItem(hmenu, idLastMerged - idCmdFirst, MF_BYPOSITION); // make the last menu, Properties, the default
  453.     }
  454.     return ResultFromShort(idLastMerged - idCmdFirst);    // number of menu items    
  455. }
  456. HRESULT CControlItem::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
  457. {
  458.     UINT i;
  459.     int idCmd = GetCmdID((LPCTSTR)(pici->lpVerb));
  460.     HRESULT hres = S_OK;
  461. //  LPOLESTR                 szMimeType = NULL;
  462. //  LPOLESTR                 szExtension = NULL;
  463. //  LPOLESTR                 szCodeBase = NULL;
  464. //  IBindCtx                *pbc = NULL;
  465. //  CodeDownloadBSC         *pCDLBSC = NULL;
  466.     DebugMsg(DM_TRACE, TEXT("ci - cm - InvokeCommand() called."));
  467.     if (idCmd == IDM_CTRL_REMOVECONTROL)
  468.     {
  469.         hres = Remove(pici->hwnd);
  470.     }
  471.     else if (idCmd == IDM_CTRL_SHOWALL) {
  472.         ToggleShowAllFiles();
  473.         GenerateEvent(SHCNE_UPDATEITEM, m_pCFolder->m_pidl, 0, NULL);
  474.     }
  475.     else
  476.     {
  477.         for (i = 0; i < m_cItems && SUCCEEDED(hres); i++)
  478.             if (m_ppcei[i]) 
  479.             {
  480.                 switch (idCmd)
  481.                 {
  482.                 case IDM_CTRL_PROPERTIES: 
  483.                     hres = CreatePropDialog(pici->hwnd, m_ppcei[i]);
  484.                     break;;
  485.                 case IDM_CTRL_UPDATE:
  486.                     hres = Update( pici, m_ppcei[i] );
  487.  /*
  488.                     hres = CreateBindCtx(0, &pbc);
  489.                     if (SUCCEEDED(hres)) {
  490.                         LPITEMIDLIST pidlUpdate = ILCombine(m_pCFolder->m_pidl,(LPITEMIDLIST)(m_ppcei[i]));
  491.                      
  492.                         // destructor of CodeDownloadBSC will free pidlUpdate 
  493.                         if ( pidlUpdate != NULL &&
  494.                              (pCDLBSC = new CodeDownloadBSC( pici->hwnd, pidlUpdate )) != NULL && 
  495.                              SUCCEEDED(hres = RegisterBindStatusCallback(pbc, pCDLBSC, NULL, 0)))
  496.                         {
  497.                             PFNASYNCINSTALLDU        pfnAsyncInstallDU;
  498.                             HINSTANCE                hModule;
  499.                             pCDLBSC->Release();
  500.                             hModule = LoadLibrary("URLMON.DLL");
  501. #ifdef UNICODE
  502.                             WCHAR swzCodeBase =  (m_ppcei[i])->ci.szCodeBase;
  503.                             WCHAR swzDUName = (m_ppcei[i])->ci.szCLSID;
  504. #else
  505.                             MAKE_WIDEPTR_FROMANSI(swzCodeBase, (m_ppcei[i])->ci.szCodeBase);
  506.                             MAKE_WIDEPTR_FROMANSI(swzDUName, (m_ppcei[i])->ci.szCLSID);
  507. #endif
  508.                             pfnAsyncInstallDU = (PFNASYNCINSTALLDU)GetProcAddress((HMODULE)hModule, "AsyncInstallDistributionUnit");
  509.                             pfnAsyncInstallDU( swzDUName, szMimeType, szExtension,
  510.                                                0xFFFFFFFF, 0xFFFFFFFF,
  511.                                                swzCodeBase,
  512.                                                pbc,
  513.                                                NULL, 0);
  514.                             FreeLibrary(hModule);
  515.                         } 
  516.                         else
  517.                         {
  518.                             if ( pCDLBSC != NULL )
  519.                                 delete pCDLBSC;
  520.                             else if ( pidlUpdate != NULL )
  521.                                 ILFree( pidlUpdate );
  522.                         }
  523.                         if (pbc != NULL) {
  524.                             pbc->Release();
  525.                         }
  526.                     }
  527. */
  528.                     break;
  529.                 default:
  530.                     hres = E_FAIL;
  531.                     break;
  532.                 }
  533.             }
  534.     }
  535.     return hres;
  536. }
  537. HRESULT CControlItem::GetCommandString(
  538.                                    UINT_PTR idCmd, 
  539.                                    UINT uFlags, 
  540.                                    UINT *pwReserved,
  541.                                    LPTSTR pszName, 
  542.                                    UINT cchMax)
  543. {
  544.     HRESULT hres = E_FAIL;
  545.     DebugMsg(DM_TRACE, TEXT("ci - cm - GetCommandString() called."));
  546.     pszName[0] = '';
  547.     if (uFlags == GCS_VERB)
  548.     {
  549.         for (int i = 0; rgcmds[i].pszVerb != NULL; i++)
  550.             if (idCmd == rgcmds[i].idCmd)
  551.             {
  552.                 lstrcpyn(pszName, rgcmds[i].pszVerb, cchMax);
  553.                 hres = NOERROR;
  554.             }
  555.     }
  556.     else if (uFlags == GCS_HELPTEXT)
  557.     {
  558.         hres = NOERROR;
  559.         switch (idCmd)
  560.         {
  561.         case IDM_CTRL_REMOVECONTROL:
  562.             MLLoadString(IDS_HELP_REMOVECONTROL, pszName, cchMax);
  563.             break;
  564.         case IDM_CTRL_PROPERTIES:
  565.             MLLoadString(IDS_HELP_PROPERTIES, pszName, cchMax);
  566.             break;
  567.         case IDM_CTRL_UPDATE:
  568.             MLLoadString(IDS_HELP_UPDATE, pszName, cchMax);
  569.             break;
  570.         default:
  571.             hres = E_FAIL;
  572.         }
  573.     }
  574.     return hres;
  575. }
  576. HRESULT
  577. CControlItem::Update(LPCMINVOKECOMMANDINFO pici, LPCONTROLPIDL pcpidl )
  578. {
  579.     HRESULT         hres = NOERROR;
  580.     m_piciUpdate = pici;
  581.     m_pcpidlUpdate = pcpidl;
  582.     if (pici->hwnd)
  583.     {
  584.         INT_PTR nRes = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_OCUPDATE),
  585.                                   pici->hwnd, CControlItem::DlgProc, (LPARAM)this);
  586.     }
  587.     return hres;
  588. }
  589. INT_PTR CControlItem::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  590. {
  591.     BOOL fRet = TRUE;
  592.     CControlItem* pctlitem = (CControlItem*)GetWindowLongPtr(hDlg, DWLP_USER);
  593.     HRESULT     hr = S_OK;
  594.     IBindCtx    *pbc = NULL;
  595.     LPOLESTR    szMimeType = NULL;
  596.     LPOLESTR    szExtension = NULL;
  597.     TCHAR       szBuf[MESSAGE_MAXSIZE];
  598.     switch (msg)
  599.     {
  600.     case WM_INITDIALOG:
  601.         SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  602.         pctlitem = (CControlItem*)lParam;
  603.         MLLoadString(IDS_UPDATE_CAPTION, szBuf, ARRAYSIZE(szBuf));
  604.         lstrcatn( szBuf, pctlitem->m_pcpidlUpdate->ci.szName, ARRAYSIZE(szBuf));
  605.         SetWindowText( hDlg, szBuf );
  606.         hr = CreateBindCtx(0, &pbc);
  607.         if (SUCCEEDED(hr)) 
  608.         {
  609.             LPITEMIDLIST pidlUpdate = ILCombine(pctlitem->m_pCFolder->m_pidl,(LPITEMIDLIST)(pctlitem->m_pcpidlUpdate));
  610.      
  611.             // destructor of CodeDownloadBSC will free pidlUpdate
  612.             // BUGBUG: if new succeeds but register fails, we'll deallocate pidlUpdate twice.
  613.             if ( pidlUpdate != NULL &&
  614.                  (pctlitem->m_pcdlbsc = new CodeDownloadBSC( pctlitem->m_piciUpdate->hwnd, hDlg, pidlUpdate )) != NULL && 
  615.                  SUCCEEDED(hr = RegisterBindStatusCallback(pbc, pctlitem->m_pcdlbsc, NULL, 0)))
  616.             {
  617.                 PFNASYNCINSTALLDU        pfnAsyncInstallDU;
  618.                 HINSTANCE                hModule;
  619.                 hModule = LoadLibrary("URLMON.DLL");
  620.     #ifdef UNICODE
  621.                 WCHAR swzCodeBase =  pctlitem->m_pcpidlUpdate->ci.szCodeBase;
  622.                 WCHAR swzDUName = pctlitem->m_pcpidlUpdate->ci.szCLSID;
  623.     #else
  624.                 MAKE_WIDEPTR_FROMANSI(swzCodeBase, pctlitem->m_pcpidlUpdate->ci.szCodeBase);
  625.                 MAKE_WIDEPTR_FROMANSI(swzDUName, pctlitem->m_pcpidlUpdate->ci.szCLSID);
  626.     #endif
  627.                 pfnAsyncInstallDU = (PFNASYNCINSTALLDU)GetProcAddress((HMODULE)hModule, "AsyncInstallDistributionUnit");
  628.                 if ( pfnAsyncInstallDU != NULL )
  629.                     hr = pfnAsyncInstallDU( swzDUName, szMimeType, szExtension,
  630.                                            0xFFFFFFFF, 0xFFFFFFFF,
  631.                                            swzCodeBase,
  632.                                            pbc,
  633.                                            NULL, 0);
  634.                 else
  635.                     hr = E_FAIL;
  636.                 FreeLibrary(hModule);
  637.             } 
  638.             else
  639.             {
  640.                 if ( pctlitem->m_pcdlbsc != NULL )
  641.                 {
  642.                     delete pctlitem->m_pcdlbsc;
  643.                     pctlitem->m_pcdlbsc = NULL;
  644.                 }
  645.                 else if ( pidlUpdate != NULL )
  646.                     ILFree( pidlUpdate );
  647.             }
  648.             if (pbc != NULL) {
  649.                 pbc->Release();
  650.             }
  651.         }
  652.         if ( SUCCEEDED(hr) )
  653.         {
  654.             Animate_Open(GetDlgItem(hDlg, IDC_DOWNLOADANIMATE), IDA_DOWNLOAD);
  655.             Animate_Play(GetDlgItem(hDlg, IDC_DOWNLOADANIMATE), 0, -1, -1);
  656.         }
  657.         else
  658.             EndDialog(hDlg, FALSE);
  659.         fRet = 0;
  660.         break;
  661.     case WM_COMMAND:
  662.         switch (LOWORD(wParam))
  663.         {
  664.         case IDCANCEL:
  665.             Assert( pctlitem->m_pcdlbsc != NULL );
  666.             hr = pctlitem->m_pcdlbsc->Abort();
  667.             Assert( SUCCEEDED( hr ) );
  668.             EndDialog(hDlg, FALSE);
  669.             break;
  670.         case DOWNLOAD_PROGRESS:
  671.             SendMessage(GetDlgItem(hDlg, IDC_DOWNLOADPROGRESS), PBM_SETPOS,
  672.                         lParam, 0);
  673.             break;
  674.         case DOWNLOAD_COMPLETE:
  675.             if (lParam)
  676.                 SendMessage(GetDlgItem(hDlg, IDC_DOWNLOADPROGRESS), PBM_SETPOS,
  677.                             100, 0);
  678.             EndDialog(hDlg, lParam);
  679.             break;
  680.         }
  681.         break;
  682.     case WM_CLOSE:
  683.         EndDialog(hDlg, FALSE);
  684.         break;
  685.     case WM_DESTROY:
  686.         Assert( pctlitem->m_pcdlbsc != NULL );
  687.         pctlitem->m_pcdlbsc->_hdlg = NULL;
  688.         pctlitem->m_pcdlbsc->Release();
  689.         break;
  690.     default:
  691.         fRet = FALSE;
  692.     }
  693.     return fRet;
  694. }
  695. BOOL CControlItem::IsGlobalOffline()
  696. {
  697.     DWORD   dwState = 0, dwSize = sizeof(DWORD);
  698.     BOOL    fRet = FALSE;
  699.     if(InternetQueryOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState,
  700.         &dwSize))
  701.     {
  702.         if(dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
  703.             fRet = TRUE;
  704.     }
  705.     return fRet;
  706. }