Red de conocimiento informático - Problemas con los teléfonos móviles - Cómo utilizar secuencias del kernel en win7

Cómo utilizar secuencias del kernel en win7

El modelo de controlador de flujo del kernel se usa más comúnmente en aplicaciones multimedia. Los controladores que admiten el modelo de transmisión del kernel pueden

informar su rendimiento al sistema y entregar datos de manera eficiente y universal. En términos sencillos, esto significa que los datos de la cámara se pueden pasar directamente a la tarjeta gráfica para su visualización sin pasar por la capa de aplicación. Evita la transferencia de datos entre la capa de aplicación y la capa del núcleo, pero es transparente para la capa superior. Al mismo tiempo, el uso del modelo de flujo del núcleo de multiplexación por división de longitud de onda también puede lograr la independencia del dispositivo, lo que hace que el programa sea altamente portátil y versátil. Generalmente, las cámaras QQ se implementan utilizando componentes basados ​​en flujos centrales de multiplexación por división de longitud de onda. Por lo tanto, cuando la cámara está encendida, se puede cambiar fácilmente para reproducir archivos de audio/video para la otra parte (usando los mismos componentes y procesos que arriba, simplemente cambiando el filtro de fuente). Cabe señalar que minidriver generalmente está relacionado con dispositivos de hardware, pero no es lo mismo que estar relacionado con dispositivos de hardware. También puede llamar a otros componentes en la capa del kernel, como cámaras virtuales y otras aplicaciones.

En términos generales, los dispositivos de hardware proporcionarán un componente KsProxy, que puede completar algunas extensiones correspondientes y transmitir diferentes tipos de datos. La aplicación de la capa superior puede controlar el flujo de datos subyacentes, en lugar de copiar los datos a la capa de aplicación y pasarlos a la capa del núcleo para su procesamiento (similar al procesamiento de DirectX, ya que DirectShow alguna vez fue miembro de DirectX).

Aunque ahora Microsoft ha ajustado la estructura del kernel de transmisión, el nuevo tipo de transmisión es AVStream (aparecerá a continuación en el marco narrativo de AVStream). Pero por ahora, en muchos casos se siguen utilizando los métodos actuales de procesamiento de datos.

La estructura del marco de este controlador se explica a continuación en forma de código fuente y tipos de datos. Intentaremos evitar entrar en detalles específicos del dispositivo en el código y centrarnos en describir el flujo y la estructura de la clase de transmisión:

---------------- -------------------------------------------------- -------------- ----------------------------------- ----- --------------------------------------------- ----- ----------------

1. Punto de entrada del controlador:

NTSTATUS DriverEntry(__en PDRIVER_OBJECT DriverObject, __en PUNICODE_STRING

RegistryPath)

{

HW_INITIALIZATION_DATA HwInitData;

RtlZeroMemory( &HwInitData, sizeof(HW_INITIALIZATION_DATA) );

HwInitData.DmaBufferSize = 0;

//Registrar StreamPortDriver y función de devolución de llamada

return ( StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData));

}

Como puede ver desde aquí, el punto de entrada del controlador básicamente solo registra la función de devolución de llamada y la información en la clase de transmisión. La extensión del dispositivo

y la extensión de transmisión aquí deben ser definidas por nosotros mismos.

La función de devolución de llamada de tiempo de espera y la función de devolución de llamada de cancelación en sí no hacen nada especial. La clave está en la función de devolución de llamada del comando de control, que recibirá el paquete de control enviado por la capa superior (es decir, la clase de flujo).

La descripción detallada de la función de devolución de llamada del comando de control es la siguiente:

2.Función MyReceivePacket:

VOID

MyReceivePacket(IN PHW_STREAM_REQUEST_BLOCK pSrb)

