blob: 52423d5570f0ba979f64cc5288872645ef40277b [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <objbase.h>
#include <shlobj.h>
#include <shlwapi.h>
// Windows defines GetCommandLine as a macro to GetCommandLineW which
// breaks our Application::GetCommandLine call below; thus we undefine
// it after including our Windows headers.
#undef GetCommandLine
#include <cstdlib>
#include <cstring>
#include <string>
#include "starboard/log.h"
#include "starboard/shared/nouser/user_internal.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/starboard/command_line.h"
#include "starboard/shared/win32/application_win32.h"
#include "starboard/shared/win32/error_utils.h"
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/string.h"
#include "starboard/system.h"
namespace sbwin32 = starboard::shared::win32;
using starboard::shared::starboard::CommandLine;
namespace starboard {
namespace shared {
namespace nouser {
bool GetHomeDirectory(SbUser user, char* out_path, int path_size) {
if (user != SbUserGetCurrent()) {
return false;
}
PWSTR local_app_data_path = nullptr;
if (S_OK == SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr,
&local_app_data_path)) {
TCHAR wide_path[MAX_PATH];
wcscpy(wide_path, local_app_data_path);
CoTaskMemFree(local_app_data_path);
// Instead of using the raw local AppData directory, we create a program
// app directory if it doesn't exist already.
CommandLine* command_line =
sbwin32::ApplicationWin32::Get()->GetCommandLine();
SB_DCHECK(command_line);
const std::string program_name = command_line->argv()[0];
PathAppend(
wide_path,
sbwin32::CStringToWString(program_name.c_str()).c_str());
if (!PathFileExists(wide_path)) {
SECURITY_ATTRIBUTES security_attributes = {sizeof(SECURITY_ATTRIBUTES),
NULL, TRUE};
const BOOL created_directory =
CreateDirectory(wide_path, &security_attributes);
if (!created_directory) {
SB_LOG(ERROR) << "Failed to create home directory";
sbwin32::DebugLogWinError();
return false;
}
}
const size_t actual_path_length = wcslen(wide_path);
if (path_size < actual_path_length) {
SB_LOG(ERROR) << "Home directory length exceeds max path size";
return false;
}
std::wcstombs(out_path, wide_path, actual_path_length + 1);
return true;
}
SB_LOG(ERROR) << "Unable to open local AppData as home directory.";
sbwin32::DebugLogWinError();
return false;
}
} // namespace nouser
} // namespace shared
} // namespace starboard