Chromium中跨进程文件句柄传递

简介: 实现说明在Chromium跨进程架构下,也会有Browser/Renderer两个进程对相同文件进行操作的需求。

实现说明

在Chromium跨进程架构下,也会有Browser/Renderer两个进程对相同文件进行操作的需求。比如Browser的某个任务依赖于Renderer端对指定文件的输出。而在POXIS下,允许不同进程间传递文件描述符(File Descriptor))的, 比如传递socket,或者普通文件,进而可以达到不需要重新打开文件,而对相同文件读写的效果(并不是分享文件句柄)。Chromium对这个特性做了封装,也包括了Windows下的实现(也包括了Windows下的实现)。涉及的基本结构如下:
structure

其中dbus::FileDescriptor,定义在dbus/file_descriptor.h中。因为安全原因不能传递目录的FD。
base::File是对不同平台文件句柄的封装,定义在base/file.h中。
PlatformFile是一组函数,定义在base/ipc_platform_file.h,其中两个重要的API是:

IPC_EXPORT PlatformFileForTransit GetFileHandleForProcess(
    base::PlatformFile file,
    base::ProcessHandle process, 
    bool close_source_handle);  

参数解释:
base::PlatformFile file, // 当前进程打开的文件句柄
base::ProcessHandle process, // 目标process
bool close_source_handle); // 是否会关闭当前的文件句柄,如果不会,就需要多创建当前文件句柄的副本,以避免IPC传递时出现异常。否则就复用当前的文件描述符(File descriptor,Windows下为Handle)。

IPC_EXPORT PlatformFileForTransit TakeFileHandleForProcess(
    base::File file,
    base::ProcessHandle process);

这个版本就是GetFileHandleForProcess第三个参数(close_source_handle)为true的情况,这时当前进程不需要再持有这个文件句柄,看起来像是将所有权也转移到目标进程。

使用示例

// MHTMLGenerationManager (Browser)
void MHTMLGenerationManager::StreamMHTML(
    WebContents* web_contents,
    base::File browser_file, // 传入一个文件句柄browser_file
    const GenerateMHTMLCallback& callback) {

   // 转换到跨进程的FD, 并不释放所有权,所以第三个参数传递的是false。
   PC::PlatformFileForTransit renderer_file =
       IPC::GetFileHandleForProcess(browser_file.GetPlatformFile(),
                                  renderer_process, false);

   // 随后在FileAvailable函数将renderer_file传递出去。
   rvh->Send(new ViewMsg_SavePageAsMHTML(rvh->GetRoutingID(), job_id,
                                        renderer_file));
}

经过IPC,传递到Renderer进程。

// MHTMLGenerator (Renderer)
void MHTMLGenerator::OnSavePageAsMHTML(int job_id, IPC::PlatformFileForTransit file_for_transit) {
  // 从消息中的FD,转换到base::File, 可以进行相关的文件操作了。
  base::File file_ = IPC::PlatformFileForTransitToFile(file_for_transit);
  int bytes_written = file_.Write(total_bytes_written,
                                    data + total_bytes_written, copy_size);

  file_.Close();

注意多进程下,只是共享了文件描述符,可以理解共享了对相同的读写操作,但不是共享文件句柄,所以各个进程仍然要独立地进行半闭的操作 (打开时是在发起进程完成的。)

目录
相关文章
|
9月前
|
前端开发 Android开发
Electron 中 webview 如何与主进程渲染进程进行事件监听通信
Electron 中 webview 如何与主进程渲染进程进行事件监听通信
|
1月前
|
Shell
【进程通信】利用管道创建进程池(结合代码)
【进程通信】利用管道创建进程池(结合代码)
|
6月前
|
监控 安全 API
6.9 Windows驱动开发:内核枚举进线程ObCall回调
在笔者上一篇文章`《内核枚举Registry注册表回调》`中我们通过特征码定位实现了对注册表回调的枚举,本篇文章`LyShark`将教大家如何枚举系统中的`ProcessObCall`进程回调以及`ThreadObCall`线程回调,之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用结构体`_OB_CALLBACK`以及`_OBJECT_TYPE`所以放在一起来讲解最好不过。
67 1
6.9 Windows驱动开发:内核枚举进线程ObCall回调
|
7月前
|
存储 API Windows
4.1 Windows驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。
61 1
4.1 Windows驱动开发:内核中进程与句柄互转
|
6月前
|
监控 安全 API
7.1 Windows驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
74 0
7.1 Windows驱动开发:内核监控进程与线程回调
|
6月前
|
Windows
5.4 Windows驱动开发:内核通过PEB取进程参数
PEB结构`(Process Envirorment Block Structure)`其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。在应用层下,如果想要得到PEB的基地址只需要取`fs:[0x30]`即可,TEB线程环境块则是`fs:[0x18]`,如果在内核层想要得到应用层进程的PEB信息我们需要调用特定的内核函数来获取。
64 0
5.4 Windows驱动开发:内核通过PEB取进程参数
|
6月前
|
监控 安全 Windows
4.3 Windows驱动开发:监控进程与线程对象操作
在内核中,可以使用`ObRegisterCallbacks`这个内核回调函数来实现监控进程和线程对象操作。通过注册一个`OB_CALLBACK_REGISTRATION`回调结构体,可以指定所需的回调函数和回调的监控类型。这个回调结构体包含了回调函数和监控的对象类型,还有一个`Altitude`字段,用于指定回调函数的优先级。优先级越高的回调函数会先被调用,如果某个回调函数返回了一个非NULL值,后续的回调函数就不会被调用。当有进程或线程对象创建、删除、复制或重命名时,内核会调用注册的回调函数。回调函数可以访问被监控对象的信息,如句柄、进程ID等,并可以采取相应的操作,如打印日志、记录信息等。
47 0
4.3 Windows驱动开发:监控进程与线程对象操作
|
存储 API Windows
驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。
329 0
驱动开发:内核枚举进程与线程ObCall回调
在笔者上一篇文章`《驱动开发:内核枚举Registry注册表回调》`中我们通过特征码定位实现了对注册表回调的枚举,本篇文章`LyShark`将教大家如何枚举系统中的`ProcessObCall`进程回调以及`ThreadObCall`线程回调,之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用结构体`_OB_CALLBACK`以及`_OBJECT_TYPE`所以放在一起来讲解最好不过。
289 0
驱动开发:内核枚举进程与线程ObCall回调
|
监控
驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
340 0
驱动开发:内核监控进程与线程回调