Compartir a través de


Registro de una interfaz de extensión

Después de que una aplicación de Winsock Kernel (WSK) haya creado correctamente un socket, puede registrar ese socket para una o varias de las interfaces de extensión compatibles con el subsistema WSK. Una aplicación WSK determina qué conjunto de interfaces de extensión son compatibles con el subsistema WSK examinando el miembro Version de la estructura de WSK_PROVIDER_DISPATCH que el subsistema WSK devolvió a la aplicación durante los datos adjuntos.

Cada interfaz de extensión se define mediante un NPI que es independiente del NPI de WSK. Sin embargo, tenga en cuenta que las NPIs para las interfaces de extensión no admiten características específicas de NPI.

Una aplicación WSK se registra para una interfaz de extensión mediante la ejecución de la operación IOCTL de SIO_WSK_REGISTER_EXTENSION socket en el socket. Para obtener más información sobre cómo ejecutar operaciones de IOCTL de socket, vea Realizar operaciones de control en un socket.

Si una aplicación WSK intenta registrar un socket para una interfaz de extensión que no es compatible con el subsistema WSK, la operación de IOCTL de SIO_WSK_REGISTER_EXTENSION socket devolverá STATUS_NOT_SUPPORTED.

Por ejemplo, supongamos que una interfaz de extensión se define como en el ejemplo de código siguiente.

const NPIID EXAMPLE_EXTIF_NPIID = {...};

typedef struct _EXAMPLE_EXTIF_PROVIDER_DISPATCH {
  .
  . // Function pointers for the functions that are
  . // defined by the extension interface.
  .
} EXAMPLE_EXTIF_PROVIDER_DISPATCH, *PEXAMPLE_EXTIF_PROVIDER_DISPATCH;

typedef struct _EXAMPLE_EXTIF_CLIENT_DISPATCH {
  .
  . // Function pointers for the callback functions
  . // that are defined by the extension interface.
  .
} EXAMPLE_EXTIF_CLIENT_DISPATCH, *PEXAMPLE_EXTIF_CLIENT_DISPATCH;

A continuación se muestra cómo una aplicación WSK puede registrarse para esta interfaz de extensión para un socket orientado a la conexión.

// Client dispatch structure for the extension interface
const EXAMPLE_EXTIF_CLIENT_DISPATCH ExtIfClientDispatch = {
  .
  . // The WSK application's callback functions
  . // for the extension interface
  .
};

// Context structure type for the example extension interface
typedef struct _EXAMPLE_EXTIF_CLIENT_CONTEXT
{
  const EXAMPLE_EXTIF_PROVIDER_DISPATCH *ExtIfProviderDispatch;
  PVOID ExtIfProviderContext;
    .
    .  // Other application-specific members
    .
} EXAMPLE_EXTIF_CLIENT_CONTEXT, *PEXAMPLE_EXTIF_CLIENT_CONTEXT;

// Function to register the example extension interface
NTSTATUS
  RegisterExampleExtIf(
    PWSK_SOCKET Socket,
    PEXAMPLE_EXTIF_CLIENT_CONTEXT ExtIfClientContext
    )
{
  PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
  WSK_EXTENSION_CONTROL_IN ExtensionControlIn;
  WSK_EXTENSION_CONTROL_OUT ExtensionControlOut;
  NTSTATUS Status;

  // Get pointer to the socket's provider dispatch structure
  Dispatch =
    (PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);

  // Fill in the WSK_EXTENSION_CONTROL_IN structure
  ExtensionControlIn.NpiId = &EXAMPLE_EXTIF_NPIID;
  ExtensionControlIn.ClientContext = ExtIfClientContext;
  ExtensionControlIn.ClientDispatch = &ExtIfClientDispatch;

  // Initiate the IOCTL operation on the socket
  Status =
    Dispatch->WskControlSocket(
      Socket,
      WskIoctl,
      SIO_WSK_REGISTER_EXTENSION,
      0,
      sizeof(WSK_EXTENSION_CONTROL_IN),
      &ExtensionControlIn,
      sizeof(WSK_EXTENSION_CONTROL_OUT),
      &ExtensionControlOut,
      NULL,
      NULL  // No IRP used for this IOCTL operation
      );

  // Check result
  if (Status == STATUS_SUCCESS)
  {
    // Save provider dispatch table and provider context
    ExtIfClientContext->ExtIfProviderDispatch =
      (const EXAMPLE_EXTIF_PROVIDER_DISPATCH *)
        ExtensionControlOut.ProviderDispatch;
    ExtIfClientContext->ExtIfProviderContext =
      ExtensionControlOut.ProviderContext;
  }

  // Return the status of the call to WskControlSocket()
  return Status;
}

Una aplicación WSK se registra para las interfaces de extensión en un socket por socket.