summaryrefslogtreecommitdiffstats
path: root/chrome_elf/create_file/chrome_create_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_elf/create_file/chrome_create_file.cc')
-rw-r--r--chrome_elf/create_file/chrome_create_file.cc237
1 files changed, 0 insertions, 237 deletions
diff --git a/chrome_elf/create_file/chrome_create_file.cc b/chrome_elf/create_file/chrome_create_file.cc
deleted file mode 100644
index 529e014..0000000
--- a/chrome_elf/create_file/chrome_create_file.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome_elf/create_file/chrome_create_file.h"
-
-#include <string>
-
-#include "base/strings/string16.h"
-#include "chrome_elf/chrome_elf_constants.h"
-#include "chrome_elf/ntdll_cache.h"
-#include "sandbox/win/src/nt_internals.h"
-
-namespace {
-
-// From ShlObj.h in the Windows SDK.
-#define CSIDL_LOCAL_APPDATA 0x001c
-
-typedef BOOL (WINAPI *PathIsUNCFunction)(
- IN LPCWSTR path);
-
-typedef BOOL (WINAPI *PathAppendFunction)(
- IN LPWSTR path,
- IN LPCWSTR more);
-
-typedef BOOL (WINAPI *PathIsPrefixFunction)(
- IN LPCWSTR prefix,
- IN LPCWSTR path);
-
-typedef HRESULT (WINAPI *SHGetFolderPathFunction)(
- IN HWND hwnd_owner,
- IN int folder,
- IN HANDLE token,
- IN DWORD flags,
- OUT LPWSTR path);
-
-PathIsUNCFunction g_path_is_unc_func;
-PathAppendFunction g_path_append_func;
-PathIsPrefixFunction g_path_is_prefix_func;
-SHGetFolderPathFunction g_get_folder_func;
-
-// Populates the g_*_func pointers to functions which will be used in
-// ShouldBypass(). Chrome_elf cannot have a load-time dependency on shell32 or
-// shlwapi as this would induce a load-time dependency on user32.dll. Instead,
-// the addresses of the functions we need are retrieved the first time this
-// method is called, and cached to avoid subsequent calls to GetProcAddress().
-// It is assumed that the host process will never unload these functions.
-// Returns true if all the functions needed are present.
-bool PopulateShellFunctions() {
- // Early exit if functions have already been populated.
- if (g_path_is_unc_func && g_path_append_func &&
- g_path_is_prefix_func && g_get_folder_func) {
- return true;
- }
-
- // Get the addresses of the functions we need and store them for future use.
- // These handles are intentionally leaked to ensure that these modules do not
- // get unloaded.
- HMODULE shell32 = ::LoadLibrary(L"shell32.dll");
- HMODULE shlwapi = ::LoadLibrary(L"shlwapi.dll");
-
- if (!shlwapi || !shell32)
- return false;
-
- g_path_is_unc_func = reinterpret_cast<PathIsUNCFunction>(
- ::GetProcAddress(shlwapi, "PathIsUNCW"));
- g_path_append_func = reinterpret_cast<PathAppendFunction>(
- ::GetProcAddress(shlwapi, "PathAppendW"));
- g_path_is_prefix_func = reinterpret_cast<PathIsPrefixFunction>(
- ::GetProcAddress(shlwapi, "PathIsPrefixW"));
- g_get_folder_func = reinterpret_cast<SHGetFolderPathFunction>(
- ::GetProcAddress(shell32, "SHGetFolderPathW"));
-
- return g_path_is_unc_func && g_path_append_func &&
- g_path_is_prefix_func && g_get_folder_func;
-}
-
-} // namespace
-
-HANDLE WINAPI CreateFileWRedirect(
- LPCWSTR file_name,
- DWORD desired_access,
- DWORD share_mode,
- LPSECURITY_ATTRIBUTES security_attributes,
- DWORD creation_disposition,
- DWORD flags_and_attributes,
- HANDLE template_file) {
- if (ShouldBypass(file_name)) {
- return CreateFileNTDLL(file_name,
- desired_access,
- share_mode,
- security_attributes,
- creation_disposition,
- flags_and_attributes,
- template_file);
- }
- return CreateFile(file_name,
- desired_access,
- share_mode,
- security_attributes,
- creation_disposition,
- flags_and_attributes,
- template_file);
-
-}
-
-HANDLE CreateFileNTDLL(
- LPCWSTR file_name,
- DWORD desired_access,
- DWORD share_mode,
- LPSECURITY_ATTRIBUTES security_attributes,
- DWORD creation_disposition,
- DWORD flags_and_attributes,
- HANDLE template_file) {
- HANDLE file_handle = INVALID_HANDLE_VALUE;
- NTSTATUS result = STATUS_UNSUCCESSFUL;
- IO_STATUS_BLOCK io_status_block = {};
-
- // Convert from Win32 domain to to NT creation disposition values.
- switch (creation_disposition) {
- case CREATE_NEW:
- creation_disposition = FILE_CREATE;
- break;
- case CREATE_ALWAYS:
- creation_disposition = FILE_OVERWRITE_IF;
- break;
- case OPEN_EXISTING:
- creation_disposition = FILE_OPEN;
- break;
- case OPEN_ALWAYS:
- creation_disposition = FILE_OPEN_IF;
- break;
- case TRUNCATE_EXISTING:
- creation_disposition = FILE_OVERWRITE;
- break;
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
-
- if (!g_ntdll_lookup["NtCreateFile"] ||
- !g_ntdll_lookup["RtlInitUnicodeString"]) {
- return INVALID_HANDLE_VALUE;
- }
-
- NtCreateFileFunction create_file =
- reinterpret_cast<NtCreateFileFunction>(g_ntdll_lookup["NtCreateFile"]);
-
- RtlInitUnicodeStringFunction init_unicode_string =
- reinterpret_cast<RtlInitUnicodeStringFunction>(
- g_ntdll_lookup["RtlInitUnicodeString"]);
-
- UNICODE_STRING path_unicode_string;
-
- // Format the path into an NT path. Arguably this should be done with
- // RtlDosPathNameToNtPathName_U, but afaict this is equivalent for
- // local paths. Using this with a UNC path name will almost certainly
- // break in interesting ways.
- base::string16 filename_string(L"\\??\\");
- filename_string += file_name;
-
- init_unicode_string(&path_unicode_string, filename_string.c_str());
-
- OBJECT_ATTRIBUTES path_attributes = {};
- InitializeObjectAttributes(&path_attributes,
- &path_unicode_string,
- OBJ_CASE_INSENSITIVE,
- NULL, // No Root Directory
- NULL); // No Security Descriptor
-
- // Set create_options, desired_access, and flags_and_attributes to match those
- // set by kernel32!CreateFile.
- ULONG create_options = FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_ARCHIVE;
- desired_access |= 0x100080;
- flags_and_attributes &= 0x2FFA7;
-
- result = create_file(&file_handle,
- desired_access,
- &path_attributes,
- &io_status_block,
- 0, // Allocation size
- flags_and_attributes,
- share_mode,
- creation_disposition,
- create_options,
- NULL,
- 0);
-
- if (result != STATUS_SUCCESS) {
- if (result == STATUS_OBJECT_NAME_COLLISION &&
- creation_disposition == FILE_CREATE) {
- SetLastError(ERROR_FILE_EXISTS);
- }
- return INVALID_HANDLE_VALUE;
- }
-
- if (creation_disposition == FILE_OPEN_IF) {
- SetLastError(io_status_block.Information == FILE_OPENED ?
- ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
- } else if (creation_disposition == FILE_OVERWRITE_IF) {
- SetLastError(io_status_block.Information == FILE_OVERWRITTEN ?
- ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
- } else {
- SetLastError(ERROR_SUCCESS);
- }
-
- return file_handle;
-}
-
-bool ShouldBypass(LPCWSTR file_name) {
- // If the shell functions are not present, forward the call to kernel32.
- if (!PopulateShellFunctions())
- return false;
-
- // Forward all UNC filepaths to kernel32.
- if (g_path_is_unc_func(file_name))
- return false;
-
- wchar_t local_appdata_path[MAX_PATH];
-
- // Get the %LOCALAPPDATA% Path and append the location of our UserData
- // directory to it.
- HRESULT appdata_result = g_get_folder_func(
- NULL, CSIDL_LOCAL_APPDATA, NULL, 0, local_appdata_path);
-
- // If getting the %LOCALAPPDATA% path or appending to it failed, then forward
- // the call to kernel32.
- if (!SUCCEEDED(appdata_result) ||
- !g_path_append_func(local_appdata_path, kAppDataDirName) ||
- !g_path_append_func(local_appdata_path, kUserDataDirName)) {
- return false;
- }
-
- // Check if we are trying to access something in the UserData dir. If so,
- // then redirect the call to bypass kernel32.
- return !!g_path_is_prefix_func(local_appdata_path, file_name);
-}