PMRX_CREATE_V_NET_ROOT回调函数 (mrx.h)

RDBSS 调用 MRxCreateVNetRoot 例程,请求网络微型重定向程序创建V_NET_ROOT结构,在某些情况下创建NET_ROOT结构。

语法

PMRX_CREATE_V_NET_ROOT PmrxCreateVNetRoot;

NTSTATUS PmrxCreateVNetRoot(
  IN OUT PMRX_CREATENETROOT_CONTEXT Context
)
{...}

参数

Context

[in, out]指向网络微型重定向程序用于在调用最终完成时通知 RDBSS 的回调上下文的指针。 这包括 Context-RxContext> 中请求的RX_CONTEXT结构。 Context 参数包括在 Context-pVNetRoot> 处构造的V_NET_ROOT结构。 此V_NET_ROOT结构包含指向 pVNetRoot-pNetRoot> 处的 NET_ROOT 结构的指针。 NET_ROOT 结构还包含指向 pNetRoot-pSrvCall> 处的 SRV_CALL 结构的指针。

返回值

RDBSS 预期 MRxCreateVNetRoot 在成功或失败时返回STATUS_PENDING。 之所以出现此行为,是因为 RDBSS 要求以异步方式完成此调用。 网络微型重定向程序应将STATUS_SUCCESS映射到STATUS_PENDING作为 MRxCreateVNetRoot 的返回值。

一旦调用完成,并且上下文结构的回调成员中的例程由网络微型重定向程序调用,最终完成状态将在 Context-VirtualNetRootStatus>Context-NetRootStatus> 成员中返回。 这些成员最初包含STATUS_SUCCESS,直到网络微型重定向程序在完成时更改此值。 如果调用成功完成,则这两个成员都包含STATUS_SUCCESS。

如果无法创建V_NET_ROOT或NET_ROOT结构,则会 (返回VirtualNetRootStatusNetRootStatus 成员的以下常见错误代码之一,尽管其他错误代码可能) :

返回代码 说明
STATUS_CONNECTION_RESET 与远程资源的连接已重置。
STATUS_IO_TIMEOUT I/O 请求超时。
STATUS_RETRY 远程启动服务器未准备好满足请求。
STATUS_UNEXPECTED_NETWORK_ERROR 意外的网络错误通常是由无效句柄引起的。

注解

RDBSS 与网络微型重定向程序之间的接口中使用的两个重要抽象是SRV_CALL结构和NET_ROOT/V_NET_ROOT结构。 SRV_CALL结构对应于与已建立连接的服务器关联的上下文。 NET_ROOT结构对应于服务器上的共享。 可以将V_NET_ROOT结构视为网络微型重定向程序声明的NET_ROOT结构下命名空间的一部分。

创建NET_ROOT/V_NET_ROOT结构通常至少涉及一次网络往返。 此操作可能需要相当长的时间才能完成,因为可能需要建立与远程资源的网络连接。 为了确保异步操作继续,NET_ROOT/V_NET_ROOT 结构的创建建模为两阶段活动。 每次调用用于创建NET_ROOT/V_NET_ROOT结构的网络微型重定向程序后,都会从网络微型重定向程序回调到 RDBSS,向 RDBSS 指示向网络微型重定向程序发出的请求的完成状态。 由于 RDBSS 要求以异步方式完成 MRxCreateVNetRoot ,因此 RDBSS 要求 MRxCreateVNetRoot 返回STATUS_PENDING。 调用最终完成时,将使用回调例程通知 RDBSS。

MRxCreateVNetRoot 必须处理两个相关情况:

  • 正在创建新的V_NET_ROOT结构和关联的新NET_ROOT结构。
  • 正在创建与现有NET_ROOT结构关联的新V_NET_ROOT结构。

可以通过检查与NET_ROOT结构关联的上下文是否为 NULL 来区分这两种情况。

