chrome sandbox中的几个有用函数

//判断句柄与路径是否是一样的
// We get a |full_path| of the form /??/c:/some/foo/bar, and the name that
// we'll get from |handle| will be /device/harddiskvolume1/some/foo/bar.
bool SameObject(HANDLE handle, const wchar_t* full_path) {
  std::wstring path(full_path);
  DCHECK(!path.empty());

  // Check if it's a pipe.
  if (IsPipe(path))
    return true;

  std::wstring actual_path;
  if (!GetPathFromHandle(handle, &actual_path))
    return false;

  // This may end with a backslash.
  const wchar_t kBackslash = '//';
  if (path[path.length() - 1] == kBackslash)
    path = path.substr(0, path.length() - 1);

  // Perfect match (case-insesitive check).
  if (0 == _wcsicmp(actual_path.c_str(), path.c_str()))
    return true;

  // Look for the drive letter.
  size_t colon_pos = path.find(L':');
  if (colon_pos == 0 || colon_pos == std::wstring::npos)
    return false;

  // Only one character for the drive.
  if (colon_pos > 1 && path[colon_pos - 2] != kBackslash)
    return false;

  // We only need 3 chars, but let's alloc a buffer for four.
  wchar_t drive[4] = {0};
  wchar_t vol_name[MAX_PATH];
  memcpy(drive, &path[colon_pos - 1], 2 * sizeof(*drive));

  // We'll get a double null terminated string.
  DWORD vol_length = ::QueryDosDeviceW(drive, vol_name, MAX_PATH);
  if (vol_length < 2 || vol_length == MAX_PATH)
    return false;

  // Ignore the nulls at the end.
  vol_length = static_cast(wcslen(vol_name));

  // The two paths should be the same length.
  if (vol_length + path.size() - (colon_pos + 1) != actual_path.size())
    return false;

  // Check up to the drive letter.
  if (0 != _wcsnicmp(actual_path.c_str(), vol_name, vol_length))
    return false;

  // Check the path after the drive letter.
  if (0 != _wcsicmp(&actual_path[vol_length], &path[colon_pos + 1]))
    return false;

  return true;
}

//将短路径转换为长路径
// Convert a short path (C:/path~1 or //??//c:/path~1) to the long version of
// the path. If the path is not a valid filesystem path, the function returns
// false and the output parameter is not modified.

bool ConvertToLongPath(const std::wstring& short_path,
                       std::wstring* long_path) {
  // Check if the path is a NT path.
  bool is_nt_path = false;
  std::wstring path = short_path;
  if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) {
    path = path.substr(kNTPrefixLen);
    is_nt_path = true;
  }

  DWORD size = MAX_PATH;
  scoped_array long_path_buf(new wchar_t[size]);

  DWORD return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(),
                                         size);
  while (return_value >= size) {
    size *= 2;
    long_path_buf.reset(new wchar_t[size]);
    return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), size);
  }

  DWORD last_error = ::GetLastError();
  if (0 == return_value && (ERROR_FILE_NOT_FOUND == last_error ||
                            ERROR_PATH_NOT_FOUND == last_error ||
                            ERROR_INVALID_NAME == last_error)) {
    // The file does not exist, but maybe a sub path needs to be expanded.
    std::wstring::size_type last_slash = path.rfind(L'//');
    if (std::wstring::npos == last_slash)
      return false;

    std::wstring begin = path.substr(0, last_slash);
    std::wstring end = path.substr(last_slash);
    if (!ConvertToLongPath(begin, &begin))
      return false;

    // Ok, it worked. Let's reset the return value.
    path = begin + end;
    return_value = 1;
  } else if (0 != return_value) {
    path = long_path_buf.get();
  }

  if (return_value != 0) {
    if (is_nt_path) {
      *long_path = kNTPrefix;
      *long_path += path;
    } else {
      *long_path = path;
    }

    return true;
  }

  return false;
}

//根据句柄获取路径
bool GetPathFromHandle(HANDLE handle, std::wstring* path) {
  NtQueryObjectFunction NtQueryObject = NULL;
  ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);

  OBJECT_NAME_INFORMATION initial_buffer;
  OBJECT_NAME_INFORMATION* name = &initial_buffer;
  ULONG size = sizeof(initial_buffer);
  // Query the name information a first time to get the size of the name.
  NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size,
                                  &size);

  scoped_ptr name_ptr;
  if (size) {
    name = reinterpret_cast(new BYTE[size]);
    name_ptr.reset(name);

    // Query the name information a second time to get the name of the
    // object referenced by the handle.
    status = NtQueryObject(handle, ObjectNameInformation, name, size, &size);
  }

  if (STATUS_SUCCESS != status)
    return false;

  path->assign(name->ObjectName.Buffer, name->ObjectName.Length /
                                        sizeof(name->ObjectName.Buffer[0]));
  return true;
}

//将win32类型的路径转换为Native(Nt)类型的path
//http://stackoverflow.com/questions/4445108/how-can-i-convert-a-native-nt-pathname-into-a-win32-path-name
//http://pdh11.blogspot.com/2009/05/pathcanonicalize-versus-what-it-says-on.html
// Resolves a win32 path to an nt path using GetPathFromHandle. The path must
// exist. Returs true if the translation was succesful.
bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) {
  HANDLE file = ::CreateFileW(path.c_str(), 0,
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (file == INVALID_HANDLE_VALUE)
    return false;
  bool rv = GetPathFromHandle(file, nt_path);
  ::CloseHandle(file);
  return rv;
}
 
 
文件路径:D:/project/chrome/src/src/sandbox/src/win_utils.cc 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值