mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
359 lines
10 KiB
359 lines
10 KiB
/*
|
|
* vckernel.h
|
|
*
|
|
*
|
|
* 32-bit Video Capture driver
|
|
*
|
|
* definition of interface between hardware-specific portions of
|
|
* kernel driver and the helper library vckernel.lib
|
|
*
|
|
*
|
|
* The hardware-specific portion of a video capture driver will
|
|
* have an NT-specific DriverEntry function that will call VC_Init
|
|
* to initialise the helper library after performing hardware detect and
|
|
* initialise. All NT interaction will then be done by the library vckernel.lib
|
|
* calling back to the hardware-specific code only through the dispatch
|
|
* table below.
|
|
*
|
|
*
|
|
* All h/w specific functions are given a pointer to a PDEVICE_INFO structure
|
|
* which they can pass to VC_IN(), VC_OUT(). VC_GetHWInfo() will return a
|
|
* pointer to the hardware-specific data structure requested from VC_Init().
|
|
*
|
|
* Geraint Davies, Feb 93
|
|
*/
|
|
|
|
#ifndef _VCKERNEL_
|
|
#define _VCKERNEL_
|
|
|
|
/* include necessary headers so that hardware-specific callers do not
|
|
* explicitly reference NT-specific headers.
|
|
*/
|
|
#include <ntddk.h>
|
|
#include <windef.h>
|
|
#include <wingdi.h> // for RGBQUAD
|
|
#include <vcstruct.h>
|
|
#include <ntddvidc.h>
|
|
|
|
|
|
|
|
/*
|
|
* hardware-independent device-extension data structure - opaque to
|
|
* h/w specific functions.
|
|
*/
|
|
typedef struct _DEVICE_INFO DEVICE_INFO, *PDEVICE_INFO;
|
|
|
|
/* --- callbacks to h/w specific code --------------------------*/
|
|
|
|
|
|
/* these are the hardware-specific functions called from the dispatcher */
|
|
|
|
typedef struct _VC_CALLBACK {
|
|
|
|
/* return TRUE for success */
|
|
|
|
/* called on device open/close - optional routines */
|
|
BOOLEAN (*DeviceOpenFunc)(PDEVICE_INFO);
|
|
BOOLEAN (*DeviceCloseFunc)(PDEVICE_INFO);
|
|
|
|
BOOLEAN (*ConfigFormatFunc)(PDEVICE_INFO, PCONFIG_INFO);
|
|
BOOLEAN (*ConfigDisplayFunc)(PDEVICE_INFO, PCONFIG_INFO);
|
|
BOOLEAN (*ConfigSourceFunc)(PDEVICE_INFO, PCONFIG_INFO);
|
|
|
|
/* overlay functions - all optional */
|
|
|
|
/* return overlay mode DWORD */
|
|
DWORD (*GetOverlayModeFunc) (PDEVICE_INFO);
|
|
|
|
/* return TRUE for success */
|
|
BOOLEAN (*SetKeyRGBFunc)(PDEVICE_INFO, PRGBQUAD);
|
|
BOOLEAN (*SetKeyPalIdxFunc)(PDEVICE_INFO, ULONG);
|
|
BOOLEAN (*SetOverlayRectsFunc)(PDEVICE_INFO, POVERLAY_RECTS);
|
|
BOOLEAN (*SetOverlayOffsetFunc)(PDEVICE_INFO, PRECT);
|
|
ULONG (*GetKeyColourFunc)(PDEVICE_INFO);
|
|
|
|
BOOLEAN (*CaptureFunc)(PDEVICE_INFO, BOOL);
|
|
|
|
BOOLEAN (*OverlayFunc)(PDEVICE_INFO, BOOL);
|
|
|
|
/* capture routines - start/stop, interrupt and capture are
|
|
* required routines
|
|
*/
|
|
BOOLEAN (*StreamInitFunc)(PDEVICE_INFO pDevInfo, ULONG microsecperframe);
|
|
BOOLEAN (*StreamFiniFunc)(PDEVICE_INFO);
|
|
BOOLEAN (*StreamStartFunc)(PDEVICE_INFO);
|
|
BOOLEAN (*StreamStopFunc)(PDEVICE_INFO);
|
|
ULONG (*StreamGetPositionFunc)(PDEVICE_INFO);
|
|
|
|
/* returns TRUE if Capture Service should happen */
|
|
BOOLEAN (*InterruptAcknowledge)(PDEVICE_INFO);
|
|
|
|
/*
|
|
* returns bytes written to buffer PUCHAR (whose length is ULONG)
|
|
* - not called if no buffer
|
|
*/
|
|
ULONG (*CaptureService)(PDEVICE_INFO, PUCHAR, PULONG, ULONG);
|
|
|
|
|
|
/*
|
|
* writes a frame to the device for display
|
|
*/
|
|
BOOLEAN (*DrawFrameFunc)(PDEVICE_INFO, PDRAWBUFFER);
|
|
|
|
/* called on driver-unload */
|
|
BOOLEAN (*CleanupFunc)(PDEVICE_INFO);
|
|
|
|
} VC_CALLBACK, * PVC_CALLBACK;
|
|
|
|
|
|
/* --- support functions in vckernel.lib -------------------------- */
|
|
|
|
|
|
|
|
/*
|
|
* VC_Init
|
|
*
|
|
* Create the device object, and any necessary related setup, and
|
|
* allocate device extension data. The device extension data is
|
|
* a DEVICE_INFO struct plus however much data the caller wants for
|
|
* hardware-specific data.
|
|
*
|
|
* parameters:
|
|
* pDriverObject - pointer to driver object (arg to DriverEntry)
|
|
* RegistryPathName - entry for this driver in registry (arg to DriverEntry)
|
|
* HWInfoSize - amount of data to allocate at end of DeviceExtension
|
|
*
|
|
* returns pointer to device extension data as DEVICE_INFO struct.
|
|
*/
|
|
PDEVICE_INFO
|
|
VC_Init(
|
|
PDRIVER_OBJECT pDriverObject,
|
|
PUNICODE_STRING RegistryPathName,
|
|
ULONG HWInfoSize);
|
|
|
|
|
|
/*
|
|
* VC_GetResources
|
|
*
|
|
* map port and frame buffer into system address space or i/o space, and
|
|
* report resource usage of the ports, interrupt and physical memory
|
|
* address used.
|
|
*
|
|
* Note: We do not connect the interrupt: this is not done until
|
|
* a subsequent call to VC_ConnectInterrupt. We do, however, report
|
|
* usage of the interrupt.
|
|
*
|
|
* we return TRUE if success, or FALSE if we couldn't get the resources.
|
|
*/
|
|
BOOLEAN
|
|
VC_GetResources(
|
|
PDEVICE_INFO pDevInfo,
|
|
PDRIVER_OBJECT pDriverObject,
|
|
PUCHAR PortBase,
|
|
ULONG NrOfPorts,
|
|
ULONG Interrupt,
|
|
BOOLEAN bLatched,
|
|
PUCHAR pFrameBuffer,
|
|
ULONG FrameLength);
|
|
|
|
/*
|
|
* VC_ConnectInterrupt
|
|
*
|
|
* This assumes that VC_GetResources has already been called to report the
|
|
* resource usage, and that the VC_CALLBACK table has been set up
|
|
* to handle interrupts.
|
|
*
|
|
* returns TRUE if success.
|
|
*/
|
|
BOOLEAN VC_ConnectInterrupt(
|
|
PDEVICE_INFO pDevInfo,
|
|
ULONG Interrupt,
|
|
BOOLEAN bLatched);
|
|
|
|
|
|
|
|
/* call to unload or abort load of the driver */
|
|
VOID
|
|
VC_Cleanup(
|
|
PDRIVER_OBJECT pDriverObject
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
* get the hardware specific portion of the device extension
|
|
*/
|
|
PVOID VC_GetHWInfo(PDEVICE_INFO);
|
|
|
|
/*
|
|
* output one BYTE to the port. bOffset is the offset from
|
|
* the port base address.
|
|
*/
|
|
|
|
VOID VC_Out(PDEVICE_INFO pDevInfo, BYTE bOffset, BYTE bData);
|
|
|
|
/*
|
|
* input one byte from the port at bOffset offset from the port base address
|
|
*/
|
|
BYTE VC_In(PDEVICE_INFO pDevInfo, BYTE bOffset);
|
|
|
|
|
|
/*
|
|
* i/o memory on adapter cards such as the frame buffer memory cannot
|
|
* be accessed like ordinary memory on all processors (especially alpha).
|
|
* You must read and write this memory using the following macros. These are
|
|
* wrappers for the appropriate NT macros.
|
|
*/
|
|
|
|
// return one ULONG from the frame buffer at p
|
|
#ifdef i386
|
|
|
|
#define VC_ReadIOMemoryULONG(p) ( * (DWORD volatile *)p)
|
|
|
|
// return a word from the frame buffer at p
|
|
#define VC_ReadIOMemoryUSHORT(p) ( * (USHORT volatile *)p)
|
|
|
|
// return a byte from the frame buffer at p
|
|
#define VC_ReadIOMemoryBYTE(p) ( * (unsigned char volatile *) p)
|
|
|
|
#else
|
|
|
|
#define VC_ReadIOMemoryULONG(p) READ_REGISTER_ULONG((PULONG)p)
|
|
|
|
// return a word from the frame buffer at p
|
|
#define VC_ReadIOMemoryUSHORT(p) READ_REGISTER_USHORT((PUSHORT)p)
|
|
|
|
// return a byte from the frame buffer at p
|
|
#define VC_ReadIOMemoryBYTE(p) READ_REGISTER_UCHAR(p)
|
|
|
|
#endif
|
|
|
|
// read a block of c bytes (in ULONGS) from the frame buffer at s
|
|
//to memory at d. length must be multiple of ulongs.
|
|
#define VC_ReadIOMemoryBlock(d, s, c) \
|
|
READ_REGISTER_BUFFER_ULONG( \
|
|
(PULONG) s, \
|
|
(PULONG) d, \
|
|
(c)/sizeof(DWORD))
|
|
|
|
// write a byte b to the frame buffer at p
|
|
#define VC_WriteIOMemoryBYTE(p, b) WRITE_REGISTER_UCHAR(p, b)
|
|
|
|
// write a word w to the frame buffer at p
|
|
#define VC_WriteIOMemoryUSHORT(p, w) WRITE_REGISTER_USHORT((PUSHORT)p, w)
|
|
|
|
// write a ULONG l to the frame buffer at p
|
|
#define VC_WriteIOMemoryULONG(p, l) WRITE_REGISTER_ULONG((PULONG)p, l)
|
|
|
|
// write a block of c bytes to the frame buffer d from memory at s
|
|
#define VC_WriteIOMemoryBlock(d, s, c) WRITE_REGISTER_BUFFER_UCHAR(d, s, c)
|
|
|
|
|
|
|
|
|
|
PVC_CALLBACK VC_GetCallbackTable(PDEVICE_INFO);
|
|
|
|
/* get a pointer to the frame buffer mapped into system memory */
|
|
PUCHAR VC_GetFrameBuffer(PDEVICE_INFO);
|
|
|
|
|
|
/*
|
|
* report the expected image size. attempts to queue buffers with a size
|
|
* smaller than this will be rejected by vckernel.
|
|
*/
|
|
VOID VC_SetImageSize(PDEVICE_INFO, int);
|
|
|
|
|
|
/* this function is a wrapper for KeSynchronizeExecution (at least in the NT
|
|
* version). It will call back the function specified with the context
|
|
* argument specified, having first disabled the video interrupt in
|
|
* a multi-processor safe way.
|
|
*/
|
|
typedef BOOLEAN (*PSYNC_ROUTINE)(PVOID);
|
|
BOOLEAN VC_SynchronizeExecution(PDEVICE_INFO, PSYNC_ROUTINE, PVOID);
|
|
|
|
/*
|
|
* This function can be used like VC_SynchronizeExecution, to sync
|
|
* between the captureservice routine and the passive-level requests. This
|
|
* will not necessarily disable interrupts. On win-16, this function may be
|
|
* the same as VC_SynchronizeExecution. On NT, the CaptureService func
|
|
* runs as a DPC, at a lower interrupt priority than the isr itself, and
|
|
* so can be protected using this (spinlock-based) function without having
|
|
* to disable all interrupts.
|
|
*/
|
|
BOOLEAN VC_SynchronizeDPC(PDEVICE_INFO, PSYNC_ROUTINE, PVOID);
|
|
|
|
|
|
|
|
/*
|
|
* VC_AccessData gives access to the data in kernel mode in a safe way.
|
|
* It calls the given function with the address and size of the buffer
|
|
* after any necessary mapping, and wrapped in exception handlers
|
|
* as necessary.
|
|
*
|
|
* This function cannot be called from the InterruptAcknowledge or
|
|
* ServiceCapture call back functions - it must be running in the
|
|
* context of the calling thread (in kernel mode).
|
|
*/
|
|
typedef BOOLEAN (*PACCESS_ROUTINE)(PDEVICE_INFO, PUCHAR, ULONG, PVOID);
|
|
BOOLEAN VC_AccessData(PDEVICE_INFO, PUCHAR, ULONG, PACCESS_ROUTINE, PVOID);
|
|
|
|
/* these functions allocate and free non-paged memory for use
|
|
* in kernel mode, including at interrupt time.
|
|
*/
|
|
PVOID VC_AllocMem(PDEVICE_INFO, ULONG);
|
|
VOID VC_FreeMem(PDEVICE_INFO, PVOID, ULONG);
|
|
|
|
|
|
/*
|
|
* delay for a number of milliseconds. This is accurate only to
|
|
* +- 15msecs at best.
|
|
*/
|
|
VOID VC_Delay(int nMillisecs);
|
|
|
|
/* block for given number of microseconds by polling. Not recommended
|
|
* for more than 25 usecs.
|
|
*/
|
|
VOID VC_Stall(int nMicrosecs);
|
|
|
|
|
|
/*
|
|
* read a value from this device's section of the registry or profile.
|
|
* returns the dword value associated with ValueName, or Default if ValueName
|
|
* cannot be found.
|
|
*/
|
|
DWORD VC_ReadProfile(PDEVICE_INFO pDevInfo, PWCHAR ValueName, DWORD Default);
|
|
|
|
/*
|
|
* write a dword value to this device's section of the registry or profile.
|
|
* ValueName is a unicode string representing the registry value name or
|
|
* profile key, and ValueData is the dword data written. Returns TRUE if
|
|
* successfully written.
|
|
*/
|
|
BOOL VC_WriteProfile(PDEVICE_INFO pDevInfo, PWCHAR ValueName, DWORD ValueData);
|
|
|
|
|
|
|
|
#if DBG
|
|
|
|
extern ULONG VCDebugLevel;
|
|
void dbgPrintf(char * szFormat, ...);
|
|
|
|
#define dprintf(_x_) dbgPrintf _x_
|
|
#define dprintf1(_x_) if (VCDebugLevel >= 1) dbgPrintf _x_
|
|
#define dprintf2(_x_) if (VCDebugLevel >= 2) dbgPrintf _x_
|
|
#define dprintf3(_x_) if (VCDebugLevel >= 3) dbgPrintf _x_
|
|
#define dprintf4(_x_) if (VCDebugLevel >= 4) dbgPrintf _x_
|
|
|
|
#else
|
|
|
|
#define dprintf(_x_)
|
|
#define dprintf1(_x_)
|
|
#define dprintf2(_x_)
|
|
#define dprintf3(_x_)
|
|
#define dprintf4(_x_)
|
|
|
|
#endif
|
|
|
|
#endif // _VCKERNEL_
|
|
|