18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FileSystem.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NotImplemented.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PlatformString.h"
36d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/HashMap.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <windows.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <winbase.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <shlobj.h>
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <shlwapi.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool statFile(String path, struct _stat64& st)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_ARG(path, !path.isNull());
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !_wstat64(path.charactersWithNullTermination(), &st) && (st.st_mode & _S_IFMT) == _S_IFREG;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool getFileSize(const String& path, long long& result)
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct _stat64 sb;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!statFile(path, sb))
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = sb.st_size;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool getFileModificationTime(const String& path, time_t& result)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct _stat64 st;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!statFile(path, st))
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = st.st_mtime;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool fileExists(const String& path)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct _stat64 st;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return statFile(path, st);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool deleteFile(const String& path)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String filename = path;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !!DeleteFileW(filename.charactersWithNullTermination());
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool deleteEmptyDirectory(const String& path)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String filename = path;
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !!RemoveDirectoryW(filename.charactersWithNullTermination());
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString pathByAppendingComponent(const String& path, const String& component)
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UChar> buffer(MAX_PATH);
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (path.length() + 1 > buffer.size())
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(buffer.data(), path.characters(), path.length() * sizeof(UChar));
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer[path.length()] = '\0';
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String componentCopy = component;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!PathAppendW(buffer.data(), componentCopy.charactersWithNullTermination()))
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer.resize(wcslen(buffer.data()));
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String::adopt(buffer);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString fileSystemRepresentation(const String&)
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "";
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool makeAllDirectories(const String& path)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String fullPath = path;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (SHCreateDirectoryEx(0, fullPath.charactersWithNullTermination(), 0) != ERROR_SUCCESS) {
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DWORD error = GetLastError();
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (error != ERROR_FILE_EXISTS && error != ERROR_ALREADY_EXISTS) {
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG_ERROR("Failed to create path %s", path.ascii().data());
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString homeDirectoryPath()
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    notImplemented();
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "";
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString pathGetFileName(const String& path)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String(::PathFindFileName(String(path).charactersWithNullTermination()));
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString directoryName(const String& path)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    String fileName = pathGetFileName(path);
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    String dirName = String(path);
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    dirName.truncate(dirName.length() - pathGetFileName(path).length());
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return dirName;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic String bundleName()
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool initialized;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static String name = "WebKit";
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!initialized) {
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initialized = true;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (CFBundleRef bundle = CFBundleGetMainBundle())
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (CFTypeRef bundleExecutable = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleExecutableKey))
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (CFGetTypeID(bundleExecutable) == CFStringGetTypeID())
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    name = reinterpret_cast<CFStringRef>(bundleExecutable);
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return name;
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic String storageDirectory(DWORD pathIdentifier)
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UChar> buffer(MAX_PATH);
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (FAILED(SHGetFolderPathW(0, pathIdentifier | CSIDL_FLAG_CREATE, 0, 0, buffer.data())))
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer.resize(wcslen(buffer.data()));
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String directory = String::adopt(buffer);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static const String companyNameDirectory = "Apple Computer\\";
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    directory = pathByAppendingComponent(directory, companyNameDirectory + bundleName());
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!makeAllDirectories(directory))
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return directory;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic String cachedStorageDirectory(DWORD pathIdentifier)
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static HashMap<DWORD, String> directories;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashMap<DWORD, String>::iterator it = directories.find(pathIdentifier);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (it != directories.end())
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return it->second;
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String directory = storageDirectory(pathIdentifier);
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    directories.add(pathIdentifier, directory);
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return directory;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCString openTemporaryFile(const char*, PlatformFileHandle& handle)
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    handle = INVALID_HANDLE_VALUE;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char tempPath[MAX_PATH];
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int tempPathLength = ::GetTempPathA(_countof(tempPath), tempPath);
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tempPathLength <= 0 || tempPathLength > _countof(tempPath))
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return CString();
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HCRYPTPROV hCryptProv = 0;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return CString();
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char proposedPath[MAX_PATH];
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (1) {
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char tempFile[] = "XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names)
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const int randomPartLength = 8;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!CryptGenRandom(hCryptProv, randomPartLength, reinterpret_cast<BYTE*>(tempFile)))
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation.
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // don't include both upper and lowercase since Windows file systems are typically not case sensitive.
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < randomPartLength; ++i)
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)];
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(strlen(tempFile) == sizeof(tempFile) - 1);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!PathCombineA(proposedPath, tempPath, tempFile))
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // use CREATE_NEW to avoid overwriting an existing file with the same name
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        handle = CreateFileA(proposedPath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS)
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CryptReleaseContext(hCryptProv, 0);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isHandleValid(handle))
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return CString();
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return proposedPath;
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid closeFile(PlatformFileHandle& handle)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isHandleValid(handle)) {
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::CloseHandle(handle);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        handle = invalidPlatformFileHandle;
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint writeToFile(PlatformFileHandle handle, const char* data, int length)
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isHandleValid(handle))
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD bytesWritten;
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool success = WriteFile(handle, data, length, &bytesWritten, 0);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!success)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<int>(bytesWritten);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool unloadModule(PlatformModule module)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ::FreeLibrary(module);
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString localUserSpecificStorageDirectory()
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return cachedStorageDirectory(CSIDL_LOCAL_APPDATA);
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString roamingUserSpecificStorageDirectory()
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return cachedStorageDirectory(CSIDL_APPDATA);
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool safeCreateFile(const String& path, CFDataRef data)
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create a temporary file.
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WCHAR tempDirPath[MAX_PATH];
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!GetTempPathW(ARRAYSIZE(tempDirPath), tempDirPath))
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WCHAR tempPath[MAX_PATH];
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!GetTempFileNameW(tempDirPath, L"WEBKIT", 0, tempPath))
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HANDLE tempFileHandle = CreateFileW(tempPath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tempFileHandle == INVALID_HANDLE_VALUE)
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Write the data to this temp file.
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD written;
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!WriteFile(tempFileHandle, CFDataGetBytePtr(data), static_cast<DWORD>(CFDataGetLength(data)), &written, 0))
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CloseHandle(tempFileHandle);
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Copy the temp file to the destination file.
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String destination = path;
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!MoveFileExW(tempPath, destination.charactersWithNullTermination(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectVector<String> listDirectory(const String& path, const String& filter)
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> entries;
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    notImplemented();
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return entries;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
311