Creazione di socket

Dopo che un'applicazione WSK (Winsock Kernel) è stata collegata correttamente al sottosistema WSK, può creare socket che possono essere usati per le operazioni di I/O di rete. Un'applicazione WSK crea socket chiamando la funzioneWskSocket. La funzione WskSocket è indicata dal membro WskSocket della struttura WSK_PROVIDER_DISPATCH restituita dal sottosistema WSK durante la connessione.

Un'applicazione WSK deve specificare la categoria di socket WSK che sta creando ogni volta che crea un nuovo socket. Per altre informazioni sulle categorie di socket WSK, vedere Categorie socket kernel Winsock.

Un'applicazione WSK deve inoltre specificare la famiglia di indirizzi, il tipo di socket e il protocollo ogni volta che crea un nuovo socket. Per altre informazioni sulle famiglie di indirizzi supportate da WSK, vedere famiglie di indirizzi WSK.

Quando si crea un nuovo socket, un'applicazione WSK deve fornire un valore di contesto del socket e un puntatore a una struttura di tabella di distribuzione del client se l'applicazione abiliterà qualsiasi funzione di callback degli eventi sul socket. Per altre informazioni sull'abilitazione delle funzioni di callback degli eventi in un socket, vedere Abilitazione e disabilitazione delle funzioni di callback degli eventi.

Se il socket viene creato correttamente, il campo IoStatus.Information di IRP contiene un puntatore a una struttura di oggetti socket ( WSK_SOCKET) per il nuovo socket. Per ulteriori informazioni sull'uso dei pacchetti di richiesta I/O (IRP) con le funzioni del Kernel Winsock, vedere Uso di IRP con le Funzioni del Kernel Winsock.

L'esempio di codice seguente illustra come un'applicazione WSK può creare un socket di ascolto.

// Context structure for each socket
typedef struct _WSK_APP_SOCKET_CONTEXT {
  PWSK_SOCKET Socket;
  .
  .  // Other application-specific members
  .
} WSK_APP_SOCKET_CONTEXT, *PWSK_APP_SOCKET_CONTEXT;

// Prototype for the socket creation IoCompletion routine
NTSTATUS
  CreateListeningSocketComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    );

// Function to create a new listening socket
NTSTATUS
  CreateListeningSocket(
    PWSK_PROVIDER_NPI WskProviderNpi,
    PWSK_APP_SOCKET_CONTEXT SocketContext,
    PWSK_CLIENT_LISTEN_DISPATCH Dispatch,
    )
{
  PIRP Irp;
  NTSTATUS Status;

  // Allocate an IRP
  Irp =
    IoAllocateIrp(
      1,
      FALSE
      );

  // Check result
  if (!Irp)
  {
    // Return error
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // Set the completion routine for the IRP
  IoSetCompletionRoutine(
    Irp,
    CreateListeningSocketComplete,
    SocketContext,
    TRUE,
    TRUE,
    TRUE
    );

  // Initiate the creation of the socket
  Status =
    WskProviderNpi->Dispatch->
        WskSocket(
          WskProviderNpi->Client,
          AF_INET,
          SOCK_STREAM,
          IPPROTO_TCP,
          WSK_FLAG_LISTEN_SOCKET,
          SocketContext,
          Dispatch,
          NULL,
          NULL,
          NULL,
          Irp
          );

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

// Socket creation IoCompletion routine
NTSTATUS
  CreateListeningSocketComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    )
{
  UNREFERENCED_PARAMETER(DeviceObject);

  PWSK_APP_SOCKET_CONTEXT SocketContext;

  // Check the result of the socket creation
  if (Irp->IoStatus.Status == STATUS_SUCCESS)
  {
    // Get the pointer to the socket context
    SocketContext =
      (PWSK_APP_SOCKET_CONTEXT)Context;

    // Save the socket object for the new socket
    SocketContext->Socket =
      (PWSK_SOCKET)(Irp->IoStatus.Information);

    // Set any socket options for the new socket
    ...

    // Enable any event callback functions on the new socket
    ...

    // Perform any other initializations
    ...
  }

  // Error status
  else
  {
    // Handle error
    ...
  }

  // Free the IRP
  IoFreeIrp(Irp);

  // Always return STATUS_MORE_PROCESSING_REQUIRED to
  // terminate the completion processing of the IRP.
  return STATUS_MORE_PROCESSING_REQUIRED;
}

Per i socket orientati alla connessione, un'applicazione WSK può chiamare la funzione WskSocketConnect per creare, associare e connettere un socket in una singola chiamata di funzione.