Поделиться через


Регистрация интерфейса расширения

После успешного создания сокета приложением Winsock Kernel (WSK) он может зарегистрировать его для одного или нескольких интерфейсов расширения, поддерживаемых подсистемой WSK. Приложение WSK определяет, какой набор интерфейсов расширений поддерживается подсистемой WSK, проверяя элемент VersionWSK_PROVIDER_DISPATCH структуры, возвращенной подсистемой WSK в приложение во время вложения.

Каждый интерфейс расширения определяется NPI, который не зависит от NPI WSK. Однако обратите внимание, что NPI для интерфейсов расширений не поддерживают характеристики NPI.

Приложение WSK регистрируется для интерфейса расширения, выполняя операцию IOCTL сокета SIO_WSK_REGISTER_EXTENSION в сокете. Дополнительные сведения о выполнении операций IOCTL сокета см. в разделе Выполнение управляющих операций в сокете.

Если приложение WSK пытается зарегистрировать сокет для интерфейса расширения, который не поддерживается подсистемой WSK, операция IOCTL SIO_WSK_REGISTER_EXTENSION сокета вернет STATUS_NOT_SUPPORTED.

Например, предположим, что интерфейс расширения определен, как показано в следующем примере кода.

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;

Ниже показано, как приложение WSK может зарегистрировать для этого интерфейса расширения для сокета, ориентированного на подключение.

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

Приложение WSK регистрируется для интерфейсов расширений на основе сокета за сокетом.