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

Windows Kernel

Development Platform:

Visual C++

  1. //==========================================================================================
  2. // HISTDATA helper (should be a static member)
  3. //==========================================================================================
  4. #define CUrlHistoryProp IntsiteProp
  5. //==========================================================================================
  6. // IntsiteProp class implementation
  7. //==========================================================================================
  8. #ifdef DEBUG
  9. /*----------------------------------------------------------
  10. Purpose: Dump the properties in this object
  11. */
  12. STDMETHODIMP_(void)
  13.     CUrlHistoryProp::Dump(void)
  14. {
  15.     if (IsFlagSet(g_dwDumpFlags, DF_URLPROP))
  16.     {
  17.         TraceMsg(TF_ALWAYS, "  Intsite Property obj: %s", m_szURL);
  18.         URLProp::Dump();
  19.     }
  20. }
  21. #endif
  22. /*----------------------------------------------------------
  23. Purpose: Constructor for URLProp 
  24. */
  25. CUrlHistoryProp::CUrlHistoryProp(void)
  26. {
  27.     // Don't validate this until after construction.
  28.     
  29.     // This object should only be allocated, not used on the stack,
  30.     // because we don't zero-initialize the member variables.
  31.     // Here's a sanity assertion.
  32.     
  33.     ASSERT(NULL == m_pintshcut);
  34.     
  35.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntsiteProp));
  36.     
  37.     return;
  38. }
  39. /*----------------------------------------------------------
  40. Purpose: Destructor for CUrlHistoryProp
  41. */
  42. CUrlHistoryProp::~CUrlHistoryProp(void)
  43. {
  44.     if (m_pintshcut)
  45.     {
  46.         if (!m_fPrivate)
  47.             m_pintshcut->Release();
  48.         m_pintshcut = NULL;
  49.     }
  50.     
  51.     return;
  52. }
  53. STDAPI CIntsiteProp_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppvOut)
  54. {
  55.     HRESULT hres;
  56.     
  57.     *ppvOut = NULL;
  58.     
  59.     ASSERT(punkOuter==NULL)
  60.     IUnknown * piunk = (IUnknown *)new IntsiteProp;
  61.     if ( !piunk ) 
  62.     {
  63.         hres = E_OUTOFMEMORY;
  64.     }
  65.     else
  66.     {
  67.         hres = piunk->QueryInterface(riid, ppvOut);
  68.         piunk->Release();
  69.     }
  70.     
  71.     return hres;        // S_OK or E_NOINTERFACE
  72. }
  73. HRESULT CUrlHistoryProp::Init(void)
  74. {
  75.     return URLProp::Init();
  76. }
  77. STDMETHODIMP CUrlHistoryProp::InitFromDB(LPCTSTR pszURL, Intshcut *pintshcut, BOOL fPrivObj)
  78. {
  79.     // TraceMsg(DM_HISTPROP, "CUHP::InitFromDB called for %s", pszURL);
  80.     // Initialize the in-memory property storage from the file
  81.     // and database
  82.     
  83.     HRESULT hres = Init();
  84.     if (SUCCEEDED(hres))
  85.     {
  86.         if (NULL == m_pintshcut)
  87.         {
  88.             m_fPrivate = fPrivObj;
  89.             if (!m_fPrivate)
  90.                 pintshcut->AddRef();
  91.             m_pintshcut = pintshcut;
  92.         }
  93.         else
  94.         {
  95.             // We can't switch from Private->Public or visaversa.
  96.             ASSERT(fPrivObj == m_fPrivate);
  97.         }
  98.         
  99.         if (pszURL)
  100.         {
  101.             // Is this really a URL?? 
  102.             PARSEDURL pu;
  103.             
  104.             pu.cbSize = SIZEOF(pu);
  105.             hres = ParseURL(pszURL, &pu);
  106.             
  107.             if (S_OK == hres)
  108.             {
  109.                 // Yes; go ahead and initialize
  110.                 StrCpyN(m_szURL, pszURL, SIZECHARS(m_szURL));
  111.                 hres = LoadFromDB(pszURL);
  112.             }
  113.         }
  114.     }
  115.     
  116.     return hres;
  117. }
  118. HRESULT CUrlHistoryProp::LoadFromDB(
  119.     IN LPCTSTR pszURL)
  120. {
  121.     TraceMsg(DM_HISTPROP, "CUHP::LoadFromDB called for %s", pszURL);
  122.     CEI_PREALLOC buf;
  123.     CUrlHistory::s_ConvertToPrefixedUrlW(pszURL, buf.szPrefixedUrl, ARRAYSIZE(buf.szPrefixedUrl), &buf.pszFragment);
  124.     CUrlHistory::s_RetrievePrefixedUrlInfo(buf.szPrefixedUrl, &buf);
  125.     //
  126.     // if there is already an entry for this Url, then we will reuse some of the
  127.     // settings.  retrieve the relevant info if possible.
  128.     //
  129.     if (buf.pcei) {
  130.         CHistoryData* phdPrev =  CHistoryData::s_GetHistoryData(buf.pcei);
  131.         if (phdPrev) {
  132.             //
  133.             // Initialize non-string properties first
  134.             //
  135.             const static PROPSPEC c_aprspec[] = {
  136.                 { PRSPEC_PROPID, PID_INTSITE_FLAGS },
  137.                 { PRSPEC_PROPID, PID_INTSITE_LASTVISIT },
  138.                 { PRSPEC_PROPID, PID_INTSITE_LASTMOD },
  139.                 { PRSPEC_PROPID, PID_INTSITE_WATCH },
  140.             };
  141.             PROPVARIANT apropvar[ARRAYSIZE(c_aprspec)] = { 0 };
  142.             apropvar[0].vt = VT_UI4;
  143.             apropvar[0].lVal = phdPrev->dwFlags;
  144.             apropvar[1].vt = VT_FILETIME;
  145.             apropvar[1].filetime = buf.pcei->LastAccessTime;
  146.             apropvar[2].vt = VT_FILETIME;
  147.             apropvar[2].filetime = buf.pcei->LastModifiedTime;
  148.             apropvar[3].vt = VT_UI4;
  149.             apropvar[3].lVal = phdPrev->dwWatch;
  150.             TraceMsg(DM_HISTPROP, "CUHP::InitFromDB calling WriteMultiple (wFlags=%x)", phdPrev->dwFlags);
  151.            WriteMultiple(ARRAYSIZE(c_aprspec), c_aprspec, apropvar, 0);
  152.             PropStg_DirtyMultiple(m_hstg, ARRAYSIZE(c_aprspec), c_aprspec, FALSE);
  153.             //
  154.             // Then, initialize others
  155.             //
  156.             PROPSPEC prspec;
  157.             prspec.ulKind = PRSPEC_PROPID;
  158.             for (const HISTEXTRA* phextPrev = phdPrev->_GetExtra();
  159.                  !phextPrev->IsTerminator();
  160.                  phextPrev = phextPrev->GetNextFast())
  161.             {
  162.                 TraceMsg(DM_HISTPROP, "CUHP::InitFromDB found HISTEXTRA (id=%d, vt=%d)",
  163.                          phextPrev->idExtra, phextPrev->cbExtra);
  164.                 WCHAR wszBuf[MAX_URL_STRING]; // NOTES: scope must be right
  165.                 apropvar[0].vt = phextPrev->vtExtra;
  166.                 switch(phextPrev->vtExtra) {
  167.                 case VT_LPWSTR:
  168.                     apropvar[0].pwszVal = (LPWSTR)phextPrev->abExtra;
  169.                     break;
  170.                 case VT_LPSTR:
  171.                     //
  172.                     // Notice that we always convert it to LPWSTR
  173.                     //
  174.                     {
  175.                         apropvar[0].pwszVal = wszBuf;
  176.                         LPCSTR pszExtra = (LPCSTR)phextPrev->abExtra;
  177.                         AnsiToUnicode(pszExtra, wszBuf, ARRAYSIZE(wszBuf));
  178.                         apropvar[0].vt = VT_LPWSTR;
  179.                     }
  180.                     break;
  181.                 case VT_UI4:
  182.                 case VT_I4:
  183.                     apropvar[0].lVal = *(DWORD*)phextPrev->abExtra;
  184.                     break;
  185.                 case VT_NULL:
  186.                     ASSERT(phextPrev->idExtra == PID_INTSITE_FRAGMENT);
  187.                     continue;
  188.                 default:
  189.                     ASSERT(0);
  190.                     continue;
  191.                 }
  192.                 prspec.propid = phextPrev->idExtra;
  193.                 WriteMultiple(1, &prspec, apropvar, 0);
  194.                 PropStg_DirtyMultiple(m_hstg, 1, &prspec, FALSE);
  195.             }
  196.         } else {
  197.             TraceMsg(DM_HISTPROP, "CUHP::LoadFromDB can't get phdPrev");
  198.         }
  199.     } else {
  200.         TraceMsg(DM_HISTPROP, "CUHP::LoadFromDB can't get pcei");
  201.     }
  202.     return S_OK;
  203. }
  204. struct URLHIST_ENUMPARAM {
  205.     CUrlHistoryProp* that;
  206.     INTERNET_CACHE_ENTRY_INFO cei;
  207.     LPINTERNET_CACHE_ENTRY_INFO pceiPrev;
  208.     CHistoryData* phdPrev;
  209.     LPHISTEXTRA phextCur;
  210.     UINT cbHistExtra;
  211.     BOOL fDirty;
  212. };
  213. STDAPI s_CommitHistItem(
  214.     IN PROPID        propid,
  215.     IN PROPVARIANT * ppropvar,
  216.     IN LPARAM        lParam)
  217. {
  218.     URLHIST_ENUMPARAM* peparam = (URLHIST_ENUMPARAM*)lParam;
  219.     CHistoryData* phdNew = (CHistoryData*)peparam->cei.lpHeaderInfo;
  220.     TraceMsg(DM_HISTEXTRA, "CUHP::s_CommitHistItem called for id=%d vt=%d (phextCur=%x)",
  221.                 propid, ppropvar->vt, peparam->phextCur);
  222.     UINT cbExtra = 0;
  223.     UINT cbRequired;
  224.     switch(propid) {
  225.     case PID_INTSITE_FLAGS:
  226.         if (ppropvar->vt == VT_UI4 && phdNew) {
  227.             TraceMsg(DM_HISTPROP, "CUHP::s_CommitHistItem updating PID_INSITE_FLAGS (%x to %x)",
  228.                      phdNew->dwFlags, ppropvar->lVal);
  229.             phdNew->dwFlags = ppropvar->lVal;
  230.             peparam->fDirty = TRUE;
  231.         }
  232.         break;
  233.     case PID_INTSITE_WATCH:
  234.         if (ppropvar->vt == VT_UI4 && phdNew) {
  235.             TraceMsg(DM_HISTPROP, "CUHP::s_CommitHistItem updating PID_INSITE_WATCH (%x to %x)",
  236.                      phdNew->dwFlags, ppropvar->lVal);
  237.             phdNew->dwWatch = ppropvar->lVal;
  238.             peparam->fDirty = TRUE;
  239.         }
  240.         break;
  241.     case PID_INTSITE_LASTVISIT:
  242.     case PID_INTSITE_LASTMOD:
  243.         // They are read-only. We can change it if we want.
  244.         ASSERT(0);
  245.         break;
  246.     default:
  247.         switch(ppropvar->vt) {
  248.         case VT_UI4:
  249.         case VT_I4:
  250.             cbExtra = DW_ALIGNED(SIZEOF(HISTEXTRA)-SIZEOF(peparam->phextCur->abExtra)+SIZEOF(UINT));
  251.             if (peparam->phextCur) {
  252.                 peparam->phextCur->cbExtra = cbExtra;
  253.                 peparam->phextCur->idExtra = propid;
  254.                 peparam->phextCur->vtExtra = ppropvar->vt;
  255.                 *(DWORD*)peparam->phextCur->abExtra = ppropvar->lVal;
  256.                 peparam->fDirty = TRUE;
  257.             }
  258.             break;
  259.         case VT_LPWSTR:
  260.             cbRequired = WideCharToMultiByte(CP_ACP, 0, ppropvar->pwszVal, -1,
  261.                                 NULL, 0, NULL, NULL);
  262.             cbExtra = DW_ALIGNED(SIZEOF(HISTEXTRA) + cbRequired);
  263.             if (peparam->phextCur)
  264.             {
  265.                 peparam->phextCur->cbExtra = cbExtra;
  266.                 peparam->phextCur->idExtra = propid;
  267.                 peparam->phextCur->vtExtra = VT_LPSTR;
  268.                 WideCharToMultiByte(CP_ACP, 0, ppropvar->pwszVal, -1, 
  269.                     (LPSTR)peparam->phextCur->abExtra, cbRequired, NULL, NULL);
  270.                 peparam->fDirty = TRUE;
  271.             }
  272.             break;
  273.         case VT_EMPTY:
  274.             if (peparam->phextCur) {
  275.                 peparam->fDirty = TRUE;
  276.             }
  277.             break;
  278.         default:
  279.             ASSERT(0);
  280.             break;
  281.         }
  282.         if (peparam->phextCur) {
  283.             // We are saving the data, move the write pointer.
  284.             TraceMsg(DM_HISTEXTRA, "s_CommitHistItem moving phextCur forward %d bytes",
  285.                      peparam->phextCur->cbExtra);
  286.             peparam->phextCur = peparam->phextCur->GetNextFastForSave();
  287.             ASSERT(peparam->phextCur->cbExtra == 0);
  288.         } else {
  289.             // We are calcurating the required size, just add the size.
  290.             TraceMsg(DM_HISTEXTRA, "s_CommitHistItem adding %d", cbExtra);
  291.             peparam->cbHistExtra += cbExtra;
  292.             // Remove existing one. 
  293.             if (peparam->phdPrev) {
  294.                 // BUGBUG: Bad const to non-const cast
  295.                 HISTEXTRA* phextPrev =
  296.                     (HISTEXTRA*)peparam->phdPrev->_FindExtra(propid);
  297.     
  298.                 if (phextPrev) {
  299.                     TraceMsg(DM_HISTEXTRA, "s_CommitHistItem invalidate an old one id=%d %d bytes",
  300.                               phextPrev->idExtra, phextPrev->cbExtra);
  301.                     phextPrev->vtExtra = VT_EMPTY;
  302.                 }
  303.             }
  304. }
  305.     }
  306.     return S_OK;
  307. };
  308. HRESULT CUrlHistoryProp::Commit(IN DWORD dwFlags)
  309. {
  310.     TraceMsg(DM_HISTPROP, "CUHP::Commit called for %s", m_szURL);
  311.     CEI_PREALLOC buf;
  312.     CUrlHistory::s_ConvertToPrefixedUrlW(m_szURL, buf.szPrefixedUrl, ARRAYSIZE(buf.szPrefixedUrl), &buf.pszFragment);
  313.     CUrlHistory::s_RetrievePrefixedUrlInfo(buf.szPrefixedUrl, &buf);
  314.     HRESULT hres;
  315.     URLHIST_ENUMPARAM eparam = { this };
  316.     ASSERT(eparam.fDirty == FALSE);
  317.     eparam.pceiPrev = buf.pcei;
  318.     if (eparam.pceiPrev) {
  319.         eparam.cei = *eparam.pceiPrev;
  320.         eparam.phdPrev =  CHistoryData::s_GetHistoryData(eparam.pceiPrev);
  321.     }
  322.     // First, enemerate once to get the size for extra. 
  323.     eparam.cei.lpHeaderInfo = NULL;
  324.     eparam.cbHistExtra = 0;
  325.     hres = PropStg_Enum(m_hstg, PSTGEF_DIRTY, s_CommitHistItem, (LPARAM)&eparam);
  326.     DWORD dwFlagsPrev = 0;
  327.     if (eparam.phdPrev) {
  328.         eparam.cbHistExtra += eparam.phdPrev->GetTotalExtraSize();
  329.         dwFlagsPrev = eparam.phdPrev->dwFlags;
  330.     }
  331.     TraceMsg(DM_HISTEXTRA, "CUHP::Commit total size is %d", eparam.cbHistExtra);
  332.     CHistoryData* phdNew = CHistoryData::s_AllocateHeaderInfo(
  333.                                 eparam.cbHistExtra, eparam.phdPrev,
  334.                                 &eparam.cei.dwHeaderInfoSize);
  335.     if (phdNew) {
  336.         eparam.cei.lpHeaderInfo = (LPTSTR)phdNew;
  337.         eparam.phextCur = phdNew->_GetExtra();
  338.         // Enumerate again to fill the extra data. 
  339.         hres = PropStg_Enum(m_hstg, PSTGEF_DIRTY, s_CommitHistItem, (LPARAM)&eparam);
  340.         if (eparam.fDirty)
  341.         {
  342.             if (eparam.phdPrev) {
  343.                 eparam.phdPrev->CopyExtra(eparam.phextCur);
  344.             }
  345.             TraceMsg(DM_HISTPROP, "CUHP::Commit It's dirty. save it (header = %d bytes)",
  346.                      eparam.cei.dwHeaderInfoSize);
  347.             ASSERT(eparam.cbHistExtra == phdNew->GetTotalExtraSize());
  348.             CUrlHistory::s_CommitUrlCacheEntry(buf.szPrefixedUrl, &eparam.cei);
  349.             if ((dwFlagsPrev & PIDISF_RECENTLYCHANGED)
  350.                     != (phdNew->dwFlags & PIDISF_RECENTLYCHANGED))
  351.             {
  352.                 // Yes; update the images
  353.                 CUrlHistory::s_UpdateIcon(m_pintshcut, dwFlagsPrev);
  354.             }
  355.         }
  356.         LocalFree(phdNew);
  357.     }
  358.     return hres;
  359. }