| /* |
| * Copyright (C) 2014 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "WebKitDLL.h" |
| #include "WebApplicationCache.h" |
| |
| #include "CFDictionaryPropertyBag.h" |
| #include "MarshallingHelpers.h" |
| #include "WebPreferences.h" |
| #include "WebSecurityOrigin.h" |
| #include <WebCore/ApplicationCache.h> |
| #include <WebCore/ApplicationCacheStorage.h> |
| #include <WebCore/COMPtr.h> |
| #include <WebCore/SecurityOrigin.h> |
| #include <comutil.h> |
| #include <wtf/FileSystem.h> |
| #include <wtf/RetainPtr.h> |
| |
| using namespace WebCore; |
| |
| #if USE(CF) |
| static CFStringRef WebKitLocalCacheDefaultsKey = CFSTR("WebKitLocalCache"); |
| #endif |
| |
| // WebApplicationCache --------------------------------------------------------------------------- |
| |
| WebApplicationCache::WebApplicationCache() |
| : m_refCount(0) |
| { |
| gClassCount++; |
| gClassNameCount().add("WebApplicationCache"_s); |
| } |
| |
| WebApplicationCache::~WebApplicationCache() |
| { |
| gClassCount--; |
| gClassNameCount().remove("WebApplicationCache"_s); |
| } |
| |
| WebApplicationCache* WebApplicationCache::createInstance() |
| { |
| WebApplicationCache* instance = new WebApplicationCache(); |
| instance->AddRef(); |
| return instance; |
| } |
| |
| static String applicationCachePath() |
| { |
| String path = FileSystem::localUserSpecificStorageDirectory(); |
| |
| #if USE(CF) |
| auto cacheDirectoryPreference = adoptCF(CFPreferencesCopyAppValue(WebKitLocalCacheDefaultsKey, WebPreferences::applicationId())); |
| if (cacheDirectoryPreference && CFStringGetTypeID() == CFGetTypeID(cacheDirectoryPreference.get())) |
| path = static_cast<CFStringRef>(cacheDirectoryPreference.get()); |
| #endif |
| |
| return path; |
| } |
| |
| WebCore::ApplicationCacheStorage& WebApplicationCache::storage() |
| { |
| static ApplicationCacheStorage& storage = ApplicationCacheStorage::create(applicationCachePath(), "ApplicationCache"_s).leakRef(); |
| |
| return storage; |
| } |
| |
| // IUnknown ------------------------------------------------------------------- |
| |
| HRESULT WebApplicationCache::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IUnknown)) |
| *ppvObject = static_cast<WebApplicationCache*>(this); |
| else if (IsEqualGUID(riid, IID_IWebApplicationCache)) |
| *ppvObject = static_cast<WebApplicationCache*>(this); |
| else |
| return E_NOINTERFACE; |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| ULONG WebApplicationCache::AddRef() |
| { |
| return ++m_refCount; |
| } |
| |
| ULONG WebApplicationCache::Release() |
| { |
| ULONG newRef = --m_refCount; |
| if (!newRef) |
| delete(this); |
| |
| return newRef; |
| } |
| |
| // IWebApplicationCache ------------------------------------------------------------------------------ |
| |
| HRESULT WebApplicationCache::maximumSize(long long* size) |
| { |
| if (!size) |
| return E_POINTER; |
| |
| *size = storage().maximumSize(); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::setMaximumSize(long long size) |
| { |
| storage().deleteAllEntries(); |
| storage().setMaximumSize(size); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::defaultOriginQuota(long long* quota) |
| { |
| if (!quota) |
| return E_POINTER; |
| |
| *quota = storage().defaultOriginQuota(); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::setDefaultOriginQuota(long long quota) |
| { |
| storage().setDefaultOriginQuota(quota); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::diskUsageForOrigin(IWebSecurityOrigin* origin, long long* size) |
| { |
| if (!origin || !size) |
| return E_POINTER; |
| |
| COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin); |
| if (!webSecurityOrigin) |
| return E_FAIL; |
| |
| *size = storage().diskUsageForOrigin(webSecurityOrigin->securityOrigin()->data()); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::deleteAllApplicationCaches() |
| { |
| storage().deleteAllCaches(); |
| return S_OK; |
| } |
| |
| |
| HRESULT WebApplicationCache::deleteCacheForOrigin(IWebSecurityOrigin* origin) |
| { |
| if (!origin) |
| return E_POINTER; |
| |
| COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin); |
| if (!webSecurityOrigin) |
| return E_FAIL; |
| |
| storage().deleteCacheForOrigin(webSecurityOrigin->securityOrigin()->data()); |
| return S_OK; |
| } |
| |
| HRESULT WebApplicationCache::originsWithCache(IPropertyBag** origins) |
| { |
| if (!origins) |
| return E_POINTER; |
| |
| auto coreOrigins = storage().originsWithCache(); |
| |
| #if USE(CF) |
| RetainPtr<CFMutableArrayRef> arrayItem = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, coreOrigins.size(), &MarshallingHelpers::kIUnknownArrayCallBacks)); |
| |
| for (auto& coreOrigin : coreOrigins) |
| CFArrayAppendValue(arrayItem.get(), reinterpret_cast<void*>(WebSecurityOrigin::createInstance(coreOrigin.securityOrigin().ptr()))); |
| |
| auto dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); |
| auto key = MarshallingHelpers::BSTRToCFStringRef(_bstr_t(L"origins")); |
| CFDictionaryAddValue(dictionary.get(), key.get(), arrayItem.get()); |
| |
| COMPtr<CFDictionaryPropertyBag> result = CFDictionaryPropertyBag::createInstance(); |
| result->setDictionary(dictionary.get()); |
| *origins = result.leakRef(); |
| #endif |
| |
| return S_OK; |
| } |