master 2e4b1ba48e31 cached
62 files
306.0 KB
82.7k tokens
112 symbols
1 requests
Download .txt
Showing preview only (325K chars total). Download the full file or copy to clipboard to get everything.
Repository: robot9706/VirtualCameraDriver
Branch: master
Commit: 2e4b1ba48e31
Files: 62
Total size: 306.0 KB

Directory structure:
gitextract_gda5v0rh/

├── .gitignore
├── Driver/
│   └── avshws/
│       ├── README.md
│       ├── avshws.h
│       ├── avshws.inf
│       ├── avshws.rc
│       ├── avshws.sln
│       ├── avshws.vcxproj
│       ├── avshws.vcxproj.Filters
│       ├── capture.cpp
│       ├── capture.h
│       ├── customprops.h
│       ├── device.cpp
│       ├── device.h
│       ├── filter.cpp
│       ├── filter.h
│       ├── hwsim.cpp
│       ├── hwsim.h
│       ├── image.cpp
│       ├── image.h
│       └── purecall.c
├── LICENSE
├── README.md
└── UserLand/
    ├── .gitignore
    ├── DriverInterface/
    │   ├── Common.h
    │   ├── Device.cpp
    │   ├── Device.h
    │   ├── DeviceEnumeration.cpp
    │   ├── DeviceEnumeration.h
    │   ├── DriverInterface.cpp
    │   ├── DriverInterface.vcxproj
    │   ├── DriverInterface.vcxproj.filters
    │   └── dllmain.cpp
    ├── DriverInterfaceWrapper/
    │   ├── DeviceInfo.cs
    │   ├── DriverInterface.cs
    │   ├── DriverInterfaceWrapper.csproj
    │   ├── Native.cs
    │   └── Properties/
    │       └── AssemblyInfo.cs
    ├── UserDriverCanon/
    │   ├── App.config
    │   ├── CameraListItem.cs
    │   ├── FitPictureBox.cs
    │   ├── MainForm.Designer.cs
    │   ├── MainForm.cs
    │   ├── MainForm.resx
    │   ├── Program.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── UserDriverCanon.csproj
    ├── UserDriverStaticImage/
    │   ├── App.config
    │   ├── MainForm.Designer.cs
    │   ├── MainForm.cs
    │   ├── MainForm.resx
    │   ├── Program.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── UserDriverStaticImage.csproj
    └── VirtualCameraDriver.sln

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# CodeRush personal settings
.cr/personal

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# Local History for Visual Studio
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb

# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/


================================================
FILE: Driver/avshws/README.md
================================================
---
page_type: sample
description: "A simulated hardware sample driver providing a pin-centric capture driver to simulate AV capture hardware."
languages:
- cpp
products:
- windows
- windows-wdk
---

# AVStream simulated hardware sample driver (Avshws)

