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 }