1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/migration/src/nsIEHistoryEnumerator.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,139 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "nsIEHistoryEnumerator.h" 1.9 + 1.10 +#include <urlhist.h> 1.11 +#include <shlguid.h> 1.12 + 1.13 +#include "nsStringAPI.h" 1.14 +#include "nsNetUtil.h" 1.15 +#include "nsIVariant.h" 1.16 +#include "nsCOMArray.h" 1.17 +#include "nsArrayEnumerator.h" 1.18 + 1.19 +namespace { 1.20 + 1.21 + PRTime FileTimeToPRTime(FILETIME* filetime) 1.22 + { 1.23 + SYSTEMTIME st; 1.24 + ::FileTimeToSystemTime(filetime, &st); 1.25 + PRExplodedTime prt; 1.26 + prt.tm_year = st.wYear; 1.27 + // SYSTEMTIME's day-of-month parameter is 1-based, 1.28 + // PRExplodedTime's is 0-based. 1.29 + prt.tm_month = st.wMonth - 1; 1.30 + prt.tm_mday = st.wDay; 1.31 + prt.tm_hour = st.wHour; 1.32 + prt.tm_min = st.wMinute; 1.33 + prt.tm_sec = st.wSecond; 1.34 + prt.tm_usec = st.wMilliseconds * 1000; 1.35 + prt.tm_wday = 0; 1.36 + prt.tm_yday = 0; 1.37 + prt.tm_params.tp_gmt_offset = 0; 1.38 + prt.tm_params.tp_dst_offset = 0; 1.39 + return PR_ImplodeTime(&prt); 1.40 + } 1.41 + 1.42 +} // Anonymous namespace. 1.43 + 1.44 +//////////////////////////////////////////////////////////////////////////////// 1.45 +//// nsIEHistoryEnumerator 1.46 + 1.47 +NS_IMPL_ISUPPORTS(nsIEHistoryEnumerator, nsISimpleEnumerator) 1.48 + 1.49 +nsIEHistoryEnumerator::nsIEHistoryEnumerator() 1.50 +{ 1.51 + ::CoInitialize(nullptr); 1.52 +} 1.53 + 1.54 +nsIEHistoryEnumerator::~nsIEHistoryEnumerator() 1.55 +{ 1.56 + ::CoUninitialize(); 1.57 +} 1.58 + 1.59 +void 1.60 +nsIEHistoryEnumerator::EnsureInitialized() 1.61 +{ 1.62 + if (mURLEnumerator) 1.63 + return; 1.64 + 1.65 + HRESULT hr = ::CoCreateInstance(CLSID_CUrlHistory, 1.66 + nullptr, 1.67 + CLSCTX_INPROC_SERVER, 1.68 + IID_IUrlHistoryStg2, 1.69 + getter_AddRefs(mIEHistory)); 1.70 + if (FAILED(hr)) 1.71 + return; 1.72 + 1.73 + hr = mIEHistory->EnumUrls(getter_AddRefs(mURLEnumerator)); 1.74 + if (FAILED(hr)) 1.75 + return; 1.76 +} 1.77 + 1.78 +NS_IMETHODIMP 1.79 +nsIEHistoryEnumerator::HasMoreElements(bool* _retval) 1.80 +{ 1.81 + *_retval = false; 1.82 + 1.83 + EnsureInitialized(); 1.84 + MOZ_ASSERT(mURLEnumerator, "Should have instanced an IE History URLEnumerator"); 1.85 + if (!mURLEnumerator) 1.86 + return NS_OK; 1.87 + 1.88 + STATURL statURL; 1.89 + ULONG fetched; 1.90 + 1.91 + // First argument is not implemented, so doesn't matter what we pass. 1.92 + HRESULT hr = mURLEnumerator->Next(1, &statURL, &fetched); 1.93 + if (FAILED(hr) || fetched != 1UL) { 1.94 + // Reached the last entry. 1.95 + return NS_OK; 1.96 + } 1.97 + 1.98 + nsCOMPtr<nsIURI> uri; 1.99 + if (statURL.pwcsUrl) { 1.100 + nsDependentString url(statURL.pwcsUrl); 1.101 + nsresult rv = NS_NewURI(getter_AddRefs(uri), url); 1.102 + ::CoTaskMemFree(statURL.pwcsUrl); 1.103 + if (NS_FAILED(rv)) { 1.104 + // Got a corrupt or invalid URI, continue to the next entry. 1.105 + return HasMoreElements(_retval); 1.106 + } 1.107 + } 1.108 + 1.109 + nsDependentString title(statURL.pwcsTitle); 1.110 + 1.111 + PRTime lastVisited = FileTimeToPRTime(&(statURL.ftLastVisited)); 1.112 + 1.113 + mCachedNextEntry = do_CreateInstance("@mozilla.org/hash-property-bag;1"); 1.114 + MOZ_ASSERT(mCachedNextEntry, "Should have instanced a new property bag"); 1.115 + if (mCachedNextEntry) { 1.116 + mCachedNextEntry->SetPropertyAsInterface(NS_LITERAL_STRING("uri"), uri); 1.117 + mCachedNextEntry->SetPropertyAsAString(NS_LITERAL_STRING("title"), title); 1.118 + mCachedNextEntry->SetPropertyAsInt64(NS_LITERAL_STRING("time"), lastVisited); 1.119 + 1.120 + *_retval = true; 1.121 + } 1.122 + 1.123 + if (statURL.pwcsTitle) 1.124 + ::CoTaskMemFree(statURL.pwcsTitle); 1.125 + 1.126 + return NS_OK; 1.127 +} 1.128 + 1.129 +NS_IMETHODIMP 1.130 +nsIEHistoryEnumerator::GetNext(nsISupports** _retval) 1.131 +{ 1.132 + *_retval = nullptr; 1.133 + 1.134 + if (!mCachedNextEntry) 1.135 + return NS_ERROR_FAILURE; 1.136 + 1.137 + NS_ADDREF(*_retval = mCachedNextEntry); 1.138 + // Release the cached entry, so it can't be returned twice. 1.139 + mCachedNextEntry = nullptr; 1.140 + 1.141 + return NS_OK; 1.142 +}