chrome sandbox中的几个有用函数

今天药忘吃喽~ 2022-09-30 00:31 274阅读 0赞
  1. //判断句柄与路径是否是一样的
  2. // We get a |full_path| of the form /??/c:/some/foo/bar, and the name that
  3. // we'll get from |handle| will be /device/harddiskvolume1/some/foo/bar.
  4. bool SameObject(HANDLE handle, const wchar_t* full_path) {
  5. std::wstring path(full_path);
  6. DCHECK(!path.empty());
  7. // Check if it's a pipe.
  8. if (IsPipe(path))
  9. return true;
  10. std::wstring actual_path;
  11. if (!GetPathFromHandle(handle, &actual_path))
  12. return false;
  13. // This may end with a backslash.
  14. const wchar_t kBackslash = '//';
  15. if (path[path.length() - 1] == kBackslash)
  16. path = path.substr(0, path.length() - 1);
  17. // Perfect match (case-insesitive check).
  18. if (0 == _wcsicmp(actual_path.c_str(), path.c_str()))
  19. return true;
  20. // Look for the drive letter.
  21. size_t colon_pos = path.find(L':');
  22. if (colon_pos == 0 || colon_pos == std::wstring::npos)
  23. return false;
  24. // Only one character for the drive.
  25. if (colon_pos > 1 && path[colon_pos - 2] != kBackslash)
  26. return false;
  27. // We only need 3 chars, but let's alloc a buffer for four.
  28. wchar_t drive[4] = {0};
  29. wchar_t vol_name[MAX_PATH];
  30. memcpy(drive, &path[colon_pos - 1], 2 * sizeof(*drive));
  31. // We'll get a double null terminated string.
  32. DWORD vol_length = ::QueryDosDeviceW(drive, vol_name, MAX_PATH);
  33. if (vol_length < 2 || vol_length == MAX_PATH)
  34. return false;
  35. // Ignore the nulls at the end.
  36. vol_length = static_cast(wcslen(vol_name));
  37. // The two paths should be the same length.
  38. if (vol_length + path.size() - (colon_pos + 1) != actual_path.size())
  39. return false;
  40. // Check up to the drive letter.
  41. if (0 != _wcsnicmp(actual_path.c_str(), vol_name, vol_length))
  42. return false;
  43. // Check the path after the drive letter.
  44. if (0 != _wcsicmp(&actual_path[vol_length], &path[colon_pos + 1]))
  45. return false;
  46. return true;
  47. }
  48. //将短路径转换为长路径
  49. // Convert a short path (C:/path~1 or //??//c:/path~1) to the long version of
  50. // the path. If the path is not a valid filesystem path, the function returns
  51. // false and the output parameter is not modified.
  52. bool ConvertToLongPath(const std::wstring& short_path,
  53. std::wstring* long_path) {
  54. // Check if the path is a NT path.
  55. bool is_nt_path = false;
  56. std::wstring path = short_path;
  57. if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) {
  58. path = path.substr(kNTPrefixLen);
  59. is_nt_path = true;
  60. }
  61. DWORD size = MAX_PATH;
  62. scoped_array long_path_buf(new wchar_t[size]);
  63. DWORD return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(),
  64. size);
  65. while (return_value >= size) {
  66. size *= 2;
  67. long_path_buf.reset(new wchar_t[size]);
  68. return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), size);
  69. }
  70. DWORD last_error = ::GetLastError();
  71. if (0 == return_value && (ERROR_FILE_NOT_FOUND == last_error ||
  72. ERROR_PATH_NOT_FOUND == last_error ||
  73. ERROR_INVALID_NAME == last_error)) {
  74. // The file does not exist, but maybe a sub path needs to be expanded.
  75. std::wstring::size_type last_slash = path.rfind(L'//');
  76. if (std::wstring::npos == last_slash)
  77. return false;
  78. std::wstring begin = path.substr(0, last_slash);
  79. std::wstring end = path.substr(last_slash);
  80. if (!ConvertToLongPath(begin, &begin))
  81. return false;
  82. // Ok, it worked. Let's reset the return value.
  83. path = begin + end;
  84. return_value = 1;
  85. } else if (0 != return_value) {
  86. path = long_path_buf.get();
  87. }
  88. if (return_value != 0) {
  89. if (is_nt_path) {
  90. *long_path = kNTPrefix;
  91. *long_path += path;
  92. } else {
  93. *long_path = path;
  94. }
  95. return true;
  96. }
  97. return false;
  98. }
  99. //根据句柄获取路径
  100. bool GetPathFromHandle(HANDLE handle, std::wstring* path) {
  101. NtQueryObjectFunction NtQueryObject = NULL;
  102. ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
  103. OBJECT_NAME_INFORMATION initial_buffer;
  104. OBJECT_NAME_INFORMATION* name = &initial_buffer;
  105. ULONG size = sizeof(initial_buffer);
  106. // Query the name information a first time to get the size of the name.
  107. NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size,
  108. &size);
  109. scoped_ptr name_ptr;
  110. if (size) {
  111. name = reinterpret_cast(new BYTE[size]);
  112. name_ptr.reset(name);
  113. // Query the name information a second time to get the name of the
  114. // object referenced by the handle.
  115. status = NtQueryObject(handle, ObjectNameInformation, name, size, &size);
  116. }
  117. if (STATUS_SUCCESS != status)
  118. return false;
  119. path->assign(name->ObjectName.Buffer, name->ObjectName.Length /
  120. sizeof(name->ObjectName.Buffer[0]));
  121. return true;
  122. }
  123. //将win32类型的路径转换为Native(Nt)类型的path
  124. //http://stackoverflow.com/questions/4445108/how-can-i-convert-a-native-nt-pathname-into-a-win32-path-name
  125. //http://pdh11.blogspot.com/2009/05/pathcanonicalize-versus-what-it-says-on.html
  126. // Resolves a win32 path to an nt path using GetPathFromHandle. The path must
  127. // exist. Returs true if the translation was succesful.
  128. bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) {
  129. HANDLE file = ::CreateFileW(path.c_str(), 0,
  130. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
  131. OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  132. if (file == INVALID_HANDLE_VALUE)
  133. return false;
  134. bool rv = GetPathFromHandle(file, nt_path);
  135. ::CloseHandle(file);
  136. return rv;
  137. }
  138. 文件路径:D:/project/chrome/src/src/sandbox/src/win_utils.cc

发表评论

表情:
评论列表 (有 0 条评论,274人围观)

还没有评论,来说两句吧...

相关阅读