{

PIO_STACK_LOCATION IrpStack;

PMY_EXTENSION pDevExt = (PMY_EXTENSION) pSrb->HwDeviceExtension;

PAGED_CODE();

pSrb-> Estado = STATUS_SUCCESS;

Cambiar (pSrb->comando) {

caso SRB_INITIALIZE_DEVICE://Inicializar dispositivo

romper;

case SRB_INITIALIZATION_COMPLETE: //Inicialización del dispositivo completada

bbreak;

case SRB_ GET_STREAM_INFO:// Obtener información del dispositivo

break;

case SRB_OPEN_STREAM ://Abrir flujo de datos

break;

case SRB_CLOSE_STREAM:// Cerrar flujo de datos

break;

case SRB_SURPRISE_REMOVAL:/ / Eliminar dispositivo

break;

Ejemplo SRB_UNKNOWN_DEVICE_COMMAND: // Comando desconocido

break;

Ejemplo SRB_ UNINITIALIZE_DEVICE: // Desinstalar dispositivo

break;

Ejemplo SRB_GET_DATA_INTERSECTION: // Obtener formato y rango

break;

Ejemplo SRB_CHANGE_POWER_ STATE:

case SRB_GET_DEVICE_PROPERTY: // Obtener propiedades del dispositivo

break;

case SRB_SET_DEVICE_PROPERTY: // Establecer propiedades del dispositivo

break;

caso SRB_PAGING_OUT_DRIVER: // ?

romper;

predeterminado:

pSrb->Estado = STATUS_NOT_IMPLEMENTED;

romper ;

}

StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension,

pSrb);

}

Como puede verse, la capa superior controlará el comportamiento del dispositivo enviando paquetes de comando a esta función que controla el comportamiento del dispositivo. El controlador del puerto debe decidir por sí solo de qué réplica obtener datos o cómo responder a la capa superior.

No hay muchos comandos de transmisión que requieran atención y, dado que el dispositivo puede ser un dispositivo USB/dispositivo 1394/componente de red

/tarjeta de captura de imágenes, es difícil dar una código específico.

Pero con los siguientes comandos,

deberíamos poder crear fácilmente un código de dispositivo específico:

2.1 Comando de inicialización: durante la fase de inicialización del dispositivo, la clase de flujo enviará el siguiente comando

p>

SRB_INITIALIZE_DEVICE->SRB_GET_STREAM_INFO->.STREAM_INFO->SRB_INITIALIZATION_COMPLETE

En términos generales, el comando SRB_INITIALIZE_DEVICE se centra en la inicialización de extensiones de dispositivo y estructuras de atributos,

Mientras que el comando SRB_GET_STREAM_INFO escribe sus propias propiedades en el registro y proporciona el conjunto correspondiente de otras funciones de devolución de llamada a la clase Stream para facilitar un control más microscópico, el comando SRB_INITIALIZATION_COMPLETE suele ser una función de devolución de llamada de finalización

.

El siguiente código revela el procesamiento que normalmente se realiza durante el comando SRB_GET_STREAM_INFO:

typedef struct _HW_STREAM_HEADER {

ULONG NumberOfStreams // Número de transmisiones admitidas

p>

ULONG SizeOfHwStreamInformation; // Tamaño de la estructura

ULONG NumDevPropArrayEntries; // Tamaño de la matriz de propiedades admitida

PKSPROPERTY_SET DevicePropertiesArray; // PropertiesArray

ULONG NumDevEventArrayEntries; // Tamaño de las matrices de eventos admitidas

PKSEVENT_SET DeviceEventsArray; // Matriz de eventos

PKSTOPOLOGY Topología; //

PHW_EVENT_ROUTINE DeviceEventRoutine; / Tiempo de espera

ULONG Reservado[2]; // Reservado

}.

HW_STREAM_HEADER, *PHW_STREAM_HEADER;

typedef struct _HW_STREAM_INFORMATION {

ULONG NumberOfPossibleInstances; // Número de transmisiones admitidas por el dispositivo

KSPIN_DATAFLOW DataFlow // Dirección de los datos; flow

BOOLEAN DataAccessible;

ULONG NumberOfFormatArrayEntries; // Información de atributos admitidos

PKSDATARANGE* StreamFormatsArray // Matriz de información de atributos

PVOID; ClassReserved[4];

ULONG NumStreamPropArrayEntries; // Stream admite subíndices en matrices de propiedades

PKSPROPERTY_SET StreamPropertiesArray; // Matriz de propiedades

ULONG NumStreamEventArrayEntries;

PKSEVENT_SET StreamEventsArray;

GUID* Categoría; // Rango de pines

GUID* Nombre; // Nombre del pin

ULONG MediumsCount

const KSPIN_MEDIUM* Medios; // Tipo de medio

BOOLEAN BridgeStream; // ¿Permitir puenteo de flujo?

ULONG Reservado[2];

}HW_STREAM_INFORMATION, *PHW_STREAM_INFORMATION;

