Partager via


Inscription d’une interface d’extension

Une fois qu’une application WSK (Winsock Kernel) a correctement créé un socket, elle peut inscrire ce socket pour une ou plusieurs des interfaces d’extension prises en charge par le sous-système WSK. Une application WSK détermine quel ensemble d’interfaces d’extension sont prises en charge par le sous-système WSK en examinant le membre Version de la structure WSK_PROVIDER_DISPATCH que le sous-système WSK a retourné à l’application lors de la pièce jointe.

Chaque interface d’extension est définie par un NPI indépendant du NPI WSK. Notez, toutefois, que les NPI pour les interfaces d’extension ne prennent pas en charge les caractéristiques spécifiques à NPI.

Une application WSK s’inscrit pour une interface d’extension en exécutant l’opération IOCTL de socket SIO_WSK_REGISTER_EXTENSION sur le socket. Pour plus d’informations sur l’exécution d’opérations IOCTL de socket, consultez Exécution d’opérations de contrôle sur un socket.

Si une application WSK tente d’inscrire un socket pour une interface d’extension qui n’est pas prise en charge par le sous-système WSK, l’opération IOCTL de socket SIO_WSK_REGISTER_EXTENSION retourne STATUS_NOT_SUPPORTED.

Par exemple, supposons qu’une interface d’extension soit définie comme dans l’exemple de code suivant.

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;

L’exemple suivant montre comment une application WSK peut s’inscrire pour cette interface d’extension pour un socket orienté connexion.

// 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;
}

Une application WSK s’inscrit pour les interfaces d’extension sur une base socket par socket.