The AVStream simulated hardware sample driver (Avshws) provides a pin-centric [AVStream](https://docs.microsoft.com/windows-hardware/drivers/stream/avstream-overview) capture driver for a simulated piece of hardware. This streaming media driver performs video captures at 320 x 240 pixels in either RGB24 or YUV422 format using direct memory access (DMA) into capture buffers. The purpose of the sample is to demonstrate how to write a pin-centric AVStream minidriver. The sample also shows how to implement DMA by using the related functionality provided by the AVStream class driver.

This sample features enhanced parameter validation and overflow detection.

## Provision a target computer

After you've installed the sample on your host computer, run Visual Studio, and from the **File** menu, select **Open**, then **Project/Solution...**, navigate to the directory where you've copied the Avshws sample, then to the C++ folder, and select **avshws.vcxproj** (the VC++ Project).

In the **Solution Explorer** pane in Visual Studio, at the top is **Solution 'avshws'**. Right-click this and select **Configuration Manager**. Follow the instructions in [Building a Driver with Visual Studio and the WDK](https://docs.microsoft.com/windows-hardware/drivers/develop/building-a-driver) to set the platform, operating system, and debug configuration you want to use, and to build the sample. This sample project will automatically sign the driver package.

Provision your target computer using instructions in, for example, [Provision a computer for driver deployment and testing](https://docs.microsoft.com/windows-hardware/drivers/gettingstarted/provision-a-target-computer-wdk-8-1). Ensure that in the **Network and Sharing Center** control panel your target computer has **Network Discovery** and **File and Printer Sharing** enabled.

## Deploy the driver to the target computer

Now you can deploy the Avshws driver that you've just built to the target computer, using guidance in [Deploying a Driver to a Test Computer](https://docs.microsoft.com/windows-hardware/drivers/develop/deploying-a-driver-to-a-test-computer). Specifically, find the package file under the **Package** folder in the Avshws solution. Right-click **package** and select **Properties**. Under Configuration Properties, click **Driver install** and then **Deployment**. Here you must click the check box for **Enable deployment**, and then click the button to the right of **\<Configure Computer...\>**. In the next dialog you enter the **Target Computer Name** and can let the host computer automatically provision the target computer and set up debugger options.

Finally, in Visual Studio, from the **Build** menu select **Deploy Solution** to deploy the sample to the target computer. On the target computer, you can see the deployed package in the **%Systemdrive%\\drivertest\\drivers** folder.

## Install the driver

On the target computer, open Device Manager, and follow these steps:

1. In the **Action** menu, click **Add Legacy Hardware**, and the **Add Hardware Wizard** appears. Click **Next** and then **Next** again.

1. In the **Add Hardware** window, select **Show All Devices**.

1. In the **Manufacturer** list in the left pane, click **Microsoft**.

1. You should see the **AVStream Simulated Hardware Sample** in the **Model** pane on the right. Click this and then click **Next**.

1. Click **Next** again to install the driver, and then click **Finish** to exit the wizard.

The sample driver now appears in the Device Manager console tree under **Sound, video and game controllers**. The Avshws INF file will be on the system drive at, for example, **...windows\\System32\\DriverStore\\FileRepository\\**.

## Sample code hierarchy

[**DriverEntry**](https://docs.microsoft.com/previous-versions//ff558717(v=vs.85)) in Device.cpp is the initial point of entry into the driver. This routine passes control to AVStream by calling the [**KsInitializeDriver**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/nf-ks-ksinitializedriver) function. In this call, the minidriver passes the device descriptor, an AVStream structure that recursively defines the AVStream object hierarchy for a driver. This is common behavior for an AVStream minidriver.

At device start time, a simulated piece of capture hardware is created (the **CHardwareSimulation** class), and a DMA adapter is acquired from the operating system and is registered with AVStream by calling the [**KsDeviceRegisterAdapterObject**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/nf-ks-ksdeviceregisteradapterobject) function. This call is required for a sample that performs DMA access directly into the capture buffers, instead of using DMA access to write to a common buffer. The driver creates the [KS Filter](https://docs.microsoft.com/windows-hardware/drivers/stream/ks-filters) for this device dynamically by calling the [**KsCreateFilterFactory**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/nf-ks-kscreatefilterfactory) function.

Filter.cpp is where the sample lays out the [**KSPIN\_DESCRIPTOR\_EX**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/ns-ks-_kspin_descriptor_ex) structure for the single video pin. In addition, a [**KSFILTER\_DISPATCH**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/ns-ks-_ksfilter_dispatch) structure and a [**KSFILTER\_DESCRIPTOR**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/ns-ks-_ksfilter_descriptor) structure are provided in this source file. The filter dispatch provides only a create dispatch, a routine that is included in Filter.cpp. The process dispatch is provided on the pin because this is a pin-centric sample.

Capture.cpp contains source for the video capture pin on the capture filter. This is where the [**KSPIN\_DISPATCH**](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ks/ns-ks-_kspin_dispatch) structure for the unique pin is provided. This dispatch structure specifies a *Process* callback routine, also defined in this source file. This routine is where stream pointer manipulation and cloning occurs.

The process callback is one of two routines of interest in Capture.cpp that demonstrate how to perform DMA transfers with AVStream functionality. The other is the **CCapturePin::CompleteMappings** method. These two methods show how to use the queue, obtain clone pointers, use scatter/gather lists, and perform other DMA-related tasks.

For more information, see the comments in all .cpp files.

## Run the sample

Follow these steps to see how the sample driver functions:

1. After installation has completed, access the driver through the Graphedt tool. Graphedt.exe is available in the *tools* directory of the WDK.

1. Before running GraphEdit, use the regsvr32 utility to register the proppage.dll DLL and to enable GraphEdit to display property pages for some of the built-in Microsoft DirectShow filters. Open an elevated command window with Administrator privileges, and navigate to the WDK or SDK *tools* directory that contains proppage.dll.

1. On the command line, type regsvr32 proppage.dll. If the registration succeeds, you'll get a message, "DllRegisterServer in proppage.dll succeeded." Click OK.

1. In the Graphedt tool, click the **Graph** menu and click **Insert Filters**. The sample appears under "WDM Streaming Capture Devices" as "avshws Source."

1. Click **Insert Filter**. The sample appears in the graph as a single filter labeled, "avshws Source." There is one output pin, which is the video capture pin. This pin emits video in YUY2 format.

1. Attach this filter to either a DirectShow Video Renderer or to the VMR default video renderer. Then click **Play**.

The output that is produced by the sample is a 320 x 240 pixel image of standard EIA-189-A color bars. In the middle of the image near the bottom, a clock appears over the image. This clock displays the elapsed time since the graph was introduced into the run state following the last stop. The clock display format is MINUTES:SECONDS.HUNDREDTHS.

In the upper-left corner of the image, a counter counts the number of frames that have been dropped since the graph was introduced into the run state after the last stop.

## File manifest

| File | Description |
| --- | --- |
| Avshws.h | Main header file for the sample |
| Avshws.inf | Sample installation file |


================================================
FILE: Driver/avshws/avshws.h
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        avshws.h

    Abstract:

        AVStream Simulated Hardware Sample header file.  This is the 
        main header.

    History:

        created 3/12/2001

**************************************************************************/

/*************************************************

    Standard Includes

*************************************************/

#ifndef _avshws_h_
#define _avshws_h_

extern "C" {
#include <wdm.h>
}

#include <windef.h>
#include <stdio.h>
#include <ntstrsafe.h>
#include <stdlib.h>
#include <windef.h>
#define NOBITMAP
#include <mmreg.h>
#undef NOBITMAP
#include <unknown.h>
#include <ks.h>
#include <ksmedia.h>

#include "customprops.h"

/*************************************************

    Misc Definitions

*************************************************/
#pragma warning (disable : 4100 4127 4131 4189 4701 4706)
#define STR_MODULENAME "avshws: "
#define DEBUGLVL_VERBOSE 2
#define DEBUGLVL_TERSE 1
#define DEBUGLVL_ERROR 0

const DebugLevel = DEBUGLVL_TERSE;

#if (DBG)
#define _DbgPrintF(lvl, strings) \
{ \
    if (lvl <= DebugLevel) {\
        DbgPrint(STR_MODULENAME);\
        DbgPrint##strings;\
        DbgPrint("\n");\
        if ((lvl) == DEBUGLVL_ERROR) {\
            NT_ASSERT(0);\
        } \
    }\
}
#else // !DBG
   #define _DbgPrintF(lvl, strings)
#endif // !DBG

#define ABS(x) ((x) < 0 ? (-(x)) : (x))

#ifndef mmioFOURCC    
#define mmioFOURCC( ch0, ch1, ch2, ch3 )                \
        ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |    \
        ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
#endif

#define FOURCC_YUY2         mmioFOURCC('Y', 'U', 'Y', '2')
//
// CAPTURE_PIN_DATA_RANGE_COUNT:
//
// The number of ranges supported on the capture pin.
//
#define CAPTURE_PIN_DATA_RANGE_COUNT 1 // 2

//
// CAPTURE_FILTER_PIN_COUNT:
//
// The number of pins on the capture filter.
//
#define CAPTURE_FILTER_PIN_COUNT 1

//
// CAPTURE_FILTER_CATEGORIES_COUNT:
//
// The number of categories for the capture filter.
//
#define CAPTURE_FILTER_CATEGORIES_COUNT 3

#define AVSHWS_POOLTAG 'hSVA'

/*************************************************

    Externed information

*************************************************/
//
// filter.cpp externs:
//
extern
const
KSFILTER_DISPATCH
CaptureFilterDispatch;

extern
const
KSFILTER_DESCRIPTOR
CaptureFilterDescriptor;

extern
const
KSPIN_DESCRIPTOR_EX
CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT];

extern
const
GUID
CaptureFilterCategories [CAPTURE_FILTER_CATEGORIES_COUNT];

//
// capture.cpp externs:
//
extern 
const
KSALLOCATOR_FRAMING_EX
CapturePinAllocatorFraming;

extern 
const
KSPIN_DISPATCH
CapturePinDispatch;

extern
const
PKSDATARANGE
CapturePinDataRanges [CAPTURE_PIN_DATA_RANGE_COUNT];

/*************************************************

    Enums / Typedefs

*************************************************/

typedef enum _HARDWARE_STATE {

    HardwareStopped = 0,
    HardwarePaused,
    HardwareRunning

} HARDWARE_STATE, *PHARDWARE_STATE;

/*************************************************

    Class Definitions

*************************************************/

//
// IHardwareSink:
//
// This interface is used by the hardware simulation to fake interrupt
// service routines.  The Interrupt method is called at DPC as a fake
// interrupt.
//
class IHardwareSink {

public:

    virtual
    void
    Interrupt (
        ) = 0;

};

//
// ICaptureSink:
//
// This is a capture sink interface.  The device level calls back the
// CompleteMappings method passing the number of completed mappings for
// the capture pin.  This method is called during the device DPC.
//
class ICaptureSink {

public:

    virtual
    void
    CompleteMappings (
        IN ULONG NumMappings
        ) = 0;

};



/*************************************************

    Global Functions

*************************************************/
#ifndef _NEW_DELETE_OPERATORS_
#define _NEW_DELETE_OPERATORS_

/*************************************************

    Add definitions that are missing for C++14.

*************************************************/

PVOID operator new
(
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
       __drv_reportError("Must succeed pool allocations are forbidden. "
             "Allocation failures cause a system crash"))
    POOL_TYPE       poolType
);

PVOID operator new
(
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
       __drv_reportError("Must succeed pool allocations are forbidden. "
             "Allocation failures cause a system crash"))
    POOL_TYPE       poolType,
    ULONG           tag
);

/*++

Routine Description:

    Array new() operator for creating objects with a specified allocation tag.

Arguments:

    iSize -
        The size of the entire allocation.

    poolType -
        The type of allocation.  Ex: PagedPool or NonPagedPoolNx

    tag -
        A 4-byte allocation identifier.

Return Value:

    None

--*/
PVOID 
operator new[](
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
        __drv_reportError("Must succeed pool allocations are forbidden. "
            "Allocation failures cause a system crash"))
    POOL_TYPE       poolType,
    ULONG           tag
);

/*++

Routine Description:

    Array delete() operator.

Arguments:

    pVoid -
        The memory to free.

Return Value:

    None

--*/
void 
__cdecl 
operator delete[](
    PVOID pVoid
);

/*++

Routine Description:

    Sized delete() operator.

Arguments:

    pVoid -
        The memory to free.

    size -
        The size of the memory to free.

Return Value:

    None

--*/
void __cdecl operator delete
(
    void *pVoid,
    size_t /*size*/
);

/*++

Routine Description:

    Sized delete[]() operator.

Arguments:

    pVoid -
        The memory to free.

    size -
        The size of the memory to free.

Return Value:

    None

--*/
void __cdecl operator delete[]
(
    void *pVoid,
    size_t /*size*/
);

#endif // _NEW_DELETE_OPERATORS_




/*************************************************

    Internal Includes

*************************************************/

#include "image.h"
#include "hwsim.h"
#include "device.h"
#include "filter.h"
#include "capture.h"
#include <uuids.h>
#endif //_avshws_h_

================================================
FILE: Driver/avshws/avshws.inf
================================================
;/*++
;
;Copyright (c) Microsoft Corporation.  All rights reserved.
;
;    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;    PURPOSE.
;
;Module Name:
;
;    AVSHWS.INF
;
;Abstract:
;
;
;AVStream pin centric sample mini driver (AVSHWS.sys) installation file. 
;Supports x86, amd64, arm and arm64 platforms
;
;--*/

[Version]
signature="$WINDOWS NT$"
Class=Camera
ClassGuid={ca3e7ab9-b4c3-4ae6-8251-579ef933890f}
Provider=%ProviderName%
Catalogfile=avshws.cat
DriverVer=01/01/2020,6.0.5600.0

[SourceDisksNames]
1000=%cdname%,,,

[SourceDisksFiles]
avshws.sys=1000

[DestinationDirs]
DefaultDestDir=12
avshws.CopyFiles=12

[avshws.CopyFiles]
avshws.sys

[Manufacturer]
%ManufacturerName%=Standard,NTx86,NTamd64,ntarm,ntarm64

[Standard.NTx86]
%avshws.DeviceDesc%=avshws.NTx86,AVSHWS

[Standard.NTamd64]
%avshws.DeviceDesc%=avshws.NTamd64,AVSHWS

[Standard.NTarm]
%avshws.DeviceDesc%=avshws.NTarm,AVSHWS

[Standard.NTarm64]
%avshws.DeviceDesc%=avshws.NTarm64,AVSHWS

;---------------------------------------------------------------
;                x 86  D D I n s t a l l
;---------------------------------------------------------------

[avshws.NTx86]
Include=ks.inf, KSCAPTUR.inf
Needs=KS.Registration,KSCAPTUR.Registration.NT
CopyFiles=avshws.CopyFiles

;---------------------------------------------------------------
;                A M D 64  D D I n s t a l l
;---------------------------------------------------------------

[avshws.NTamd64]
Include=ks.inf,KSCAPTUR.inf
Needs=KS.Registration,KSCAPTUR.Registration.NT
CopyFiles=avshws.CopyFiles

;---------------------------------------------------------------
;                A R M  D D I n s t a l l
;---------------------------------------------------------------

[avshws.NTarm]
Include=ks.inf,KSCAPTUR.inf
Needs=KS.Registration,KSCAPTUR.Registration.NT
CopyFiles=avshws.CopyFiles

;---------------------------------------------------------------
;                A R M 64  D D I n s t a l l
;---------------------------------------------------------------

[avshws.NTarm64]
Include=ks.inf,KSCAPTUR.inf
Needs=KS.Registration,KSCAPTUR.Registration.NT
CopyFiles=avshws.CopyFiles

;---------------------------------------------------------------
;                I n t e r f a c e s
;---------------------------------------------------------------

[avshws.NTx86.Interfaces]
AddInterface=%KSCATEGORY_CAPTURE%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO_CAMERA%,"GLOBAL",CaptureInterface.NT,0

[avshws.NTamd64.Interfaces]
AddInterface=%KSCATEGORY_CAPTURE%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO_CAMERA%,"GLOBAL",CaptureInterface.NT,0

[avshws.NTarm.Interfaces]
AddInterface=%KSCATEGORY_CAPTURE%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO_CAMERA%,"GLOBAL",CaptureInterface.NT,0

[avshws.NTarm64.Interfaces]
AddInterface=%KSCATEGORY_CAPTURE%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO%,"GLOBAL",CaptureInterface.NT,0
AddInterface=%KSCATEGORY_VIDEO_CAMERA%,"GLOBAL",CaptureInterface.NT,0

[CaptureInterface.NT]
AddReg=avshws.Reader.AddReg

;---------------------------------------------------------------
;                A d d R e g
;---------------------------------------------------------------

[avshws.Reader.AddReg]
HKR,,CLSID,,%Proxy.CLSID%
HKR,,FriendlyName,,%avshws.Reader.FriendlyName%

;---------------------------------------------------------------
;                S e r v i c e s  
;---------------------------------------------------------------

[avshws.NTx86.Services]
AddService=avshws, 0x00000002, avshws.ServiceInstall

[avshws.NTamd64.Services]
AddService=avshws, 0x00000002, avshws.ServiceInstall

[avshws.NTarm.Services]
AddService=avshws, 0x00000002, avshws.ServiceInstall

[avshws.NTarm64.Services]
AddService=avshws, 0x00000002, avshws.ServiceInstall

[avshws.ServiceInstall]
DisplayName=%avshws.DeviceDesc%
ServiceType=%SERVICE_KERNEL_DRIVER%
StartType=%SERVICE_DEMAND_START%
ErrorControl=%SERVICE_ERROR_NORMAL%
ServiceBinary=%12%\avshws.sys

;---------------------------------------------------------------
;                S t r i n g s
;---------------------------------------------------------------

[Strings]
; non-localizable
Proxy.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_VIDEO="{6994AD05-93EF-11D0-A3CC-00A0C9223196}"
KSCATEGORY_VIDEO_CAMERA="{E5323777-F976-4f5b-9B55-B94699C46E44}"

SERVICE_KERNEL_DRIVER=1
SERVICE_DEMAND_START=3
SERVICE_ERROR_NORMAL=1
REG_DWORD=0x00010001

;localizable
ProviderName="TODO-Set-Provider"
ManufacturerName="TODO-Set-Manufacturer"
avshws.DeviceDesc="AVStream Simulated Hardware Sample"
avshws.Reader.FriendlyName="avshws Source"
cdname="AVSHWS Installation Disk"

================================================
FILE: Driver/avshws/avshws.rc
================================================
//+-------------------------------------------------------------------------
//
//  Microsoft Windows
//
//  Copyright (C) Microsoft Corporation, 1999 - 1999
//
//  File:       captst.rc
//
//--------------------------------------------------------------------------

#include <windows.h>

#include <ntverp.h>

#define VER_FILETYPE                VFT_DRV
#define VER_FILESUBTYPE             VFT2_UNKNOWN
#define VER_FILEDESCRIPTION_STR     "AVStream Simulated Hardware Sample"
#define VER_INTERNALNAME_STR        "avshws.sys"
#define VER_ORIGINALFILENAME_STR    "avshws.sys"

#include "common.ver"



================================================
FILE: Driver/avshws/avshws.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.136
MinimumVisualStudioVersion = 12.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avshws", "avshws.vcxproj", "{77FA53EC-3637-411C-B708-C8EED64543A4}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|ARM = Debug|ARM
		Debug|ARM64 = Debug|ARM64
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		Release|ARM = Release|ARM
		Release|ARM64 = Release|ARM64
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.ActiveCfg = Debug|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.Build.0 = Debug|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM.Deploy.0 = Debug|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.ActiveCfg = Debug|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.Build.0 = Debug|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|ARM64.Deploy.0 = Debug|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|Win32.ActiveCfg = Debug|Win32
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|Win32.Build.0 = Debug|Win32
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|x64.ActiveCfg = Debug|x64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Debug|x64.Build.0 = Debug|x64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.ActiveCfg = Release|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.Build.0 = Release|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM.Deploy.0 = Release|ARM
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.ActiveCfg = Release|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.Build.0 = Release|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|ARM64.Deploy.0 = Release|ARM64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|Win32.ActiveCfg = Release|Win32
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|Win32.Build.0 = Release|Win32
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|x64.ActiveCfg = Release|x64
		{77FA53EC-3637-411C-B708-C8EED64543A4}.Release|x64.Build.0 = Release|x64
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {5EBC439F-EC31-448F-B129-434D42485011}
	EndGlobalSection
EndGlobal


================================================
FILE: Driver/avshws/avshws.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|ARM">
      <Configuration>Debug</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|ARM64">
      <Configuration>Debug</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM">
      <Configuration>Release</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM64">
      <Configuration>Release</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{77FA53EC-3637-411C-B708-C8EED64543A4}</ProjectGuid>
    <RootNamespace>$(MSBuildProjectName)</RootNamespace>
    <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
    <Platform Condition="'$(Platform)' == ''">Win32</Platform>
    <SampleGuid>{555099C6-5354-4C50-A241-A09CDD72299D}</SampleGuid>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>False</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>True</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>False</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>False</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>False</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>True</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>True</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>True</UseDebugLibraries>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>WDM</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <PropertyGroup>
    <OutDir>$(IntDir)</OutDir>
  </PropertyGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
  </ImportGroup>
  <ItemGroup Label="WrappedTaskItems" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <TargetName>avshws</TargetName>
    <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
    <TargetName>avshws</TargetName>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <Link>
      <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ks.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
      <AdditionalOptions>%(AdditionalOptions)  -merge:PAGECONST=PAGE</AdditionalOptions>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
    <ResourceCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </ResourceCompile>
    <ClCompile>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <TreatWarningAsError>true</TreatWarningAsError>
      <WarningLevel>Level4</WarningLevel>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
      <ExceptionHandling>
      </ExceptionHandling>
    </ClCompile>
    <Midl>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE;DEBUG_LEVEL=DEBUGLVL_BLAB;_WIN2K_COMPAT_SLIST_USAGE;_NO_SYS_GUID_OPERATOR_EQ_</PreprocessorDefinitions>
    </Midl>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="capture.cpp" />
    <ClCompile Include="device.cpp" />
    <ClCompile Include="filter.cpp" />
    <ClCompile Include="hwsim.cpp" />
    <ClCompile Include="image.cpp" />
    <ClCompile Include="purecall.c" />
    <ResourceCompile Include="avshws.rc" />
  </ItemGroup>
  <ItemGroup>
    <Inf Exclude="@(Inf)" Include="*.inf" />
    <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
  </ItemGroup>
  <ItemGroup>
    <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
    <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
    <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="avshws.h" />
    <ClInclude Include="capture.h" />
    <ClInclude Exclude="@(ClInclude)" Include="customprops.h" />
    <ClInclude Include="device.h" />
    <ClInclude Include="filter.h" />
    <ClInclude Include="hwsim.h" />
    <ClInclude Include="image.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

================================================
FILE: Driver/avshws/avshws.vcxproj.Filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
      <UniqueIdentifier>{124F9628-D980-4A5F-BCB3-C73BBF85F98E}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files">
      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
      <UniqueIdentifier>{53840AE7-57A9-46F8-8D16-B52859B4C272}</UniqueIdentifier>
    </Filter>
    <Filter Include="Resource Files">
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
      <UniqueIdentifier>{1156F063-8F29-4654-8347-0519BE2E0418}</UniqueIdentifier>
    </Filter>
    <Filter Include="Driver Files">
      <Extensions>inf;inv;inx;mof;mc;</Extensions>
      <UniqueIdentifier>{77087805-4D7E-4591-B71F-4ABA9576DD2A}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="capture.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="device.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="filter.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="hwsim.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="purecall.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="image.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="avshws.rc">
      <Filter>Resource Files</Filter>
    </ResourceCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="capture.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="customprops.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="device.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="filter.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="hwsim.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="image.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="customprops.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="avshws.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="capture.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="device.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="filter.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="hwsim.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="image.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <Inf Include="*.inf">
      <Filter>Driver Files</Filter>
    </Inf>
  </ItemGroup>
  <ItemGroup>
    <None Include="*.txt;*.htm;*.html" />
  </ItemGroup>
</Project>

================================================
FILE: Driver/avshws/capture.cpp
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        capture.cpp

    Abstract:

        This file contains source for the video capture pin on the capture
        filter.  The capture sample performs "fake" DMA directly into
        the capture buffers.  Common buffer DMA will work slightly differently.

        For common buffer DMA, the general technique would be DPC schedules
        processing with KsPinAttemptProcessing.  The processing routine grabs
        the leading edge, copies data out of the common buffer and advances.
        Cloning would not be necessary with this technique.  It would be 
        similiar to the way "AVSSamp" works, but it would be pin-centric.

    History:

        created 3/8/2001

**************************************************************************/

#include "avshws.h"
#include <ksmedia.h>
#include <ntintsafe.h>

/**************************************************************************

    PAGEABLE CODE

**************************************************************************/


#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA

//OG: 320x240
#define DMAX_X 1280
#define DMAX_Y 720
#define D_X 1280
#define D_Y 720

CCapturePin::
CCapturePin (
    IN PKSPIN Pin
    ) :
    m_Pin (Pin)
    ,m_PresentationTime (0)

/*++

Routine Description:

    Construct a new capture pin.

Arguments:

    Pin -
        The AVStream pin object corresponding to the capture pin

Return Value:

    None

--*/

{

    PAGED_CODE();

    PKSDEVICE Device = KsPinGetDevice (Pin);

    //
    // Set up our device pointer.  This gives us access to "hardware I/O"
    // during the capture routines.
    //
    m_Device = reinterpret_cast <CCaptureDevice *> (Device -> Context);
}

/*************************************************/


NTSTATUS
CCapturePin::
DispatchCreate (
    IN PKSPIN Pin,
    IN PIRP Irp
    )

/*++

Routine Description:

    Create a new capture pin.  This is the creation dispatch for
    the video capture pin.

Arguments:

    Pin -
        The pin being created

    Irp -
        The creation Irp

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    CCapturePin *CapPin = new (NonPagedPoolNx, 'niPC') CCapturePin (Pin);

    if (!CapPin) {
        //
        // Return failure if we couldn't create the pin.
        //
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {
        //
        // Add the item to the object bag if we we were successful. 
        // Whenever the pin closes, the bag is cleaned up and we will be
        // freed.
        //
        Status = KsAddItemToObjectBag (
            Pin -> Bag,
            reinterpret_cast <PVOID> (CapPin),
            reinterpret_cast <PFNKSFREE> (CCapturePin::Cleanup)
            );

        if (!NT_SUCCESS (Status)) {
            delete CapPin;
        } else {
            Pin -> Context = reinterpret_cast <PVOID> (CapPin);
        }

    }

    //
    // If we succeeded so far, stash the video info header away and change
    // our allocator framing to reflect the fact that only now do we know
    // the framing requirements based on the connection format.
    //
    PKS_VIDEOINFOHEADER VideoInfoHeader = NULL;

    if (NT_SUCCESS (Status)) {

        VideoInfoHeader = CapPin -> CaptureVideoInfoHeader ();
        if (!VideoInfoHeader) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    if (NT_SUCCESS(Status)) {
        //
        // We need to edit the descriptor to ensure we don't mess up any other
        // pins using the descriptor or touch read-only memory.
        //
        Status = KsEdit (
            Pin, 
            &Pin -> Descriptor, 
            AVSHWS_POOLTAG);

        if (NT_SUCCESS (Status)) { 

            //
            // If the edits proceeded without running out of memory, adjust 
            // the framing based on the video info header.
            //
            Status = KsEdit (
                Pin, 
                &Pin -> Descriptor -> AllocatorFraming, 
                AVSHWS_POOLTAG);

            if (NT_SUCCESS (Status)) {

                //
                // We've KsEdit'ed this...  I'm safe to cast away constness as
                // long as the edit succeeded.
                //
                PKSALLOCATOR_FRAMING_EX Framing =
                    const_cast <PKSALLOCATOR_FRAMING_EX> (
                        Pin -> Descriptor -> AllocatorFraming
                        );

                Framing -> FramingItem [0].Frames = 2;

                //
                // The physical and optimal ranges must be biSizeImage.  We only
                // support one frame size, precisely the size of each capture
                // image.
                //
                Framing -> FramingItem [0].PhysicalRange.MinFrameSize =
                    Framing -> FramingItem [0].PhysicalRange.MaxFrameSize =
                    Framing -> FramingItem [0].FramingRange.Range.MinFrameSize =
                    Framing -> FramingItem [0].FramingRange.Range.MaxFrameSize =
                    VideoInfoHeader -> bmiHeader.biSizeImage;

                Framing -> FramingItem [0].PhysicalRange.Stepping = 
                    Framing -> FramingItem [0].FramingRange.Range.Stepping =
                    0;

            }

        }
    }

    if (NT_SUCCESS (Status)) {
        //
        // Adjust the stream header size.  The video packets have extended
        // header info (KS_FRAME_INFO).
        //
        Pin -> StreamHeaderSize = sizeof (KSSTREAM_HEADER) +
            sizeof (KS_FRAME_INFO);

    }
    return Status;
}

/*************************************************/


PKS_VIDEOINFOHEADER 
CCapturePin::
CaptureVideoInfoHeader (
    )

/*++

Routine Description:

    Capture the video info header out of the connection format.  This
    is what we use to base synthesized images off.

Arguments:

    None

Return Value:

    The captured video info header or NULL if there is insufficient
    memory.

--*/

{

    PAGED_CODE();

    PKS_VIDEOINFOHEADER ConnectionHeader =
        &((reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER> 
            (m_Pin -> ConnectionFormat)) -> 
            VideoInfoHeader);

    m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> (
        ExAllocatePoolWithTag (
            NonPagedPoolNx,
            KS_SIZE_VIDEOHEADER (ConnectionHeader),
            AVSHWS_POOLTAG
            )
        );

    if (!m_VideoInfoHeader)
        return NULL;

    //
    // Bag the newly allocated header space.  This will get cleaned up
    // automatically when the pin closes.
    //
    NTSTATUS Status =
        KsAddItemToObjectBag (
            m_Pin -> Bag,
            reinterpret_cast <PVOID> (m_VideoInfoHeader),
            NULL
            );

    if (!NT_SUCCESS (Status)) {

        ExFreePool (m_VideoInfoHeader);
        return NULL;

    } else {

        //
        // Copy the connection format video info header into the newly 
        // allocated "captured" video info header.
        //
        RtlCopyMemory (
            m_VideoInfoHeader,
            ConnectionHeader,
            KS_SIZE_VIDEOHEADER (ConnectionHeader)
            );

    }

    return m_VideoInfoHeader;

}


NTSTATUS
CCapturePin::
Process (
    )

/*++

Routine Description:

    The process dispatch for the pin bridges to this location.
    We handle setting up scatter gather mappings, etc...

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;
    PKSSTREAM_POINTER Leading;

    _DbgPrintF(DEBUGLVL_VERBOSE, ("Process"));

    Leading = KsPinGetLeadingEdgeStreamPointer (
        m_Pin,
        KSSTREAM_POINTER_STATE_LOCKED
        );

    while (NT_SUCCESS (Status) && Leading) {

        PKSSTREAM_POINTER ClonePointer;
        PSTREAM_POINTER_CONTEXT SPContext = NULL;

        //
        // If no data is present in the Leading edge stream pointer, just 
        // move on to the next frame
        //
        if ( NULL == Leading -> StreamHeader -> Data ) {
            Status = KsStreamPointerAdvance(Leading);
            continue;
        }
        //
        // For optimization sake in this particular sample, I will only keep
        // one clone stream pointer per frame.  This complicates the logic
        // here but simplifies the completions.
        //
        // I'm also choosing to do this since I need to keep track of the
        // virtual addresses corresponding to each mapping since I'm faking
        // DMA.  It simplifies that too.
        //
        if (!m_PreviousStreamPointer) {
            //
            // First thing we need to do is clone the leading edge.  This allows
            // us to keep reference on the frames while they're in DMA.
            //
            Status = KsStreamPointerClone (
                Leading,
                NULL,
                sizeof (STREAM_POINTER_CONTEXT),
                &ClonePointer
                );

            //
            // I use this for easy chunking of the buffer.  We're not really
            // dealing with physical addresses.  This keeps track of what 
            // virtual address in the buffer the current scatter / gather 
            // mapping corresponds to for the fake hardware.
            //
            if (NT_SUCCESS (Status)) {

                //
                // Set the stream header data used to 0.  We update this 
                // in the DMA completions.  For queues with DMA, we must
                // update this field ourselves.
                //
                ClonePointer -> StreamHeader -> DataUsed = 0;

                SPContext = reinterpret_cast <PSTREAM_POINTER_CONTEXT> 
                    (ClonePointer -> Context);

                SPContext -> BufferVirtual = 
                    reinterpret_cast <PUCHAR> (
                        ClonePointer -> StreamHeader -> Data
                        );
            }

        } else {

            ClonePointer = m_PreviousStreamPointer;
            SPContext = reinterpret_cast <PSTREAM_POINTER_CONTEXT> 
                (ClonePointer -> Context);
            Status = STATUS_SUCCESS;
        }

        //
        // If the clone failed, likely we're out of resources.  Break out
        // of the loop for now.  We may end up starving DMA.
        //
        if (!NT_SUCCESS (Status)) {
            KsStreamPointerUnlock (Leading, FALSE);
            break;
        }

        //
        // Program the fake hardware.  I would use Clone -> OffsetOut.*, but
        // because of the optimization of one stream pointer per frame, it
        // doesn't make complete sense.
        //
        ULONG MappingsUsed =
            m_Device -> ProgramScatterGatherMappings (
                ClonePointer,
                &(SPContext -> BufferVirtual),
                Leading -> OffsetOut.Mappings,
                Leading -> OffsetOut.Remaining
                );

        //
        // In order to keep one clone per frame and simplify the fake DMA
        // logic, make a check to see if we completely used the mappings in
        // the leading edge.  Set a flag.
        //
        if (MappingsUsed == Leading -> OffsetOut.Remaining) {
            m_PreviousStreamPointer = NULL;
        } else {
            m_PreviousStreamPointer = ClonePointer;
        }

        if (MappingsUsed) {
            //
            // If any mappings were added to scatter / gather queues, 
            // advance the leading edge by that number of mappings.  If 
            // we run off the end of the queue, Status will be 
            // STATUS_DEVICE_NOT_READY.  Otherwise, the leading edge will
            // point to a new frame.  The previous one will not have been
            // dismissed (unless "DMA" completed) since there's a clone
            // pointer referencing the frames.
            //
            Status =
                KsStreamPointerAdvanceOffsets (
                    Leading,
                    0,
                    MappingsUsed,
                    FALSE
                    );
        } else {

            //
            // The hardware was incapable of adding more entries.  The S/G
            // table is full.
            //
            Status = STATUS_PENDING;
            break;

        }

    }

    //
    // If the leading edge failed to lock (this is always possible, remember
    // that locking CAN occassionally fail), don't blow up passing NULL
    // into KsStreamPointerUnlock.  Also, set m_PendIo to kick us later...
    //
    if (!Leading) {

        m_PendIo = TRUE;

        //
        // If the lock failed, there's no point in getting called back 
        // immediately.  The lock could fail due to insufficient memory,
        // etc...  In this case, we don't want to get called back immediately.
        // Return pending.  The m_PendIo flag will cause us to get kicked
        // later.
        //
        Status = STATUS_PENDING;
    }

    //
    // If we didn't run the leading edge off the end of the queue, unlock it.
    //
    if (NT_SUCCESS (Status) && Leading) {
        KsStreamPointerUnlock (Leading, FALSE);
    } else {
        //
        // DEVICE_NOT_READY indicates that the advancement ran off the end
        // of the queue.  We couldn't lock the leading edge.
        //
        if (Status == STATUS_DEVICE_NOT_READY) Status = STATUS_SUCCESS;
    }

    //
    // If we failed with something that requires pending, set the pending I/O
    // flag so we know we need to start it again in a completion DPC.
    //
    if (!NT_SUCCESS (Status) || Status == STATUS_PENDING) {
        m_PendIo = TRUE;
    }

    _DbgPrintF(DEBUGLVL_VERBOSE, ("Leaving Process..."));
    return Status;

}

/*************************************************/


NTSTATUS
CCapturePin::
CleanupReferences (
    )

/*++

Routine Description:

    Clean up any references we're holding on frames after we abruptly
    stop the hardware.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    PKSSTREAM_POINTER Clone = KsPinGetFirstCloneStreamPointer (m_Pin);
    PKSSTREAM_POINTER NextClone = NULL;

    //
    // Walk through the clones, deleting them, and setting DataUsed to
    // zero since we didn't use any data!
    //
    while (Clone) {

        NextClone = KsStreamPointerGetNextClone (Clone);

        Clone -> StreamHeader -> DataUsed = 0;
        KsStreamPointerDelete (Clone);

        Clone = NextClone;

    }

    return STATUS_SUCCESS;

}

/*************************************************/


NTSTATUS
CCapturePin::
SetState (
    IN KSSTATE ToState,
    IN KSSTATE FromState
    )

/*++

Routine Description:

    This is called when the caputre pin transitions state.  The routine
    attempts to acquire / release any hardware resources and start up
    or shut down capture based on the states we are transitioning to
    and away from.

Arguments:

    ToState -
        The state we're transitioning to

    FromState -
        The state we're transitioning away from

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    switch (ToState) {

        case KSSTATE_STOP:

            //
            // First, stop the hardware if we actually did anything to it.
            //
            if (m_HardwareState != HardwareStopped) {
                Status = m_Device -> Stop ();
                NT_ASSERT (NT_SUCCESS (Status));

                m_HardwareState = HardwareStopped;
            }

            //
            // We've stopped the "fake hardware".  It has cleared out
            // it's scatter / gather tables and will no longer be 
            // completing clones.  We had locks on some frames that were,
            // however, in hardware.  This will clean them up.  An
            // alternative location would be in the reset dispatch.
            // Note, however, that the reset dispatch can occur in any
            // state and this should be understood.
            //
            // Some hardware may fill all S/G mappings before stopping...
            // in this case, you may not have to do this.  The 
            // "fake hardware" here simply stops filling mappings and 
            // cleans its scatter / gather tables out on the Stop call.
            //
            Status = CleanupReferences ();

            //
            // Release any hardware resources related to this pin.
            //
            if (m_AcquiredResources) {
                //
                // If we got an interface to the clock, we must release it.
                //
                if (m_Clock) {
                    m_Clock -> Release ();
                    m_Clock = NULL;
                }

                m_Device -> ReleaseHardwareResources (
                    );

                m_AcquiredResources = FALSE;
            }

            break;

        case KSSTATE_ACQUIRE:
            //
            // Acquire any hardware resources related to this pin.  We should
            // only acquire them here -- **NOT** at filter create time. 
            // This means we do not fail creation of a filter because of
            // limited hardware resources.
            //
            if (FromState == KSSTATE_STOP) {
                Status = m_Device -> AcquireHardwareResources (
                    this,
                    m_VideoInfoHeader
                    );

                if (NT_SUCCESS (Status)) {
                    m_AcquiredResources = TRUE;

                    //
                    // Attempt to get an interface to the master clock.
                    // This will fail if one has not been assigned.  Since
                    // one must be assigned while the pin is still in 
                    // KSSTATE_STOP, this is a guranteed method of getting
                    // the clock should one be assigned.
                    //
                    if (!NT_SUCCESS (
                        KsPinGetReferenceClockInterface (
                            m_Pin,
                            &m_Clock
                            )
                        )) {

                        //
                        // If we could not get an interface to the clock,
                        // don't use one.  
                        //
                        m_Clock = NULL;

                    }

                } else {
                    m_AcquiredResources = FALSE;
                }

            } else {
                //
                // Standard transport pins will always receive transitions in
                // +/- 1 manner.  This means we'll always see a PAUSE->ACQUIRE
                // transition before stopping the pin.  
                //
                // The below is done because on DirectX 8.0, when the pin gets
                // a message to stop, the queue is inaccessible.  The reset 
                // which comes on every stop happens after this (at which time
                // the queue is inaccessible also).  So, for compatibility with
                // DirectX 8.0, I am stopping the "fake" hardware at this
                // point and cleaning up all references we have on frames.  See
                // the comments above regarding the CleanupReferences call.
                //
                // If this sample were targeting XP only, the below code would
                // not be here.  Again, I only do this so the sample does not
                // hang when it is stopped running on a configuration such as
                // Win2K + DX8. 
                //
                if (m_HardwareState != HardwareStopped) {
                    Status = m_Device -> Stop ();
                    NT_ASSERT (NT_SUCCESS (Status));

                    m_HardwareState = HardwareStopped;
                }

                Status = CleanupReferences ();
            }

            m_FrameNumber   = 0;
            m_DroppedFrames = 0;
            break;

        case KSSTATE_PAUSE:
            //
            // Stop the hardware simulation if we're coming down from run.
            //
            if (FromState == KSSTATE_RUN) {

                m_PresentationTime = 0;
                Status = m_Device -> Pause (TRUE);

                if (NT_SUCCESS (Status)) {
                    m_HardwareState = HardwarePaused;
                }

            }
            m_FrameNumber   = 0;
            break;

        case KSSTATE_RUN:
            //
            // Start the hardware simulation or unpause it depending on
            // whether we're initially running or we've paused and restarted.
            //
            if (m_HardwareState == HardwarePaused) {
                Status = m_Device -> Pause (FALSE);
            } else {
                Status = m_Device -> Start ();
            }

            if (NT_SUCCESS (Status)) {
                m_HardwareState = HardwareRunning;
            }

            break;

    }

    return Status;

}

/*************************************************/


NTSTATUS
CCapturePin::
IntersectHandler (
    IN PKSFILTER Filter,
    IN PIRP Irp,
    IN PKSP_PIN PinInstance,
    IN PKSDATARANGE CallerDataRange,
    IN PKSDATARANGE DescriptorDataRange,
    IN ULONG BufferSize,
    OUT PVOID Data OPTIONAL,
    OUT PULONG DataSize
    )

/*++

Routine Description:

    This routine handles video pin intersection queries by determining the
    intersection between two data ranges.

Arguments:

    Filter -
        Contains a void pointer to the  filter structure.

    Irp -
        Contains a pointer to the data intersection property request.

    PinInstance -
        Contains a pointer to a structure indicating the pin in question.

    CallerDataRange -
        Contains a pointer to one of the data ranges supplied by the client
        in the data intersection request.  The format type, subtype and
        specifier are compatible with the DescriptorDataRange.

    DescriptorDataRange -
        Contains a pointer to one of the data ranges from the pin descriptor
        for the pin in question.  The format type, subtype and specifier are
        compatible with the CallerDataRange.

    BufferSize -
        Contains the size in bytes of the buffer pointed to by the Data
        argument.  For size queries, this value will be zero.

    Data -
        Optionally contains a pointer to the buffer to contain the data 
        format structure representing the best format in the intersection 
        of the two data ranges.  For size queries, this pointer will be 
        NULL.

    DataSize -
        Contains a pointer to the location at which to deposit the size 
        of the data format.  This information is supplied by the function 
        when the format is actually delivered and in response to size 
        queries.

Return Value:

    STATUS_SUCCESS if there is an intersection and it fits in the supplied
    buffer, STATUS_BUFFER_OVERFLOW for successful size queries, 
    STATUS_NO_MATCH if the intersection is empty, or 
    STATUS_BUFFER_TOO_SMALL if the supplied buffer is too small.

--*/

{
    PAGED_CODE();

    const GUID VideoInfoSpecifier = 
        {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};
    
    NT_ASSERT(Filter);
    NT_ASSERT(Irp);
    NT_ASSERT(PinInstance);
    NT_ASSERT(CallerDataRange);
    NT_ASSERT(DescriptorDataRange);
    NT_ASSERT(DataSize);
    
    ULONG DataFormatSize;
    
    //
    // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
    //
    if (IsEqualGUID(CallerDataRange->Specifier, VideoInfoSpecifier) &&
        CallerDataRange -> FormatSize >= sizeof (KS_DATARANGE_VIDEO)) {
            
        PKS_DATARANGE_VIDEO callerDataRange = 
            reinterpret_cast <PKS_DATARANGE_VIDEO> (CallerDataRange);

        PKS_DATARANGE_VIDEO descriptorDataRange = 
            reinterpret_cast <PKS_DATARANGE_VIDEO> (DescriptorDataRange);

        PKS_DATAFORMAT_VIDEOINFOHEADER FormatVideoInfoHeader;

        //
        // Check that the other fields match
        //
        if ((callerDataRange->bFixedSizeSamples != 
                descriptorDataRange->bFixedSizeSamples) ||
            (callerDataRange->bTemporalCompression != 
                descriptorDataRange->bTemporalCompression) ||
            (callerDataRange->StreamDescriptionFlags != 
                descriptorDataRange->StreamDescriptionFlags) ||
            (callerDataRange->MemoryAllocationFlags != 
                descriptorDataRange->MemoryAllocationFlags) ||
            (RtlCompareMemory (&callerDataRange->ConfigCaps,
                    &descriptorDataRange->ConfigCaps,
                    sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) != 
                    sizeof (KS_VIDEO_STREAM_CONFIG_CAPS))) 
        {
            return STATUS_NO_MATCH;
        }

        //
        // KS_SIZE_VIDEOHEADER() below is relying on bmiHeader.biSize from
        // the caller's data range.  This **MUST** be validated; the
        // extended bmiHeader size (biSize) must not extend past the end
        // of the range buffer.  Possible arithmetic overflow is also
        // checked for.
        //
        {
            ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER (
                &callerDataRange->VideoInfoHeader
                );

            ULONG DataRangeSize = 
                FIELD_OFFSET (KS_DATARANGE_VIDEO, VideoInfoHeader) +
                VideoHeaderSize;

            //
            // Check that biSize does not extend past the buffer.  The 
            // first two checks are for arithmetic overflow on the 
            // operations to compute the alleged size.  (On unsigned
            // math, a+b < a iff an arithmetic overflow occurred).
            //
            if (
                VideoHeaderSize < callerDataRange->
                    VideoInfoHeader.bmiHeader.biSize ||
                DataRangeSize < VideoHeaderSize ||
                DataRangeSize > callerDataRange -> DataRange.FormatSize
                ) {

                return STATUS_INVALID_PARAMETER;

            }

        }

        DataFormatSize = 
            sizeof (KSDATAFORMAT) + 
            KS_SIZE_VIDEOHEADER (&callerDataRange->VideoInfoHeader);

            
        //
        // If the passed buffer size is 0, it indicates that this is a size
        // only query.  Return the size of the intersecting data format and
        // pass back STATUS_BUFFER_OVERFLOW.
        //
        if (BufferSize == 0) {

            *DataSize = DataFormatSize;
            return STATUS_BUFFER_OVERFLOW;

        }
        
        //
        // Verify that the provided structure is large enough to
        // accept the result.
        //
        if (BufferSize < DataFormatSize) 
        {
            return STATUS_BUFFER_TOO_SMALL;
        }

        //
        // Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader
        //
        *DataSize = DataFormatSize;
            
        FormatVideoInfoHeader = PKS_DATAFORMAT_VIDEOINFOHEADER( Data );

        //
        // Copy over the KSDATAFORMAT.  This is precisely the same as the
        // KSDATARANGE (it's just the GUIDs, etc...  not the format information
        // following any data format.
        // 
        RtlCopyMemory (
            &FormatVideoInfoHeader->DataFormat, 
            DescriptorDataRange, 
            sizeof (KSDATAFORMAT));

        FormatVideoInfoHeader->DataFormat.FormatSize = DataFormatSize;

        //
        // Copy over the callers requested VIDEOINFOHEADER
        //

        RtlCopyMemory (
            &FormatVideoInfoHeader->VideoInfoHeader, 
            &callerDataRange->VideoInfoHeader,
            KS_SIZE_VIDEOHEADER (&callerDataRange->VideoInfoHeader) 
            );

        //
        // Calculate biSizeImage for this request, and put the result in both
        // the biSizeImage field of the bmiHeader AND in the SampleSize field
        // of the DataFormat.
        //
        // Note that for compressed sizes, this calculation will probably not
        // be just width * height * bitdepth
        //
        FormatVideoInfoHeader->VideoInfoHeader.bmiHeader.biSizeImage =
            FormatVideoInfoHeader->DataFormat.SampleSize = 
            KS_DIBSIZE (FormatVideoInfoHeader->VideoInfoHeader.bmiHeader);

        //
        // REVIEW - Perform other validation such as cropping and scaling checks
        // 
        
        return STATUS_SUCCESS;
        
    } // End of VIDEOINFOHEADER specifier
    
    return STATUS_NO_MATCH;
}

/*************************************************/

BOOL
MultiplyCheckOverflow (
    ULONG a,
    ULONG b,
    ULONG *pab
    )

/*++

Routine Description:

    Perform a 32 bit unsigned multiplication and check for arithmetic overflow.

Arguments:

    a -
        First operand

    b -
        Second operand

    pab -
        Result

Return Value:

    TRUE -
        no overflow

    FALSE -
        overflow occurred

--*/

{
    PAGED_CODE();

    *pab = a * b;
    if ((a == 0) || (((*pab) / a) == b)) {
        return TRUE;
    }
    return FALSE;
}

/*************************************************/


NTSTATUS
CCapturePin::
DispatchSetFormat (
    IN PKSPIN Pin,
    IN PKSDATAFORMAT OldFormat OPTIONAL,
    IN PKSMULTIPLE_ITEM OldAttributeList OPTIONAL,
    IN const KSDATARANGE *DataRange,
    IN const KSATTRIBUTE_LIST *AttributeRange OPTIONAL
    )

/*++

Routine Description:

    This is the set data format dispatch for the capture pin.  It is called
    in two circumstances.

        1: before Pin's creation dispatch has been made to verify that
           Pin -> ConnectionFormat is an acceptable format for the range
           DataRange.  In this case OldFormat is NULL.

        2: after Pin's creation dispatch has been made and an initial format
           selected in order to change the format for the pin.  In this case,
           OldFormat will not be NULL.

    Validate that the format is acceptable and perform the actions necessary
    to change format if appropriate.

Arguments:

    Pin -
        The pin this format is being set on.  The format itself will be in
        Pin -> ConnectionFormat.

    OldFormat -
        The previous format used on this pin.  If this is NULL, it is an
        indication that Pin's creation dispatch has not yet been made and
        that this is a request to validate the initial format and not to
        change formats.

    OldAttributeList -
        The old attribute list for the prior format

    DataRange -
        A range out of our list of data ranges which was determined to be
        at least a partial match for Pin -> ConnectionFormat.  If the format
        there is unacceptable for the range, STATUS_NO_MATCH should be
        returned.

    AttributeRange -
        The attribute range

Return Value:

    Success / Failure

        STATUS_SUCCESS -
            The format is acceptable / the format has been changed

        STATUS_NO_MATCH -
            The format is not-acceptable / the format has not been changed

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_NO_MATCH;

    const GUID VideoInfoSpecifier = 
        {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};

    CCapturePin *CapPin = NULL;

    //
    // Find the pin, if it exists yet.  OldFormat will be an indication of 
    // this.  If we're changing formats, OldFormat will be non-NULL.
    //
    // You cannot use Pin -> Context to make the determination.  AVStream
    // preinitializes this to the filter's context.
    //
    if (OldFormat) {
        CapPin = reinterpret_cast <CCapturePin *> (Pin -> Context);
    }

    if (IsEqualGUID (Pin -> ConnectionFormat -> Specifier,
            VideoInfoSpecifier) &&
        Pin -> ConnectionFormat -> FormatSize >=
            sizeof (KS_DATAFORMAT_VIDEOINFOHEADER)) {

        PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat =
            reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER> 
                (Pin -> ConnectionFormat);

        //
        // DataRange comes out of OUR data range list.  I know the range
        // is valid as such.
        //
        const KS_DATARANGE_VIDEO *VIRange =
            reinterpret_cast <const KS_DATARANGE_VIDEO *>
                (DataRange);

        //
        // Check that bmiHeader.biSize is valid since we use it later.
        //
        ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER (
            &ConnectionFormat -> VideoInfoHeader
            );

        ULONG DataFormatSize = FIELD_OFFSET (
            KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader
            ) + VideoHeaderSize;

        if (
            VideoHeaderSize < ConnectionFormat->
                VideoInfoHeader.bmiHeader.biSize ||
            DataFormatSize < VideoHeaderSize ||
            DataFormatSize > ConnectionFormat -> DataFormat.FormatSize
            ) {

            Status = STATUS_INVALID_PARAMETER;

        }

        //
        // Check that the format is a match for the selected range. 
        //
        else if (
            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biWidth !=
                VIRange -> VideoInfoHeader.bmiHeader.biWidth) ||

            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biHeight !=
                VIRange -> VideoInfoHeader.bmiHeader.biHeight) ||

            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biCompression !=
                VIRange -> VideoInfoHeader.bmiHeader.biCompression) 

            ) {

            Status = STATUS_NO_MATCH;

        } else {

            //
            // Compute the minimum size of our buffers to validate against.
            // The image synthesis routines synthesize |biHeight| rows of
            // biWidth pixels in either RGB24 or UYVY.  In order to ensure
            // safe synthesis into the buffer, we need to know how large an
            // image this will produce.
            //
            // I do this explicitly because of the method that the data is
            // synthesized.  A variation of this may or may not be necessary
            // depending on the mechanism the driver in question fills the 
            // capture buffers.  The important thing is to ensure that they
            // aren't overrun during capture.
            //
            ULONG ImageSize;

            if (!MultiplyCheckOverflow (
                (ULONG)ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth,
                (ULONG)abs (ConnectionFormat->
                    VideoInfoHeader.bmiHeader.biHeight),
                &ImageSize
                )) {

                Status = STATUS_INVALID_PARAMETER;
            }

            //
            // We only support KS_BI_RGB (24) and KS_BI_YUV422 (16), so
            // this is valid for those formats.
            //
            else if (!MultiplyCheckOverflow (
                ImageSize,
                (ULONG)(ConnectionFormat->
                    VideoInfoHeader.bmiHeader.biBitCount / 8),
                &ImageSize
                )) {

                Status = STATUS_INVALID_PARAMETER;

            }

            //
            // Valid for the formats we use.  Otherwise, this would be
            // checked later.
            //
            else if (ConnectionFormat->VideoInfoHeader.bmiHeader.biSizeImage <
                    ImageSize) {

                Status = STATUS_INVALID_PARAMETER;

            } else {

                //
                // We can accept the format. 
                //
                Status = STATUS_SUCCESS;

                //
                // OldFormat is an indication that this is a format change.  
                // Since I do not implement the 
                // KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, by default, I do 
                // not handle dynamic format changes.
                //
                // If something changes while we're in the stop state, we're 
                // fine to handle it since we haven't "configured the hardware"
                // yet.
                //
                if (OldFormat) {
                    //
                    // If we're in the stop state, we can handle just about any
                    // change.  We don't support dynamic format changes. 
                    //
                    if (Pin -> DeviceState == KSSTATE_STOP) {
                        if (!CapPin -> CaptureVideoInfoHeader ()) {
                            Status = STATUS_INSUFFICIENT_RESOURCES;
                        }
                    } else {
                        //
                        // Because we don't accept dynamic format changes, we
                        // should never get here.  Just being over-protective.
                        //
                        Status = STATUS_INVALID_DEVICE_STATE;
                    }
                }

            }

        }

    }
    return Status;
}

/**************************************************************************

    LOCKED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA

void
CCapturePin::
CompleteMappings (
    IN ULONG NumMappings
    )

/*++

Routine Description:

    Called to notify the pin that a given number of scatter / gather
    mappings have completed.  Let the buffers go if possible.
    We're called at DPC.

Arguments:

    NumMappings -
        The number of mappings that have completed.

Return Value:

    None

--*/

{

    ULONG MappingsRemaining = NumMappings;

    //
    // Walk through the clones list and delete clones whose time has come.
    // The list is guaranteed to be kept in the order they were cloned.
    //
    PKSSTREAM_POINTER Clone = KsPinGetFirstCloneStreamPointer (m_Pin);

    while (MappingsRemaining && Clone) {

        PKSSTREAM_POINTER NextClone = KsStreamPointerGetNextClone (Clone);

        // 
        // If we have completed all remaining mappings in this clone, it
        // is an indication that the clone is ready to be deleted and the
        // buffer released.  Set anything required in the stream header which
        // has not yet been set.  If we have a clock, we can timestamp the
        // sample.
        //
        if (Clone -> StreamHeader -> DataUsed >= Clone -> OffsetOut.Remaining) {
            Clone -> StreamHeader -> Duration =
                m_VideoInfoHeader -> AvgTimePerFrame;

            Clone -> StreamHeader -> PresentationTime.Numerator =
                Clone -> StreamHeader -> PresentationTime.Denominator = 1;

            //
            // If a clock has been assigned, timestamp the packets with the
            // time shown on the clock. 
            //
            if (m_Clock) {

                LONGLONG ClockTime = m_Clock -> GetTime ();

                Clone -> StreamHeader -> PresentationTime.Time = ClockTime;

                Clone -> StreamHeader -> OptionsFlags =
                    KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
                    KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;

            } else {
	      //
	      // If there is no clock, don't time stamp the packets.
	      //
	      Clone -> StreamHeader -> PresentationTime.Time = 0;
	      
            }

            //
            // Increment the frame number.  This is the total count of frames which
            // have attempted capture.
            //
            m_FrameNumber++;

            //
            // Double check the Stream Header size.  AVStream makes no guarantee
            // that because StreamHeaderSize is set to a specific size that you
            // will get that size.  If the proper data type handlers are not 
            // installed, the stream header will be of default size.
            //
            if ( Clone -> StreamHeader -> Size >= sizeof (KSSTREAM_HEADER) +
                sizeof (KS_FRAME_INFO)) {

                PKS_FRAME_INFO FrameInfo = reinterpret_cast <PKS_FRAME_INFO> (
                    Clone -> StreamHeader + 1
                    );
    
                FrameInfo -> ExtendedHeaderSize = sizeof (KS_FRAME_INFO);
                FrameInfo -> dwFrameFlags       = KS_VIDEO_FLAG_FRAME;
                FrameInfo -> PictureNumber      = (LONGLONG)m_FrameNumber;

                // I don't really have a way to tell if the device has dropped a frame 
                // or was not able to send a frame on time.
                FrameInfo -> DropCount = (LONGLONG)m_DroppedFrames;
            }


            //
            // If all of the mappings in this clone have been completed,
            // delete the clone.  We've already updated DataUsed above.
            //

            MappingsRemaining--;
            KsStreamPointerDelete (Clone);

        } else {
            //
            // If only part of the mappings in this clone have been completed,
            // update the pointers.  Since we're guaranteed this won't advance
            // to a new frame by the check above, it won't fail.
            //
            (void)KsStreamPointerAdvanceOffsets (
                Clone,
                0,
                Clone -> StreamHeader -> DataUsed,
                FALSE
                );

            MappingsRemaining = 0;

        }

        //
        // Go to the next clone.
        //
        Clone = NextClone;

    }

    //
    // If we've used all the mappings in hardware and pended, we can kick
    // processing to happen again if we've completed mappings.
    //
    if (m_PendIo) {
        m_PendIo = TRUE;
        KsPinAttemptProcessing (m_Pin, TRUE);
    }

}

/**************************************************************************

    DISPATCH AND DESCRIPTOR LAYOUT

**************************************************************************/

//
// FormatRGB24Bpp_Capture:
//
// This is the data range description of the RGB24 capture format we support.
//
const 
KS_DATARANGE_VIDEO 
FormatRGB24Bpp_Capture = {

    //
    // KSDATARANGE
    //
    {   
        sizeof (KS_DATARANGE_VIDEO),                // FormatSize
        0,                                          // Flags
        D_X * D_Y * 3,                              // SampleSize
        0,                                          // Reserved

        STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO),     // aka. MEDIATYPE_Video
        0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 
            0xaf, 0x0b, 0xa7, 0x70,                 // aka. MEDIASUBTYPE_RGB24,
        STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
    },

    TRUE,               // BOOL,  bFixedSizeSamples (all samples same size?)
    FALSE,              // BOOL,  bTemporalCompression (all I frames?)
    0,                  // Reserved (was StreamDescriptionFlags)
    0,                  // Reserved (was MemoryAllocationFlags   
                        //           (KS_VIDEO_ALLOC_*))
    //
    // _KS_VIDEO_STREAM_CONFIG_CAPS  
    //
    {
        STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
        KS_AnalogVideo_None,                            // AnalogVideoStandard
        D_X,D_Y,        // InputSize, (the inherent size of the incoming signal
                        //             with every digitized pixel unique)
        D_X,D_Y,        // MinCroppingSize, smallest rcSrc cropping rect allowed
        D_X,D_Y,        // MaxCroppingSize, largest  rcSrc cropping rect allowed
        8,              // CropGranularityX, granularity of cropping size
        1,              // CropGranularityY
        8,              // CropAlignX, alignment of cropping rect 
        1,              // CropAlignY;
        D_X, D_Y,       // MinOutputSize, smallest bitmap stream can produce
        D_X, D_Y,       // MaxOutputSize, largest  bitmap stream can produce
        8,              // OutputGranularityX, granularity of output bitmap size
        1,              // OutputGranularityY;
        0,              // StretchTapsX  (0 no stretch, 1 pix dup, 2 interp...)
        0,              // StretchTapsY
        0,              // ShrinkTapsX 
        0,              // ShrinkTapsY 
        333667,         // MinFrameInterval, 100 nS units
        640000000,      // MaxFrameInterval, 100 nS units
        8 * 3 * 30 * D_X * D_Y,  // MinBitsPerSecond;
        8 * 3 * 30 * D_X * D_Y   // MaxBitsPerSecond;
    }, 
        
    //
    // KS_VIDEOINFOHEADER (default format)
    //
    {
        0,0,0,0,                            // RECT  rcSource; 
        0,0,0,0,                            // RECT  rcTarget; 
        D_X * D_Y * 3 * 8 * 30,             // DWORD dwBitRate;
        0L,                                 // DWORD dwBitErrorRate; 
        333667,                             // REFERENCE_TIME  AvgTimePerFrame;   
        sizeof (KS_BITMAPINFOHEADER),       // DWORD biSize;
        D_X,                                // LONG  biWidth;
        D_Y,                                // LONG  biHeight;
        1,                                  // WORD  biPlanes;
        24,                                 // WORD  biBitCount;
        KS_BI_RGB,                          // DWORD biCompression;
        D_X * D_Y * 3,                      // DWORD biSizeImage;
        0,                                  // LONG  biXPelsPerMeter;
        0,                                  // LONG  biYPelsPerMeter;
        0,                                  // DWORD biClrUsed;
        0                                   // DWORD biClrImportant;
    }
}; 