MRxCreateVNetRoot 的网络微型重定向程序实现应返回初始调用STATUS_PENDING。 处理完成后,网络微型重定向程序将调用作为 Context 参数的一部分传入的回调例程,以通知 RDBSS 调用已完成并返回完成状态。 网络微型重定向程序应调用的回调例程指定为作为 Context 参数传递的MRX_CREATENETROOT_CONTEXT结构中的 Callback 成员。 MRxCreateVNetRoot 调用的最终完成状态必须存储在 Context 参数的 VirtualNetRootStatusNetRootStatus 成员中。 请注意,为NET_ROOT和V_NET_ROOT结构返回单独的状态。

由于需要传输句柄,在网络微型重定向程序中实现 MRxCreateVNetRoot 也变得复杂。 某些与传输相关的接口需要创建句柄并将其用于所有通信。 创建NET_ROOT或V_NET_ROOT结构可能需要为网络通信建立与传输相关的句柄。 由于建立网络连接的过程可能很耗时,因此建立连接后,尽可能长时间地使用该连接进行通信是有意义的。 建立远程网络资源的传输句柄后,任何其他应用程序请求都可以重复使用该句柄。 当用户应用程序终止时,将删除与进程关联的句柄。 因此,在暂时性用户模式进程的上下文中建立可能生存期较短的传输句柄是没有意义的。 因此,通常需要在已知进程的上下文中初始化NET_ROOT或V_NET_ROOT结构,这些进程在使用这些传输句柄进行通信时不会消失。

在网络微型重定向器中用于管理这一点的一种方法是让 RDBSS 系统进程分配这些传输句柄。 这会影响 MRxCreateVNetRoot 例程的执行方式。 如果向 MRxCreateVNetRoot 发出的请求是在 RDBSS 系统进程的上下文中发出的,则此调用可以立即执行,而无需发布到工作队列。 但是,为了避免出现问题,如果对 MRxCreateVNetRoot 的请求来自任何其他进程,则会使用 RxDispatchToWorkerThread 将请求发布到系统工作队列,以供以后执行。 RDBSS 稍后将使用其系统线程之一来处理工作队列请求并执行 MRxCreateVNetRoot。 这可确保任何传输句柄都归系统进程所有。

网络微型重定向程序可以通过调用 RxGetRDBSSProcess 来确定是否直接从 RDBSS 接收了对 MRxCreateVNetRoot 的调用。 RxGetRDBSSProcess 返回 RDBBS 进程,此值可以与通过调用 IoGetCurrentProcess 返回的当前进程进行比较。 如果在 RDBSS 系统进程的上下文中未启动对 MRxCreateVNetRoot 的调用,则 MRxCreateVNetRoot 可以返回STATUS_PENDING并使用 RxDispatchToWorkerThread 将调用发布到工作队列,供 RDBSS 稍后执行。 通常,这些调用将发布到 DelayedWorkQueue

由网络微型重定向程序决定如何实现 MRxCreateVNetRoot 。 如果此过程可能需要相当长的时间,则此调用应以异步方式完成。 如果需要传输句柄,则网络微型重定向程序可能需要一个长期存在的系统进程来建立这些句柄。

如果无法建立连接,网络微型重定向程序可以尝试将NET_ROOT和V_NET_ROOT结构转换为断开连接模式, (如果) 支持此模式并脱机建立连接。

MRxCreateVNetRoot 完成后,应使用适当的NET_ROOT修改 Context 参数,并V_NET_ROOT从网络微型重定向器更新的结构信息。

要求

要求
目标平台 桌面
标头 mrx.h (包括 Mrx.h)

另请参阅

IoGetCurrentProcess

MRxCreateSrvCall

MRxExtractNetRootName

MRxFinalizeNetRoot

MRxFinalizeSrvCall

MRxFinalizeVNetRoot

MRxPreparseName

MRxSrvCallWinnerNotify

RxDispatchToWorkerThread

RxGetRDBSSProcess