/* * 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 #include #include // for RGBQUAD #include #include /* * 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_