//
// FormatYUY2_Capture:
//
// This is the data range description of the YUY2 format we support.
//
const 
KS_DATARANGE_VIDEO 
FormatYUY2_Capture = {

    //
    // KSDATARANGE
    //
    {   
        sizeof (KS_DATARANGE_VIDEO),            // FormatSize
        0,                                      // Flags
        DMAX_X * DMAX_Y * 2,                    // SampleSize
        0,                                      // Reserved
        STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO), // aka. MEDIATYPE_Video
        0x32595559, 0x0000, 0x0010, 0x80, 0x00, 
        0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,     //aka. MEDIASUBTYPE_YUY2,
        STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
    },

    TRUE,               // BOOL,  bFixedSizeSamples (all samples same size?)
    FALSE,              // BOOL,  bTemporalCompression (all I frames?)
    0,                  // Reserved (was StreamDescriptionFlags)
    0,                  // Reserved (was MemoryAllocationFlags   
                        //           (KS_VIDEO_ALLOC_*))

    //
    // _KS_VIDEO_STREAM_CONFIG_CAPS  
    //
    {
        STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
        KS_AnalogVideo_None,                            // AnalogVideoStandard
        DMAX_X, DMAX_Y, // InputSize, (the inherent size of the incoming signal
                        //             with every digitized pixel unique)
        D_X,D_Y,        // MinCroppingSize, smallest rcSrc cropping rect allowed
        DMAX_X, DMAX_Y, // MaxCroppingSize, largest  rcSrc cropping rect allowed
        8,              // CropGranularityX, granularity of cropping size
        1,              // CropGranularityY
        8,              // CropAlignX, alignment of cropping rect 
        1,              // CropAlignY;
        D_X, D_Y,       // MinOutputSize, smallest bitmap stream can produce
        DMAX_X, DMAX_Y, // MaxOutputSize, largest  bitmap stream can produce
        8,              // OutputGranularityX, granularity of output bitmap size
        1,              // OutputGranularityY;
        0,              // StretchTapsX  (0 no stretch, 1 pix dup, 2 interp...)
        0,              // StretchTapsY
        0,              // ShrinkTapsX 
        0,              // ShrinkTapsY 
        333667,         // MinFrameInterval, 100 nS units
        640000000,      // MaxFrameInterval, 100 nS units
        8 * 2 * 30 * D_X * D_Y,  // MinBitsPerSecond;
        8 * 2 * 30 * DMAX_X * DMAX_Y,   // MaxBitsPerSecond;
    }, 
        
    //
    // KS_VIDEOINFOHEADER (default format)
    //
    {
        0, 0, 0, 0,                         // RECT  rcSource; 
        0, 0, 0, 0,                         // RECT  rcTarget; 
        DMAX_X * DMAX_Y * 2 * 8 * 30,       // DWORD dwBitRate;
        0L,                                 // DWORD dwBitErrorRate; 
        333667,                             // REFERENCE_TIME  AvgTimePerFrame;   
        sizeof (KS_BITMAPINFOHEADER),       // DWORD biSize;
        DMAX_X,                             // LONG  biWidth;
        DMAX_Y,                             // LONG  biHeight;
        1,                                  // WORD  biPlanes;
        16,                                 // WORD  biBitCount;
        FOURCC_YUY2,                        // DWORD biCompression;
        DMAX_X * DMAX_Y * 2,                // DWORD biSizeImage;
        0,                                  // LONG  biXPelsPerMeter;
        0,                                  // LONG  biYPelsPerMeter;
        0,                                  // DWORD biClrUsed;
        0                                   // DWORD biClrImportant;
    }
}; 

