Subdevice Creation

The term subdevice is used to describe the binding of the four components that are listed in the following table.

Component Description

Miniport object

An object that exposes the miniport driver's IMiniportXxx interface

Port object

An object that exposes the port driver's IPortXxx interface

Resource list object

An object containing a list of adapter driver resources that are assigned to the subdevice

Reference string

A name added to the device path name to specify a subdevice during filter creation

A subdevice's IMiniportXxx and IPortXxx interfaces inherit from base interfaces IMiniport and IPort, respectively.

The PortCls system driver does not distinguish between the port driver and the miniport driver. It simply requires an object, such as the port object, with an interface that can handle system-generated requests.

Similarly, PortCls is not directly involved in managing resources. It only needs to bind the request handler (the port driver) to a resource list. The adapter driver is responsible for binding the port, miniport, and resource list objects together.

The following code example shows how the adapter driver performs these actions:

  //
  // Instantiate the port by calling a function supplied by PortCls.
  //
  PPORT    port;
  NTSTATUS ntStatus = PcNewPort(&port, PortClassId);

  if (NT_SUCCESS(ntStatus))
  {
      PUNKNOWN miniport;
      //
      // Create the miniport object.
      //
      if (MiniportCreate)   // a function to create a proprietary miniport
      {
          ntStatus = MiniportCreate(&miniport,
                                    MiniportClassId, NULL, NonPagedPool);
      }
      else   // Ask PortCls for one of its built-in miniports.
      {
          ntStatus = PcNewMiniport((PMINIPORT*)&miniport,
                                   MiniportClassId);
      }

      if (NT_SUCCESS(ntStatus))
      {
          //
          // Bind the port, miniport, and resources.
          //
          ntStatus = port->Init(DeviceObject,
                                Irp, miniport, UnknownAdapter, ResourceList);
          if (NT_SUCCESS(ntStatus))
          {
              //
              // Hand the port driver and the reference
              // string to PortCls.
              //
              ntStatus = PcRegisterSubdevice(DeviceObject,
                                             Name, port);
          }

          //
          // We no longer need to reference the miniport driver.
          // Either the port driver now references it,
          // or binding failed and it should be deleted.
          //
          miniport->Release();
      }

      //
      // Release the reference that existed when PcNewPort() gave us
      // the pointer in the first place. This reference must be released
      // regardless of whether the binding of the port and miniport
      // drivers succeeded.
      //
      port->Release();
  }

For information about the PortCls function calls in the preceding code example, see PcNewPort, PcNewMiniport, and PcRegisterSubdevice.