Skapa socketar

När ett Winsock Kernel-program (WSK) har anslutits till WSK-undersystemet kan det skapa socketar som kan användas för nätverks-I/O-åtgärder. Ett WSK-program skapar socketar genom att anropa funktionen WskSocket. Funktionen WskSocket pekas på av WskSocket medlemmen i den WSK_PROVIDER_DISPATCH strukturen som returnerades av WSK-undersystemet under anslutningen.

Ett WSK-program måste ange vilken kategori av WSK-socket som skapas när det skapar en ny socket. Mer information om WSK-socketkategorier finns i Winsock Kernel Socket Categories.

Ett WSK-program måste också ange adressfamilj, sockettyp och protokoll när det skapar en ny socket. Mer information om adressfamiljer som stöds av WSK finns i WSK Address Families.

När du skapar en ny socket måste en WSK-applikation ange ett socketkontextvärde och en pekare till en klientdispatchtabellstruktur om applikationen aktiverar några funktioner för händelseåteranrop på socketen. Mer information om hur du aktiverar funktioner för återanrop av händelser på en socket finns i Aktivera och inaktivera funktioner för återanrop av händelser.

Om socketen skapas utan problem innehåller IRP:s IoStatus.Information-fält en pekare till socketobjektstrukturen ( WSK_SOCKET) för en ny socket. Mer information om hur du använder IRP:er med WSK-funktioner finns i Using IRPs with Winsock Kernel Functions.

Följande kodexempel visar hur ett WSK-program kan skapa en lyssningssocket.

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

För anslutningsorienterade socketar kan ett WSK-program anropa funktionen WskSocketConnect för att skapa, binda och ansluta en socket i ett enda funktionsanrop.