//
// CapturePinDispatch:
//
// This is the dispatch table for the capture pin.  It provides notifications
// about creation, closure, processing, data formats, etc...
//
const
KSPIN_DISPATCH
CapturePinDispatch = {
    CCapturePin::DispatchCreate,            // Pin Create
    NULL,                                   // Pin Close
    CCapturePin::DispatchProcess,           // Pin Process
    NULL,                                   // Pin Reset
    CCapturePin::DispatchSetFormat,         // Pin Set Data Format
    CCapturePin::DispatchSetState,          // Pin Set Device State
    NULL,                                   // Pin Connect
    NULL,                                   // Pin Disconnect
    NULL,                                   // Clock Dispatch
    NULL                                    // Allocator Dispatch
};

//
// CapturePinAllocatorFraming:
//
// This is the simple framing structure for the capture pin.  Note that this
// will be modified via KsEdit when the actual capture format is determined.
//
DECLARE_SIMPLE_FRAMING_EX (
    CapturePinAllocatorFraming,
    STATICGUIDOF (KSMEMORY_TYPE_KERNEL_NONPAGED),
    KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
        KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY,
    2,
    0,
    2 * PAGE_SIZE,
    2 * PAGE_SIZE
    );

//
// CapturePinDataRanges:
//
// This is the list of data ranges supported on the capture pin.  We support
// two: one RGB24, and one YUY2.
//
const 
PKSDATARANGE 
CapturePinDataRanges [CAPTURE_PIN_DATA_RANGE_COUNT] = {
    //(PKSDATARANGE) &FormatYUY2_Capture,
    (PKSDATARANGE) &FormatRGB24Bpp_Capture
    };


================================================
FILE: Driver/avshws/capture.h
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        capture.h

    Abstract:

        This file contains header for the video capture pin on the capture
        filter.  The capture sample performs "fake" DMA directly into
        the capture buffers.  Common buffer DMA will work slightly differently.

        For common buffer DMA, the general technique would be DPC schedules
        processing with KsPinAttemptProcessing.  The processing routine grabs
        the leading edge, copies data out of the common buffer and advances.
        Cloning would not be necessary with this technique.  It would be 
        similiar to the way "AVSSamp" works, but it would be pin-centric.

    History:

        created 3/8/2001

**************************************************************************/
#include <initguid.h>
//
// STREAM_POINTER_CONTEXT:
//
// This is the context structure we associate with all clone stream pointers.
// It allows the mapping code to rip apart the buffer into chunks the same
// size as the scatter/gather mappings in order to fake scatter / gather
// bus-master DMA.
//
typedef struct _STREAM_POINTER_CONTEXT {
    
    PUCHAR BufferVirtual;

} STREAM_POINTER_CONTEXT, *PSTREAM_POINTER_CONTEXT;

//
// CCapturePin:
//
// The video capture pin class.
//
class CCapturePin :
    public ICaptureSink {

private:

    //
    // The AVStream pin we're associated with.
    //
    PKSPIN m_Pin;

    //
    // Pointer to the internal device object for our capture device.
    // We access the "fake" hardware through this object.
    //
    CCaptureDevice *m_Device;
    
    //
    // The state we've put the hardware into.  This allows us to keep track
    // of whether to do things like unpausing or restarting.
    //
    HARDWARE_STATE m_HardwareState;

    //
    // The clock we've been assigned.  As with other capture filters, we do
    // not expose a clock.  If one has been assigned, we will use it to
    // time stamp packets (plus a reasonable delta to work the capture stream
    // in a preview graph).
    //
    PIKSREFERENCECLOCK m_Clock;

    //
    // The captured video info header.  The settings for "fake" hardware will be
    // programmed via this video info header.
    //
    PKS_VIDEOINFOHEADER m_VideoInfoHeader;

    //
    // If we are unable to insert all of the mappings in a stream pointer into
    // the "fake" hardware's scatter / gather table, we set this to the
    // stream pointer that's incomplete.  This is done both to make the 
    // relasing easier and to make it easier to fake the scatter / gather
    // hardware.
    //
    PKSSTREAM_POINTER m_PreviousStreamPointer;

    //
    // An indication of whether or not we pended I/O for some reason.  If this
    // is set, the DPC will resume I/O when any mappings are completed.
    //
    BOOLEAN m_PendIo;

    //
    // An indication of whether or not this pin has acquired the necessary
    // hardware resources to operate.  When the pin reaches KSSTATE_ACQUIRE,
    // we attempt to acquire the hardware.  This flag will be set based on
    // our success / failure.
    //
    BOOLEAN m_AcquiredResources;
    
    //
    // Presentation time for the sample
    //
    LONGLONG m_PresentationTime;

    LONGLONG m_FrameNumber;
    LONGLONG m_DroppedFrames;

    //
    // CleanupReferences():
    //
    // Clean up any references we hold on frames in the queue.  This is called
    // when we abruptly stop the fake hardware.
    //
    NTSTATUS
    CleanupReferences (
        );

    //
    // SetState():
    //
    // This is the state transition handler for the capture pin.  It attempts
    // to acquire resources for the capture pin (or releasing them if
    // necessary) and starts and stops the hardware as required.
    //
    NTSTATUS
    SetState (
        IN KSSTATE ToState,
        IN KSSTATE FromState
        );

    //
    // Process():
    //
    // This is the processing dispatch for the capture pin.  It handles
    // programming the scatter / gather tables for the hardware as buffers
    // become available.  This processing routine is designed for a direct
    // into the capture buffers kind of DMA as opposed to common-buffer
    // and copy strategies.
    //
    NTSTATUS
    Process (
        );
    //
    // CaptureVideoInfoHeader():
    //
    // This routine stashes the video info header set on the pin connection
    // in the CCapturePin object.  This is used to base hardware settings.
    //
    PKS_VIDEOINFOHEADER
    CaptureVideoInfoHeader (
        );

    //
    // Cleanup():
    //
    // This is the free callback from the bagged item (CCapturePin).  If we
    // do not provide a callback when we bag the CCapturePin, ExFreePool
    // would be called.  This is not desirable for C++ constructed objects.
    // We merely delete the object here.
    //
    static
    void
    Cleanup (
        IN CCapturePin *Pin
        )
    {
        delete Pin;
    }

public:
    //
    // CCapturePin():
    //
    // The capture pin's constructor.  Initialize any non-0, non-NULL fields
    // (since new will have zero'ed the memory anyway) and set up our
    // device level pointers for access during capture routines.
    //
    CCapturePin (
        IN PKSPIN Pin
        );

    //
    // ~CCapturePin():
    //
    // The capture pin's destructor.
    //
    ~CCapturePin (
        )
    {
    }

    //
    // ICaptureSink::CompleteMappings()
    //
    // This is the capture sink notification mechanism for mapping completion.
    // When the device DPC detects that a given number of mappings have been
    // completed by the fake hardware, it signals the capture sink of this
    // through this method.
    //
    virtual
    void
    CompleteMappings (
        IN ULONG NumMappings
        );

    /*************************************************

        Dispatch Routines

    *************************************************/

    //
    // DispatchCreate():
    //
    // This is the creation dispatch for the capture pin.  It creates
    // the CCapturePin object and associates it with the AVStream object
    // bagging it in the process.
    //
    static
    NTSTATUS
    DispatchCreate (
        IN PKSPIN Pin,
        IN PIRP Irp
        );

    //
    // DispatchSetState():
    //
    // This is the set device state dispatch for the pin.  The routine bridges
    // to SetState() in the context of the CCapturePin.
    //
    static
    NTSTATUS
    DispatchSetState (
        IN PKSPIN Pin,
        IN KSSTATE ToState,
        IN KSSTATE FromState
        )
    {
        return 
            (reinterpret_cast <CCapturePin *> (Pin -> Context)) ->
                SetState (ToState, FromState);
    }

    //
    // DispatchSetFormat():
    //
    // This is the set data format dispatch for the pin.  This will be called
    // BEFORE pin creation to validate that a data format selected is a match
    // for the range pulled out of our range list.  It will also be called
    // for format changes.
    //
    // If OldFormat is NULL, this is an indication that it's the initial
    // call and not a format change.  Even fixed format pins get this call
    // once.
    //
    static
    NTSTATUS
    DispatchSetFormat (
        IN PKSPIN Pin,
        IN PKSDATAFORMAT OldFormat OPTIONAL,
        IN PKSMULTIPLE_ITEM OldAttributeList OPTIONAL,
        IN const KSDATARANGE *DataRange,
        IN const KSATTRIBUTE_LIST *AttributeRange OPTIONAL
        );

    //
    // DispatchProcess():
    //
    // This is the processing dispatch for the capture pin.  The routine 
    // bridges to Process() in the context of the CCapturePin.
    //
    static 
    NTSTATUS
    DispatchProcess (
        IN PKSPIN Pin
        )
    {
        return 
            (reinterpret_cast <CCapturePin *> (Pin -> Context)) ->
               Process ();
            
    }

    //
    // IntersectHandler():
    //
    // This is the data intersection handler for the capture pin.  This 
    // determines an optimal format in the intersection of two ranges,
    // one local and one possibly foreign.  If there is no compatible format,
    // STATUS_NO_MATCH is returned.
    //
    static
    NTSTATUS
    IntersectHandler (
        IN PKSFILTER Filter,
        IN PIRP Irp,
        IN PKSP_PIN PinInstance,
        IN PKSDATARANGE CallerDataRange,
        IN PKSDATARANGE DescriptorDataRange,
        IN ULONG BufferSize,
        OUT PVOID Data OPTIONAL,
        OUT PULONG DataSize
        );

};

================================================
FILE: Driver/avshws/customprops.h
================================================
#pragma once


#define DEFINE_STD_PROPERTY_SET(SET, PROPERTIES)    \
    DEFINE_KSPROPERTY_SET(                          \
        &SET,                                       \
        SIZEOF_ARRAY(PROPERTIES),                   \
        PROPERTIES,                                 \
        0,                                          \
        NULL)

#define DEFINE_PROP_ITEM_WITH_VALUES( T, ctrl, type, name, values )     \
    DEFINE_KSPROPERTY_ITEM(                                             \
        ctrl,                                                           \
        (&T::Prop<type, T, &T::Get##name>),                             \
        sizeof(KSPROPERTY),                                             \
        0,                                                              \
        (&T::Prop<type, T, &T::Set##name>),                             \
        values, 0, NULL, NULL, 0                                        \
        )


#define DEFINE_PROP_ITEM( T, ctrl, type, name )                         \
    DEFINE_PROP_ITEM_WITH_VALUES( T, ctrl, type, name, NULL )


//  Declare a property's GET handler.
#define DECLARE_PROPERTY_GET_HANDLER( name )      \
    static NTSTATUS                                            \
    Get##name(                                          \
        _In_ PIRP Irp, _In_ PKSIDENTIFIER Request, _Inout_ PVOID Data  \
        );

//  Declare a property's SET handler.
#define DECLARE_PROPERTY_SET_HANDLER( name )      \
    static NTSTATUS                                            \
    Set##name(                                          \
        _In_ PIRP Irp, _In_ PKSIDENTIFIER Request, _Inout_ PVOID Data  \
        );

//  Declare a property's GET and SET handlers.
#define DECLARE_PROPERTY_HANDLERS( name )         \
DECLARE_PROPERTY_GET_HANDLER( name )              \
DECLARE_PROPERTY_SET_HANDLER( name )

// {CB043957-7B35-456E-9B61-5513930F4D8E}
#define STATIC_PROPSETID_VIDCAP_CUSTOMCONTROL 0xcb043957, 0x7b35, 0x456e, 0x9b, 0x61, 0x55, 0x13, 0x93, 0xf, 0x4d, 0x8e
DEFINE_GUIDSTRUCT("CB043957-7B35-456E-9B61-5513930F4D8E", PROPSETID_VIDCAP_CUSTOMCONTROL);
#define PROPSETID_VIDCAP_CUSTOMCONTROL DEFINE_GUIDNAMED(PROPSETID_VIDCAP_CUSTOMCONTROL )


enum
{
	KSPROPERTY_CUSTOMCONTROL_DUMMY
};

================================================
FILE: Driver/avshws/device.cpp
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        device.cpp

    Abstract:

        This file contains the device level implementation of the AVStream
        hardware sample.  Note that this is not the "fake" hardware.  The
        "fake" hardware is in hwsim.cpp.

    History:

        created 3/9/2001

**************************************************************************/

#include "avshws.h"

PVOID operator new
(
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
       __drv_reportError("Must succeed pool allocations are forbidden. "
             "Allocation failures cause a system crash"))
    POOL_TYPE       poolType
)
{
    PVOID result = ExAllocatePoolWithTag(poolType,iSize,'wNCK');

    if (result) {
        RtlZeroMemory(result,iSize);
    }

    return result;
}

PVOID operator new
(
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
       __drv_reportError("Must succeed pool allocations are forbidden. "
             "Allocation failures cause a system crash"))
    POOL_TYPE       poolType,
    ULONG           tag
)
{
    PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag);

    if (result) {
        RtlZeroMemory(result,iSize);
    }

    return result;
}

PVOID 
operator new[](
    size_t          iSize,
    _When_((poolType & NonPagedPoolMustSucceed) != 0,
        __drv_reportError("Must succeed pool allocations are forbidden. "
            "Allocation failures cause a system crash"))
    POOL_TYPE       poolType,
    ULONG           tag
)
{
    PVOID result = ExAllocatePoolWithTag(poolType, iSize, tag);

    if (result)
    {
        RtlZeroMemory(result, iSize);
    }

    return result;
}

/*++

Routine Description:

    Array delete() operator.

Arguments:

    pVoid -
        The memory to free.

Return Value:

    None

--*/
void 
__cdecl 
operator delete[](
    PVOID pVoid
)
{
    if (pVoid)
    {
        ExFreePool(pVoid);
    }
}

/*++

Routine Description:

    Sized delete() operator.

Arguments:

    pVoid -
        The memory to free.

    size -
        The size of the memory to free.

Return Value:

    None

--*/
void __cdecl operator delete
(
    void *pVoid,
    size_t /*size*/
)
{
    if (pVoid)
    {
        ExFreePool(pVoid);
    }
}

/*++

Routine Description:

    Sized delete[]() operator.

Arguments:

    pVoid -
        The memory to free.

    size -
        The size of the memory to free.

Return Value:

    None

--*/
void __cdecl operator delete[]
(
    void *pVoid,
    size_t /*size*/
)
{
    if (pVoid)
    {
        ExFreePool(pVoid);
    }
}