VOID MyGetStreamInfo(IN PHW_STREAM_REQUEST_ BLOCK Srb)

{

PHW_STREAM_HEADER StreamHeader = &(Srb->CommandData.StreamBuffer->StreamHeader);

PMY_ EXTENSION pDevExt = (PMY_EXTENSION) Srb->HwDeviceExtension;

PHW_STREAM_INFORMATION StreamInfo; = &(Srb->CommandData.

PAGED_CODE();

ASSERT (Srb->NumberOfBytesToTransfer >=

tamañode (HW_STREAM_HEADER) +

tamaño de (HW_STREAM_INFORMATION));

RtlZeroMemory(StreamHeader,

tamaño de (HW_STREAM_HEADER) +

tamaño de (HW_STREAM_INFORMATION));

sizeof (HW_STREAM_ INFORMACIÓN));

StreamHeader->NumberOfStreams = 1;

StreamHeader->SizeOfHwStreamInformation = sizeof(HW_STREAM_ INFORMACIÓN);<

/p>

StreamHeader->SizeOfHwStreamInformation = sizeof(HW_STREAM_ INFORMACIÓN);

StreamHeader->NumDevPropArrNumDevPropArrayEntries = pDevExt-> ulPropSetSupported;

StreamHeader-> DevicePropertiesArray = &pDevExt->VideoProcAmpS y ;

StreamInfo-> NumberOfPossibleInstances = 1;

StreamInfo-> DataFlow = KSPIN_DATAFLOW_OUT; NumStreamPropArrayEntries = NUMBER_VIDEO_STREAM_PROPERTIES;

StreamInfo->StreamPropertiesArray = (PKSPROPERTY_SET) VideoStreamProperties

StreamInfo->Nombre = (GUID *) & PINNAME_VIDEO_CAPTURE;

StreamInfo->Categoría = (GUID *) & PINNAME_VIDEO_CAPTURE;

Srb->CommandData StreamBuffer->StreamPropertiesArray = (PKSPROPERTY_SET)StreamBuffer->StreamHeader.Topology = &Topology;

Srb->Status = STATUS _SUCCESS;

}

2.2 Abrir. y Cerrar la secuencia: los comandos SRB_OPEN_STREAM/SRB_CLOSE_STREAM requieren negociación

porque las capas superior e inferior necesitan negociar qué tipo de datos pasar.

El siguiente fragmento de código enmascara detalles específicos del hardware y describe las partes relevantes para la clase de transmisión:

VOID MyOpenStream(IN PHW_STREAM_REQUEST_BLOCK pSrb)

{

PIRB Irb;

ULONG nSize;

PMY_EXTENSION pDevExt;

PSTREAMEX pStrmEx;

PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =

(PKS_ DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.

PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =

& pKSDataFormat->VideoInfoHeader;

PAGED_CODE() ;

Irb = (PIRB) pSrb->SRBExtension;

pDevExt = (PMY_EXTENSION) pSrb->HwDeviceExtension;

pStrmEx = (PSTREAMEX) pSrb-> StreamObject-> HwStreamExtension;

// Extensión de flujo de caché

pDevExt->.pStrmEx = pStrmEx

pSrb->Status = STATUS_SUCCESS;

//Determinar qué secuencias de numeración están abiertas. Estos números aparecen en la matriz de desplazamiento de la estructura de información de flujo denominada

// adaptador de información de flujo

//p>

// Entonces:

// 0 - Datos de vídeo de la cámara

///////////////////////////// // //////////////// 0 - datos de vídeo del hardware