tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsIEHistoryEnumerator.cpp (3352B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "nsIEHistoryEnumerator.h"
      6 
      7 #include <urlhist.h>
      8 #include <shlguid.h>
      9 
     10 #include "nsArrayEnumerator.h"
     11 #include "nsComponentManagerUtils.h"
     12 #include "nsCOMArray.h"
     13 #include "nsIURI.h"
     14 #include "nsNetUtil.h"
     15 #include "nsString.h"
     16 #include "nsWindowsMigrationUtils.h"
     17 #include "prtime.h"
     18 
     19 ////////////////////////////////////////////////////////////////////////////////
     20 //// nsIEHistoryEnumerator
     21 
     22 nsIEHistoryEnumerator::nsIEHistoryEnumerator() { ::CoInitialize(nullptr); }
     23 
     24 nsIEHistoryEnumerator::~nsIEHistoryEnumerator() { ::CoUninitialize(); }
     25 
     26 void nsIEHistoryEnumerator::EnsureInitialized() {
     27  if (mURLEnumerator) return;
     28 
     29  HRESULT hr =
     30      ::CoCreateInstance(CLSID_CUrlHistory, nullptr, CLSCTX_INPROC_SERVER,
     31                         IID_IUrlHistoryStg2, getter_AddRefs(mIEHistory));
     32  if (FAILED(hr)) return;
     33 
     34  hr = mIEHistory->EnumUrls(getter_AddRefs(mURLEnumerator));
     35  if (FAILED(hr)) return;
     36 }
     37 
     38 NS_IMETHODIMP
     39 nsIEHistoryEnumerator::HasMoreElements(bool* _retval) {
     40  *_retval = false;
     41 
     42  EnsureInitialized();
     43  MOZ_ASSERT(mURLEnumerator,
     44             "Should have instanced an IE History URLEnumerator");
     45  if (!mURLEnumerator) return NS_OK;
     46 
     47  STATURL statURL;
     48  ULONG fetched;
     49 
     50  // First argument is not implemented, so doesn't matter what we pass.
     51  HRESULT hr = mURLEnumerator->Next(1, &statURL, &fetched);
     52  if (FAILED(hr) || fetched != 1UL) {
     53    // Reached the last entry.
     54    return NS_OK;
     55  }
     56 
     57  nsCOMPtr<nsIURI> uri;
     58  if (statURL.pwcsUrl) {
     59    nsDependentString url(statURL.pwcsUrl);
     60    nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
     61    ::CoTaskMemFree(statURL.pwcsUrl);
     62    if (NS_FAILED(rv)) {
     63      // Got a corrupt or invalid URI, continue to the next entry.
     64      return HasMoreElements(_retval);
     65    }
     66  }
     67 
     68  nsDependentString title(statURL.pwcsTitle ? statURL.pwcsTitle : L"");
     69 
     70  bool lastVisitTimeIsValid;
     71  PRTime lastVisited = WinMigrationFileTimeToPRTime(&(statURL.ftLastVisited),
     72                                                    &lastVisitTimeIsValid);
     73 
     74  mCachedNextEntry = do_CreateInstance("@mozilla.org/hash-property-bag;1");
     75  MOZ_ASSERT(mCachedNextEntry, "Should have instanced a new property bag");
     76  if (mCachedNextEntry) {
     77    mCachedNextEntry->SetPropertyAsInterface(u"uri"_ns, uri);
     78    mCachedNextEntry->SetPropertyAsAString(u"title"_ns, title);
     79    if (lastVisitTimeIsValid) {
     80      mCachedNextEntry->SetPropertyAsInt64(u"time"_ns, lastVisited);
     81    }
     82 
     83    *_retval = true;
     84  }
     85 
     86  if (statURL.pwcsTitle) ::CoTaskMemFree(statURL.pwcsTitle);
     87 
     88  return NS_OK;
     89 }
     90 
     91 NS_IMETHODIMP
     92 nsIEHistoryEnumerator::GetNext(nsISupports** _retval) {
     93  *_retval = nullptr;
     94 
     95  EnsureInitialized();
     96  MOZ_ASSERT(mURLEnumerator,
     97             "Should have instanced an IE History URLEnumerator");
     98  if (!mURLEnumerator) return NS_OK;
     99 
    100  if (!mCachedNextEntry) {
    101    bool hasMore = false;
    102    nsresult rv = this->HasMoreElements(&hasMore);
    103    if (NS_FAILED(rv)) {
    104      return rv;
    105    }
    106    if (!hasMore) {
    107      return NS_ERROR_FAILURE;
    108    }
    109  }
    110 
    111  NS_ADDREF(*_retval = mCachedNextEntry);
    112  // Release the cached entry, so it can't be returned twice.
    113  mCachedNextEntry = nullptr;
    114 
    115  return NS_OK;
    116 }