void __cdecl operator delete
(
    PVOID pVoid
    )
{
    if (pVoid) {
        ExFreePool(pVoid);
    }
}

/**************************************************************************

    PAGEABLE CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA

NTSTATUS
CCaptureDevice::
DispatchCreate (
    IN PKSDEVICE Device
    )

/*++

Routine Description:

    Create the capture device.  This is the creation dispatch for the
    capture device.

Arguments:

    Device -
        The AVStream device being created.

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status;

    CCaptureDevice *CapDevice = new (NonPagedPoolNx, 'veDC') CCaptureDevice (Device);

    if (!CapDevice) {
        //
        // Return failure if we couldn't create the pin.
        //
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {

        //
        // Add the item to the object bag if we were successful.
        // Whenever the device goes away, the bag is cleaned up and
        // we will be freed.
        //
        // For backwards compatibility with DirectX 8.0, we must grab
        // the device mutex before doing this.  For Windows XP, this is
        // not required, but it is still safe.
        //
        KsAcquireDevice (Device);
        Status = KsAddItemToObjectBag (
            Device -> Bag,
            reinterpret_cast <PVOID> (CapDevice),
            reinterpret_cast <PFNKSFREE> (CCaptureDevice::Cleanup)
            );
        KsReleaseDevice (Device);

        if (!NT_SUCCESS (Status)) {
            delete CapDevice;
        } else {
            Device -> Context = reinterpret_cast <PVOID> (CapDevice);
        }

    }

    return Status;

}

/*************************************************/


NTSTATUS
CCaptureDevice::
PnpStart (
    IN PCM_RESOURCE_LIST TranslatedResourceList,
    IN PCM_RESOURCE_LIST UntranslatedResourceList
    )

/*++

Routine Description:

    Called at Pnp start.  We start up our virtual hardware simulation.

Arguments:

    TranslatedResourceList -
        The translated resource list from Pnp

    UntranslatedResourceList -
        The untranslated resource list from Pnp

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    //
    // Normally, we'd do things here like parsing the resource lists and
    // connecting our interrupt.  Since this is a simulation, there isn't
    // much to parse.  The parsing and connection should be the same as
    // any WDM driver.  The sections that will differ are illustrated below
    // in setting up a simulated DMA.
    //

    NTSTATUS Status = STATUS_SUCCESS;

    if (!m_Device -> Started) {
        // Create the Filter for the device
        KsAcquireDevice(m_Device);
        Status = KsCreateFilterFactory( m_Device->FunctionalDeviceObject,
                                        &CaptureFilterDescriptor,
                                        L"GLOBAL",
                                        NULL,
                                        KSCREATE_ITEM_FREEONSTOP,
                                        NULL,
                                        NULL,
                                        NULL );
        KsReleaseDevice(m_Device);

    }
    //
    // By PnP, it's possible to receive multiple starts without an intervening
    // stop (to reevaluate resources, for example).  Thus, we only perform
    // creations of the simulation on the initial start and ignore any 
    // subsequent start.  Hardware drivers with resources should evaluate
    // resources and make changes on 2nd start.
    //
    if (NT_SUCCESS(Status) && (!m_Device -> Started)) {

        m_HardwareSimulation = new (NonPagedPoolNx, 'miSH') CHardwareSimulation (this);
        if (!m_HardwareSimulation) {
            //
            // If we couldn't create the hardware simulation, fail.
            //
            Status = STATUS_INSUFFICIENT_RESOURCES;
    
        } else {
            Status = KsAddItemToObjectBag (
                m_Device -> Bag,
                reinterpret_cast <PVOID> (m_HardwareSimulation),
                reinterpret_cast <PFNKSFREE> (CHardwareSimulation::Cleanup)
                );

            if (!NT_SUCCESS (Status)) {
                delete m_HardwareSimulation;
            }
        }
    }
    
    return Status;

}

/*************************************************/


void
CCaptureDevice::
PnpStop (
    )

/*++

Routine Description:

    This is the pnp stop dispatch for the capture device.  It releases any
    adapter object previously allocated by IoGetDmaAdapter during Pnp Start.

Arguments:

    None

Return Value:

    None

--*/

{

    PAGED_CODE();

    if (m_DmaAdapterObject) {
        //
        // Return the DMA adapter back to the system.
        //
        m_DmaAdapterObject -> DmaOperations -> 
            PutDmaAdapter (m_DmaAdapterObject);

        m_DmaAdapterObject = NULL;
    }

}

/*************************************************/


NTSTATUS
CCaptureDevice::
AcquireHardwareResources (
    IN ICaptureSink *CaptureSink,
    IN PKS_VIDEOINFOHEADER VideoInfoHeader
    )

/*++

Routine Description:

    Acquire hardware resources for the capture hardware.  If the 
    resources are already acquired, this will return an error.
    The hardware configuration must be passed as a VideoInfoHeader.

Arguments:

    CaptureSink -
        The capture sink attempting to acquire resources.  When scatter /
        gather mappings are completed, the capture sink specified here is
        what is notified of the completions.

    VideoInfoHeader -
        Information about the capture stream.  This **MUST** remain
        stable until the caller releases hardware resources.  Note
        that this could also be guaranteed by bagging it in the device
        object bag as well.

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    //
    // If we're the first pin to go into acquire (remember we can have
    // a filter in another graph going simultaneously), grab the resources.
    //
    if (InterlockedCompareExchange (
        &m_PinsWithResources,
        1,
        0) == 0) {

        m_VideoInfoHeader = VideoInfoHeader;

        //
        // If there's an old hardware simulation sitting around for some
        // reason, blow it away.
        //
        if (m_ImageSynth) {
            delete m_ImageSynth;
            m_ImageSynth = NULL;
        }
    
        //
        // Create the necessary type of image synthesizer.
        //
        if (m_VideoInfoHeader -> bmiHeader.biBitCount == 24 &&
            m_VideoInfoHeader -> bmiHeader.biCompression == KS_BI_RGB) {
    
            //
            // If we're RGB24, create a new RGB24 synth.  RGB24 surfaces
            // can be in either orientation.  The origin is lower left if
            // height < 0.  Otherwise, it's upper left.
            //
            m_ImageSynth = new (NonPagedPoolNx, 'RysI') 
                CRGB24Synthesizer (
                    m_VideoInfoHeader -> bmiHeader.biHeight >= 0
                    );
    
        } else
        if (m_VideoInfoHeader -> bmiHeader.biBitCount == 16 &&
           (m_VideoInfoHeader -> bmiHeader.biCompression == FOURCC_YUY2)) {
    
            //
            // If we're UYVY, create the YUV synth.
            //
            m_ImageSynth = new(NonPagedPoolNx, 'YysI') CYUVSynthesizer;
    
        }
        else
            //
            // We don't synthesize anything but RGB 24 and UYVY.
            //
            Status = STATUS_INVALID_PARAMETER;
    
        if (NT_SUCCESS (Status) && !m_ImageSynth) {
    
            Status = STATUS_INSUFFICIENT_RESOURCES;
    
        } 

        if (NT_SUCCESS (Status)) {
            //
            // If everything has succeeded thus far, set the capture sink.
            //
            m_CaptureSink = CaptureSink;

        } else {
            //
            // If anything failed in here, we release the resources we've
            // acquired.
            //
            ReleaseHardwareResources ();
        }
    
    } else {

        //
        // TODO: Better status code?
        //
        Status = STATUS_SHARING_VIOLATION;

    }

    return Status;

}

/*************************************************/


void
CCaptureDevice::
ReleaseHardwareResources (
    )

/*++

Routine Description:

    Release hardware resources.  This should only be called by
    an object which has acquired them.

Arguments:

    None

Return Value:

    None

--*/

{

    PAGED_CODE();

    //
    // Blow away the image synth.
    //
    if (m_ImageSynth) {
        delete m_ImageSynth;
        m_ImageSynth = NULL;

    }

    m_VideoInfoHeader = NULL;
    m_CaptureSink = NULL;

    //
    // Release our "lock" on hardware resources.  This will allow another
    // pin (perhaps in another graph) to acquire them.
    //
    InterlockedExchange (
        &m_PinsWithResources,
        0
        );

}

/*************************************************/


NTSTATUS
CCaptureDevice::
Start (
    )

/*++

Routine Description:

    Start the capture device based on the video info header we were told
    about when resources were acquired.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    m_LastMappingsCompleted = 0;
    m_InterruptTime = 0;

    return
        m_HardwareSimulation -> Start (
            m_ImageSynth,
            m_VideoInfoHeader -> AvgTimePerFrame,
            m_VideoInfoHeader -> bmiHeader.biWidth,
            ABS (m_VideoInfoHeader -> bmiHeader.biHeight),
            m_VideoInfoHeader -> bmiHeader.biSizeImage
            );


}

/*************************************************/


NTSTATUS
CCaptureDevice::
Pause (
    IN BOOLEAN Pausing
    )

/*++

Routine Description:

    Pause or unpause the hardware simulation.  This is an effective start
    or stop without resetting counters and formats.  Note that this can
    only be called to transition from started -> paused -> started.  Calling
    this without starting the hardware with Start() does nothing.

Arguments:

    Pausing -
        An indicatation of whether we are pausing or unpausing

        TRUE -
            Pause the hardware simulation

        FALSE -
            Unpause the hardware simulation

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    return
        m_HardwareSimulation -> Pause (
            Pausing
            );

}

/*************************************************/


NTSTATUS
CCaptureDevice::
Stop (
    )

/*++

Routine Description:

    Stop the capture device.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    return
        m_HardwareSimulation -> Stop ();

}

/*************************************************/


ULONG
CCaptureDevice::
ProgramScatterGatherMappings (
    IN PKSSTREAM_POINTER Clone,
    IN PUCHAR *Buffer,
    IN PKSMAPPING Mappings,
    IN ULONG MappingsCount
    )

/*++

Routine Description:

    Program the scatter / gather mappings for the "fake" hardware.

Arguments:

    Buffer -
        Points to a pointer to the virtual address of the topmost
        scatter / gather chunk.  The pointer will be updated as the
        device "programs" mappings.  Reason for this is that we get
        the physical addresses and sizes, but must calculate the virtual
        addresses...  This is used as scratch space for that.

    Mappings -
        An array of mappings to program

    MappingsCount -
        The count of mappings in the array

Return Value:

    The number of mappings successfully programmed

--*/

{

    PAGED_CODE();

    

    return 
        m_HardwareSimulation -> ProgramScatterGatherMappings (
            Clone,
            Buffer,
            Mappings,
            MappingsCount,
            sizeof (KSMAPPING)
            );

}

/*************************************************************************

    LOCKED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA


ULONG
CCaptureDevice::
QueryInterruptTime (
    )

/*++

Routine Description:

    Return the number of frame intervals that have elapsed since the
    start of the device.  This will be the frame number.

Arguments:

    None

Return Value:

    The interrupt time of the device (the number of frame intervals that
    have elapsed since the start of the device).

--*/

{

    return m_InterruptTime;

}

/*************************************************/


void
CCaptureDevice::
Interrupt (
    )

/*++

Routine Description:

    This is the "faked" interrupt service routine for this device.  It
    is called at dispatch level by the hardware simulation.

Arguments:

    None

Return Value:

    None

--*/

{

    m_InterruptTime++;

    //
    // Realistically, we'd do some hardware manipulation here and then queue
    // a DPC.  Since this is fake hardware, we do what's necessary here.  This
    // is pretty much what the DPC would look like short of the access
    // of hardware registers (ReadNumberOfMappingsCompleted) which would likely
    // be done in the ISR.
    //
    ULONG NumMappingsCompleted = 
        m_HardwareSimulation -> ReadNumberOfMappingsCompleted ();

    //
    // Inform the capture sink that a given number of scatter / gather
    // mappings have completed.
    //
    m_CaptureSink -> CompleteMappings (
        NumMappingsCompleted - m_LastMappingsCompleted
        );

    m_LastMappingsCompleted = NumMappingsCompleted;

}

/**************************************************************************

    DESCRIPTOR AND DISPATCH LAYOUT

**************************************************************************/

//
// CaptureFilterDescriptor:
//
// The filter descriptor for the capture device.
DEFINE_KSFILTER_DESCRIPTOR_TABLE (FilterDescriptors) { 
    &CaptureFilterDescriptor
};

//
// CaptureDeviceDispatch:
//
// This is the dispatch table for the capture device.  Plug and play
// notifications as well as power management notifications are dispatched
// through this table.
//
const
KSDEVICE_DISPATCH
CaptureDeviceDispatch = {
    CCaptureDevice::DispatchCreate,         // Pnp Add Device
    CCaptureDevice::DispatchPnpStart,       // Pnp Start
    NULL,                                   // Post-Start
    NULL,                                   // Pnp Query Stop
    NULL,                                   // Pnp Cancel Stop
    CCaptureDevice::DispatchPnpStop,        // Pnp Stop
    NULL,                                   // Pnp Query Remove
    NULL,                                   // Pnp Cancel Remove
    NULL,                                   // Pnp Remove
    NULL,                                   // Pnp Query Capabilities
    NULL,                                   // Pnp Surprise Removal
    NULL,                                   // Power Query Power
    NULL,                                   // Power Set Power
    NULL                                    // Pnp Query Interface
};

//
// CaptureDeviceDescriptor:
//
// This is the device descriptor for the capture device.  It points to the
// dispatch table and contains a list of filter descriptors that describe
// filter-types that this device supports.  Note that the filter-descriptors
// can be created dynamically and the factories created via 
// KsCreateFilterFactory as well.  
//
const
KSDEVICE_DESCRIPTOR
CaptureDeviceDescriptor = {
    &CaptureDeviceDispatch,
    0,
    NULL
};

/**************************************************************************

    INITIALIZATION CODE

**************************************************************************/

extern "C" DRIVER_INITIALIZE DriverEntry;

extern "C"
NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    Driver entry point.  Pass off control to the AVStream initialization
    function (KsInitializeDriver) and return the status code from it.

Arguments:

    DriverObject -
        The WDM driver object for our driver

    RegistryPath -
        The registry path for our registry info

Return Value:

    As from KsInitializeDriver

--*/

{
    //
    // Simply pass the device descriptor and parameters off to AVStream
    // to initialize us.  This will cause filter factories to be set up
    // at add & start.  Everything is done based on the descriptors passed
    // here.
    //
	return
        KsInitializeDriver (
            DriverObject,
            RegistryPath,
            &CaptureDeviceDescriptor
            );
}

void CCaptureDevice::SetData(PVOID data, ULONG dataLength)
{
	m_HardwareSimulation->SetData(data, dataLength);
}

================================================
FILE: Driver/avshws/device.h
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        device.h

    Abstract:

        The header for the device level of the simulated hardware.  This is
        not actually the hardware simulation itself.  The hardware simulation
        is contained in hwsim.*, image.*.
        
    History:

        created 3/9/2001

**************************************************************************/

class CCaptureDevice :
    public IHardwareSink {

private:

    //
    // The AVStream device we're associated with.
    //
    PKSDEVICE m_Device;

    //
    // Number of pins with resources acquired.  This is used as a locking
    // mechanism for resource acquisition on the device.
    //
    LONG m_PinsWithResources;

    //
    // Since we don't have physical hardware, this provides the hardware
    // simulation.  m_HardwareSimulation provides the fake ISR, fake DPC,
    // etc...  m_ImageSynth provides RGB24 and UYVY image synthesis and
    // overlay in software.
    //
    CHardwareSimulation *m_HardwareSimulation;
    CImageSynthesizer *m_ImageSynth;

    //
    // The number of ISR's that have occurred since capture started.
    //
    ULONG m_InterruptTime;

    //
    // The last reading of mappings completed.
    //
    ULONG m_LastMappingsCompleted;

    //
    // The Dma adapter object we acquired through IoGetDmaAdapter() during
    // Pnp start.  This must be initialized with AVStream in order to perform
    // Dma directly into the capture buffers.
    //
    PADAPTER_OBJECT m_DmaAdapterObject;

    //
    // The number of map registers returned from IoGetDmaAdapter().
    //
    ULONG m_NumberOfMapRegisters;

    //
    // The capture sink.  When we complete scatter / gather mappings, we
    // notify the capture sink.
    //
    ICaptureSink *m_CaptureSink;

    //
    // The video info header we're basing hardware settings on.  The pin
    // provides this to us when acquiring resources and must guarantee its
    // stability until resources are released.
    //
    PKS_VIDEOINFOHEADER m_VideoInfoHeader;

    //
    // Cleanup():
    //
    // This is the free callback for the bagged capture device.  Not providing
    // one will call ExFreePool, which is not what we want for a constructed
    // C++ object.  This simply deletes the capture device.
    //
    static
    void
    Cleanup (
        IN CCaptureDevice *CapDevice
        )
    {
        delete CapDevice;
    }

    //
    // PnpStart():
    //
    // This is the Pnp start routine for our simulated hardware.  Note that
    // DispatchStart bridges to here in the context of the CCaptureDevice.
    //
    NTSTATUS
    PnpStart (
        IN PCM_RESOURCE_LIST TranslatedResourceList,
        IN PCM_RESOURCE_LIST UntranslatedResourceList
        );

    //
    // PnpStop():
    //
    // This is the Pnp stop routine for our simulated hardware.  Note that
    // DispatchStop bridges to here in the context of the CCaptureDevice.
    //
    void
    PnpStop (
        );

public:

    //
    // CCaptureDevice():
    //
    // The capture device class constructor.  Since everything should have
    // been zero'ed by the new operator, don't bother setting anything to
    // zero or NULL.  Only initialize non-NULL, non-0 fields.
    //
    CCaptureDevice (
        IN PKSDEVICE Device
        ) :
        m_Device (Device)
    {
    }

    //
    // ~CCaptureDevice():
    //
    // The capture device destructor.
    //
    ~CCaptureDevice (
        )
    {
    }

    //
    // DispatchCreate():
    //
    // This is the Add Device dispatch for the capture device.  It creates
    // the CCaptureDevice and associates it with the device via the bag.
    //
    static
    NTSTATUS
    DispatchCreate (
        IN PKSDEVICE Device
        );
    //
    // DispatchPnpStart():
    //
    // This is the Pnp Start dispatch for the capture device.  It simply
    // bridges to PnpStart() in the context of the CCaptureDevice.
    //
    static
    NTSTATUS
    DispatchPnpStart (
        IN PKSDEVICE Device,
        IN PIRP Irp,
        IN PCM_RESOURCE_LIST TranslatedResourceList,
        IN PCM_RESOURCE_LIST UntranslatedResourceList
        )
    {
        return 
            (reinterpret_cast <CCaptureDevice *> (Device -> Context)) ->
            PnpStart (
                TranslatedResourceList,
                UntranslatedResourceList
                );
    }

    //
    // DispatchPnpStop():
    //
    // This is the Pnp stop dispatch for the capture device.  It simply
    // bridges to PnpStop() in the context of the CCaptureDevice.
    //
    static
    void
    DispatchPnpStop (
        IN PKSDEVICE Device,
        IN PIRP Irp
        )
    {
        return
            (reinterpret_cast <CCaptureDevice *> (Device -> Context)) ->
            PnpStop (
                );
    }

    //
    // AcquireHardwareResources():
    //
    // Called to acquire hardware resources for the device based on a given
    // video info header.  This will fail if another object has already
    // acquired hardware resources since we emulate a single capture
    // device.
    //
    NTSTATUS
    AcquireHardwareResources (
        IN ICaptureSink *CaptureSink,
        IN PKS_VIDEOINFOHEADER VideoInfoHeader
        );

    //
    // ReleaseHardwareResources():
    //
    // Called to release hardware resources for the device.
    //
    void
    ReleaseHardwareResources (
        );

    //
    // Start():
    //
    // Called to start the hardware simulation.  This causes us to simulate
    // interrupts, simulate filling buffers with synthesized data, etc...
    //
    NTSTATUS
    Start (
        );

    //
    // Pause():
    //
    // Called to pause or unpause the hardware simulation.  This will be
    // indentical to a start or stop but it will not reset formats and 
    // counters.
    //
    NTSTATUS
    Pause (
        IN BOOLEAN Pausing
        );

    //
    // Stop():
    //
    // Called to stop the hardware simulation.  This causes interrupts to
    // stop issuing.  When this call returns, the "fake" hardware has
    // stopped accessing all s/g buffers, etc...
    //
    NTSTATUS
    Stop (
        );

    //
    // ProgramScatterGatherMappings():
    //
    // Called to program the hardware simulation's scatter / gather table.
    // This synchronizes with the "fake" ISR and hardware simulation via
    // a spinlock.
    //
    ULONG
    ProgramScatterGatherMappings (
        IN PKSSTREAM_POINTER Clone,
        IN PUCHAR *Buffer,
        IN PKSMAPPING Mappings,
        IN ULONG MappingsCount
        );

    //
    // QueryInterruptTime():
    //
    // Determine the frame number that this frame corresponds to.  
    //
    ULONG
    QueryInterruptTime (
        );

    //
    // IHardwareSink::Interrupt():
    //
    // The interrupt service routine as called through the hardware sink
    // interface.  The "fake" hardware uses this method to inform the device
    // of a "fake" ISR.  The routine is called at dispatch level and must
    // be in locked code.
    //
    virtual
    void
    Interrupt (
        );

    LONG GetDroppedFrameCount(){return m_HardwareSimulation->GetSkippedFrameCount();};



public:
	//
	//  Recast():
	//
	//  Helper function.  Used to convert from a PKSDEVICE to a CCaptureDevice *
	//
	static
		inline
		CCaptureDevice *
		Recast(
			_In_ PKSDEVICE Device
		)
	{
		return reinterpret_cast <CCaptureDevice *> (Device->Context);
	}

	//
	// SetData();
	//
	// Sets the virtual frame buffer of the device.
	//
	void SetData(PVOID data, ULONG dataLength);
};


