Cómo utilizar secuencias del kernel en win7
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));
} p>
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)
{ p>
PIRB Irb;
ULONG nSize;
PMY_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat = p>
(PKS_ DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.
PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
& pKSDataFormat->VideoInfoHeader;
PAGED_CODE() ; p>
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