147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32filesystem.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h" 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <shellapi.h> 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <shlobj.h> 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <tchar.h> 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/fileutils.h" 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/pathutils.h" 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/scoped_ptr.h" 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stream.h" 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringutils.h" 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// In several places in this file, we test the integrity level of the process 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// before calling GetLongPathName. We do this because calling GetLongPathName 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// when running under protected mode IE (a low integrity process) can result in 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// a virtualized path being returned, which is wrong if you only plan to read. 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Waiting to hear back from IE team on whether this is the 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// best approach; IEIsProtectedModeProcess is another possible solution. 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::CreateFolder(const Pathname &pathname) { 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (pathname.pathname().empty() || !pathname.filename().empty()) 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::wstring path16; 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!Utf8ToWindowsFilename(pathname.pathname(), &path16)) 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD res = ::GetFileAttributes(path16.c_str()); 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (res != INVALID_FILE_ATTRIBUTES) { 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Something exists at this location, check if it is a directory 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ((res & FILE_ATTRIBUTE_DIRECTORY) != 0); 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if ((GetLastError() != ERROR_FILE_NOT_FOUND) 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org && (GetLastError() != ERROR_PATH_NOT_FOUND)) { 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Unexpected error 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Directory doesn't exist, look up one directory level 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!pathname.parent_folder().empty()) { 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Pathname parent(pathname); 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org parent.SetFolder(pathname.parent_folder()); 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!CreateFolder(parent)) { 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (::CreateDirectory(path16.c_str(), NULL) != 0); 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFileStream *Win32Filesystem::OpenFile(const Pathname &filename, 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const std::string &mode) { 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FileStream *fs = new FileStream(); 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete fs; 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org fs = NULL; 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return fs; 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::CreatePrivateFile(const Pathname &filename) { 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // To make the file private to the current user, we first must construct a 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // SECURITY_DESCRIPTOR specifying an ACL. This code is mostly based upon 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // http://msdn.microsoft.com/en-us/library/ms707085%28VS.85%29.aspx 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get the current process token. 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HANDLE process_token = INVALID_HANDLE_VALUE; 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::OpenProcessToken(::GetCurrentProcess(), 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TOKEN_QUERY, 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &process_token)) { 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "OpenProcessToken() failed"; 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get the size of its TOKEN_USER structure. Return value is not checked 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // because we expect it to fail. 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD token_user_size = 0; 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (void)::GetTokenInformation(process_token, 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TokenUser, 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NULL, 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0, 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &token_user_size); 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get the TOKEN_USER structure. 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_ptr<char[]> token_user_bytes(new char[token_user_size]); 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PTOKEN_USER token_user = reinterpret_cast<PTOKEN_USER>( 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org token_user_bytes.get()); 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(token_user, 0, token_user_size); 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL success = ::GetTokenInformation(process_token, 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TokenUser, 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org token_user, 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org token_user_size, 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &token_user_size); 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We're now done with this. 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ::CloseHandle(process_token); 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!success) { 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "GetTokenInformation() failed"; 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsValidSid(token_user->User.Sid)) { 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "Current process has invalid user SID"; 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Compute size needed for an ACL that allows access to just this user. 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetLengthSid(token_user->User.Sid); 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Allocate it. 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_ptr<char[]> acl_bytes(new char[acl_size]); 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PACL acl = reinterpret_cast<PACL>(acl_bytes.get()); 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(acl, 0, acl_size); 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::InitializeAcl(acl, acl_size, ACL_REVISION)) { 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "InitializeAcl() failed"; 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Allow access to only the current user. 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::AddAccessAllowedAce(acl, 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ACL_REVISION, 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GENERIC_READ | GENERIC_WRITE | STANDARD_RIGHTS_ALL, 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org token_user->User.Sid)) { 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "AddAccessAllowedAce() failed"; 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Now make the security descriptor. 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SECURITY_DESCRIPTOR security_descriptor; 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::InitializeSecurityDescriptor(&security_descriptor, 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SECURITY_DESCRIPTOR_REVISION)) { 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "InitializeSecurityDescriptor() failed"; 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Put the ACL in it. 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::SetSecurityDescriptorDacl(&security_descriptor, 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TRUE, 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org acl, 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FALSE)) { 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "SetSecurityDescriptorDacl() failed"; 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Finally create the file. 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SECURITY_ATTRIBUTES security_attributes; 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org security_attributes.nLength = sizeof(security_attributes); 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org security_attributes.lpSecurityDescriptor = &security_descriptor; 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org security_attributes.bInheritHandle = FALSE; 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HANDLE handle = ::CreateFile( 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(filename.pathname()).c_str(), 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GENERIC_READ | GENERIC_WRITE, 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &security_attributes, 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CREATE_NEW, 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0, 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NULL); 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (INVALID_HANDLE_VALUE == handle) { 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "CreateFile() failed"; 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::CloseHandle(handle)) { 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_ERR(LS_ERROR) << "CloseFile() failed"; 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Continue. 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::DeleteFile(const Pathname &filename) { 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Deleting file " << filename.pathname(); 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsFile(filename)) { 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(IsFile(filename)); 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0; 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::DeleteEmptyFolder(const Pathname &folder) { 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Deleting folder " << folder.pathname(); 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ::RemoveDirectory(ToUtf16(no_slash).c_str()) != 0; 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetTemporaryFolder(Pathname &pathname, bool create, 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const std::string *append) { 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org wchar_t buffer[MAX_PATH + 1]; 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::GetTempPath(ARRAY_SIZE(buffer), buffer)) 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsCurrentProcessLowIntegrity() && 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t len = strlen(buffer); 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((len > 0) && (buffer[len-1] != '\\')) { 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, L"\\"); 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len >= ARRAY_SIZE(buffer) - 1) 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pathname.clear(); 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pathname.SetFolder(ToUtf8(buffer)); 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (append != NULL) { 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(!append->empty()); 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pathname.AppendFolder(*append); 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return !create || CreateFolder(pathname); 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string Win32Filesystem::TempFilename(const Pathname &dir, 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const std::string &prefix) { 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org wchar_t filename[MAX_PATH]; 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::GetTempFileName(ToUtf16(dir.pathname()).c_str(), 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(prefix).c_str(), 0, filename) != 0) 22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ToUtf8(filename); 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ""; 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::MoveFile(const Pathname &old_path, 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const Pathname &new_path) { 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsFile(old_path)) { 23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(IsFile(old_path)); 23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Moving " << old_path.pathname() 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << " to " << new_path.pathname(); 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ::MoveFile(ToUtf16(old_path.pathname()).c_str(), 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(new_path.pathname()).c_str()) != 0; 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::MoveFolder(const Pathname &old_path, 24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const Pathname &new_path) { 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsFolder(old_path)) { 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(IsFolder(old_path)); 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Moving " << old_path.pathname() 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << " to " << new_path.pathname(); 25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::MoveFile(ToUtf16(old_path.pathname()).c_str(), 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(new_path.pathname()).c_str()) == 0) { 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::GetLastError() != ERROR_NOT_SAME_DEVICE) { 25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_GLE(LS_ERROR) << "Failed to move file"; 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!CopyFolder(old_path, new_path)) 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!DeleteFolderAndContents(old_path)) 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::IsFolder(const Pathname &path) { 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WIN32_FILE_ATTRIBUTE_DATA data = {0}; 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetFileExInfoStandard, &data)) 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FILE_ATTRIBUTE_DIRECTORY; 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::IsFile(const Pathname &path) { 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WIN32_FILE_ATTRIBUTE_DATA data = {0}; 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetFileExInfoStandard, &data)) 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::IsAbsent(const Pathname& path) { 28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WIN32_FILE_ATTRIBUTE_DATA data = {0}; 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 != ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), 28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetFileExInfoStandard, &data)) 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD err = ::GetLastError(); 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (ERROR_FILE_NOT_FOUND == err || ERROR_PATH_NOT_FOUND == err); 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::CopyFile(const Pathname &old_path, 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const Pathname &new_path) { 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ::CopyFile(ToUtf16(old_path.pathname()).c_str(), 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(new_path.pathname()).c_str(), TRUE) != 0; 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::IsTemporaryPath(const Pathname& pathname) { 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TCHAR buffer[MAX_PATH + 1]; 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::GetTempPath(ARRAY_SIZE(buffer), buffer)) 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsCurrentProcessLowIntegrity() && 30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) 30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (::strnicmp(ToUtf16(pathname.pathname()).c_str(), 30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer, strlen(buffer)) == 0); 30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetFileSize(const Pathname &pathname, size_t *size) { 30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WIN32_FILE_ATTRIBUTE_DATA data = {0}; 30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::GetFileAttributesEx(ToUtf16(pathname.pathname()).c_str(), 31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetFileExInfoStandard, &data) == 0) 31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *size = data.nFileSizeLow; 31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetFileTime(const Pathname& path, FileTimeType which, 31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org time_t* time) { 31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WIN32_FILE_ATTRIBUTE_DATA data = {0}; 31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), 32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetFileExInfoStandard, &data) == 0) 32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (which) { 32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case FTT_CREATED: 32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FileTimeToUnixTime(data.ftCreationTime, time); 32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case FTT_MODIFIED: 32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FileTimeToUnixTime(data.ftLastWriteTime, time); 32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case FTT_ACCESSED: 33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FileTimeToUnixTime(data.ftLastAccessTime, time); 33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetAppPathname(Pathname* path) { 33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TCHAR buffer[MAX_PATH + 1]; 34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == ::GetModuleFileName(NULL, buffer, ARRAY_SIZE(buffer))) 34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->SetPathname(ToUtf8(buffer)); 34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetAppDataFolder(Pathname* path, bool per_user) { 34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(!organization_name_.empty()); 34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(!application_name_.empty()); 34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TCHAR buffer[MAX_PATH + 1]; 35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int csidl = per_user ? CSIDL_LOCAL_APPDATA : CSIDL_COMMON_APPDATA; 35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!::SHGetSpecialFolderPath(NULL, buffer, csidl, TRUE)) 35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsCurrentProcessLowIntegrity() && 35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer))) 35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t len = strcatn(buffer, ARRAY_SIZE(buffer), __T("\\")); 35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, 35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(organization_name_).c_str()); 35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((len > 0) && (buffer[len-1] != __T('\\'))) { 36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\")); 36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, 36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ToUtf16(application_name_).c_str()); 36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((len > 0) && (buffer[len-1] != __T('\\'))) { 36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\")); 36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len >= ARRAY_SIZE(buffer) - 1) 36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->clear(); 37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->SetFolder(ToUtf8(buffer)); 37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return CreateFolder(*path); 37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetAppTempFolder(Pathname* path) { 37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!GetAppPathname(path)) 37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string filename(path->filename()); 37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return GetTemporaryFolder(*path, true, &filename); 37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Win32Filesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) { 38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!freebytes) { 38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char drive[4]; 38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::wstring drive16; 38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const wchar_t* target_drive = NULL; 38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (path.GetDrive(drive, sizeof(drive))) { 38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org drive16 = ToUtf16(drive); 39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org target_drive = drive16.c_str(); 39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (path.folder().substr(0, 2) == "\\\\") { 39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // UNC path, fail. 39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Handle UNC paths. 39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The path is probably relative. GetDriveType and GetDiskFreeSpaceEx 39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // use the current drive if NULL is passed as the drive name. 39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Add method to Pathname to determine if the path is relative. 39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Add method to Pathname to convert a path to absolute. 40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UINT driveType = ::GetDriveType(target_drive); 40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ( (driveType & DRIVE_REMOTE) || (driveType & DRIVE_UNKNOWN) ) { 40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_VERBOSE) << " remove or unknown drive " << drive; 40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int64 totalNumberOfBytes; // receives the number of bytes on disk 40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int64 totalNumberOfFreeBytes; // receives the free bytes on disk 40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // make sure things won't change in 64 bit machine 41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO replace with compile time assert 41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(sizeof(ULARGE_INTEGER) == sizeof(uint64)); //NOLINT 41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (::GetDiskFreeSpaceEx(target_drive, 41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (PULARGE_INTEGER)freebytes, 41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (PULARGE_INTEGER)&totalNumberOfBytes, 41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (PULARGE_INTEGER)&totalNumberOfFreeBytes)) { 41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_VERBOSE) << " GetDiskFreeSpaceEx returns error "; 41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgPathname Win32Filesystem::GetCurrentDirectory() { 42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Pathname cwd; 42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int path_len = 0; 42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_ptr<wchar_t[]> path; 42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org do { 42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int needed = ::GetCurrentDirectory(path_len, path.get()); 42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (needed == 0) { 43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Error. 43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_GLE(LS_ERROR) << "::GetCurrentDirectory() failed"; 43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return cwd; // returns empty pathname 43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (needed <= path_len) { 43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // It wrote successfully. 43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Else need to re-alloc for "needed". 43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path.reset(new wchar_t[needed]); 44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path_len = needed; 44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } while (true); 44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org cwd.SetFolder(ToUtf8(path.get())); 44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return cwd; 44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Consider overriding DeleteFolderAndContents for speed and potentially 44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// better OS integration (recycle bin?) 44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::wstring temp_path16 = ToUtf16(temp_path.pathname()); 45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org temp_path16.append(1, '*'); 45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org temp_path16.append(1, '\0'); 45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SHFILEOPSTRUCT file_op = { 0 }; 45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org file_op.wFunc = FO_DELETE; 45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org file_op.pFrom = temp_path16.c_str(); 45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; 45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (0 == SHFileOperation(&file_op)); 45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org*/ 45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 461