================================================
FILE: Driver/avshws/filter.cpp
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        filter.cpp

    Abstract:

        This file contains the filter level implementation for the 
        capture filter.

    History:

        created 3/12/2001

**************************************************************************/

#include "avshws.h"

/**************************************************************************

    PAGEABLE CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA


NTSTATUS
CCaptureFilter::
DispatchCreate (
    IN PKSFILTER Filter,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the creation dispatch for the capture filter.  It creates
    the CCaptureFilter object, associates it with the AVStream filter
    object, and bag the CCaptureFilter for later cleanup.

Arguments:

    Filter -
        The AVStream filter being created

    Irp -
        The creation Irp

Return Value:
    
    Success / failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    CCaptureFilter *CapFilter = new (NonPagedPoolNx, 'liFC') CCaptureFilter (Filter);

    if (!CapFilter) {
        //
        // Return failure if we couldn't create the filter.
        //
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {
        //
        // Add the item to the object bag if we we were successful. 
        // Whenever the filter closes, the bag is cleaned up and we will be
        // freed.
        //
        Status = KsAddItemToObjectBag (
            Filter -> Bag,
            reinterpret_cast <PVOID> (CapFilter),
            reinterpret_cast <PFNKSFREE> (CCaptureFilter::Cleanup)
            );

        if (!NT_SUCCESS (Status)) {
            delete CapFilter;
        } else {
            Filter -> Context = reinterpret_cast <PVOID> (CapFilter);
        }

    }

    return Status;

}

//  Get KSPROPERTY_CUSTOMCONTROL_DUMMY.
NTSTATUS
CCaptureFilter::
GetData(
	_In_ PIRP Irp,
	_In_ PKSIDENTIFIER Request,
	_Inout_ PVOID Data
)
{
	PAGED_CODE();

	PDWORD dataPtr = (PDWORD)Data;

	*dataPtr = 0xAA77AA77;
	Irp->IoStatus.Information = sizeof(DWORD);

	return STATUS_SUCCESS;
}

//  Set KSPROPERTY_CUSTOMCONTROL_DUMMY.
NTSTATUS
CCaptureFilter::
SetData(
	_In_ PIRP Irp,
	_In_ PKSIDENTIFIER Request,
	_Inout_ PVOID Data
)
{
	PAGED_CODE();

	CCaptureFilter* filter = reinterpret_cast<CCaptureFilter*>(KsGetFilterFromIrp(Irp)->Context);

	PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
	ULONG bufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	if (bufferLength == 0 || Data == NULL) {
		return STATUS_SUCCESS;
	}

	CCaptureDevice* device = CCaptureDevice::Recast(KsFilterGetDevice(filter->m_Filter));
	device->SetData(Data, bufferLength);

	return STATUS_SUCCESS;
}

/**************************************************************************

	PROPERTY TABLE STUFF

**************************************************************************/

DEFINE_KSPROPERTY_TABLE(CustomPropertyTable)
{
	{
		0,											//PropertyId
		(PFNKSHANDLER)&CCaptureFilter::GetData,		//GetPropertyHandler
		(ULONG)sizeof(KSPROPERTY),					//MinProperty
		(ULONG)0,								//MinData
		(PFNKSHANDLER)&CCaptureFilter::SetData,		//SetPropertyHandler
		(PKSPROPERTY_VALUES)NULL,					//Values
		0,											//RelationsCount
		(PKSPROPERTY)NULL,							//Relations
		(PFNKSHANDLER)NULL,							//SupportHandler
		(ULONG)0									//SerializedSize
	}
};

DEFINE_KSPROPERTY_SET_TABLE(PropertySetTable)
{
	DEFINE_STD_PROPERTY_SET(PROPSETID_VIDCAP_CUSTOMCONTROL, CustomPropertyTable)
};


DEFINE_KSAUTOMATION_TABLE(AvsFilterAutomationTable)
{
	DEFINE_KSAUTOMATION_PROPERTIES(PropertySetTable),
	DEFINE_KSAUTOMATION_METHODS_NULL,
	DEFINE_KSAUTOMATION_EVENTS_NULL
};

/**************************************************************************

    DESCRIPTOR AND DISPATCH LAYOUT

**************************************************************************/

GUID g_PINNAME_VIDEO_CAPTURE = {STATIC_PINNAME_VIDEO_CAPTURE};

//
// CaptureFilterCategories:
//
// The list of category GUIDs for the capture filter.
//
const
GUID
CaptureFilterCategories [CAPTURE_FILTER_CATEGORIES_COUNT] = {
    STATICGUIDOF (KSCATEGORY_VIDEO),
    STATICGUIDOF (KSCATEGORY_CAPTURE),
    STATICGUIDOF (KSCATEGORY_VIDEO_CAMERA)
};

//
// CaptureFilterPinDescriptors:
//
// The list of pin descriptors on the capture filter.  
//
const 
KSPIN_DESCRIPTOR_EX
CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT] = {
    //
    // Video Capture Pin
    //
    {
        &CapturePinDispatch,
        NULL,             
        {
            0,                              // Interfaces (NULL, 0 == default)
            NULL,
            0,                              // Mediums (NULL, 0 == default)
            NULL,
            SIZEOF_ARRAY(CapturePinDataRanges),// Range Count
            CapturePinDataRanges,           // Ranges
            KSPIN_DATAFLOW_OUT,             // Dataflow
            KSPIN_COMMUNICATION_BOTH,       // Communication
            &PIN_CATEGORY_CAPTURE,          // Category
            &g_PINNAME_VIDEO_CAPTURE,       // Name
            0                               // Reserved
        },
        KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY,// Pin Flags
        1,                                  // Instances Possible
        1,                                  // Instances Necessary
        &CapturePinAllocatorFraming,        // Allocator Framing
        reinterpret_cast <PFNKSINTERSECTHANDLEREX> 
            (CCapturePin::IntersectHandler)
    }
};

//
// CaptureFilterDispatch:
//
// This is the dispatch table for the capture filter.  It provides notification
// of creation, closure, processing (for filter-centrics, not for the capture
// filter), and resets (for filter-centrics, not for the capture filter).
//
const 
KSFILTER_DISPATCH
CaptureFilterDispatch = {
    CCaptureFilter::DispatchCreate,         // Filter Create
    NULL,                                   // Filter Close
    NULL,                                   // Filter Process
    NULL                                    // Filter Reset
};


//
// CaptureFilterDescription:
//
// The descriptor for the capture filter.  We don't specify any topology
// since there's only one pin on the filter.  Realistically, there would
// be some topological relationships here because there would be input 
// pins from crossbars and the like.
//
const 
KSFILTER_DESCRIPTOR 
CaptureFilterDescriptor = {
    &CaptureFilterDispatch,                 // Dispatch Table
    &AvsFilterAutomationTable,              // Automation Table
    KSFILTER_DESCRIPTOR_VERSION,            // Version
    0,                                      // Flags
    &KSNAME_Filter,                         // Reference GUID
    DEFINE_KSFILTER_PIN_DESCRIPTORS (CaptureFilterPinDescriptors),
    DEFINE_KSFILTER_CATEGORIES (CaptureFilterCategories),
    0,
    sizeof (KSNODE_DESCRIPTOR),
    NULL,
    0,
    NULL,
    NULL                                    // Component ID
};

================================================
FILE: Driver/avshws/filter.h
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        filter.h

    Abstract:

        This file contains the filter level header for the capture filter.

    History:

        created 3/12/2001

**************************************************************************/

class CCaptureFilter {

private:

    //
    // The AVStream filter object associated with this CCaptureFilter.
    //
    PKSFILTER m_Filter;
   
    //
    // Cleanup():
    //
    // This is the bag cleanup callback for the CCaptureFilter.  Not providing
    // one would cause ExFreePool to be used.  This is not good for C++
    // constructed objects.  We simply delete the object here.
    //
    static
    void
    Cleanup (
        IN CCaptureFilter *CapFilter
        )
    {
        delete CapFilter;
    }

public:

    //
    // CCaptureFilter():
    //
    // The capture filter object constructor.  Since the new operator will
    // have zeroed the memory, do not bother initializing any NULL or 0
    // fields.  Only initialize non-NULL, non-0 fields.
    //
    CCaptureFilter (
        IN PKSFILTER Filter
        ) :
        m_Filter (Filter)
    {
    }

    //
    // ~CCaptureFilter():
    //
    // The capture filter destructor.
    //
    ~CCaptureFilter (
        )
    {
    }

    //
    // DispatchCreate():
    //
    // This is the filter creation dispatch for the capture filter.  It
    // creates the CCaptureFilter object, associates it with the AVStream
    // object, and bags it for easy cleanup later.
    //
    static
    NTSTATUS
    DispatchCreate (
        IN PKSFILTER Filter,
        IN PIRP Irp
        );


	//  Example of adding a new, custom property.
	DECLARE_PROPERTY_HANDLERS(Data)

};




================================================
FILE: Driver/avshws/hwsim.cpp
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        hwsim.cpp

    Abstract:
        
        This file contains the hardware simulation.  It fakes "DMA" transfers,
        scatter gather mapping handling, ISR's, etc...  The ISR routine in
        here will be called when an ISR would be generated by the fake hardware
        and it will directly call into the device level ISR for more accurate
        simulation.

    History:

        created 3/9/2001

**************************************************************************/

#include "avshws.h"


/*************************************************/
KDEFERRED_ROUTINE SimulatedInterrupt;

void
SimulatedInterrupt (
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArg1,
    IN PVOID SystemArg2
    )
{
    CHardwareSimulation* HardwareSim = (CHardwareSimulation*)DeferredContext;
    
    if (HardwareSim)
    {
        HardwareSim -> FakeHardware ();
    }
}


/**************************************************************************

    PAGEABLE CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA



CHardwareSimulation::
CHardwareSimulation (
    IN IHardwareSink *HardwareSink
    ) :
    m_HardwareSink (HardwareSink),
    m_ScatterGatherMappingsMax (SCATTER_GATHER_MAPPINGS_MAX)

/*++

Routine Description:

    Construct a hardware simulation

Arguments:

    HardwareSink -
        The hardware sink interface.  This is used to trigger
        fake interrupt service routines from.

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    //
    // Initialize the DPC's, timer's, and locks necessary to simulate
    // this capture hardware.
    //
    KeInitializeDpc (
        &m_IsrFakeDpc, 
        SimulatedInterrupt, 
        this
        );

    KeInitializeEvent (
        &m_HardwareEvent,
        SynchronizationEvent,
        FALSE
        );

    KeInitializeTimer (&m_IsrTimer);

    KeInitializeSpinLock (&m_ListLock);

}

/*************************************************/


CHardwareSimulation *
CHardwareSimulation::
Initialize (
    IN KSOBJECT_BAG Bag,
    IN IHardwareSink *HardwareSink
    )

/*++

Routine Description:

    Initialize the hardware simulation

Arguments:

    HardwareSink -
        The hardware sink interface.  This is what ISR's will be
        triggered through.

Return Value:

    A fully initialized hardware simulation or NULL if the simulation
    could not be initialized.

--*/

{

    PAGED_CODE();

    CHardwareSimulation *HwSim = 
        new (NonPagedPoolNx, 'miSH') CHardwareSimulation (HardwareSink);

    return HwSim;

}

/*************************************************/


NTSTATUS
CHardwareSimulation::
Start (
    IN CImageSynthesizer *ImageSynth,
    IN LONGLONG TimePerFrame,
    IN ULONG Width,
    IN ULONG Height,
    IN ULONG ImageSize
    )

/*++

Routine Description:

    Start the hardware simulation.  This will kick the interrupts on,
    begin issuing DPC's, filling in capture information, etc...
    We keep track of starvation starting at this point.

Arguments:

    ImageSynth -
        The image synthesizer to use to generate pictures to display
        on the capture buffer.

    TimePerFrame -
        The time per frame...  we issue interrupts this often.

    Width -
        The image width

    Height -
        The image height

    ImageSize - 
        The size of the image.  We allocate a temporary scratch buffer
        based on this size to fake hardware.

Return Value:

    Success / Failure (typical failure will be out of memory on the 
    scratch buffer, etc...)

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    m_ImageSynth = ImageSynth;
    m_TimePerFrame = TimePerFrame;
    m_ImageSize = ImageSize;
    m_Height = Height;
    m_Width = Width;

    InitializeListHead (&m_ScatterGatherMappings);
    m_NumMappingsCompleted = 0;
    m_ScatterGatherMappingsQueued = 0;
    m_NumFramesSkipped = 0;
    m_InterruptTime = 0;

    KeQuerySystemTime (&m_StartTime);

    //
    // Allocate a scratch buffer for the synthesizer.
    //
    m_SynthesisBuffer = reinterpret_cast <PUCHAR> (
        ExAllocatePoolWithTag (
            NonPagedPoolNx,
            m_ImageSize,
            AVSHWS_POOLTAG
            )
        );

    if (!m_SynthesisBuffer) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }

	//
	// Allocate a temporary frame buffer;
	//
	m_TemporaryBuffer = reinterpret_cast <PUCHAR> (
		ExAllocatePoolWithTag(
			NonPagedPoolNx,
			m_ImageSize,
			AVSHWS_POOLTAG
			)
		);

	if (!m_TemporaryBuffer) {
		Status = STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlZeroMemory(m_TemporaryBuffer, m_ImageSize);
	
    //
    // If everything is ok, start issuing interrupts.
    //
    if (NT_SUCCESS (Status)) {

        //
        // Initialize the entry lookaside.
        //
        ExInitializeNPagedLookasideList (
            &m_ScatterGatherLookaside,
            NULL,
            NULL,
            POOL_NX_ALLOCATION,
            sizeof (SCATTER_GATHER_ENTRY),
            'nEGS',
            0
            );

        //
        // Set up the synthesizer with the width, height, and scratch buffer.
        //
        m_ImageSynth -> SetImageSize (m_Width, m_Height);
        m_ImageSynth -> SetBuffer (m_SynthesisBuffer);

        LARGE_INTEGER NextTime;
        NextTime.QuadPart = m_StartTime.QuadPart + m_TimePerFrame;

        m_HardwareState = HardwareRunning;
        KeSetTimer (&m_IsrTimer, NextTime, &m_IsrFakeDpc);

    }

    return Status;
        
}

/*************************************************/


NTSTATUS
CHardwareSimulation::
Pause (
    BOOLEAN Pausing
    )

/*++

Routine Description:

    Pause the hardware simulation...  When the hardware simulation is told
    to pause, it stops issuing interrupts, etc...  but it does not reset
    the counters 

Arguments:

    Pausing -
        Indicates whether the hardware is pausing or not. 

        TRUE -
            Pause the hardware

        FALSE -
            Unpause the hardware from a previous pause


Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    if (Pausing && m_HardwareState == HardwareRunning) {
        //
        // If we were running, stop completing mappings, etc...
        //
        m_StopHardware = TRUE;
    
        KeWaitForSingleObject (
            &m_HardwareEvent,
            Suspended,
            KernelMode,
            FALSE,
            NULL
            );

        NT_ASSERT (m_StopHardware == FALSE);

        m_HardwareState = HardwarePaused; 

    } else if (!Pausing && m_HardwareState == HardwarePaused) {

        //
        // For unpausing the hardware, we need to compute the relative time
        // and restart interrupts.
        //
        LARGE_INTEGER UnpauseTime;

        KeQuerySystemTime (&UnpauseTime);
        m_InterruptTime = (ULONG) (
            (UnpauseTime.QuadPart - m_StartTime.QuadPart) /
            m_TimePerFrame
            );

        UnpauseTime.QuadPart = m_StartTime.QuadPart +
            (m_InterruptTime + 1) * m_TimePerFrame;

        m_HardwareState = HardwareRunning;
        KeSetTimer (&m_IsrTimer, UnpauseTime, &m_IsrFakeDpc);

    }

    return STATUS_SUCCESS;

}

/**************************************************************************

    LOCKED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA

NTSTATUS
CHardwareSimulation::
Stop (
    )

/*++

Routine Description:

    Stop the hardware simulation....  Wait until the hardware simulation
    has successfully stopped and then return.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{
    KIRQL Irql;
    //
    // If the hardware is told to stop while it's running, we need to
    // halt the interrupts first.  If we're already paused, this has
    // already been done.
    //
    if (m_HardwareState == HardwareRunning) {
    
        m_StopHardware = TRUE;
    
        KeWaitForSingleObject (
            &m_HardwareEvent,
            Suspended,
            KernelMode,
            FALSE,
            NULL
            );
    
        NT_ASSERT (m_StopHardware == FALSE);

    }

    m_HardwareState = HardwareStopped;

    //
    // The image synthesizer may still be around.  Just for safety's
    // sake, NULL out the image synthesis buffer and toast it.
    //
    m_ImageSynth -> SetBuffer (NULL);

    if (m_SynthesisBuffer) {
        ExFreePool (m_SynthesisBuffer);
        m_SynthesisBuffer = NULL;
    }

	if (m_TemporaryBuffer) {
		ExFreePool(m_TemporaryBuffer);
		m_TemporaryBuffer = NULL;
	}

    //
    // Protect the S/G list
    //
    KeAcquireSpinLock (&m_ListLock, &Irql);
    // 
    // Free S/G buffer 
    // 
    // 
    while (m_ScatterGatherMappingsQueued > 0) {
        LIST_ENTRY *listEntry = RemoveHeadList (&m_ScatterGatherMappings);
        m_ScatterGatherMappingsQueued--;
        PSCATTER_GATHER_ENTRY SGEntry =
            reinterpret_cast <PSCATTER_GATHER_ENTRY> (
                CONTAINING_RECORD (
                    listEntry,
                    SCATTER_GATHER_ENTRY,
                    ListEntry
                    )
                );
        // 
        // Release the scatter / gather entry back to our lookaside. 
        // 
        ExFreeToNPagedLookasideList (
            &m_ScatterGatherLookaside,
            reinterpret_cast <PVOID> (SGEntry)
            );
    } 

    m_NumMappingsCompleted = 0;
    m_ScatterGatherBytesQueued = 0;
    //
    // Delete the scatter / gather lookaside for this run.
    //
    ExDeleteNPagedLookasideList (&m_ScatterGatherLookaside);

    KeReleaseSpinLock (&m_ListLock, Irql);

    return STATUS_SUCCESS;

}


ULONG
CHardwareSimulation::
ReadNumberOfMappingsCompleted (
    )

/*++

Routine Description:

    Read the number of scatter / gather mappings which have been
    completed (TOTAL NUMBER) since the last reset of the simulated
    hardware

Arguments:

    None

Return Value:

    Total number of completed mappings.

--*/

{

    //
    // Don't care if this is being updated this moment in the DPC...  I only
    // need a number to return which isn't too great (too small is ok).
    // In real hardware, this wouldn't be done this way anyway.
    //
    return m_NumMappingsCompleted;

}

/*************************************************/


ULONG
CHardwareSimulation::
ProgramScatterGatherMappings (
    IN PKSSTREAM_POINTER Clone,
    IN PUCHAR *Buffer,
    IN PKSMAPPING Mappings,
    IN ULONG MappingsCount,
    IN ULONG MappingStride
    )

/*++

Routine Description:

    Program the scatter gather mapping list.  This shoves a bunch of 
    entries on a list for access during the fake interrupt.  Note that
    we have physical addresses here only for simulation.  We really
    access via the virtual address....  although we chunk it into multiple
    buffers to more realistically simulate S/G

Arguments:

    Buffer -
        The virtual address of the buffer mapped by the mapping list 

    Mappings -
        The KSMAPPINGS array corresponding to the buffer

    MappingsCount -
        The number of mappings in the mappings array

    MappingStride -
        The mapping stride used in initialization of AVStream DMA

Return Value:

    Number of mappings actually inserted.

--*/

{

    KIRQL Irql;

    ULONG MappingsInserted = 0;

    //
    // Protect our S/G list with a spinlock.
    //
    KeAcquireSpinLock (&m_ListLock, &Irql);

    //
    // Loop through the scatter / gather list and break the buffer up into
    // chunks equal to the scatter / gather mappings.  Stuff the virtual
    // addresses of these chunks on a list somewhere.  We update the buffer
    // pointer the caller passes as a more convenient way of doing this.
    //
    // If I could just remap physical in the list to virtual easily here,
    // I wouldn't need to do it.
    //
    do
    {
        PSCATTER_GATHER_ENTRY Entry =
            reinterpret_cast <PSCATTER_GATHER_ENTRY> (
                ExAllocateFromNPagedLookasideList (
                    &m_ScatterGatherLookaside
                    )
                );

        if (!Entry) {
            break;
        }
        Entry -> Virtual    = *Buffer;
        Entry -> ByteCount  = MappingsCount;
        Entry -> CloneEntry = Clone;

        //
        // Move forward a specific number of bytes in chunking this into
        // mapping sized va buffers.
        //
        *Buffer += MappingsCount;
        Mappings = reinterpret_cast <PKSMAPPING> (
            (reinterpret_cast <PUCHAR> (Mappings) + MappingStride)
            );

        InsertTailList (&m_ScatterGatherMappings, &(Entry -> ListEntry));
        MappingsInserted = MappingsCount;
        m_ScatterGatherMappingsQueued++;
        m_ScatterGatherBytesQueued += MappingsCount;

   }
    while(FALSE);

    KeReleaseSpinLock (&m_ListLock, Irql);

    return MappingsInserted;

}

/*************************************************/


NTSTATUS
CHardwareSimulation::
FillScatterGatherBuffers (
    )

/*++

Routine Description:

    The hardware has synthesized a buffer in scratch space and we're to
    fill scatter / gather buffers.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    //
    // We're using this list lock to protect our scatter / gather lists instead
    // of some hardware mechanism / KeSynchronizeExecution / whatever.
    //
    KeAcquireSpinLockAtDpcLevel (&m_ListLock);

    PUCHAR Buffer = reinterpret_cast <PUCHAR> (m_SynthesisBuffer);
    ULONG BufferRemaining = m_ImageSize;

    //
    // For simplification, if there aren't enough scatter / gather buffers
    // queued, we don't partially fill the ones that are available.  We just
    // skip the frame and consider it starvation.
    //
    // This could be enforced by only programming scatter / gather mappings
    // for a buffer if all of them fit in the table also...
    //
    while (BufferRemaining &&
        m_ScatterGatherMappingsQueued > 0 &&
        m_ScatterGatherBytesQueued >= BufferRemaining) {

        LIST_ENTRY *listEntry = RemoveHeadList (&m_ScatterGatherMappings);
        m_ScatterGatherMappingsQueued--;

        PSCATTER_GATHER_ENTRY SGEntry =  
            reinterpret_cast <PSCATTER_GATHER_ENTRY> (
                CONTAINING_RECORD (
                    listEntry,
                    SCATTER_GATHER_ENTRY,
                    ListEntry
                    )
                );

        //
        // Since we're software, we'll be accessing this by virtual address...
        //
        ULONG BytesToCopy = 
            (BufferRemaining < SGEntry -> ByteCount) ?
            BufferRemaining :
            SGEntry -> ByteCount;

        LONG Width = m_Width*(m_ImageSynth->GetBytesPerPixel());

        LONG Stride = Width;
        if(SGEntry->CloneEntry->StreamHeader->Size >= sizeof(KSSTREAM_HEADER)+sizeof(KS_FRAME_INFO))
        {
            PKS_FRAME_INFO FrameInfo = reinterpret_cast <PKS_FRAME_INFO> (SGEntry->CloneEntry->StreamHeader+1);
            if(FrameInfo->lSurfacePitch != 0)
            {
                Stride = FrameInfo->lSurfacePitch;
                if(FrameInfo->lSurfacePitch < 0)
                {
                    Stride = -Stride;
                }
            }
        }

        for(ULONG y = 0; y < m_Height; y++)
        {
            RtlCopyMemory((SGEntry->Virtual+(ULONG)Stride*y), Buffer, Width);
            Buffer += Width;
            BytesToCopy -= Width;
            BufferRemaining -= Width;
        }

        m_NumMappingsCompleted++;
        m_ScatterGatherBytesQueued -= SGEntry -> ByteCount;

        //
        // Release the scatter / gather entry back to our lookaside.
        //
        ExFreeToNPagedLookasideList (
            &m_ScatterGatherLookaside,
            reinterpret_cast <PVOID> (SGEntry)
            );

    }
    
    KeReleaseSpinLockFromDpcLevel (&m_ListLock);

    if (BufferRemaining) return STATUS_INSUFFICIENT_RESOURCES;
    else return STATUS_SUCCESS;
    
}

/*************************************************/


void
CHardwareSimulation::
FakeHardware (
    )

/*++

Routine Description:

    Simulate an interrupt and what the hardware would have done in the
    time since the previous interrupt.

Arguments:

    None

Return Value:

    None

--*/

{

    m_InterruptTime++;

	if (m_HardwareState == HardwareRunning)
	{
		RtlCopyMemory(m_SynthesisBuffer, m_TemporaryBuffer, m_ImageSize);

		if (!NT_SUCCESS(FillScatterGatherBuffers())) {
			InterlockedIncrement(PLONG(&m_NumFramesSkipped));
		}
	}

    //
    // Issue an interrupt to our hardware sink.  This is a "fake" interrupt.
    // It will occur at DISPATCH_LEVEL.
    //
    m_HardwareSink -> Interrupt ();

    //
    // Reschedule the timer if the hardware isn't being stopped.
    //
    if (!m_StopHardware) {

        //
        // Reschedule the timer for the next interrupt time.
        //
        LARGE_INTEGER NextTime;
        NextTime.QuadPart = m_StartTime.QuadPart + 
            (m_TimePerFrame * (m_InterruptTime + 1));

        KeSetTimer (&m_IsrTimer, NextTime, &m_IsrFakeDpc);
        
    } else {
        //
        // If someone is waiting on the hardware to stop, raise the stop
        // event and clear the flag.
        //
        m_StopHardware = FALSE;
        KeSetEvent (&m_HardwareEvent, IO_NO_INCREMENT, FALSE);
    }

}


void CHardwareSimulation::SetData(PVOID data, ULONG dataLength)
{
	if (m_HardwareState != HardwareRunning) 
	{
		return;
	}

	if (m_TemporaryBuffer == NULL)
	{
		return;
	}

	if (dataLength < m_Width * m_Height * 3)
	{
		return;
	}

	for (ULONG y = 0; y < m_Height; y++)
	{
		PUCHAR buffer = m_TemporaryBuffer + ((m_Width * 3) * (m_Height - 1 - y));
		PUCHAR dataLine = (PUCHAR)(data) + ((m_Width * 3) * y);

		RtlCopyMemory(buffer, dataLine, m_Width * 3);
	}
}

================================================
FILE: Driver/avshws/hwsim.h
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        hwsim.cpp

    Abstract:
        
        This file is the hardware simulation header.  

        The simulation fakes "DMA" transfers, scatter gather mapping handling, 
        ISR's, etc...  The ISR routine in here will be called when an ISR 
        would be generated by the fake hardware and it will directly call into 
        the device level ISR for more accurate simulation.

    History:

        created 3/9/2001

**************************************************************************/

//
// SCATTER_GATHER_MAPPINGS_MAX:
//
// The maximum number of entries in the hardware's scatter/gather list.  I
// am making this so large for a few reasons:
//
//     1) we're faking this with uncompressed surfaces -- 
//            these are large buffers which will map to a lot of s/g entries
//     2) the fake hardware implementation requires at least one frame's
//            worth of s/g entries to generate a frame
//
#define SCATTER_GATHER_MAPPINGS_MAX 128

//
// SCATTER_GATHER_ENTRY:
//
// This structure is used to keep the scatter gather table for the fake
// hardware as a doubly linked list.
//
typedef struct _SCATTER_GATHER_ENTRY {

    LIST_ENTRY ListEntry;
    PKSSTREAM_POINTER CloneEntry;
    PUCHAR Virtual;
    ULONG ByteCount;

} SCATTER_GATHER_ENTRY, *PSCATTER_GATHER_ENTRY;

//
// CHardwareSimulation:
//
// The hardware simulation class.
//
class CHardwareSimulation {

private:

    //
    // The image synthesizer.  This is a piece of code which actually draws
    // the requested images.
    //
    CImageSynthesizer *m_ImageSynth;

    //
    // The synthesis buffer.  This is a private buffer we use to generate the
    // capture image in.  The fake "scatter / gather" mappings are filled
    // in from this buffer during each interrupt.
    //
    PUCHAR m_SynthesisBuffer;

	//
	// A temporary frame buffer;
	//
	PUCHAR m_TemporaryBuffer;

    //
    // Key information regarding the frames we generate.
    //
    LONGLONG m_TimePerFrame;
    ULONG m_Width;
    ULONG m_Height;
    ULONG m_ImageSize;

    //
    // Scatter gather mappings for the simulated hardware.
    //
    KSPIN_LOCK m_ListLock;
    LIST_ENTRY m_ScatterGatherMappings;

    //
    // Lookaside for memory for the scatter / gather entries on the scatter /
    // gather list.
    //
    NPAGED_LOOKASIDE_LIST m_ScatterGatherLookaside;

    //
    // The current state of the fake hardware.
    //
    HARDWARE_STATE m_HardwareState;

    //
    // The pause / stop hardware flag and event.
    //
    BOOLEAN m_StopHardware;
    KEVENT m_HardwareEvent;

    //
    // Maximum number of scatter / gather mappins in the s/g table of the
    // fake hardware.
    //
    ULONG m_ScatterGatherMappingsMax;

    //
    // Number of scatter / gather mappings that have been completed (total)
    // since the start of the hardware or any reset.
    //
    ULONG m_NumMappingsCompleted;

    //
    // Number of scatter / gather mappings that are queued for this hardware.
    //
    ULONG m_ScatterGatherMappingsQueued;
    ULONG m_ScatterGatherBytesQueued;

    //
    // Number of frames skipped due to lack of scatter / gather mappings.
    //
    ULONG m_NumFramesSkipped;

    //
    // The "Interrupt Time".  Number of "fake" interrupts that have occurred
    // since the hardware was started.
    // 
    ULONG m_InterruptTime;

    //
    // The system time at start.
    //
    LARGE_INTEGER m_StartTime;
    
    //
    // The DPC used to "fake" ISR
    //
    KDPC m_IsrFakeDpc;
    KTIMER m_IsrTimer;

    //
    // The hardware sink that will be used for interrupt notifications.
    //
    IHardwareSink *m_HardwareSink;

    //
    // FillScatterGatherBuffers():
    //
    // This is called by the hardware simulation to fill a series of scatter /
    // gather buffers with synthesized data.
    //
    NTSTATUS
    FillScatterGatherBuffers (
        );

public:

    LONG GetSkippedFrameCount()
    {
        return InterlockedExchange((LONG*)&this->m_NumFramesSkipped, this->m_NumFramesSkipped);
    }
    //
    // CHardwareSimulation():
    //
    // The hardware simulation constructor.  Since the new operator will
    // have zeroed the memory, only initialize non-NULL, non-0 fields. 
    //
    CHardwareSimulation (
        IN IHardwareSink *HardwareSink
        );

    //
    // ~CHardwareSimulation():
    //
    // The hardware simulation destructor.
    //
    ~CHardwareSimulation (
        )
    {
    }

    //
    // Cleanup():
    //
    // This is the free callback for the bagged hardware sim.  Not providing
    // one will call ExFreePool, which is not what we want for a constructed
    // C++ object.  This simply deletes the simulation.
    //
    static
    void
    Cleanup (
        IN CHardwareSimulation *HwSim
        )
    {
        delete HwSim;
    }

    //
    // FakeHardware():
    //
    // Called from the simulated interrupt.  First we fake the hardware's
    // actions (at DPC) then we call the "Interrupt service routine" on
    // the hardware sink.
    //
    void
    FakeHardware (
        );

    //
    // Start():
    //
    // "Start" the fake hardware.  This will start issuing interrupts and 
    // DPC's. 
    //
    // The frame rate, image size, and a synthesizer must be provided.
    //
    NTSTATUS
    Start (
        CImageSynthesizer *ImageSynth,
        IN LONGLONG TimePerFrame,
        IN ULONG Width,
        IN ULONG Height,
        IN ULONG ImageSize
        );

    //
    // Pause():
    //
    // "Pause" or "unpause" the fake hardware.  This will stop issuing 
    // interrupts or DPC's on a pause and restart them on an unpause.  Note
    // that this will not reset counters as a Stop() would.
    //
    NTSTATUS
    Pause (
        IN BOOLEAN Pausing
        );

    //
    // Stop():
    //
    // "Stop" the fake hardware.  This will stop issuing interrupts and
    // DPC's.
    //
    NTSTATUS
    Stop (
        );

    //
    // ProgramScatterGatherMappings():
    //
    // Program a series of scatter gather mappings into the fake hardware.
    //
    ULONG
    ProgramScatterGatherMappings (
        IN PKSSTREAM_POINTER Clone,
        IN PUCHAR *Buffer,
        IN PKSMAPPING Mappings,
        IN ULONG MappingsCount,
        IN ULONG MappingStride
        );

    //
    // Initialize():
    //
    // Initialize a piece of simulated hardware.
    //
    static 
    CHardwareSimulation *
    Initialize (
        IN KSOBJECT_BAG Bag,
        IN IHardwareSink *HardwareSink
        );

    //
    // ReadNumberOfMappingsCompleted():
    //
    // Read the number of mappings completed since the last hardware reset.
    //
    ULONG
    ReadNumberOfMappingsCompleted (
        );


	//
	// SetData();
	//
	// Sets the virtual frame buffer of the simulation.
	//
	void SetData(PVOID data, ULONG dataLength);
};



================================================
FILE: Driver/avshws/image.cpp
================================================
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        image.cpp

    Abstract:

        The image synthesis and overlay code.  These objects provide image
        synthesis (pixel, color-bar, etc...) onto RGB24 and UYVY buffers as
        well as software string overlay into these buffers.

	This entire file, data and all, must be in locked segments.

    History:

        created 1/16/2001

**************************************************************************/

#include "avshws.h"

/**************************************************************************

    Constants

**************************************************************************/

//
// g_FontData:
//
// The following is an 8x8 bitmapped font for use in the text overlay
// code.
//
UCHAR g_FontData [256][8] = {
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e},
    {0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e},
    {0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00},
    {0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00},
    {0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c},
    {0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c},
    {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00},
    {0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff},
    {0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00},
    {0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff},
    {0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78},
    {0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18},
    {0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0},
    {0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0},
    {0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99},
    {0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00},
    {0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00},
    {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18},
    {0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00},
    {0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00},
    {0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78},
    {0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00},
    {0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff},
    {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00},
    {0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00},
    {0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00},
    {0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00},
    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00},
    {0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00},
    {0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00},
    {0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00},
    {0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00},
    {0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00},
    {0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00},
    {0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00},
    {0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00},
    {0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00},
    {0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00},
    {0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60},
    {0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00},
    {0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00},
    {0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00},
    {0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00},
    {0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00},
    {0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00},
    {0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00},
    {0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00},
    {0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00},
    {0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00},
    {0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00},
    {0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00},
    {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00},
    {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60},
    {0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00},
    {0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00},
    {0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00},
    {0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00},
    {0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00},
    {0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00},
    {0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00},
    {0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00},
    {0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00},
    {0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00},
    {0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00},
    {0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00},
    {0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00},
    {0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00},
    {0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00},
    {0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00},
    {0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00},
    {0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00},
    {0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00},
    {0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
    {0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00},
    {0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00},
    {0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00},
    {0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00},
    {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00},
    {0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00},
    {0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00},
    {0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00},
    {0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00},
    {0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00},
    {0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00},
    {0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00},
    {0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff},
    {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00},
    {0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00},
    {0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00},
    {0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00},
    {0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00},
    {0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00},
    {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8},
    {0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00},
    {0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78},
    {0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00},
    {0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00},
    {0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00},
    {0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00},
    {0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0},
    {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e},
    {0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00},
    {0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00},
    {0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00},
    {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00},
    {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00},
    {0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00},
    {0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00},
    {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8},
    {0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00},
    {0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00},
    {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
    {0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00},
    {0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00},
    {0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78},
    {0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00},
    {0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00},
    {0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00},
    {0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00},
    {0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00},
    {0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00},
    {0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38},
    {0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00},
    {0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00},
    {0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00},
    {0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00},
    {0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00},
    {0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00},
    {0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00},
    {0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00},
    {0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00},
    {0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00},
    {0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00},
    {0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00},
    {0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00},
    {0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00},
    {0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8},
    {0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00},
    {0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00},
    {0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18},
    {0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00},
    {0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30},
    {0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7},
    {0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70},
    {0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00},
    {0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00},
    {0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00},
    {0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00},
    {0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00},
    {0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00},
    {0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00},
    {0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00},
    {0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00},
    {0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00},
    {0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f},
    {0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03},
    {0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00},
    {0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00},
    {0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00},
    {0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88},
    {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa},
    {0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee},
    {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18},
    {0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36},
    {0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36},
    {0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18},
    {0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
    {0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00},
    {0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00},
    {0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00},
    {0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18},
    {0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00},
    {0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18},
    {0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36},
    {0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00},
    {0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36},
    {0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00},
    {0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18},
    {0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00},
    {0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18},
    {0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36},
    {0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36},
    {0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18},
    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
    {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
    {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0},
    {0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f},
    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00},
    {0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0},
    {0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00},
    {0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00},
    {0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00},
    {0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00},
    {0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0},
    {0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00},
    {0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc},
    {0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00},
    {0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00},
    {0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00},
    {0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00},
    {0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0},
    {0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00},
    {0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00},
    {0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00},
    {0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00},
    {0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00},
    {0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00},
    {0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18},
    {0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70},
    {0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00},
    {0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00},
    {0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00},
    {0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c},
    {0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00},
    {0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
};

//
// Standard definition of EIA-189-A color bars.  The actual color definitions
// are either in CRGB24Synthesizer or CYUVSynthesizer.
//
const COLOR g_ColorBars[] = 
    {WHITE, YELLOW, CYAN, GREEN, MAGENTA, RED, BLUE, BLACK};

const UCHAR CRGB24Synthesizer::Colors [MAX_COLOR][3] = {
    {0, 0, 0},          // BLACK
    {255, 255, 255},    // WHITE
    {0, 255, 255},      // YELLOW
    {255, 255, 0},      // CYAN
    {0, 255, 0},        // GREEN
    {255, 0, 255},      // MAGENTA
    {0, 0, 255},        // RED
    {255, 0, 0},        // BLUE
    {128, 128, 128}     // GREY
};

const UCHAR CYUVSynthesizer::Colors [MAX_COLOR][3] = {
    {128, 16, 128},     // BLACK
    {128, 235, 128},    // WHITE
    {16, 211, 146},     // YELLOW
    {166, 170, 16},     // CYAN
    {54, 145, 34},      // GREEN
    {202, 106, 222},    // MAGENTA
    {90, 81, 240},      // RED
    {240, 41, 109},     // BLUE
    {128, 125, 128},    // GREY
};

/**************************************************************************

    LOCKED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA


void
CImageSynthesizer::
SynthesizeBars (
    )

/*++

Routine Description:

    Synthesize EIA-189-A standard color bars onto the Image.  The image
    in question is the current synthesis buffer.

Arguments:

    None

Return Value:

    None

--*/

{
    const COLOR *CurColor = g_ColorBars;
    ULONG ColorCount = SIZEOF_ARRAY (g_ColorBars);

    //
    // Set the default cursor...
    //
    GetImageLocation (0, 0);

    //
    // Synthesize a single line.
    //
    PUCHAR ImageStart = m_Cursor;
    for (ULONG x = 0; x < m_Width; x++) 
        PutPixel (g_ColorBars [((x * ColorCount) / m_Width)]);

    PUCHAR ImageEnd = m_Cursor;
    
    //
    // Copy the synthesized line to all subsequent lines.
    //
    for (ULONG line = 1; line < m_Height; line++) {

        GetImageLocation (0, line);

        RtlCopyMemory (
            m_Cursor,
            ImageStart,
            ImageEnd - ImageStart
            );
    }
}

/*************************************************/


void 
CImageSynthesizer::
OverlayText (
    _In_ ULONG LocX,
    _In_ ULONG LocY,
    _In_ ULONG Scaling,
    _In_ LPSTR Text,
    _In_ COLOR BgColor,
    _In_ COLOR FgColor
    )

/*++

Routine Description:

    Overlay text onto the synthesized image.  Clip to fit the image
    if the overlay does not fit.  The image buffer used is the set
    synthesis buffer.

Arguments:

    LocX -
        The X location on the image to begin the overlay.  This MUST
        be inside the image.  POSITION_CENTER may be used to indicate
        horizontal centering.

    LocY -
        The Y location on the image to begin the overlay.  This MUST
        be inside the image.  POSITION_CENTER may be used to indicate
        vertical centering.

    Scaling -
        Normally, the overlay is done in 8x8 font.  A scaling of
        2 indicates 16x16, 3 indicates 24x24 and so forth.

    Text -
        A character string containing the information to overlay

    BgColor -
        The background color of the overlay window.  For transparency,
        indicate TRANSPARENT here.

    FgColor -
        The foreground color for the text overlay.

Return Value:

    None

--*/

{

    NT_ASSERT ((LocX <= m_Width || LocX == POSITION_CENTER) &&
            (LocY <= m_Height || LocY == POSITION_CENTER));

    ULONG StrLen = 0;
    CHAR* CurChar;

    //
    // Determine the character length of the string.
    //
    for (CurChar = Text; CurChar && *CurChar; CurChar++)
        StrLen++;

    //
    // Determine the physical size of the string plus border.  There is
    // a definable NO_CHARACTER_SEPARATION.  If this is defined, there will
    // be no added space between font characters.  Otherwise, one empty pixel
    // column is added between characters.
    //
    #ifndef NO_CHARACTER_SEPARATION
        ULONG LenX = (StrLen * (Scaling << 3)) + 1 + StrLen;
    #else // NO_CHARACTER_SEPARATION
        ULONG LenX = (StrLen * (Scaling << 3)) + 2;
    #endif // NO_CHARACTER_SEPARATION

    ULONG LenY = 2 + (Scaling << 3);

    //
    // Adjust for center overlays.
    //
    // NOTE: If the overlay doesn't fit into the synthesis buffer, this
    // merely left aligns the overlay and clips off the right side.
    //
    if (LocX == POSITION_CENTER) {
        if (LenX >= m_Width) {
            LocX = 0;
        } else {
            LocX = (m_Width >> 1) - (LenX >> 1);
        }
    }

    if (LocY == POSITION_CENTER) {
        if (LenY >= m_Height) {
            LocY = 0;
        } else {
            LocY = (m_Height >> 1) - (LenY >> 1);
        }
    }

    //
    // Determine the amount of space available on the synthesis buffer.
    // We will clip anything that finds itself outside the synthesis buffer.
    //
    ULONG SpaceX = m_Width - LocX;
    ULONG SpaceY = m_Height - LocY;

    //
    // Set the default cursor position.
    //
    GetImageLocation (LocX, LocY);

    //
    // Overlay a background color row.
    //
    if (BgColor != TRANSPARENT && SpaceY) {
        for (ULONG x = 0; x < LenX && x < SpaceX; x++) {
            PutPixel (BgColor);
        }
    }
    LocY++;
    if (SpaceY) SpaceY--;

    //
    // Loop across each row of the image.
    //
    for (ULONG row = 0; row < 8 && SpaceY; row++) {
        //
        // Generate a line.
        //
    
Download .txt
gitextract_gda5v0rh/

├── .gitignore
├── Driver/
│   └── avshws/
│       ├── README.md
│       ├── avshws.h
│       ├── avshws.inf
│       ├── avshws.rc
│       ├── avshws.sln
│       ├── avshws.vcxproj
│       ├── avshws.vcxproj.Filters
│       ├── capture.cpp
│       ├── capture.h
│       ├── customprops.h
│       ├── device.cpp
│       ├── device.h
│       ├── filter.cpp
│       ├── filter.h
│       ├── hwsim.cpp
│       ├── hwsim.h
│       ├── image.cpp
│       ├── image.h
│       └── purecall.c
├── LICENSE
├── README.md
└── UserLand/
    ├── .gitignore
    ├── DriverInterface/
    │   ├── Common.h
    │   ├── Device.cpp
    │   ├── Device.h
    │   ├── DeviceEnumeration.cpp
    │   ├── DeviceEnumeration.h
    │   ├── DriverInterface.cpp
    │   ├── DriverInterface.vcxproj
    │   ├── DriverInterface.vcxproj.filters
    │   └── dllmain.cpp
    ├── DriverInterfaceWrapper/
    │   ├── DeviceInfo.cs
    │   ├── DriverInterface.cs
    │   ├── DriverInterfaceWrapper.csproj
    │   ├── Native.cs
    │   └── Properties/
    │       └── AssemblyInfo.cs
    ├── UserDriverCanon/
    │   ├── App.config
    │   ├── CameraListItem.cs
    │   ├── FitPictureBox.cs
    │   ├── MainForm.Designer.cs
    │   ├── MainForm.cs
    │   ├── MainForm.resx
    │   ├── Program.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── UserDriverCanon.csproj
    ├── UserDriverStaticImage/
    │   ├── App.config
    │   ├── MainForm.Designer.cs
    │   ├── MainForm.cs
    │   ├── MainForm.resx
    │   ├── Program.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── UserDriverStaticImage.csproj
    └── VirtualCameraDriver.sln
Download .txt
SYMBOL INDEX (112 symbols across 30 files)

FILE: Driver/avshws/avshws.h
  type HARDWARE_STATE (line 162) | typedef enum _HARDWARE_STATE {
  function class (line 183) | class IHardwareSink {
  function class (line 201) | class ICaptureSink {

FILE: Driver/avshws/capture.cpp
  function NTSTATUS (line 90) | NTSTATUS
  function PKS_VIDEOINFOHEADER (line 236) | PKS_VIDEOINFOHEADER
  function NTSTATUS (line 314) | NTSTATUS
  function NTSTATUS (line 527) | NTSTATUS
  function NTSTATUS (line 578) | NTSTATUS
  function NTSTATUS (line 782) | NTSTATUS
  function BOOL (line 1011) | BOOL
  function NTSTATUS (line 1058) | NTSTATUS

FILE: Driver/avshws/capture.h
  type STREAM_POINTER_CONTEXT (line 37) | typedef struct _STREAM_POINTER_CONTEXT {
  function class (line 48) | class CCapturePin :

FILE: Driver/avshws/device.cpp
  function POOL_TYPE (line 31) | POOL_TYPE       poolType
  function NTSTATUS (line 192) | NTSTATUS
  function NTSTATUS (line 264) | NTSTATUS
  function NTSTATUS (line 396) | NTSTATUS
  function NTSTATUS (line 576) | NTSTATUS
  function NTSTATUS (line 620) | NTSTATUS
  function NTSTATUS (line 666) | NTSTATUS
  function ULONG (line 699) | ULONG
  function ULONG (line 763) | ULONG
  function NTSTATUS (line 909) | NTSTATUS

FILE: Driver/avshws/device.h
  function class (line 23) | class CCaptureDevice :

FILE: Driver/avshws/filter.cpp
  function NTSTATUS (line 35) | NTSTATUS
  function NTSTATUS (line 103) | NTSTATUS
  function NTSTATUS (line 122) | NTSTATUS

FILE: Driver/avshws/filter.h
  function class (line 21) | class CCaptureFilter {

FILE: Driver/avshws/hwsim.cpp
  function SimulatedInterrupt (line 31) | void
  function CHardwareSimulation (line 114) | CHardwareSimulation *
  function NTSTATUS (line 154) | NTSTATUS
  function NTSTATUS (line 289) | NTSTATUS
  function NTSTATUS (line 379) | NTSTATUS
  function ULONG (line 484) | ULONG
  function ULONG (line 521) | ULONG
  function NTSTATUS (line 623) | NTSTATUS

FILE: Driver/avshws/hwsim.h
  type SCATTER_GATHER_ENTRY (line 45) | typedef struct _SCATTER_GATHER_ENTRY {
  function class (line 59) | class CHardwareSimulation {

FILE: Driver/avshws/image.h
  type COLOR (line 34) | typedef enum {
  function class (line 69) | class CImageSynthesizer {
  function class (line 238) | class CRGB24Synthesizer : public CImageSynthesizer {

FILE: Driver/avshws/purecall.c
  function _purecall (line 42) | int __cdecl

FILE: UserLand/DriverInterface/Device.h
  function class (line 11) | class Device

FILE: UserLand/DriverInterface/DeviceEnumeration.cpp
  function HRESULT (line 3) | HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
  function EnumerateDevicePaths (line 21) | int EnumerateDevicePaths(string* paths, int maxCount)
  function GetFilter (line 55) | int GetFilter(string path, IBaseFilter** filter)

FILE: UserLand/DriverInterface/DriverInterface.cpp
  function EXPORT (line 14) | EXPORT int Init()
  function EXPORT (line 36) | EXPORT int Free()
  function EXPORT (line 50) | EXPORT int GetNumDevices()
  function EXPORT (line 55) | EXPORT int GetDevicePath(int index, char* str, int maxLen)
  function EXPORT (line 66) | EXPORT void DestroyDevice()
  function EXPORT (line 75) | EXPORT int SetDevice(char* str, int strLen)
  function EXPORT (line 97) | EXPORT int SetBuffer(PVOID data, DWORD stride, DWORD width, DWORD height)

FILE: UserLand/DriverInterface/dllmain.cpp
  function BOOL (line 3) | BOOL APIENTRY DllMain( HMODULE hModule,

FILE: UserLand/DriverInterfaceWrapper/DeviceInfo.cs
  class DeviceInfo (line 9) | public class DeviceInfo
    method DeviceInfo (line 17) | internal DeviceInfo(string path)
    method ToString (line 22) | public override string ToString()

FILE: UserLand/DriverInterfaceWrapper/DriverInterface.cs
  class DriverInterface (line 9) | public class DriverInterface
    method Init (line 14) | public static bool Init()
    method Free (line 19) | public static void Free()
    method GetDevices (line 24) | public static DeviceInfo[] GetDevices()
    method DestroyDevice (line 37) | public static void DestroyDevice()
    method SelectDevice (line 42) | public static bool SelectDevice(string path)
    method SetData (line 47) | public static bool SetData(IntPtr data, int stride, int width, int hei...

FILE: UserLand/DriverInterfaceWrapper/Native.cs
  class Native (line 10) | class Native
    method Init (line 12) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method Free (line 15) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method GetNumDevices (line 18) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method GetDevicePath (line 21) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method DestroyDevice (line 24) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method SetDevice (line 27) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method SetBuffer (line 30) | [DllImport("DriverInterface.dll", CallingConvention = CallingConventio...
    method GetDevicePath (line 33) | public static string GetDevicePath(int index)
    method SetDevice (line 42) | public static bool SetDevice(string path)

FILE: UserLand/UserDriverCanon/CameraListItem.cs
  class CameraListItem (line 10) | class CameraListItem
    method CameraListItem (line 14) | public CameraListItem(Camera c)
    method ToString (line 19) | public override string ToString()

FILE: UserLand/UserDriverCanon/FitPictureBox.cs
  class FitPictureBox (line 10) | public class FitPictureBox : Control
    method FitPictureBox (line 31) | public FitPictureBox()
    method OnPaint (line 36) | protected override void OnPaint(PaintEventArgs e)

FILE: UserLand/UserDriverCanon/MainForm.Designer.cs
  class MainForm (line 3) | partial class MainForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: UserLand/UserDriverCanon/MainForm.cs
  class MainForm (line 18) | public partial class MainForm : Form
    method MainForm (line 25) | public MainForm()
    method MainForm_Load (line 30) | private void MainForm_Load(object sender, EventArgs e)
    method btnDeviceRefresh_Click (line 38) | private void btnDeviceRefresh_Click(object sender, EventArgs e)
    method cbDevices_SelectedIndexChanged (line 46) | private void cbDevices_SelectedIndexChanged(object sender, EventArgs e)
    method btnRefreshCameras_Click (line 60) | private void btnRefreshCameras_Click(object sender, EventArgs e)
    method cbCameras_SelectedIndexChanged (line 69) | private void cbCameras_SelectedIndexChanged(object sender, EventArgs e)
    method ActiveCamera_LiveViewUpdated (line 90) | private void ActiveCamera_LiveViewUpdated(Camera sender, Stream img)
    method MainForm_FormClosing (line 143) | private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    method cameraKeepAlive_Tick (line 148) | private void cameraKeepAlive_Tick(object sender, EventArgs e)

FILE: UserLand/UserDriverCanon/Program.cs
  class Program (line 11) | static class Program
    method Main (line 13) | [MTAThread]

FILE: UserLand/UserDriverCanon/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 32) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: UserLand/UserDriverCanon/Properties/Settings.Designer.cs
  class Settings (line 15) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

FILE: UserLand/UserDriverStaticImage/MainForm.Designer.cs
  class MainForm (line 3) | partial class MainForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: UserLand/UserDriverStaticImage/MainForm.cs
  class MainForm (line 17) | public partial class MainForm : Form
    method MainForm (line 19) | public MainForm()
    method MainForm_Load (line 24) | private void MainForm_Load(object sender, EventArgs e)
    method btnDeviceRefresh_Click (line 29) | private void btnDeviceRefresh_Click(object sender, EventArgs e)
    method cbDevices_SelectedIndexChanged (line 37) | private void cbDevices_SelectedIndexChanged(object sender, EventArgs e)
    method btnLoadImage_Click (line 49) | private void btnLoadImage_Click(object sender, EventArgs e)

FILE: UserLand/UserDriverStaticImage/Program.cs
  class Program (line 11) | static class Program
    method Main (line 13) | [MTAThread]

FILE: UserLand/UserDriverStaticImage/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 32) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: UserLand/UserDriverStaticImage/Properties/Settings.Designer.cs
  class Settings (line 15) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
Condensed preview — 62 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (330K chars).
[
  {
    "path": ".gitignore",
    "chars": 6002,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
  },
  {
    "path": "Driver/avshws/README.md",
    "chars": 8690,
    "preview": "---\npage_type: sample\ndescription: \"A simulated hardware sample driver providing a pin-centric capture driver to simulat"
  },
  {
    "path": "Driver/avshws/avshws.h",
    "chars": 6509,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/avshws.inf",
    "chars": 5103,
    "preview": ";/*++\n;\n;Copyright (c) Microsoft Corporation.  All rights reserved.\n;\n;    THIS CODE AND INFORMATION IS PROVIDED \"AS IS\""
  },
  {
    "path": "Driver/avshws/avshws.rc",
    "chars": 599,
    "preview": "//+-------------------------------------------------------------------------\n//\n//  Microsoft Windows\n//\n//  Copyright ("
  },
  {
    "path": "Driver/avshws/avshws.sln",
    "chars": 2423,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28307.136\nMi"
  },
  {
    "path": "Driver/avshws/avshws.vcxproj",
    "chars": 20029,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.micros"
  },
  {
    "path": "Driver/avshws/avshws.vcxproj.Filters",
    "chars": 4852,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "Driver/avshws/capture.cpp",
    "chars": 50884,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/capture.h",
    "chars": 8631,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/customprops.h",
    "chars": 2266,
    "preview": "#pragma once\n\n\n#define DEFINE_STD_PROPERTY_SET(SET, PROPERTIES)    \\\n    DEFINE_KSPROPERTY_SET(                         "
  },
  {
    "path": "Driver/avshws/device.cpp",
    "chars": 19605,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/device.h",
    "chars": 7705,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/filter.cpp",
    "chars": 7194,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/filter.h",
    "chars": 1847,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/hwsim.cpp",
    "chars": 18080,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/hwsim.h",
    "chars": 7014,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/image.cpp",
    "chars": 22430,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/image.h",
    "chars": 9463,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "Driver/avshws/purecall.c",
    "chars": 807,
    "preview": "/**************************************************************************\n\n    AVStream Simulated Hardware Sample\n\n   "
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2020 Bence\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "README.md",
    "chars": 1517,
    "preview": "# VirtualCameraDriver\nWindows virtual camera driver using the AVStream minidriver.\n\nThis project was a challenge for mys"
  },
  {
    "path": "UserLand/.gitignore",
    "chars": 8,
    "preview": "EDSDKLib"
  },
  {
    "path": "UserLand/DriverInterface/Common.h",
    "chars": 217,
    "preview": "#pragma once\n\n#include <SDKDDKVer.h>\n\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#include <dshow.h>\n#include <dvdm"
  },
  {
    "path": "UserLand/DriverInterface/Device.cpp",
    "chars": 865,
    "preview": "#include \"Device.h\"\n\nconst GUID GUID_PROP_CLASS = { PROP_GUID };\n\nDevice::Device(IBaseFilter* filter)\n\t: filter(filter),"
  },
  {
    "path": "UserLand/DriverInterface/Device.h",
    "chars": 386,
    "preview": "#pragma once\n\n#include \"Common.h\"\n\n#define PROP_GUID 0xcb043957, 0x7b35, 0x456e, 0x9b, 0x61, 0x55, 0x13, 0x93, 0xf, 0x4d"
  },
  {
    "path": "UserLand/DriverInterface/DeviceEnumeration.cpp",
    "chars": 1619,
    "preview": "#include \"DeviceEnumeration.h\"\n\nHRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)\n{\n\tICreateDevEnum *pDe"
  },
  {
    "path": "UserLand/DriverInterface/DeviceEnumeration.h",
    "chars": 139,
    "preview": "#pragma once\n\n#include \"Common.h\"\n\nint EnumerateDevicePaths(string* paths, int maxCount);\nint GetFilter(string path, IBa"
  },
  {
    "path": "UserLand/DriverInterface/DriverInterface.cpp",
    "chars": 2006,
    "preview": "#include \"Common.h\"\n#include \"DeviceEnumeration.h\"\n#include \"Device.h\"\n\n#define NUM_MAX_PATHS 16\nstatic string cachedPat"
  },
  {
    "path": "UserLand/DriverInterface/DriverInterface.vcxproj",
    "chars": 8279,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microso"
  },
  {
    "path": "UserLand/DriverInterface/DriverInterface.vcxproj.filters",
    "chars": 1534,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "UserLand/DriverInterface/dllmain.cpp",
    "chars": 371,
    "preview": "#include <Windows.h>\n\nBOOL APIENTRY DllMain( HMODULE hModule,\n                       DWORD  ul_reason_for_call,\n        "
  },
  {
    "path": "UserLand/DriverInterfaceWrapper/DeviceInfo.cs",
    "chars": 459,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "UserLand/DriverInterfaceWrapper/DriverInterface.cs",
    "chars": 1191,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "UserLand/DriverInterfaceWrapper/DriverInterfaceWrapper.csproj",
    "chars": 2259,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "UserLand/DriverInterfaceWrapper/Native.cs",
    "chars": 1697,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.T"
  },
  {
    "path": "UserLand/DriverInterfaceWrapper/Properties/AssemblyInfo.cs",
    "chars": 1412,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "UserLand/UserDriverCanon/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "UserLand/UserDriverCanon/CameraListItem.cs",
    "chars": 423,
    "preview": "using EOSDigital.API;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing Syste"
  },
  {
    "path": "UserLand/UserDriverCanon/FitPictureBox.cs",
    "chars": 2048,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing Syste"
  },
  {
    "path": "UserLand/UserDriverCanon/MainForm.Designer.cs",
    "chars": 8762,
    "preview": "namespace UserDriverCanon\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// Required designer variab"
  },
  {
    "path": "UserLand/UserDriverCanon/MainForm.cs",
    "chars": 5054,
    "preview": "using DriverInterfaceWrapper;\nusing EOSDigital.API;\nusing System;\nusing System.Collections.Generic;\nusing System.Compon"
  },
  {
    "path": "UserLand/UserDriverCanon/MainForm.resx",
    "chars": 5896,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "UserLand/UserDriverCanon/Program.cs",
    "chars": 871,
    "preview": "using DriverInterfaceWrapper;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading"
  },
  {
    "path": "UserLand/UserDriverCanon/Properties/AssemblyInfo.cs",
    "chars": 1398,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "UserLand/UserDriverCanon/Properties/Resources.Designer.cs",
    "chars": 2787,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "UserLand/UserDriverCanon/Properties/Resources.resx",
    "chars": 5494,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "UserLand/UserDriverCanon/Properties/Settings.Designer.cs",
    "chars": 1070,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "UserLand/UserDriverCanon/Properties/Settings.settings",
    "chars": 240,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "UserLand/UserDriverCanon/UserDriverCanon.csproj",
    "chars": 4107,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "UserLand/UserDriverStaticImage/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "UserLand/UserDriverStaticImage/MainForm.Designer.cs",
    "chars": 7885,
    "preview": "namespace UserDriverStaticImage\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// Required designer "
  },
  {
    "path": "UserLand/UserDriverStaticImage/MainForm.cs",
    "chars": 3907,
    "preview": "using DriverInterfaceWrapper;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System"
  },
  {
    "path": "UserLand/UserDriverStaticImage/MainForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Program.cs",
    "chars": 877,
    "preview": "using DriverInterfaceWrapper;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Properties/AssemblyInfo.cs",
    "chars": 1410,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Properties/Resources.Designer.cs",
    "chars": 2799,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Properties/Resources.resx",
    "chars": 5494,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Properties/Settings.Designer.cs",
    "chars": 1076,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "UserLand/UserDriverStaticImage/Properties/Settings.settings",
    "chars": 240,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "UserLand/UserDriverStaticImage/UserDriverStaticImage.csproj",
    "chars": 3807,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "UserLand/VirtualCameraDriver.sln",
    "chars": 6524,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28307.645\nMi"
  }
]

About this extraction

This page contains the full source code of the robot9706/VirtualCameraDriver GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 62 files (306.0 KB), approximately 82.7k tokens, and a symbol index with 112 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!