sync with trunk r46493
authorJérôme Gardou <jerome.gardou@reactos.org>
Sat, 27 Mar 2010 20:19:56 +0000 (20:19 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Sat, 27 Mar 2010 20:19:56 +0000 (20:19 +0000)
svn path=/branches/reactos-yarotows/; revision=46494

332 files changed:
ReactOS-amd64.rbuild
ReactOS-i386.rbuild
base/applications/paint/rsrc.rc
base/applications/rapps/rapps/firefox3.txt
base/applications/rapps/rapps/mirandaim.txt
base/applications/rapps/rapps/openttd.txt
base/applications/rapps/rapps/opera.txt
base/applications/rapps/rapps/sambatng.txt
base/applications/rapps/rapps/seamonkey.txt
base/applications/rapps/rapps/smplayer.txt
base/applications/rapps/rapps/thunderbird.txt
base/applications/sndrec32/audio_wavein.hpp
base/applications/sndrec32/audio_waveout.hpp
base/setup/usetup/partlist.c
base/shell/cmd/cmd.c
baseaddress.rbuild
boot/bootdata/bootcd/bootcd.rbuild
boot/bootdata/livecd/livecd.rbuild
boot/bootdata/packages/reactos.dff
boot/freeldr/freeldr/debug.c
dll/cpl/sysdm/general.c
dll/cpl/usrmgr/lang/de-DE.rc
dll/directx/bdaplgin/controlnode.cpp
dll/directx/bdaplgin/devicecontrol.cpp
dll/directx/bdaplgin/digitaldemo.cpp
dll/directx/bdaplgin/frequencyfilter.cpp
dll/directx/bdaplgin/lnbinfo.cpp
dll/directx/bdaplgin/pincontrol.cpp
dll/directx/bdaplgin/precomp.h
dll/directx/bdaplgin/signalstatistics.cpp
dll/directx/ksproxy/allocator.cpp
dll/directx/ksproxy/basicaudio.cpp
dll/directx/ksproxy/clockforward.cpp
dll/directx/ksproxy/cvpconfig.cpp
dll/directx/ksproxy/cvpvbiconfig.cpp
dll/directx/ksproxy/datatype.cpp
dll/directx/ksproxy/enum_mediatypes.cpp
dll/directx/ksproxy/enumpins.cpp
dll/directx/ksproxy/input_pin.cpp
dll/directx/ksproxy/interface.cpp
dll/directx/ksproxy/ksproxy.cpp
dll/directx/ksproxy/ksproxy.rbuild
dll/directx/ksproxy/node.cpp
dll/directx/ksproxy/output_pin.cpp
dll/directx/ksproxy/precomp.h
dll/directx/ksproxy/proxy.cpp
dll/directx/ksproxy/qualityforward.cpp
dll/directx/msdvbnp/msdvbnp.cpp
dll/directx/msdvbnp/networkprovider.cpp
dll/directx/msdvbnp/pin.cpp
dll/directx/msdvbnp/precomp.h
dll/directx/msdvbnp/scanningtuner.cpp
dll/directx/qedit/samplegrabber.c
dll/directx/quartz/filtermapper.c
dll/nls/idndl/idndl.def [deleted file]
dll/nls/idndl/idndl.rbuild
dll/ntdll/dbg/dbgui.c
dll/ntdll/dispatch/dispatch.c
dll/ntdll/ldr/startup.c
dll/ntdll/ldr/utils.c
dll/ntdll/rtl/libsupp.c
dll/win32/acledit/acledit.c
dll/win32/acledit/stubs.c
dll/win32/advapi32/reg/reg.c
dll/win32/advapi32/sec/misc.c
dll/win32/avicap32/avicap32.c
dll/win32/avifil32/api.c
dll/win32/batt/batt.c [new file with mode: 0644]
dll/win32/batt/batt.rbuild [new file with mode: 0644]
dll/win32/batt/batt.rc [new file with mode: 0644]
dll/win32/batt/batt.spec [new file with mode: 0644]
dll/win32/batt/resource.h [new file with mode: 0644]
dll/win32/batt/resources/battery.ico [new file with mode: 0644]
dll/win32/beepmidi/beepmidi.c
dll/win32/browseui/internettoolbar.cpp
dll/win32/crypt32/chain.c
dll/win32/crypt32/main.c
dll/win32/crypt32/oid.c
dll/win32/dbghelp/dbghelp_private.h
dll/win32/dbghelp/dwarf.c
dll/win32/dbghelp/elf_module.c
dll/win32/dbghelp/macho_module.c
dll/win32/dbghelp/module.c
dll/win32/dbghelp/pe_module.c
dll/win32/dbghelp/symbol.c
dll/win32/fusion/fusion.c
dll/win32/fusion/fusion.spec
dll/win32/gdiplus/brush.c
dll/win32/gdiplus/image.c
dll/win32/hlink/browse_ctx.c
dll/win32/hlink/hlink_main.c
dll/win32/hlink/link.c
dll/win32/iphlpapi/iphlpapi_private.h
dll/win32/iphlpapi/resinfo_reactos.c
dll/win32/kernel32/misc/dllmain.c
dll/win32/kernel32/misc/toolhelp.c
dll/win32/kernel32/synch/critical.c
dll/win32/kernel32/thread/fiber.c
dll/win32/mshtml/De.rc
dll/win32/mshtml/Fr.rc
dll/win32/mshtml/It.rc
dll/win32/mshtml/Ja.rc
dll/win32/mshtml/Lt.rc
dll/win32/mshtml/No.rc
dll/win32/mshtml/Si.rc
dll/win32/mshtml/htmldoc.c
dll/win32/mshtml/htmldoc3.c
dll/win32/mshtml/htmlelem2.c
dll/win32/mshtml/htmlevent.c
dll/win32/mshtml/htmlevent.h
dll/win32/mshtml/htmlimg.c
dll/win32/mshtml/htmlwindow.c
dll/win32/mshtml/mshtml_private.h
dll/win32/mshtml/mutation.c
dll/win32/mshtml/navigate.c
dll/win32/mshtml/nsevents.c
dll/win32/mshtml/nsio.c
dll/win32/mshtml/omnavigator.c
dll/win32/mshtml/persist.c
dll/win32/msi/database.c
dll/win32/msi/msi_De.rc
dll/win32/msi/msi_Fr.rc
dll/win32/msi/msi_It.rc
dll/win32/msi/msi_Lt.rc
dll/win32/msi/msi_Ro.rc
dll/win32/msi/msi_Ru.rc
dll/win32/msi/msi_Si.rc
dll/win32/msi/msiquery.c
dll/win32/msi/msiserver.idl
dll/win32/msvcrt/msvcrt.def
dll/win32/msxml3/domdoc.c
dll/win32/ole32/compobj.c
dll/win32/ole32/ifs.h [deleted file]
dll/win32/ole32/ole16.c [deleted file]
dll/win32/ole32/stg_bigblockfile.c
dll/win32/ole32/stg_prop.c
dll/win32/ole32/storage32.c
dll/win32/ole32/storage32.h
dll/win32/oleaut32/typelib.c
dll/win32/oleaut32/typelib2.c
dll/win32/oledlg/oledlg_De.rc
dll/win32/oledlg/oledlg_Fr.rc
dll/win32/oledlg/oledlg_Ja.rc
dll/win32/oledlg/oledlg_Lt.rc
dll/win32/oledlg/oledlg_Si.rc
dll/win32/riched20/caret.c
dll/win32/riched20/clipboard.c
dll/win32/riched20/editor.c
dll/win32/riched20/editor.h
dll/win32/riched20/editstr.h
dll/win32/riched20/list.c
dll/win32/riched20/paint.c
dll/win32/riched20/para.c
dll/win32/riched20/reader.c
dll/win32/riched20/richole.c
dll/win32/riched20/rtf.h
dll/win32/riched20/run.c
dll/win32/riched20/style.c
dll/win32/riched20/table.c
dll/win32/riched20/txthost.c
dll/win32/riched20/txtsrv.c
dll/win32/riched20/undo.c
dll/win32/riched20/wrap.c
dll/win32/riched20/writer.c
dll/win32/rpcrt4/cproxy.c
dll/win32/rpcrt4/cpsf.c
dll/win32/rpcrt4/cpsf.h
dll/win32/rpcrt4/cstub.c
dll/win32/rpcrt4/ndr_contexthandle.c
dll/win32/rpcrt4/ndr_fullpointer.c
dll/win32/rpcrt4/ndr_marshall.c
dll/win32/rpcrt4/ndr_misc.h
dll/win32/rpcrt4/ndr_ole.c
dll/win32/rpcrt4/rpc_transport.c
dll/win32/rsaenh/implglue.c
dll/win32/rsaenh/implglue.h
dll/win32/rsaenh/rsaenh.c
dll/win32/rsaenh/rsaenh.rbuild
dll/win32/shdocvw/dochost.c
dll/win32/shdocvw/iexplore.c
dll/win32/shdocvw/navigate.c
dll/win32/shdocvw/oleobject.c
dll/win32/shdocvw/shdocvw.h
dll/win32/shdocvw/webbrowser.c
dll/win32/shell32/autocomplete.c
dll/win32/shlwapi/ordinal.c
dll/win32/shlwapi/shlwapi.spec
dll/win32/shlwapi/string.c
dll/win32/shlwapi/url.c
dll/win32/syssetup/install.c
dll/win32/urlmon/internet.c
dll/win32/urlmon/sec_mgr.c
dll/win32/urlmon/uri.c
dll/win32/urlmon/urlmon.spec
dll/win32/user32/controls/scrollbar.c
dll/win32/user32/include/dde_private.h
dll/win32/user32/include/user32.h
dll/win32/user32/misc/dllmain.c
dll/win32/user32/windows/defwnd.c
dll/win32/user32/windows/draw.c
dll/win32/user32/windows/menu.c
dll/win32/user32/windows/message.c
dll/win32/usp10/usp10.c
dll/win32/version/info.c
dll/win32/version/resource.c
dll/win32/version/version_ros.diff [deleted file]
dll/win32/win32.rbuild
dll/win32/windowscodecs/info.c
dll/win32/windowscodecs/jpegformat.c
dll/win32/windowscodecs/pngformat.c
dll/win32/wininet/http.c
dll/win32/wininet/internet.c
dll/win32/wininet/internet.h
dll/win32/ws2_32/misc/stubs.c
drivers/base/bootvid/bootvid.rbuild
drivers/base/bootvid/i386/bootvid.c
drivers/base/bootvid/i386/vga.c
drivers/battery/battc/battc.c
drivers/bus/acpi/acpi.rbuild
drivers/bus/acpi/busmgr/bus.c
drivers/bus/acpi/busmgr/button.c
drivers/bus/acpi/buspdo.c
drivers/bus/acpi/cmbatt/cmbatt.c
drivers/bus/acpi/cmbatt/cmbatt.h
drivers/bus/acpi/cmbatt/cmbatt.rbuild
drivers/bus/acpi/cmbatt/cmbpnp.c
drivers/bus/acpi/cmbatt/cmbwmi.c
drivers/bus/acpi/cmbatt/cmexec.c
drivers/bus/acpi/compbatt/compbatt.c [new file with mode: 0644]
drivers/bus/acpi/compbatt/compbatt.h [new file with mode: 0644]
drivers/bus/acpi/compbatt/compbatt.rbuild [new file with mode: 0644]
drivers/bus/acpi/compbatt/compbatt.rc [new file with mode: 0644]
drivers/bus/acpi/compbatt/compmisc.c [new file with mode: 0644]
drivers/bus/acpi/compbatt/comppnp.c [new file with mode: 0644]
drivers/bus/acpi/include/acpi_bus.h
drivers/bus/acpi/include/acpisys.h
drivers/bus/acpi/main.c
drivers/bus/acpi/osl.c
drivers/bus/isapnp/isapnp.c
drivers/directx/dxg/ddhmg.c
drivers/filesystems/ntfs/attrib.c
drivers/input/i8042prt/keyboard.c
drivers/network/afd/afd/connect.c
drivers/network/afd/afd/write.c
drivers/network/dd/ne2000/include/ne2000.h
drivers/network/dd/ne2000/ne2000/8390.c
drivers/network/ndis/include/ndissys.h
drivers/network/ndis/ndis/io.c
drivers/network/ndis/ndis/miniport.c
drivers/network/ndis/ndis/misc.c
drivers/network/tcpip/datalink/lan.c
drivers/network/tcpip/tcpip/dispatch.c
drivers/serial/serenum/detect.c
drivers/serial/serial/devctrl.c
drivers/storage/class/class2/class2.c
drivers/storage/floppy/floppy.c
drivers/storage/ide/atapi/atapi.c
drivers/storage/scsiport/scsiport.c
drivers/storage/scsiport/scsiport.rbuild
drivers/storage/scsiport/scsiport.spec [deleted file]
drivers/video/displays/framebuf_new/framebuf_new.rbuild
drivers/video/displays/vga/main/enable.c
drivers/video/font/bmfd/font.c
drivers/video/font/bmfd/glyph.c
drivers/video/videoprt/agp.c
drivers/video/videoprt/int10.c
drivers/video/videoprt/interrupt.c
drivers/video/videoprt/resource.c
drivers/video/videoprt/services.c
drivers/video/videoprt/videoprt.c
drivers/wdm/audio/legacy/wdmaud/interface.h
hal/hal.rbuild
hal/halx86/generic/amd64/systimer.S [new file with mode: 0644]
hal/halx86/generic/amd64/x86bios.c [new file with mode: 0644]
hal/halx86/generic/cmos.c
hal/halx86/generic/i386/portio.c [moved from hal/halx86/generic/portio.c with 100% similarity]
hal/halx86/generic/i386/systimer.S [moved from hal/halx86/generic/systimer.S with 100% similarity]
hal/halx86/generic/i386/trap.S [moved from hal/halx86/generic/trap.S with 100% similarity]
hal/halx86/generic/misc.c
hal/halx86/generic/pic.c [deleted file]
hal/halx86/generic/processor.c [deleted file]
hal/halx86/generic/spinlock.c
hal/halx86/hal_generic.rbuild
hal/halx86/hal_generic_mp.rbuild
hal/halx86/hal_generic_up.rbuild
hal/halx86/halamd64.rbuild
hal/halx86/halmps.rbuild
hal/halx86/include/halp.h
hal/halx86/mp/amd64/mps.S [new file with mode: 0644]
hal/halx86/mp/i386/mps.S [moved from hal/halx86/mp/mps.S with 100% similarity]
hal/halx86/mp/i386/mpsboot.asm [moved from hal/halx86/mp/mpsboot.asm with 100% similarity]
hal/halx86/mp/i386/mpsirql.c [moved from hal/halx86/mp/mpsirql.c with 89% similarity]
hal/halx86/mp/spinlock.c [deleted file]
include/ddk/acpiioct.h
include/ddk/ntstatus.h [deleted file]
include/ddk/wdm.h
include/dxsdk/dxsdk.rbuild
include/ndk/pstypes.h
include/ndk/rtlfuncs.h
include/ndk/rtltypes.h
include/ndk/umtypes.h
include/psdk/ntstatus.h
include/psdk/urlmon.idl
include/psdk/wincodec.idl
include/psdk/wincrypt.h
include/reactos/win32k/ntuser.h
include/reactos/wine/config.h
include/reactos/wine/port.h
lib/sdk/crt/math/i386/pow_asm.s
media/doc/README.WINE
media/inf/battery.inf
media/inf/cpu.inf
media/inf/inf.rbuild
ntoskrnl/config/cmalloc.c
ntoskrnl/dbgk/dbgkutil.c
ntoskrnl/include/internal/cm_x.h
ntoskrnl/io/pnpmgr/pnpmgr.c
ntoskrnl/ke/i386/usercall.c
ntoskrnl/mm/ARM3/procsup.c
ntoskrnl/po/events.c
ntoskrnl/po/power.c
ntoskrnl/rtl/libsupp.c
ntoskrnl/se/semgr.c
ntoskrnl/se/token.c
subsystems/subsystems.rbuild
subsystems/win32/win32k/include/menu.h
subsystems/win32/win32k/include/msgqueue.h
subsystems/win32/win32k/ntuser/keyboard.c
subsystems/win32/win32k/ntuser/menu.c
subsystems/win32/win32k/ntuser/message.c
subsystems/win32/win32k/ntuser/windc.c
subsystems/win32/win32k/objects/gdibatch.c

index 9d299ca..0da944f 100644 (file)
@@ -42,6 +42,9 @@
                <linkerflag>-section-alignment=0x1000</linkerflag>
                <linkerflag>--unique=.eh_frame</linkerflag>
                <linkerflag>-static</linkerflag>
+               <linkerflag>-fno-leading-underscore</linkerflag>
+               <linkerflag>-shared</linkerflag>
+               <linkerflag>--exclude-all-symbols</linkerflag>
        </group>
 
        <if property="USERMODE" value="1">
index 44e3511..5bfd52a 100644 (file)
@@ -28,6 +28,8 @@
                <compilerflag>-mpreferred-stack-boundary=2</compilerflag>
                <compilerflag compiler="midl">-m32 --win32</compilerflag>
                <compilerflag compiler="cc,cxx">-gstabs+</compilerflag>
+               <compilerflag compiler="cc,cxx">-fno-set-stack-executable</compilerflag>
+               <compilerflag compiler="cc,cxx">-fno-optimize-sibling-calls</compilerflag>
                <compilerflag compiler="as">-gstabs+</compilerflag>
        </group>
 
index 49b981a..a1e776d 100644 (file)
@@ -42,4 +42,9 @@
 // THIS WILL MAKE THE PROGRAM USE THE COMMON CONTROLS
 // LIBRARY VERSION 6.0 (IF IT IS AVAILABLE)
 //
+#ifdef _AMD64_
+1 24 "paint.exe.amd64.manifest"
+#elif _X86_
 1 24 "paint.exe.manifest"
+#endif
+
index 072eee6..e605180 100644 (file)
@@ -2,10 +2,10 @@
 
 [Section]
 Name = Mozilla Firefox 3.0
-Version = 3.0.17
+Version = 3.0.18
 Licence = MPL/GPL/LGPL
 Description = The most popular and one of the best free Web Browsers out there.
-Size = 7.1M
+Size = 7.2M
 Category = 5
 URLSite = http://www.mozilla.com/en-US/
 URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/en-US/Firefox%20Setup%203.0.18.exe
@@ -13,7 +13,7 @@ CDPath = none
 
 [Section.0407]
 Description = Der populärste und einer der besten freien Webbrowser.
-Size = 6.9M
+Size = 7.0M
 URLSite = http://www.mozilla-europe.org/de/
 URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/de/Firefox%20Setup%203.0.18.exe
 
index 5b817e1..0fff6a4 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = Miranda IM
-Version = 0.8.13
+Version = 0.8.18
 Licence = GPL
 Description = Open source multiprotocol instant messaging application - May not work completely.
 Size = 1.6MB
 Category = 5
 URLSite = http://www.miranda-im.org/
-URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.13-unicode.exe
+URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.18-unicode.exe
 CDPath = none
 
 [Section.0407]
index 6220e8a..dfc94a9 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = OpenTTD
-Version = 0.7.3
+Version = 0.7.5
 Licence = GPL v2
 Description = Open Source clone of the "Transport Tycoon Deluxe" game engine. You need a copy of Transport Tycoon.
 Size = 2.9MB
 Category = 4
 URLSite = http://www.openttd.org/
-URLDownload = http://ovh.dl.sourceforge.net/sourceforge/openttd/openttd-0.7.3-windows-win32.exe
+URLDownload = http://binaries.openttd.org/releases/0.7.5/openttd-0.7.5-windows-win32.exe
 CDPath = none
 
 [Section.0407]
index 148e79b..44e49cc 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = Opera
-Version = 10.10
+Version = 10.51
 Licence = Freeware
 Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client.
 Size = 11.0M
 Category = 5
 URLSite = http://www.opera.com/
-URLDownload = http://ftp.opera.com/pub/opera/win/1010/int/Opera_1010_in_Setup.exe
+URLDownload = http://get4.opera.com/pub/opera/win/1051/int/Opera_1051_int_Setup.exe
 CDPath = none
 
 [Section.0407]
index 4377863..6cf579a 100644 (file)
@@ -2,10 +2,10 @@
 
 [Section]
 Name = Samba TNG
-Version = 0.4.99cvs
+Version = 0.5-RC1
 Licence = GPL
 Description = This tool allows you to access your Windows shared folders/printers with ReactOS.
-Size = 1MB
+Size = 2.1MB
 Category = 5
 URLSite = http://samba-tng.org/
 URLDownload = http://svn.reactos.org/packages/samba-tng.exe
index 69a43d5..9c980d3 100644 (file)
@@ -2,31 +2,31 @@
 
 [Section]
 Name = Mozilla SeaMonkey
-Version = 2.0.2
+Version = 2.0.3
 Licence = MPL/GPL/LGPL
 Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need.
-Size = 10.1MB
+Size = 10.0MB
 Category = 5
 URLSite = http://www.seamonkey-project.org/
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.2/win32/en-US/SeaMonkey%20Setup%202.0.2.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/en-US/SeaMonkey%20Setup%202.0.3.exe
 CDPath = none
 
 [Section.0407]
 Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
-Size = 10.0MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.2/win32/de/SeaMonkey%20Setup%202.0.2.exe
+Size = 10.1MB
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/de/SeaMonkey%20Setup%202.0.3.exe
 
 [Section.040a]
 Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás.
 Size = 10.0MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.2/win32/es-ES/SeaMonkey%20Setup%202.0.2.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/es-ES/SeaMonkey%20Setup%202.0.3.exe
 
 [Section.0415]
 Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
 Size = 10.8MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.2/win32/pl/SeaMonkey%20Setup%202.0.2.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/pl/SeaMonkey%20Setup%202.0.3.exe
 
 [Section.0419]
 Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
 Size = 10.4MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.2/win32/ru/SeaMonkey%20Setup%202.0.2.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/ru/SeaMonkey%20Setup%202.0.3.exe
index b307170..a2e47d3 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = SMPlayer
-Version = 0.6.8
+Version = 0.6.9
 Licence = GPL
 Description = SMPlayer.
-Size = 13.38MB
+Size = 14.2MB
 Category = 1
 URLSite = http://smplayer.sourceforge.net/
-URLDownload = http://downloads.sourceforge.net/project/smplayer/SMPlayer/0.6.8/smplayer-0.6.8-win32.exe
+URLDownload = http://downloads.sourceforge.net/project/smplayer/SMPlayer/0.6.9/smplayer-0.6.9-win32.exe
 CDPath = none
 
 [Section.0407]
index ca8fd86..9f0cd32 100644 (file)
@@ -2,35 +2,35 @@
 
 [Section]
 Name = Mozilla Thunderbird
-Version = 3.0.1
+Version = 3.0.3
 Licence = MPL/GPL/LGPL
 Description = The most popular and one of the best free Mail Clients out there.
 Size = 8.6M
 Category = 5
 URLSite = http://www.mozilla-europe.org/en/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.1/win32/en-US/Thunderbird%20Setup%203.0.1.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/en-US/Thunderbird%20Setup%203.0.3.exe
 CDPath = none
 
 [Section.0407]
 Description = Der populärste und einer der besten freien Mail-Clients.
 Size = 8.4M
 URLSite = http://www.mozilla-europe.org/de/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.1/win32/de/Thunderbird%20Setup%203.0.1.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/de/Thunderbird%20Setup%203.0.3.exe
 
 [Section.040a]
 Description = El más popular y uno de los mejores clientes mail que hay.
 Size = 8.4M
 URLSite = http://www.mozilla-europe.org/es/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.1/win32/es-ES/Thunderbird%20Setup%203.0.1.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/es-ES/Thunderbird%20Setup%203.0.3.exe
 
 [Section.0415]
 Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty.
-Size = 9.2M
+Size = 9.3M
 URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.1/win32/pl/Thunderbird%20Setup%203.0.1.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/pl/Thunderbird%20Setup%203.0.3.exe
 
 [Section.0419]
 Description = Один из самых популярных и лучших бесплатных почтовых клиентов.
 Size = 8.8M
 URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.1/win32/ru/Thunderbird%20Setup%203.0.1.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/ru/Thunderbird%20Setup%203.0.3.exe
index 0288ea6..7f9285b 100644 (file)
@@ -305,7 +305,7 @@ class audio_wavein
             if ( aud_info.bits() == 16 )
                 svalue = ( unsigned int )  abs( *(( short * ) (main_buffer + aud_info.bytes_in_samples( nsamp ))));
             else if ( aud_info.bits() == 8 )
-               svalue = (unsigned int)(( unsigned char * ) *(main_buffer + aud_info.bytes_in_samples( nsamp )));
+               svalue = (unsigned int)(( ptrdiff_t ) *(main_buffer + aud_info.bytes_in_samples( nsamp )));
 
             else 
                 svalue = 0;
index a36518d..0e22afd 100644 (file)
@@ -229,7 +229,7 @@ class audio_waveout
             if ( aud_info.bits() == 16 )
                 svalue = ( unsigned int )  abs( *(( short * ) (main_buffer + aud_info.bytes_in_samples( nsamp ))));
             else if ( aud_info.bits() == 8 )
-               svalue = (unsigned int)(( unsigned char * ) *(main_buffer + aud_info.bytes_in_samples( nsamp )));
+               svalue = (unsigned int)(( ptrdiff_t ) *(main_buffer + aud_info.bytes_in_samples( nsamp )));
 
             else 
                 svalue = 0;
index ca0bdf7..5c553c2 100644 (file)
@@ -846,10 +846,10 @@ AddDiskToList (HANDLE FileHandle,
   DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
   DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
 
-  DPRINT ("Cylinders %d\n", DiskEntry->Cylinders);
-  DPRINT ("TracksPerCylinder %d\n", DiskEntry->TracksPerCylinder);
-  DPRINT ("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack);
-  DPRINT ("BytesPerSector %d\n", DiskEntry->BytesPerSector);
+  DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders);
+  DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
+  DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
+  DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
 
   DiskEntry->TrackSize =
     (ULONGLONG)DiskGeometry.SectorsPerTrack *
index 233cffa..59f00ea 100644 (file)
@@ -244,7 +244,7 @@ static BOOL IsConsoleProcess(HANDLE Process)
                return TRUE;
        }
 
-       return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubSystem;
+       return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubsystem;
 }
 
 
index cacc80f..80401c1 100644 (file)
        <property name="BASEADDRESS_CARDS"              value="0x701a0000" />
        <property name="BASEADDRESS_WININET"            value="0x70200000" />
        <property name="BASEADDRESS_WINHTTP"            value="0x70c60000" />
+       <property name="BASEADDRESS_BATT"               value="0x70cb0000" />
        <property name="BASEADDRESS_AMSTREAM"           value="0x71030000" />
        <property name="BASEADDRESS_ACLUI"              value="0x71550000" />
        <property name="BASEADDRESS_DHCPCSVC"           value="0x71650000" />
index 0cadb1b..471a7f4 100644 (file)
@@ -1,5 +1,12 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="bootcd" type="iso" output="ReactOS.iso">
-       <bootsector>isoboot</bootsector>
-</module>
+<if property="ARCH" value="i386>
+       <module name="bootcd" type="iso" output="ReactOS.iso">
+               <bootsector>isoboot</bootsector>
+       </module>
+</if>
+<ifnot property="ARCH" value="i386>
+       <module name="bootcd" type="iso" output="ReactOS-$(ARCH).iso">
+               <bootsector>isoboot</bootsector>
+       </module>
+</ifnot>
index 9c95cc5..e92deca 100644 (file)
@@ -1,5 +1,12 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="livecd" type="liveiso" output="ReactOS-LiveCD.iso">
-       <bootsector>isoboot</bootsector>
-</module>
+<if property="ARCH" value="i386>
+       <module name="livecd" type="liveiso" output="ReactOS-LiveCD.iso">
+               <bootsector>isoboot</bootsector>
+       </module>
+</if>
+<ifnot property="ARCH" value="i386>
+       <module name="livecd" type="liveiso" output="ReactOS-LiveCD-$(ARCH).iso">
+               <bootsector>isoboot</bootsector>
+       </module>
+</ifnot>
index 71f53de..1a37bcc 100644 (file)
@@ -262,6 +262,7 @@ dll\win32\atl\atl.dll                               1
 dll\win32\authz\authz.dll                           1
 dll\win32\avicap32\avicap32.dll                     1
 dll\win32\avifil32\avifil32.dll                     1
+dll\win32\batt\batt.dll                             1
 dll\win32\bcrypt\bcrypt.dll                         1
 dll\win32\beepmidi\beepmidi.dll                     1
 dll\win32\browseui\browseui.dll                     1
index 0de49f5..4ab9096 100644 (file)
@@ -351,7 +351,7 @@ KeBugCheckEx(
     IN ULONG_PTR  BugCheckParameter3,
     IN ULONG_PTR  BugCheckParameter4)
 {
-    char Buffer[64];
+    char Buffer[70];
     sprintf(Buffer, "*** STOP: 0x%08lX (0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX)",
         BugCheckCode, BugCheckParameter1, BugCheckParameter2,
         BugCheckParameter3, BugCheckParameter4);
index 7c2eea6..72b87de 100644 (file)
@@ -96,7 +96,16 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
                                        // build new bitmap
                                        GetObject(pImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
                                        dc = CreateCompatibleDC(GetDC(NULL));
+                                       if (dc == NULL)
+                                       {
+                                               break;
+                                       }
                                        sdc = CreateCompatibleDC(dc);
+                                       if (sdc == NULL)
+                                       {
+                                               DeleteDC(dc);
+                                               break;
+                                       }
                                        ncm.cbSize = sizeof(NONCLIENTMETRICS);
                                        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
 
index c8fa221..e3c7c31 100644 (file)
@@ -46,9 +46,9 @@ BEGIN
     EDITTEXT IDC_USER_GENERAL_FULL_NAME,77,43,168,13,ES_AUTOHSCROLL
     LTEXT "Beschreibung:", -1, 7, 64, 63, 8
     EDITTEXT IDC_USER_GENERAL_DESCRIPTION,77,61,168,13,ES_AUTOHSCROLL
-    AUTOCHECKBOX    "Benutzer muss das Passwort bei der ersten Anmeldung ändern",IDC_USER_GENERAL_FORCE_CHANGE,7,82,210,10
-    AUTOCHECKBOX    "Benutzer kann das Passwort nicht ändern",IDC_USER_GENERAL_CANNOT_CHANGE,7,95,210,10
-    AUTOCHECKBOX    "Passwort läuft nie ab",IDC_USER_GENERAL_NEVER_EXPIRES,7,108,210,10
+    AUTOCHECKBOX    "Benutzer muss das Passwort bei der ersten Anmeldung ändern",IDC_USER_GENERAL_FORCE_CHANGE,7,82,230,10
+    AUTOCHECKBOX    "Benutzer kann das Passwort nicht ändern",IDC_USER_GENERAL_CANNOT_CHANGE,7,95,210,10
+    AUTOCHECKBOX    "Passwort läuft nie ab",IDC_USER_GENERAL_NEVER_EXPIRES,7,108,210,10
     AUTOCHECKBOX    "Konto ist deativiert",IDC_USER_GENERAL_DISABLED,7,121,210,10
     AUTOCHECKBOX    "Konto ist gesperrt",IDC_USER_GENERAL_LOCKED,7,134,210,10
 END
@@ -106,7 +106,7 @@ END
 
 IDD_CHANGE_PASSWORD DIALOGEX DISCARDABLE  0, 0, 267, 74
 STYLE  DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT
-CAPTION "Passwort ändern"
+CAPTION "Passwort ändern"
 FONT 8, "MS Shell Dlg"
 BEGIN
     EDITTEXT        IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL | ES_PASSWORD
@@ -126,16 +126,16 @@ BEGIN
     EDITTEXT        IDC_USER_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL
     RTEXT           "Benutzername:", -1,7,10,96,8
     EDITTEXT        IDC_USER_NEW_FULL_NAME,107,25,153,14,ES_AUTOHSCROLL
-    RTEXT           "Vollständiger Name:", -1,7,28,96,8
+    RTEXT           "Vollständiger Name:", -1,7,28,96,8
     EDITTEXT        IDC_USER_NEW_DESCRIPTION,107,43,153,14,ES_AUTOHSCROLL
     RTEXT           "Beschreibung:", -1,7,46,96,8
     EDITTEXT        IDC_USER_NEW_PASSWORD1,107,67,153,14,ES_AUTOHSCROLL | ES_PASSWORD
     RTEXT           "Passwort:", -1,7,70,96,8
     EDITTEXT        IDC_USER_NEW_PASSWORD2,107,85,153,14,ES_AUTOHSCROLL | ES_PASSWORD
     RTEXT           "Passwort wiederholen:", -1,7,88,96,8
-    AUTOCHECKBOX    "Benutzer muss das Passwort bei der ersten Anmeldung ändern",IDC_USER_NEW_FORCE_CHANGE,7,109,200,10
-    AUTOCHECKBOX    "Benutzer kann das Passwort nicht ändern",IDC_USER_NEW_CANNOT_CHANGE,7,123,200,10,WS_DISABLED
-    AUTOCHECKBOX    "Passwort läuft nie ab",IDC_USER_NEW_NEVER_EXPIRES,7,137,200,10,WS_DISABLED
+    AUTOCHECKBOX    "Benutzer muss das Passwort bei der ersten Anmeldung ändern",IDC_USER_NEW_FORCE_CHANGE,7,109,230,10
+    AUTOCHECKBOX    "Benutzer kann das Passwort nicht ändern",IDC_USER_NEW_CANNOT_CHANGE,7,123,200,10,WS_DISABLED
+    AUTOCHECKBOX    "Passwort läuft nie ab",IDC_USER_NEW_NEVER_EXPIRES,7,137,200,10,WS_DISABLED
     AUTOCHECKBOX    "Konto ist deaktiviert",IDC_USER_NEW_DISABLED,7,151,200,10
     DEFPUSHBUTTON   "OK",IDOK,156,179,50,14,WS_DISABLED
     PUSHBUTTON      "Abbrechen",IDCANCEL,210,179,50,14
@@ -179,9 +179,9 @@ BEGIN
     END
     POPUP ""
     BEGIN
-        MENUITEM "Mitglied hinzufügen", IDM_GROUP_ADD_MEMBER, GRAYED
+        MENUITEM "Mitglied hinzufügen", IDM_GROUP_ADD_MEMBER, GRAYED
         MENUITEM SEPARATOR
-        MENUITEM "Löschen", IDM_GROUP_DELETE
+        MENUITEM "Löschen", IDM_GROUP_DELETE
         MENUITEM "Umbenennen", IDM_GROUP_RENAME
         MENUITEM SEPARATOR
         MENUITEM "Eigenschaften", IDM_GROUP_PROPERTIES
@@ -197,9 +197,9 @@ BEGIN
     END
     POPUP ""
     BEGIN
-        MENUITEM "Passwort ändern", IDM_USER_CHANGE_PASSWORD
+        MENUITEM "Passwort ändern", IDM_USER_CHANGE_PASSWORD
         MENUITEM SEPARATOR
-        MENUITEM "Löschen", IDM_USER_DELETE
+        MENUITEM "Löschen", IDM_USER_DELETE
         MENUITEM "Umbenennen", IDM_USER_RENAME
         MENUITEM SEPARATOR
         MENUITEM "Eigenschaften", IDM_USER_PROPERTIES
index 5cd98cc..40ec853 100644 (file)
@@ -9,7 +9,9 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
 const GUID IID_IKsPropertySet = {0x31efac30, 0x515c, 0x11d0, {0xa9,0xaa, 0x00,0xaa,0x00,0x61,0xbe,0x93}};
+#endif
 
 class CControlNode : public IUnknown
 {
@@ -32,12 +34,12 @@ public:
         return m_Ref;
     }
 
-    CControlNode(HANDLE hFile, ULONG NodeType, ULONG PinId) : m_Ref(0), m_hFile(hFile), m_NodeType(NodeType), m_PinId(PinId){};
+    CControlNode(IKsPropertySet * pProperty, ULONG NodeType, ULONG PinId) : m_Ref(0), m_pKsProperty(pProperty), m_NodeType(NodeType), m_PinId(PinId){};
     virtual ~CControlNode(){};
 
 protected:
     LONG m_Ref;
-    HANDLE m_hFile;
+    IKsPropertySet * m_pKsProperty;
     ULONG m_NodeType;
     ULONG m_PinId;
 };
@@ -58,19 +60,19 @@ CControlNode::QueryInterface(
     }
     else if(IsEqualGUID(refiid, IID_IBDA_FrequencyFilter))
     {
-        return CBDAFrequencyFilter_fnConstructor(m_hFile, m_NodeType, refiid, Output);
+        return CBDAFrequencyFilter_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
     }
     else if(IsEqualGUID(refiid, IID_IBDA_SignalStatistics))
     {
-        return CBDASignalStatistics_fnConstructor(m_hFile, m_NodeType, refiid, Output);
+        return CBDASignalStatistics_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
     }
     else if(IsEqualGUID(refiid, IID_IBDA_LNBInfo))
     {
-        return CBDALNBInfo_fnConstructor(m_hFile, m_NodeType, refiid, Output);
+        return CBDALNBInfo_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
     }
     else if(IsEqualGUID(refiid, IID_IBDA_DigitalDemodulator))
     {
-        return CBDADigitalDemodulator_fnConstructor(m_hFile, m_NodeType, refiid, Output);
+        return CBDADigitalDemodulator_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
     }
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[MAX_PATH];
@@ -88,7 +90,6 @@ CControlNode::QueryInterface(
 HRESULT
 WINAPI
 CControlNode_fnConstructor(
-    HANDLE hFile,
     IBaseFilter * pFilter,
     ULONG NodeType,
     ULONG PinId,
@@ -98,7 +99,7 @@ CControlNode_fnConstructor(
     WCHAR Buffer[100];
     HRESULT hr;
     IPin * pPin = NULL;
-    IKsObject * pObject = NULL;
+    IKsPropertySet * pProperty;
 
     // store pin id
     swprintf(Buffer, L"%u", PinId);
@@ -115,26 +116,21 @@ CControlNode_fnConstructor(
         return hr;
     }
 
-    // query IKsObject interface
-    hr = pPin->QueryInterface(IID_IKsObject, (void**)&pObject);
+    // query for IKsPropertySet interface
+    hr = pPin->QueryInterface(IID_IKsPropertySet, (void**)&pProperty);
+    if (FAILED(hr))
+        return hr;
 
 #ifdef BDAPLGIN_TRACE
     swprintf(Buffer, L"CControlNode_fnConstructor get IID_IKsObject status %lx\n", hr);
     OutputDebugStringW(Buffer);
 #endif
 
-    if (SUCCEEDED(hr))
-    {
-        // get pin handle
-        hFile = pObject->KsGetObjectHandle();
-        // release IKsObject interface
-        pObject->Release();
-    }
     // release IPin interface
     pPin->Release();
 
     // construct device control
-    CControlNode * handler = new CControlNode(hFile, NodeType, PinId);
+    CControlNode * handler = new CControlNode(pProperty, NodeType, PinId);
 
 #ifdef BDAPLGIN_TRACE
     OutputDebugStringW(L"CControlNode_fnConstructor\n");
index 661eba5..5d0e501 100644 (file)
@@ -9,20 +9,24 @@
 
 #include "precomp.h"
 
-const GUID CLSID_DVBTNetworkProvider = {0x216c62df, 0x6d7f, 0x4e9a, {0x85, 0x71, 0x5, 0xf1, 0x4e, 0xdb, 0x76, 0x6a}};
-const GUID IID_IAC3Filter         = {0xe4539501, 0xc609, 0x46ea, {0xad, 0x2a, 0x0e, 0x97, 0x00, 0x24, 0x56, 0x83}};
-const GUID IID_IAsyncReader       = {0x56A868AA, 0x0AD4, 0x11CE, {0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
-const GUID IID_IMatrixMixer       = {0xafc57835, 0x2fd1, 0x4541, {0xa6, 0xd9, 0x0d, 0xb7, 0x18, 0x56, 0xe5, 0x89}};
-const GUID IID_IBDA_NetworkProvider   = {0xfd501041, 0x8ebe, 0x11ce, {0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa2}};
-const GUID IID_IAMOpenProgress    = {0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};
-const GUID IID_IDistributorNotify = {0x56a868af, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
-const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
-const GUID IID_IBDA_Topology      = {0x79B56888, 0x7FEA, 0x4690, {0xB4, 0x5D, 0x38, 0xFD, 0x3C, 0x78, 0x49, 0xBE}};
 const GUID IID_IKsObject           = {0x423c13a2, 0x2070, 0x11d0, {0x9e, 0xf7, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
+
+#ifndef _MSC_VER
+const GUID CLSID_DVBTNetworkProvider = {0x216c62df, 0x6d7f, 0x4e9a, {0x85, 0x71, 0x5, 0xf1, 0x4e, 0xdb, 0x76, 0x6a}};
+
 const GUID KSPROPSETID_BdaTopology = {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
 const GUID KSMETHODSETID_BdaDeviceConfiguration = {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
-const GUID IID_IBaseFilter         = {0x56a86895, 0x0ad4, 0x11ce, {0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70}};
 const GUID KSMETHODSETID_BdaChangeSync = {0xfd0a5af3, 0xb41d, 0x11d2, {0x9c, 0x95, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
+const GUID IID_IBaseFilter         = {0x56a86895, 0x0ad4, 0x11ce, {0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70}};
+const GUID IID_IAsyncReader       = {0x56A868AA, 0x0AD4, 0x11CE, {0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
+const GUID IID_IAMOpenProgress    = {0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};
+const GUID IID_IBDA_Topology      = {0x79B56888, 0x7FEA, 0x4690, {0xB4, 0x5D, 0x38, 0xFD, 0x3C, 0x78, 0x49, 0xBE}};
+const GUID IID_IBDA_NetworkProvider   = {0xfd501041, 0x8ebe, 0x11ce, {0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa2}};
+const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
+
+const GUID IID_IDistributorNotify = {0x56a868af, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+
+#endif
 
 class CBDADeviceControl : public IBDA_DeviceControl,
                           public IBDA_Topology
@@ -468,15 +472,15 @@ CBDADeviceControl::GetControlNode(ULONG ulInputPinId, ULONG ulOutputPinId, ULONG
     hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_BDA_NODE_PIN) + sizeof(ULONG), &PinId, sizeof(ULONG), &BytesReturned);
 
 #ifdef BDAPLGIN_TRACE
-    WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADeviceControl::GetControlNode: hr %lx, BytesReturned %lu PinId %lu\n", hr, BytesReturned, PinId);
+    WCHAR Buffer[200];
+    swprintf(Buffer, L"CBDADeviceControl::GetControlNode: hr %lx, BytesReturned %lu PinId %lu ulInputPinId %lu ulOutputPinId %lu ulNodeType %lu\n", hr, BytesReturned, PinId, ulInputPinId, ulOutputPinId, ulNodeType);
     OutputDebugStringW(Buffer);
 #endif
 
     if (FAILED(hr))
         return hr;
 
-    hr = CControlNode_fnConstructor(m_Handle, m_pFilter, ulNodeType, PinId, IID_IUnknown, (LPVOID*)ppControlNode);
+    hr = CControlNode_fnConstructor(m_pFilter, ulNodeType, PinId, IID_IUnknown, (LPVOID*)ppControlNode);
 
 #ifdef BDAPLGIN_TRACE
     swprintf(Buffer, L"CBDADeviceControl::GetControlNode: hr %lx\n", hr);
index 2d1b7ed..311ddee 100644 (file)
@@ -9,8 +9,10 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
 const GUID IID_IBDA_DigitalDemodulator = {0xef30f379, 0x985b, 0x4d10, {0xb6, 0x40, 0xa7, 0x9d, 0x5e, 0x04, 0xe1, 0xe0}};
 const GUID KSPROPSETID_BdaDigitalDemodulator = {0xef30f379, 0x985b, 0x4d10, {0xb6, 0x40, 0xa7, 0x9d, 0x5e, 0x4, 0xe1, 0xe0}};
+#endif
 
 class CBDADigitalDemodulator : public IBDA_DigitalDemodulator
 {
@@ -48,12 +50,12 @@ public:
     HRESULT STDMETHODCALLTYPE put_SpectralInversion(SpectralInversion *pSpectralInversion);
     HRESULT STDMETHODCALLTYPE get_SpectralInversion(SpectralInversion *pSpectralInversion);
 
-    CBDADigitalDemodulator(HANDLE hFile, ULONG NodeId) : m_Ref(0), m_hFile(hFile), m_NodeId(NodeId){};
+    CBDADigitalDemodulator(IKsPropertySet * pProperty, ULONG NodeId) : m_Ref(0), m_pProperty(pProperty), m_NodeId(NodeId){};
     ~CBDADigitalDemodulator(){};
 
 protected:
     LONG m_Ref;
-    HANDLE m_hFile;
+    IKsPropertySet * m_pProperty;
     ULONG m_NodeId;
 };
 
@@ -86,6 +88,7 @@ CBDADigitalDemodulator::QueryInterface(
     swprintf(Buffer, L"CBDADigitalDemodulator::QueryInterface: NoInterface for %s", lpstr);
     OutputDebugStringW(Buffer);
     CoTaskMemFree(lpstr);
+DebugBreak();
 #endif
 
     return E_NOINTERFACE;
@@ -98,20 +101,17 @@ CBDADigitalDemodulator::put_ModulationType(ModulationType *pModulationType)
     KSP_NODE Node;
     HRESULT hr;
 
-    ULONG BytesReturned;
-
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_MODULATION_TYPE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pModulationType, sizeof(ModulationType), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_MODULATION_TYPE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pModulationType, sizeof(ModulationType));
+
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_ModulationType: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_ModulationType: pModulationType %lu hr %lx\n", *pModulationType, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -131,20 +131,18 @@ CBDADigitalDemodulator::put_InnerFECMethod(FECMethod *pFECMethod)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_INNER_FEC_TYPE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pFECMethod, sizeof(FECMethod), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_INNER_FEC_TYPE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pFECMethod, sizeof(FECMethod));
+
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_InnerFECMethod: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_InnerFECMethod: pFECMethod %lu hr %lx\n", *pFECMethod, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -165,20 +163,16 @@ CBDADigitalDemodulator::put_InnerFECRate(BinaryConvolutionCodeRate *pFECRate)
     KSP_NODE Node;
     HRESULT hr;
 
-    ULONG BytesReturned;
-
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_INNER_FEC_RATE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pFECRate, sizeof(BinaryConvolutionCodeRate), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_INNER_FEC_RATE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pFECRate, sizeof(BinaryConvolutionCodeRate));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_InnerFECRate: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_InnerFECRate: pFECRate %lu hr %lx\n", *pFECRate, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -198,20 +192,17 @@ CBDADigitalDemodulator::put_OuterFECMethod(FECMethod *pFECMethod)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_OUTER_FEC_TYPE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pFECMethod, sizeof(FECMethod), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_OUTER_FEC_TYPE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pFECMethod, sizeof(FECMethod));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_OuterFECMethod: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_OuterFECMethod: pFECMethod %lu hr %lx\n", *pFECMethod, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -232,20 +223,16 @@ CBDADigitalDemodulator::put_OuterFECRate(BinaryConvolutionCodeRate *pFECRate)
     KSP_NODE Node;
     HRESULT hr;
 
-    ULONG BytesReturned;
-
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_OUTER_FEC_RATE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pFECRate, sizeof(BinaryConvolutionCodeRate), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_OUTER_FEC_RATE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pFECRate, sizeof(BinaryConvolutionCodeRate));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_OuterFECRate: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_OuterFECRate: pFECRate %lu hr %lx\n", *pFECRate, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -265,20 +252,17 @@ CBDADigitalDemodulator::put_SymbolRate(ULONG *pSymbolRate)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_SYMBOL_RATE;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pSymbolRate, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_SYMBOL_RATE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pSymbolRate, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_SymbolRate: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_SymbolRate: pSymbolRate %lu hr %lx\n", *pSymbolRate, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -298,20 +282,17 @@ CBDADigitalDemodulator::put_SpectralInversion(SpectralInversion *pSpectralInvers
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaDigitalDemodulator;
-    Node.Property.Id = KSPROPERTY_BDA_SPECTRAL_INVERSION;
-    Node.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), pSpectralInversion, sizeof(SpectralInversion), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaDigitalDemodulator, KSPROPERTY_BDA_SPECTRAL_INVERSION, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), pSpectralInversion, sizeof(SpectralInversion));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDADigitalDemodulator::put_SpectralInversion: hr %lx, BytesReturned %lu\n", hr, BytesReturned);
+    swprintf(Buffer, L"CBDADigitalDemodulator::put_SpectralInversion: pSpectralInversion %lu hr %lx\n", *pSpectralInversion, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -329,13 +310,13 @@ CBDADigitalDemodulator::get_SpectralInversion(SpectralInversion *pSpectralInvers
 HRESULT
 WINAPI
 CBDADigitalDemodulator_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv)
 {
     // construct device control
-    CBDADigitalDemodulator * handler = new CBDADigitalDemodulator(hFile, NodeId);
+    CBDADigitalDemodulator * handler = new CBDADigitalDemodulator(pProperty, NodeId);
 
 #ifdef BDAPLGIN_TRACE
     OutputDebugStringW(L"CBDADigitalDemodulator_fnConstructor\n");
index 90d1e6a..ca3bc46 100644 (file)
@@ -9,8 +9,10 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
 const GUID IID_IBDA_FrequencyFilter = {0x71985f47, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x00, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
 const GUID KSPROPSETID_BdaFrequencyFilter = {0x71985f47, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
+#endif
 
 class CBDAFrequencyFilter : public IBDA_FrequencyFilter
 {
@@ -46,12 +48,12 @@ public:
     HRESULT STDMETHODCALLTYPE put_FrequencyMultiplier(ULONG ulMultiplier);
     HRESULT STDMETHODCALLTYPE get_FrequencyMultiplier(ULONG *pulMultiplier);
 
-    CBDAFrequencyFilter(HANDLE hFile, ULONG NodeId) : m_Ref(0), m_hFile(hFile), m_NodeId(NodeId){};
+    CBDAFrequencyFilter(IKsPropertySet * pProperty, ULONG NodeId) : m_Ref(0), m_pProperty(pProperty), m_NodeId(NodeId){};
     virtual ~CBDAFrequencyFilter(){};
 
 protected:
     LONG m_Ref;
-    HANDLE m_hFile;
+    IKsPropertySet * m_pProperty;
     ULONG m_NodeId;
 };
 
@@ -84,6 +86,7 @@ CBDAFrequencyFilter::QueryInterface(
     swprintf(Buffer, L"CControlNode::QueryInterface: NoInterface for %s", lpstr);
     OutputDebugStringW(Buffer);
     CoTaskMemFree(lpstr);
+DebugBreak();
 #endif
 
     return E_NOINTERFACE;
@@ -110,20 +113,16 @@ CBDAFrequencyFilter::put_Frequency(ULONG ulFrequency)
     KSP_NODE Node;
     HRESULT hr;
 
-    ULONG BytesReturned;
-
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaFrequencyFilter;
-    Node.Property.Id = KSPROPERTY_BDA_RF_TUNER_FREQUENCY;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulFrequency, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaFrequencyFilter, KSPROPERTY_BDA_RF_TUNER_FREQUENCY, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulFrequency, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDAFrequencyFilter::put_Frequency: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDAFrequencyFilter::put_Frequency: m_NodeId %lu ulFrequency %lu hr %lx\n", m_NodeId, ulFrequency, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -143,20 +142,17 @@ CBDAFrequencyFilter::put_Polarity(Polarisation Polarity)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaFrequencyFilter;
-    Node.Property.Id = KSPROPERTY_BDA_RF_TUNER_POLARITY;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &Polarity, sizeof(Polarisation), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaFrequencyFilter, KSPROPERTY_BDA_RF_TUNER_POLARITY, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &Polarity, sizeof(Polarisation));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDAFrequencyFilter::put_Polarity: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDAFrequencyFilter::put_Polarity: m_NodeId %lu Polarity %lu hr %lx\n", m_NodeId, Polarity, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -176,20 +172,17 @@ CBDAFrequencyFilter::put_Range(ULONG ulRange)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaFrequencyFilter;
-    Node.Property.Id = KSPROPERTY_BDA_RF_TUNER_RANGE;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulRange, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaFrequencyFilter, KSPROPERTY_BDA_RF_TUNER_RANGE, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulRange, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDAFrequencyFilter::put_Polarity: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDAFrequencyFilter::put_Range: m_NodeId %lu ulRange %lu hr %lx\n", m_NodeId, ulRange, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -209,20 +202,17 @@ CBDAFrequencyFilter::put_Bandwidth(ULONG ulBandwidth)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaFrequencyFilter;
-    Node.Property.Id = KSPROPERTY_BDA_RF_TUNER_BANDWIDTH;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulBandwidth, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaFrequencyFilter, KSPROPERTY_BDA_RF_TUNER_BANDWIDTH, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulBandwidth, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDAFrequencyFilter::put_Bandwidth: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDAFrequencyFilter::put_Bandwidth: m_NodeId %lu ulBandwidth %lu hr %lx\n", m_NodeId, ulBandwidth, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -241,20 +231,17 @@ CBDAFrequencyFilter::put_FrequencyMultiplier(ULONG ulMultiplier)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaFrequencyFilter;
-    Node.Property.Id = KSPROPERTY_BDA_RF_TUNER_FREQUENCY_MULTIPLIER;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulMultiplier, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaFrequencyFilter, KSPROPERTY_BDA_RF_TUNER_FREQUENCY_MULTIPLIER, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulMultiplier, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDAFrequencyFilter::put_FrequencyMultiplier: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDAFrequencyFilter::put_FrequencyMultiplier: m_NodeId %lu ulMultiplier %lu hr %lx\n", m_NodeId, ulMultiplier, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -271,13 +258,13 @@ CBDAFrequencyFilter::get_FrequencyMultiplier(ULONG *pulMultiplier)
 HRESULT
 WINAPI
 CBDAFrequencyFilter_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet* pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv)
 {
     // construct device control
-    CBDAFrequencyFilter * handler = new CBDAFrequencyFilter(hFile, NodeId);
+    CBDAFrequencyFilter * handler = new CBDAFrequencyFilter(pProperty, NodeId);
 
 #ifdef BDAPLGIN_TRACE
     OutputDebugStringW(L"CBDAFrequencyFilter_fnConstructor\n");
index a663883..689443d 100644 (file)
@@ -9,8 +9,10 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
 const GUID IID_IBDA_LNBInfo = {0x992cf102, 0x49f9, 0x4719, {0xa6, 0x64,  0xc4, 0xf2, 0x3e, 0x24, 0x08, 0xf4}};
 const GUID KSPROPSETID_BdaLNBInfo = {0x992cf102, 0x49f9, 0x4719, {0xa6, 0x64, 0xc4, 0xf2, 0x3e, 0x24, 0x8, 0xf4}};
+#endif
 
 class CBDALNBInfo : public IBDA_LNBInfo
 {
@@ -41,12 +43,12 @@ public:
     HRESULT STDMETHODCALLTYPE put_HighLowSwitchFrequency(ULONG ulSwitchFrequency);
     HRESULT STDMETHODCALLTYPE get_HighLowSwitchFrequency(ULONG *pulSwitchFrequency);
 
-    CBDALNBInfo(HANDLE hFile, ULONG NodeId) : m_Ref(0), m_hFile(hFile), m_NodeId(NodeId){};
+    CBDALNBInfo(IKsPropertySet *pProperty, ULONG NodeId) : m_Ref(0), m_pProperty(pProperty), m_NodeId(NodeId){};
     ~CBDALNBInfo(){};
 
 protected:
     LONG m_Ref;
-    HANDLE m_hFile;
+    IKsPropertySet * m_pProperty;
     ULONG m_NodeId;
 };
 
@@ -90,20 +92,17 @@ CBDALNBInfo::put_LocalOscilatorFrequencyLowBand(ULONG ulLOFLow)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaLNBInfo;
-    Node.Property.Id = KSPROPERTY_BDA_LNB_LOF_LOW_BAND;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulLOFLow, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaLNBInfo, KSPROPERTY_BDA_LNB_LOF_LOW_BAND, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulLOFLow, sizeof(LONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDALNBInfo::put_LocalOscilatorFrequencyLowBand: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDALNBInfo::put_LocalOscilatorFrequencyLowBand: m_NodeId %lu ulLOFLow %lu hr %lx\n", m_NodeId, ulLOFLow, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -123,20 +122,17 @@ CBDALNBInfo::put_LocalOscilatorFrequencyHighBand(ULONG ulLOFHigh)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaLNBInfo;
-    Node.Property.Id = KSPROPERTY_BDA_LNB_LOF_HIGH_BAND;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulLOFHigh, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaLNBInfo, KSPROPERTY_BDA_LNB_LOF_HIGH_BAND, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulLOFHigh, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDALNBInfo::put_LocalOscilatorFrequencyHighBand: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDALNBInfo::put_LocalOscilatorFrequencyHighBand: m_NodeId %lu ulLOFHigh %lu hr %lx\n", m_NodeId, ulLOFHigh, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -156,20 +152,17 @@ CBDALNBInfo::put_HighLowSwitchFrequency(ULONG ulSwitchFrequency)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaLNBInfo;
-    Node.Property.Id = KSPROPERTY_BDA_LNB_SWITCH_FREQUENCY;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = m_NodeId;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &ulSwitchFrequency, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaLNBInfo, KSPROPERTY_BDA_LNB_SWITCH_FREQUENCY, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &ulSwitchFrequency, sizeof(ULONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDALNBInfo::put_HighLowSwitchFrequency: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDALNBInfo::put_HighLowSwitchFrequency: m_NodeId %lu ulSwitchFrequency %lu hr %lx\n", m_NodeId, ulSwitchFrequency, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -186,13 +179,13 @@ CBDALNBInfo::get_HighLowSwitchFrequency(ULONG *pulSwitchFrequency)
 HRESULT
 WINAPI
 CBDALNBInfo_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet *pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv)
 {
     // construct device control
-    CBDALNBInfo * handler = new CBDALNBInfo(hFile, NodeId);
+    CBDALNBInfo * handler = new CBDALNBInfo(pProperty, NodeId);
 
 #ifdef BDAPLGIN_TRACE
     OutputDebugStringW(L"CBDALNBInfo_fnConstructor\n");
index a5b9912..4420b76 100644 (file)
@@ -9,9 +9,12 @@
 
 #include "precomp.h"
 
-const GUID IID_IBDA_PinControl       = {0x0DED49D5, 0xA8B7, 0x4d5d, {0x97, 0xA1, 0x12, 0xB0, 0xC1, 0x95, 0x87, 0x4D}};
+#ifndef _MSC_VER
 const GUID KSPROPSETID_BdaPinControl = {0x0ded49d5, 0xa8b7, 0x4d5d, {0x97, 0xa1, 0x12, 0xb0, 0xc1, 0x95, 0x87, 0x4d}};
+const GUID IID_IBDA_PinControl       = {0x0DED49D5, 0xA8B7, 0x4d5d, {0x97, 0xA1, 0x12, 0xB0, 0xC1, 0x95, 0x87, 0x4D}};
 const GUID IID_IPin = {0x56a86891, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+#endif
+
 
 class CBDAPinControl : public IBDA_PinControl
 {
@@ -39,7 +42,7 @@ public:
     HRESULT STDMETHODCALLTYPE RegistrationContext(ULONG *pulRegistrationCtx);
 
 
-    CBDAPinControl(HANDLE hFile, IBDA_NetworkProvider * pProvider, IPin * pConnectedPin) : m_Ref(0), m_Handle(hFile), m_pProvider(pProvider), m_pConnectedPin(pConnectedPin){};
+    CBDAPinControl(HANDLE hFile, IBDA_NetworkProvider * pProvider, IPin * pConnectedPin, ULONG RegistrationCtx) : m_Ref(0), m_Handle(hFile), m_pProvider(pProvider), m_pConnectedPin(pConnectedPin), m_RegistrationCtx(RegistrationCtx){};
     virtual ~CBDAPinControl()
     {
         //m_pConnectedPin->Release();
@@ -51,6 +54,7 @@ protected:
     HANDLE m_Handle;
     IBDA_NetworkProvider * m_pProvider;
     IPin * m_pConnectedPin;
+    ULONG m_RegistrationCtx;
 };
 
 HRESULT
@@ -72,16 +76,7 @@ CBDAPinControl::QueryInterface(
         reinterpret_cast<IBDA_PinControl*>(*Output)->AddRef();
         return NOERROR;
     }
-
-#ifdef BDAPLGIN_TRACE
-    WCHAR Buffer[MAX_PATH];
-    LPOLESTR lpstr;
-    StringFromCLSID(refiid, &lpstr);
-    swprintf(Buffer, L"CBDAPinControl::QueryInterface: NoInterface for %s", lpstr);
-    OutputDebugStringW(Buffer);
-    CoTaskMemFree(lpstr);
-#endif
-
+DebugBreak();
     return E_NOINTERFACE;
 }
 //-------------------------------------------------------------------
@@ -142,46 +137,124 @@ STDMETHODCALLTYPE
 CBDAPinControl::RegistrationContext(ULONG *pulRegistrationCtx)
 {
 #ifdef BDAPLGIN_TRACE
-    OutputDebugStringW(L"CBDAPinControl::RegistrationContext: NotImplemented\n");
+    OutputDebugStringW(L"CBDAPinControl::RegistrationContext\n");
 #endif
 
-    return E_NOTIMPL;
+    if (!pulRegistrationCtx)
+    {
+        // invalid argument
+        return E_POINTER;
+    }
+
+    if (m_RegistrationCtx)
+    {
+        // is registered
+        *pulRegistrationCtx = m_RegistrationCtx;
+        return NOERROR;
+    }
+
+    //pin not registered
+    return E_FAIL;
 }
 
+//-------------------------------------------------------------------
 HRESULT
-WINAPI
-CBDAPinControl_fnConstructor(
+GetNetworkProviderFromGraph(
+    IFilterGraph * pGraph,
+    IBDA_NetworkProvider ** pOutNetworkProvider)
+{
+    IEnumFilters *pEnumFilters = NULL;
+    IBaseFilter * ppFilter[1];
+    IBDA_NetworkProvider * pNetworkProvider = NULL;
+    HRESULT hr;
+
+    // get IEnumFilters interface
+    hr = pGraph->EnumFilters(&pEnumFilters);
+
+    if (FAILED(hr))
+    {
+        //clean up
+        *pOutNetworkProvider = NULL;
+        return hr;
+    }
+
+    while(pEnumFilters->Next(1, ppFilter, NULL) == S_OK)
+    {
+        // check if that filter supports the IBDA_NetworkProvider interface
+        hr = ppFilter[0]->QueryInterface(IID_IBDA_NetworkProvider, (void**)&pNetworkProvider);
+
+        // release IBaseFilter
+        ppFilter[0]->Release();
+
+        if (SUCCEEDED(hr))
+            break;
+    }
+
+    // release IEnumFilters interface
+    pEnumFilters->Release();
+
+    //store result
+    *pOutNetworkProvider = pNetworkProvider;
+
+    if (pNetworkProvider)
+        return S_OK;
+    else
+        return E_FAIL;
+}
+
+HRESULT
+CBDAPinControl_RealConstructor(
+    HANDLE hPin,
+    IBDA_NetworkProvider *pNetworkProvider,
+    IPin * pConnectedPin,
+    ULONG RegistrationCtx,
     IUnknown * pUnkOuter,
     REFIID riid,
     LPVOID * ppv)
 {
-    IPin * pConnectedPin = NULL;
-    IBDA_NetworkProvider * pNetworkProvider = NULL;
-    HANDLE hFile = INVALID_HANDLE_VALUE;
+    CBDAPinControl * handler = new CBDAPinControl(hPin, pNetworkProvider, pConnectedPin, RegistrationCtx);
 
-#if 0
-    if (!IsEqualGUID(riid, IID_IUnknown))
-    {
 #ifdef BDAPLGIN_TRACE
-    OutputDebugStringW(L"CBDAPinControl_fnConstructor: Expected IUnknown\n");
+    OutputDebugStringW(L"CBDAPinControl_fnConstructor\n");
 #endif
-        return REGDB_E_CLASSNOTREG;
+
+    if (!handler)
+        return E_OUTOFMEMORY;
+
+    if (FAILED(handler->QueryInterface(riid, ppv)))
+    {
+        /* not supported */
+        delete handler;
+        return E_NOINTERFACE;
     }
 
+    return NOERROR;
+}
 
+HRESULT
+WINAPI
+CBDAPinControl_fnConstructor(
+    IUnknown * pUnkOuter,
+    REFIID riid,
+    LPVOID * ppv)
+{
+    IPin * pConnectedPin = NULL;
+    IBDA_NetworkProvider * pNetworkProvider = NULL;
+    HANDLE hFile = INVALID_HANDLE_VALUE;
     HRESULT hr;
     IKsObject * pObject = NULL;
     IPin * pPin = NULL;
-    IEnumFilters *pEnumFilters = NULL;
-
-    IBaseFilter * ppFilter[1];
+    IUnknown * pUnknown = NULL;
     PIN_INFO PinInfo;
     FILTER_INFO FilterInfo;
-
+    ULONG RegistrationCtx = 0;
 
     if (!pUnkOuter)
         return E_POINTER;
 
+    OutputDebugStringW(L"CBDAPinControl_fnConstructor\n");
+    //DebugBreak();
+
     // query for IKsObject interface
     hr = pUnkOuter->QueryInterface(IID_IKsObject, (void**)&pObject);
 
@@ -209,8 +282,15 @@ CBDAPinControl_fnConstructor(
        return hr;
     }
 
+    if (!PinInfo.pFilter)
+    {
+        //clean up
+       pObject->Release();
+       pPin->Release();
+       return hr;
+    }
+
     // sanity checks
-    assert(PinInfo.dir == PINDIR_OUTPUT);
     assert(PinInfo.pFilter != NULL);
 
     // query filter info
@@ -219,57 +299,80 @@ CBDAPinControl_fnConstructor(
     // sanity check
     assert(FilterInfo.pGraph != NULL);
 
-    // get IEnumFilters interface
-    hr = FilterInfo.pGraph->EnumFilters(&pEnumFilters);
-
-    if (FAILED(hr))
-    {
-        //clean up
-       FilterInfo.pGraph->Release();
-       PinInfo.pFilter->Release();
-       pObject->Release();
-       pPin->Release();
-       return hr;
-    }
+    // get network provider interface
+    hr = GetNetworkProviderFromGraph(FilterInfo.pGraph, &pNetworkProvider);
 
-    while(pEnumFilters->Next(1, ppFilter, NULL) == S_OK)
+    if (SUCCEEDED(hr))
     {
-        // check if that filter supports the IBDA_NetworkProvider interface
-        hr = ppFilter[0]->QueryInterface(IID_IBDA_NetworkProvider, (void**)&pNetworkProvider);
-
-        // release IBaseFilter
-        ppFilter[0]->Release();
-
-        if (SUCCEEDED(hr))
-            break;
+        if (PinInfo.dir == PINDIR_OUTPUT)
+        {
+            // get connected pin handle
+            hr = pPin->ConnectedTo(&pConnectedPin);
+            if (SUCCEEDED(hr))
+            {
+                // get file handle
+                hFile = pObject->KsGetObjectHandle();
+                if (hFile)
+                {
+                    hr = CBDAPinControl_RealConstructor(hFile, pNetworkProvider, pConnectedPin, 0, pUnkOuter, riid, ppv);
+                    if (SUCCEEDED(hr))
+                    {
+                        // set to null to prevent releasing
+                        pNetworkProvider = NULL;
+                        pConnectedPin = NULL;
+                    }
+                }
+                else
+                {
+                    // expected file handle
+                    hr = E_UNEXPECTED;
+                }
+            }
+        }
+        else
+        {
+            // get IUnknown from base filter
+            hr = PinInfo.pFilter->QueryInterface(IID_IUnknown, (void**)&pUnknown);
+            if (SUCCEEDED(hr))
+            {
+                // register device filter
+                hr = pNetworkProvider->RegisterDeviceFilter(pUnknown, &RegistrationCtx);
+                if (SUCCEEDED(hr))
+                {
+                    // get file handle
+                    hFile = pObject->KsGetObjectHandle();
+                    if (hFile)
+                    {
+                        hr = CBDAPinControl_RealConstructor(hFile, pNetworkProvider, NULL, RegistrationCtx, pUnkOuter, riid, ppv);
+                        if (SUCCEEDED(hr))
+                        {
+                            // set to null to prevent releasing
+                            pNetworkProvider = NULL;
+                        }
+                    }
+                    else
+                    {
+                        // expected file handle
+                        hr = E_UNEXPECTED;
+                    }
+                }
+                else
+                {
+                    WCHAR Buffer[100];
+                    swprintf(Buffer, L"CBDAPinControl_fnConstructor failed to register filter with %lx\n", hr);
+                    OutputDebugStringW(Buffer);
+                    DebugBreak();
+                }
+            }
+        }
     }
 
-    // release IEnumFilters interface
-    pEnumFilters->Release();
-
     // release IFilterGraph interface
     FilterInfo.pGraph->Release();
 
     // release IBaseFilter interface
     PinInfo.pFilter->Release();
 
-    if (pNetworkProvider)
-    {
-        // get connected pin handle
-        hr = pPin->ConnectedTo(&pConnectedPin);
-
-        // get file handle
-        hFile = pObject->KsGetObjectHandle();
-
-        if (FAILED(hr) || hFile == INVALID_HANDLE_VALUE)
-        {
-            // pin not connected
-            pNetworkProvider->Release();
-            // set zero
-            pNetworkProvider = NULL;
-        }
-    }
-
     // release IPin 
     pPin->Release();
 
@@ -277,30 +380,23 @@ CBDAPinControl_fnConstructor(
     pObject->Release();
 
 
-    if (pNetworkProvider == NULL)
+    if (pNetworkProvider)
     {
-        // no network provider interface in graph
-        return E_NOINTERFACE;
+        // release network provider
+        pNetworkProvider->Release();
     }
-#endif
-
-    CBDAPinControl * handler = new CBDAPinControl(hFile, pNetworkProvider, pConnectedPin);
 
-#ifdef BDAPLGIN_TRACE
-    OutputDebugStringW(L"CBDAPinControl_fnConstructor");
-#endif
-
-    DebugBreak();
-
-    if (!handler)
-        return E_OUTOFMEMORY;
+    if (pConnectedPin)
+    {
+        // release connected pin
+        pConnectedPin->Release();
+    }
 
-    if (FAILED(handler->QueryInterface(riid, ppv)))
+    if (pUnknown)
     {
-        /* not supported */
-        delete handler;
-        return E_NOINTERFACE;
+        // release filter
+        pUnknown->Release();
     }
 
-    return NOERROR;
+    return hr;
 }
index 771a798..1bc9836 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef PRECOMP_H__
 #define PRECOMP_H__
 
-//#define BDAPLGIN_TRACE
+#define BDAPLGIN_TRACE
 #define BUILDING_KS
 #define _KSDDK_
 #include <dshow.h>
@@ -9,6 +9,7 @@
 #include <ks.h>
 #define __STREAMS__
 #include <ksproxy.h>
+#include <ksmedia.h>
 #include <stdio.h>
 #include <wchar.h>
 #include <tchar.h>
@@ -55,7 +56,6 @@ CBDAPinControl_fnConstructor(
 HRESULT
 WINAPI
 CControlNode_fnConstructor(
-    HANDLE hFile,
     IBaseFilter * pFilter,
     ULONG NodeType,
     ULONG PinId,
@@ -67,7 +67,7 @@ CControlNode_fnConstructor(
 HRESULT
 WINAPI
 CBDAFrequencyFilter_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv);
@@ -77,7 +77,7 @@ CBDAFrequencyFilter_fnConstructor(
 HRESULT
 WINAPI
 CBDASignalStatistics_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv);
@@ -87,7 +87,7 @@ CBDASignalStatistics_fnConstructor(
 HRESULT
 WINAPI
 CBDALNBInfo_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv);
@@ -96,9 +96,11 @@ CBDALNBInfo_fnConstructor(
 HRESULT
 WINAPI
 CBDADigitalDemodulator_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv);
 
+extern const GUID IID_IKsObject;
+
 #endif
index ae6079e..230ab8b 100644 (file)
@@ -9,8 +9,10 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
 const GUID IID_IBDA_SignalStatistics = {0x1347d106, 0xcf3a, 0x428a, {0xa5, 0xcb, 0xac, 0x0d, 0x9a, 0x2a, 0x43, 0x38}};
 const GUID KSPROPSETID_BdaSignalStats = {0x1347d106, 0xcf3a, 0x428a, {0xa5, 0xcb, 0xac, 0xd, 0x9a, 0x2a, 0x43, 0x38}};
+#endif
 
 class CBDASignalStatistics : public IBDA_SignalStatistics
 {
@@ -45,12 +47,12 @@ public:
     HRESULT STDMETHODCALLTYPE put_SampleTime(LONG lmsSampleTime);
     HRESULT STDMETHODCALLTYPE get_SampleTime(LONG *plmsSampleTime);
 
-    CBDASignalStatistics(HANDLE hFile, ULONG NodeId) : m_Ref(0), m_hFile(hFile), m_NodeId(NodeId){};
+    CBDASignalStatistics(IKsPropertySet * pProperty, ULONG NodeId) : m_Ref(0), m_pProperty(pProperty), m_NodeId(NodeId){};
     ~CBDASignalStatistics(){};
 
 protected:
     LONG m_Ref;
-    HANDLE m_hFile;
+    IKsPropertySet * m_pProperty;
     ULONG m_NodeId;
 };
 
@@ -75,7 +77,6 @@ CBDASignalStatistics::QueryInterface(
         reinterpret_cast<IBDA_SignalStatistics*>(*Output)->AddRef();
         return NOERROR;
     }
-
     return E_NOINTERFACE;
 }
 
@@ -95,13 +96,13 @@ CBDASignalStatistics::get_SignalStrength(LONG *plDbStrength)
     ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SIGNAL_STRENGTH;
-    Node.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
+
+    assert(m_pProperty);
+
+    hr = m_pProperty->Get(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SIGNAL_STRENGTH, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), plDbStrength, sizeof(LONG), &BytesReturned);
 
-    // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), plDbStrength, sizeof(LONG), &BytesReturned);
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
@@ -128,13 +129,11 @@ CBDASignalStatistics::get_SignalQuality(LONG *plPercentQuality)
     ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SIGNAL_QUALITY;
-    Node.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), plPercentQuality, sizeof(LONG), &BytesReturned);
+    hr = m_pProperty->Get(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SIGNAL_QUALITY, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), plPercentQuality, sizeof(LONG), &BytesReturned);
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
@@ -162,13 +161,12 @@ CBDASignalStatistics::get_SignalPresent(BOOLEAN *pfPresent)
     ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SIGNAL_PRESENT;
-    Node.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &Present, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Get(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SIGNAL_PRESENT, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &Present, sizeof(ULONG), &BytesReturned);
+
     // store result
     *pfPresent = Present;
 
@@ -198,13 +196,12 @@ CBDASignalStatistics::get_SignalLocked(BOOLEAN *pfLocked)
     ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SIGNAL_LOCKED;
-    Node.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &Locked, sizeof(ULONG), &BytesReturned);
+    hr = m_pProperty->Get(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SIGNAL_LOCKED, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &Locked, sizeof(ULONG), &BytesReturned);
+
     *pfLocked = Locked;
 
 #ifdef BDAPLGIN_TRACE
@@ -222,20 +219,17 @@ CBDASignalStatistics::put_SampleTime(LONG lmsSampleTime)
 {
     KSP_NODE Node;
     HRESULT hr;
-    ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SAMPLE_TIME;
-    Node.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), &lmsSampleTime, sizeof(LONG), &BytesReturned);
+    hr = m_pProperty->Set(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SAMPLE_TIME, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), &lmsSampleTime, sizeof(LONG));
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
-    swprintf(Buffer, L"CBDASignalStatistics::put_SampleTime: m_NodeId %lu hr %lx, BytesReturned %lu\n", m_NodeId, hr, BytesReturned);
+    swprintf(Buffer, L"CBDASignalStatistics::put_SampleTime: m_NodeId %lu hr %lx\n", m_NodeId, hr);
     OutputDebugStringW(Buffer);
 #endif
 
@@ -251,13 +245,11 @@ CBDASignalStatistics::get_SampleTime(LONG *plmsSampleTime)
     ULONG BytesReturned;
 
     // setup request
-    Node.Property.Set = KSPROPSETID_BdaSignalStats;
-    Node.Property.Id = KSPROPERTY_BDA_SAMPLE_TIME;
-    Node.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
     Node.NodeId = (ULONG)-1;
+    Node.Reserved = 0;
 
     // perform request
-    hr = KsSynchronousDeviceControl(m_hFile, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), plmsSampleTime, sizeof(LONG), &BytesReturned);
+    hr = m_pProperty->Get(KSPROPSETID_BdaSignalStats, KSPROPERTY_BDA_SAMPLE_TIME, &Node.NodeId, sizeof(KSP_NODE)-sizeof(KSPROPERTY), plmsSampleTime, sizeof(LONG), &BytesReturned);
 
 #ifdef BDAPLGIN_TRACE
     WCHAR Buffer[100];
@@ -271,13 +263,13 @@ CBDASignalStatistics::get_SampleTime(LONG *plmsSampleTime)
 HRESULT
 WINAPI
 CBDASignalStatistics_fnConstructor(
-    HANDLE hFile,
+    IKsPropertySet * pProperty,
     ULONG NodeId,
     REFIID riid,
     LPVOID * ppv)
 {
     // construct device control
-    CBDASignalStatistics * handler = new CBDASignalStatistics(hFile, NodeId);
+    CBDASignalStatistics * handler = new CBDASignalStatistics(pProperty, NodeId);
 
 #ifdef BDAPLGIN_TRACE
     OutputDebugStringW(L"CBDASignalStatistics_fnConstructor\n");
index 2b5cd1a..e7c4b1f 100644 (file)
@@ -15,6 +15,9 @@ class CKsAllocator : public IKsAllocatorEx,
                      public IMemAllocatorCallbackTemp
 {
 public:
+    typedef std::stack<IMediaSample *>MediaSampleStack;
+    typedef std::list<IMediaSample *>MediaSampleList;
+
     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
 
     STDMETHODIMP_(ULONG) AddRef()
@@ -58,9 +61,9 @@ public:
     HRESULT STDMETHODCALLTYPE GetFreeCount(LONG *plBuffersFree);
 
 
-    CKsAllocator() : m_Ref(0), m_hAllocator(0), m_Mode(KsAllocatorMode_User), m_Notify(0), m_Allocated(0), m_FreeCount(0), m_cbBuffer(0), m_cBuffers(0), m_cbAlign(0), m_cbPrefix(0){}
+    CKsAllocator();
     virtual ~CKsAllocator(){}
-
+    VOID STDMETHODCALLTYPE FreeMediaSamples();
 protected:
     LONG m_Ref;
     HANDLE m_hAllocator;
@@ -68,11 +71,16 @@ protected:
     ALLOCATOR_PROPERTIES_EX m_Properties;
     IMemAllocatorNotifyCallbackTemp *m_Notify;
     ULONG m_Allocated;
-    ULONG m_FreeCount;
-    ULONG m_cbBuffer;
-    ULONG m_cBuffers;
-    ULONG m_cbAlign;
-    ULONG m_cbPrefix;
+    LONG m_cbBuffer;
+    LONG m_cBuffers;
+    LONG m_cbAlign;
+    LONG m_cbPrefix;
+    BOOL m_Commited;
+    CRITICAL_SECTION m_CriticalSection;
+    MediaSampleStack m_FreeList;
+    MediaSampleList m_UsedList;
+    LPVOID m_Buffer;
+    BOOL m_FreeSamples;
 };
 
 
@@ -93,14 +101,33 @@ CKsAllocator::QueryInterface(
     if (IsEqualGUID(refiid, IID_IMemAllocator) ||
         IsEqualGUID(refiid, IID_IMemAllocatorCallbackTemp))
     {
-        *Output = (IDistributorNotify*)(this);
-        reinterpret_cast<IDistributorNotify*>(*Output)->AddRef();
+        *Output = (IMemAllocatorCallbackTemp*)(this);
+        reinterpret_cast<IMemAllocatorCallbackTemp*>(*Output)->AddRef();
         return NOERROR;
     }
 
     return E_NOINTERFACE;
 }
 
+CKsAllocator::CKsAllocator() : m_Ref(0), 
+                               m_hAllocator(0), 
+                               m_Mode(KsAllocatorMode_User),
+                               m_Notify(0),
+                               m_Allocated(0),
+                               m_cbBuffer(0),
+                               m_cBuffers(0),
+                               m_cbAlign(0),
+                               m_cbPrefix(0),
+                               m_Commited(FALSE),
+                               m_FreeList(),
+                               m_UsedList(),
+                               m_Buffer(0),
+                               m_FreeSamples(FALSE)
+{
+   InitializeCriticalSection(&m_CriticalSection);
+
+}
+
 //-------------------------------------------------------------------
 // IMemAllocator
 //
@@ -112,7 +139,11 @@ CKsAllocator::SetProperties(
 {
     SYSTEM_INFO SystemInfo;
 
-    OutputDebugStringW(L"CKsAllocator::SetProperties Stub\n");
+    EnterCriticalSection(&m_CriticalSection);
+
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsAllocator::SetProperties\n");
+#endif
 
     if (!pRequest || !pActual)
         return E_POINTER;
@@ -126,18 +157,28 @@ CKsAllocator::SetProperties(
     if (!pRequest->cbAlign || (pRequest->cbAlign - 1) & SystemInfo.dwAllocationGranularity)
     {
         // bad alignment
+        LeaveCriticalSection(&m_CriticalSection);
         return VFW_E_BADALIGN;
     }
 
     if (m_Mode == KsAllocatorMode_Kernel)
     {
-        // u cannt change a kernel allocator
+        // u can't change a kernel allocator
+        LeaveCriticalSection(&m_CriticalSection);
         return VFW_E_ALREADY_COMMITTED;
     }
 
-    if (m_Allocated != m_FreeCount)
+    if (m_Commited)
+    {
+        // need to decommit first
+        LeaveCriticalSection(&m_CriticalSection);
+        return VFW_E_ALREADY_COMMITTED;
+    }
+
+    if (m_Allocated != m_FreeList.size())
     {
         // outstanding buffers
+        LeaveCriticalSection(&m_CriticalSection);
         return VFW_E_BUFFERS_OUTSTANDING;
     }
 
@@ -146,6 +187,7 @@ CKsAllocator::SetProperties(
     pActual->cbPrefix = m_cbPrefix = pRequest->cbPrefix;
     pActual->cBuffers = m_cBuffers = pRequest->cBuffers;
 
+    LeaveCriticalSection(&m_CriticalSection);
     return NOERROR;
 }
 
@@ -169,28 +211,130 @@ HRESULT
 STDMETHODCALLTYPE
 CKsAllocator::Commit()
 {
+    LONG Index;
+    PUCHAR CurrentBuffer;
+    IMediaSample * Sample;
+    HRESULT hr;
+
+    //TODO integer overflow checks
+    EnterCriticalSection(&m_CriticalSection);
+
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsAllocator::Commit\n");
+#endif
+
     if (m_Mode == KsAllocatorMode_Kernel)
     {
         /* no-op for kernel allocator */
+       LeaveCriticalSection(&m_CriticalSection);
        return NOERROR;
     }
 
-    OutputDebugStringW(L"CKsAllocator::Commit NotImplemented\n");
-    return E_NOTIMPL;
+    if (m_Commited)
+    {
+        // already commited
+        LeaveCriticalSection(&m_CriticalSection);
+        return NOERROR;
+    }
+
+    if (m_cbBuffer < 0 || m_cBuffers < 0 || m_cbPrefix < 0)
+    {
+        // invalid parameter
+        LeaveCriticalSection(&m_CriticalSection);
+        return E_OUTOFMEMORY;
+    }
+
+    LONG Size = m_cbBuffer + m_cbPrefix;
+
+    if (m_cbAlign > 1)
+    {
+        //check alignment
+        LONG Mod = Size % m_cbAlign;
+        if (Mod)
+        {
+            // calculate aligned size
+            Size += m_cbAlign - Mod;
+        }
+    }
+
+    LONG TotalSize = Size * m_cBuffers;
+
+    assert(TotalSize);
+    assert(m_cBuffers);
+    assert(Size);
+
+    // now allocate buffer
+    m_Buffer = VirtualAlloc(NULL, TotalSize, MEM_COMMIT, PAGE_READWRITE);
+    if (!m_Buffer)
+    {
+        LeaveCriticalSection(&m_CriticalSection);
+        return E_OUTOFMEMORY;
+    }
+
+    ZeroMemory(m_Buffer, TotalSize);
+
+    CurrentBuffer = (PUCHAR)m_Buffer;
+
+    for (Index = 0; Index < m_cBuffers; Index++)
+    {
+        // construct media sample
+        hr = CMediaSample_Constructor((IMemAllocator*)this, CurrentBuffer + m_cbPrefix, m_cbBuffer, IID_IMediaSample, (void**)&Sample);
+        if (FAILED(hr))
+        {
+            LeaveCriticalSection(&m_CriticalSection);
+            return E_OUTOFMEMORY;
+        }
+
+        // add to free list
+        m_FreeList.push(Sample);
+        m_Allocated++;
+
+        //next sample buffer
+        CurrentBuffer += Size;
+    }
+
+    // we are now commited
+    m_Commited = true;
+
+    LeaveCriticalSection(&m_CriticalSection);
+    return S_OK;
 }
 
 HRESULT
 STDMETHODCALLTYPE
 CKsAllocator::Decommit()
 {
+    EnterCriticalSection(&m_CriticalSection);
+
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsAllocator::Decommit\n");
+#endif
+
     if (m_Mode == KsAllocatorMode_Kernel)
     {
         /* no-op for kernel allocator */
-       return NOERROR;
+        LeaveCriticalSection(&m_CriticalSection);
+        return NOERROR;
     }
 
-    OutputDebugStringW(L"CKsAllocator::Decommit NotImplemented\n");
-    return E_NOTIMPL;
+    m_Commited = false;
+
+    if (m_Allocated != m_FreeList.size())
+    {
+        // outstanding buffers
+        m_FreeSamples = true;
+        LeaveCriticalSection(&m_CriticalSection);
+        return NOERROR;
+    }
+    else
+    {
+        // no outstanding buffers
+        // free to free them
+        FreeMediaSamples();
+    }
+
+    LeaveCriticalSection(&m_CriticalSection);
+    return NOERROR;
 }
 
 
@@ -202,8 +346,50 @@ CKsAllocator::GetBuffer(
     REFERENCE_TIME *pEndTime,
     DWORD dwFlags)
 {
-    OutputDebugStringW(L"CKsAllocator::GetBuffer NotImplemented\n");
-    return E_NOTIMPL;
+    IMediaSample * Sample = NULL;
+
+    if (!m_Commited)
+        return VFW_E_NOT_COMMITTED;
+
+    do
+    {
+        EnterCriticalSection(&m_CriticalSection);
+
+        if (!m_FreeList.empty())
+        {
+            Sample = m_FreeList.top();
+            m_FreeList.pop();
+        }
+
+        LeaveCriticalSection(&m_CriticalSection);
+
+        if (dwFlags & AM_GBF_NOWAIT)
+        {
+            // never wait untill a buffer becomes available
+            break;
+        }
+    }
+    while(Sample == NULL);
+
+    if (!Sample)
+    {
+        // no sample acquired
+        //HACKKKKKKK
+        Sample = m_UsedList.back();
+        m_UsedList.pop_back();
+
+        if (!Sample)
+            return VFW_E_TIMEOUT;
+    }
+
+    // store result
+    *ppBuffer = Sample;
+
+   // store sample in used list
+   m_UsedList.push_front(Sample);
+
+    // done
+    return NOERROR;
 }
 
 HRESULT
@@ -211,8 +397,36 @@ STDMETHODCALLTYPE
 CKsAllocator::ReleaseBuffer(
     IMediaSample *pBuffer)
 {
-    OutputDebugStringW(L"CKsAllocator::ReleaseBuffer NotImplemented\n");
-    return E_NOTIMPL;
+    EnterCriticalSection(&m_CriticalSection);
+
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsAllocator::ReleaseBuffer\n");
+#endif
+
+    // media sample always 1 ref count in free list
+    pBuffer->AddRef();
+
+    // add the sample to the free list
+    m_FreeList.push(pBuffer);
+
+
+    if (m_FreeSamples)
+    {
+        // pending de-commit
+        if (m_FreeList.size () == m_Allocated)
+        {
+            FreeMediaSamples();
+        }
+    }
+
+    if (m_Notify)
+    {
+        //notify caller of an available buffer
+        m_Notify->NotifyRelease();
+    }
+
+    LeaveCriticalSection(&m_CriticalSection);
+    return S_OK;
 }
 
 //-------------------------------------------------------------------
@@ -223,7 +437,11 @@ STDMETHODCALLTYPE
 CKsAllocator::SetNotify(
     IMemAllocatorNotifyCallbackTemp *pNotify)
 {
+    EnterCriticalSection(&m_CriticalSection);
+
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsAllocator::SetNotify\n");
+#endif
 
     if (pNotify)
         pNotify->AddRef();
@@ -232,6 +450,8 @@ CKsAllocator::SetNotify(
         m_Notify->Release();
 
     m_Notify = pNotify;
+
+    LeaveCriticalSection(&m_CriticalSection);
     return NOERROR;
 }
 
@@ -240,8 +460,8 @@ STDMETHODCALLTYPE
 CKsAllocator::GetFreeCount(
     LONG *plBuffersFree)
 {
-    OutputDebugStringW(L"CKsAllocator::GetFreeCount NotImplemented\n");
-    return E_NOTIMPL;
+    *plBuffersFree = m_Allocated - m_FreeList.size();
+    return S_OK;
 }
 
 //-------------------------------------------------------------------
@@ -313,7 +533,9 @@ CKsAllocator::KsCreateAllocatorAndGetHandle(
     KSALLOCATOR_FRAMING AllocatorFraming;
     HANDLE hPin;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsAllocator::KsCreateAllocatorAndGetHandle\n");
+#endif
 
     if (m_hAllocator)
     {
@@ -349,6 +571,32 @@ CKsAllocator::KsCreateAllocatorAndGetHandle(
     return m_hAllocator;
 }
 
+//-------------------------------------------------------------------
+VOID
+STDMETHODCALLTYPE
+CKsAllocator::FreeMediaSamples()
+{
+    ULONG Index;
+
+    for(Index = 0; Index < m_FreeList.size(); Index++)
+    {
+        IMediaSample * Sample = m_FreeList.top();
+        m_FreeList.pop();
+        delete Sample;
+    }
+
+    m_FreeSamples = false;
+    m_Allocated = 0;
+
+    if (m_Buffer)
+    {
+        // release buffer
+        VirtualFree(m_Buffer, 0, MEM_RELEASE);
+
+        m_Buffer = NULL;
+    }
+}
+
 HRESULT
 WINAPI
 CKsAllocator_Constructor(
@@ -356,7 +604,9 @@ CKsAllocator_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsAllocator_Constructor\n");
+#endif
 
     CKsAllocator * handler = new CKsAllocator();
 
index 7fec05f..04c53b3 100644 (file)
@@ -97,7 +97,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsBasicAudio::Stop()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -105,7 +107,10 @@ HRESULT
 STDMETHODCALLTYPE
 CKsBasicAudio::Pause()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -114,7 +119,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::Run(
     REFERENCE_TIME tStart)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -123,7 +131,9 @@ STDMETHODCALLTYPE
 CKsBasicAudio::SetSyncSource(
     IReferenceClock *pClock)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -131,7 +141,10 @@ HRESULT
 STDMETHODCALLTYPE
 CKsBasicAudio::NotifyGraphChange()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -144,7 +157,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::GetTypeInfoCount(
     UINT *pctinfo)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -155,7 +171,9 @@ CKsBasicAudio::GetTypeInfo(
     LCID lcid,
     ITypeInfo **ppTInfo)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -168,7 +186,10 @@ CKsBasicAudio::GetIDsOfNames(
     LCID lcid,
     DISPID *rgDispId)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -184,7 +205,10 @@ CKsBasicAudio::Invoke(
     EXCEPINFO *pExcepInfo,
     UINT *puArgErr)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -197,7 +221,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::put_Volume(
     long lVolume)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -207,7 +234,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::get_Volume(
     long *plVolume)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -217,7 +247,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::put_Balance(
     long lBalance)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -227,7 +260,10 @@ STDMETHODCALLTYPE
 CKsBasicAudio::get_Balance(
     long *plBalance)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -238,7 +274,9 @@ CKsBasicAudio_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsBasicAudio_Constructor\n");
+#endif
 
     CKsBasicAudio * handler = new CKsBasicAudio();
 
index 80bf00f..868633e 100644 (file)
 const GUID KSCATEGORY_CLOCK       = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
 #endif
 
+const GUID IID_IKsClockForwarder              = {0x877e4352, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
+
+DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter);
+
 class CKsClockForwarder : public IDistributorNotify,
                           public IKsObject
 {
@@ -45,14 +49,38 @@ public:
     // IKsObject interface
     HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
 
-    CKsClockForwarder(HANDLE handle) : m_Ref(0), m_Handle(handle){}
-    virtual ~CKsClockForwarder(){ if (m_Handle) CloseHandle(m_Handle);}
-
+    CKsClockForwarder(HANDLE handle);
+    virtual ~CKsClockForwarder(){};
+    HRESULT STDMETHODCALLTYPE SetClockState(KSSTATE State);
 protected:
     LONG m_Ref;
     HANDLE m_Handle;
+    IReferenceClock * m_Clock;
+    HANDLE m_hEvent;
+    HANDLE m_hThread;
+    BOOL m_ThreadStarted;
+    BOOL m_PendingStop;
+    BOOL m_ForceStart;
+    KSSTATE m_State;
+    REFERENCE_TIME m_Time;
+
+    friend DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter);
 };
 
+CKsClockForwarder::CKsClockForwarder(
+    HANDLE handle) : m_Ref(0),
+                     m_Handle(handle),
+                     m_Clock(0),
+                     m_hEvent(NULL),
+                     m_hThread(NULL),
+                     m_ThreadStarted(FALSE),
+                     m_PendingStop(FALSE),
+                     m_ForceStart(FALSE),
+                     m_State(KSSTATE_STOP),
+                     m_Time(0)
+{
+}
+
 HRESULT
 STDMETHODCALLTYPE
 CKsClockForwarder::QueryInterface(
@@ -65,7 +93,8 @@ CKsClockForwarder::QueryInterface(
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
     }
-    if (IsEqualGUID(refiid, IID_IKsObject))
+    if (IsEqualGUID(refiid, IID_IKsObject) ||
+        IsEqualGUID(refiid, IID_IKsClockForwarder))
     {
         *Output = (IKsObject*)(this);
         reinterpret_cast<IKsObject*>(*Output)->AddRef();
@@ -79,15 +108,6 @@ CKsClockForwarder::QueryInterface(
         return NOERROR;
     }
 
-#if 0
-    if (IsEqualGUID(refiid, IID_IKsClockForwarder))
-    {
-        *Output = PVOID(this);
-        reinterpret_cast<IKsObject*>(*Output)->AddRef();
-        return NOERROR;
-    }
-#endif
-
     return E_NOINTERFACE;
 }
 
@@ -100,16 +120,86 @@ HRESULT
 STDMETHODCALLTYPE
 CKsClockForwarder::Stop()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
+    swprintf(Buffer, L"CKsClockForwarder::Stop m_ThreadStarted %u m_PendingStop %u m_hThread %p m_hEvent %p m_Handle %p\n", m_ThreadStarted, m_PendingStop, m_hThread, m_hEvent, m_Handle);
+    OutputDebugStringW(Buffer);
+#endif
+
+    m_Time = 0;
+    if (m_ThreadStarted)
+    {
+        // signal pending stop
+        m_PendingStop = true;
+
+        assert(m_hThread);
+        assert(m_hEvent);
+
+        // set stop event
+        SetEvent(m_hEvent);
+
+        // wait untill the thread has finished
+        WaitForSingleObject(m_hThread, INFINITE);
+
+        // close thread handle
+        CloseHandle(m_hThread);
+
+        // zero handle
+        m_hThread = NULL;
+    }
+
+    if (m_hEvent)
+    {
+        // close stop event
+        CloseHandle(m_hEvent);
+        m_hEvent = NULL;
+    }
+
+    m_PendingStop = false;
+
+    SetClockState(KSSTATE_STOP);
+    return NOERROR;
 }
 
 HRESULT
 STDMETHODCALLTYPE
 CKsClockForwarder::Pause()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    OutputDebugString("CKsClockForwarder::Pause\n");
+#endif
+
+    if (!m_hEvent)
+    {
+        m_hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+        if (!m_hEvent)
+            return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
+    }
+
+    if (m_State <= KSSTATE_PAUSE)
+    {
+        if (m_State == KSSTATE_STOP)
+            SetClockState(KSSTATE_ACQUIRE);
+
+        if (m_State == KSSTATE_ACQUIRE)
+            SetClockState(KSSTATE_PAUSE);
+    }
+    else
+    {
+        if (!m_ForceStart)
+        {
+            SetClockState(KSSTATE_PAUSE);
+        }
+    }
+
+    if (!m_hThread)
+    {
+        m_hThread = CreateThread(NULL, 0, CKsClockForwarder_ThreadStartup, (LPVOID)this, 0, NULL);
+        if (!m_hThread)
+            return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
+    }
+
+    return NOERROR;
 }
 
 HRESULT
@@ -117,8 +207,28 @@ STDMETHODCALLTYPE
 CKsClockForwarder::Run(
     REFERENCE_TIME tStart)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    OutputDebugString("CKsClockForwarder::Run\n");
+#endif
+
+    m_Time = tStart;
+
+    if (!m_hEvent || !m_hThread)
+    {
+        m_ForceStart = TRUE;
+        HRESULT hr = Pause();
+        m_ForceStart = FALSE;
+
+        if (FAILED(hr))
+            return hr;
+    }
+
+    assert(m_hThread);
+
+    SetClockState(KSSTATE_RUN);
+    SetEvent(m_hEvent);
+
+    return NOERROR;
 }
 
 HRESULT
@@ -126,16 +236,30 @@ STDMETHODCALLTYPE
 CKsClockForwarder::SetSyncSource(
     IReferenceClock *pClock)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    OutputDebugString("CKsClockForwarder::SetSyncSource\n");
+#endif
+
+    if (pClock)
+        pClock->AddRef();
+
+    if (m_Clock)
+        m_Clock->Release();
+
+
+    m_Clock = pClock;
+    return NOERROR;
 }
 
 HRESULT
 STDMETHODCALLTYPE
 CKsClockForwarder::NotifyGraphChange()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    OutputDebugString("CKsClockForwarder::NotifyGraphChange\n");
+#endif
+
+    return NOERROR;
 }
 
 //-------------------------------------------------------------------
@@ -149,6 +273,66 @@ CKsClockForwarder::KsGetObjectHandle()
     return m_Handle;
 }
 
+//-------------------------------------------------------------------
+HRESULT
+STDMETHODCALLTYPE
+CKsClockForwarder::SetClockState(KSSTATE State)
+{
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    Property.Set = KSPROPSETID_Clock;
+    Property.Id = KSPROPERTY_CLOCK_STATE;
+    Property.Flags = KSPROPERTY_TYPE_SET;
+
+    HRESULT hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &BytesReturned);
+    if (SUCCEEDED(hr))
+        m_State = State;
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
+    swprintf(Buffer, L"CKsClockForwarder::SetClockState m_State %u State %u hr %lx\n", m_State, State, hr);
+    OutputDebugStringW(Buffer);
+#endif
+
+    return hr;
+}
+
+DWORD
+WINAPI
+CKsClockForwarder_ThreadStartup(LPVOID lpParameter)
+{
+    REFERENCE_TIME Time;
+    ULONG BytesReturned;
+
+    CKsClockForwarder * Fwd = (CKsClockForwarder*)lpParameter;
+
+    Fwd->m_ThreadStarted = TRUE;
+
+    do
+    {
+        if (Fwd->m_PendingStop)
+            break;
+
+        if (Fwd->m_State != KSSTATE_RUN)
+            WaitForSingleObject(Fwd->m_hEvent, INFINITE);
+
+        KSPROPERTY Property;
+        Property.Set = KSPROPSETID_Clock;
+        Property.Id = KSPROPERTY_CLOCK_TIME;
+        Property.Flags = KSPROPERTY_TYPE_SET;
+
+        Fwd->m_Clock->GetTime(&Time);
+        Time -= Fwd->m_Time;
+
+        KsSynchronousDeviceControl(Fwd->m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), &Time, sizeof(REFERENCE_TIME), &BytesReturned);
+    }
+    while(TRUE);
+
+    Fwd->m_ThreadStarted = FALSE;
+    return NOERROR;
+}
+
 HRESULT
 WINAPI
 CKsClockForwarder_Constructor(
@@ -159,14 +343,18 @@ CKsClockForwarder_Constructor(
     HRESULT hr;
     HANDLE handle;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsClockForwarder_Constructor\n");
+#endif
 
     // open default clock
     hr = KsOpenDefaultDevice(KSCATEGORY_CLOCK, GENERIC_READ | GENERIC_WRITE, &handle);
 
     if (hr != NOERROR)
     {
+#ifdef KSPROXY_TRACE
          OutputDebugString("CKsClockForwarder_Constructor failed to open device\n");
+#endif
          return hr;
     }
 
index 91d2006..1333263 100644 (file)
@@ -102,7 +102,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPConfig::Stop()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -110,7 +112,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPConfig::Pause()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -119,7 +123,9 @@ STDMETHODCALLTYPE
 CVPConfig::Run(
     REFERENCE_TIME tStart)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -128,7 +134,9 @@ STDMETHODCALLTYPE
 CVPConfig::SetSyncSource(
     IReferenceClock *pClock)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -136,7 +144,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPConfig::NotifyGraphChange()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -149,7 +159,9 @@ CVPConfig::GetConnectInfo(
     LPDWORD pdwNumConnectInfo, 
     IN OUT LPDDVIDEOPORTCONNECT pddVPConnectInfo)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -158,7 +170,9 @@ STDMETHODCALLTYPE
 CVPConfig::SetConnectInfo(
     DWORD dwChosenEntry)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -167,7 +181,9 @@ STDMETHODCALLTYPE
 CVPConfig::GetVPDataInfo(
     LPAMVPDATAINFO pamvpDataInfo)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -177,7 +193,9 @@ CVPConfig::GetMaxPixelRate(
     LPAMVPSIZE pamvpSize,
     OUT LPDWORD pdwMaxPixelsPerSecond)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -187,7 +205,9 @@ CVPConfig::InformVPInputFormats(
     DWORD dwNumFormats,
     IN LPDDPIXELFORMAT pDDPixelFormats)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -197,7 +217,9 @@ CVPConfig::GetVideoFormats(
     LPDWORD pdwNumFormats, 
     IN OUT LPDDPIXELFORMAT pddPixelFormats)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -206,7 +228,9 @@ STDMETHODCALLTYPE
 CVPConfig::SetVideoFormat(
     DWORD dwChosenEntry)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -214,7 +238,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPConfig::SetInvertPolarity()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -223,7 +249,9 @@ STDMETHODCALLTYPE
 CVPConfig::GetOverlaySurface(
     LPDIRECTDRAWSURFACE* ppddOverlaySurface)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -232,7 +260,9 @@ STDMETHODCALLTYPE
 CVPConfig::SetDirectDrawKernelHandle(
     ULONG_PTR dwDDKernelHandle)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -241,7 +271,9 @@ STDMETHODCALLTYPE
 CVPConfig::SetVideoPortID(
     IN DWORD dwVideoPortID)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -252,7 +284,9 @@ CVPConfig::SetDDSurfaceKernelHandles(
     DWORD cHandles,
     IN ULONG_PTR *rgDDKernelHandles)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -264,7 +298,9 @@ CVPConfig::SetSurfaceParameters(
     IN DWORD dwXOrigin,
     IN DWORD dwYOrigin)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -277,7 +313,9 @@ STDMETHODCALLTYPE
 CVPConfig::IsVPDecimationAllowed(
     LPBOOL pbIsDecimationAllowed)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -286,13 +324,13 @@ STDMETHODCALLTYPE
 CVPConfig::SetScalingFactors(
     LPAMVPSIZE pamvpSize)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
 
-
-
 HRESULT
 WINAPI
 CVPConfig_Constructor(
@@ -300,7 +338,9 @@ CVPConfig_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CVPConfig_Constructor\n");
+#endif
 
     CVPConfig * handler = new CVPConfig();
 
index 016d060..b7b7130 100644 (file)
@@ -98,7 +98,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPVBIConfig::Stop()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -106,7 +108,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPVBIConfig::Pause()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -115,7 +119,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::Run(
     REFERENCE_TIME tStart)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -124,7 +130,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::SetSyncSource(
     IReferenceClock *pClock)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -132,7 +140,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPVBIConfig::NotifyGraphChange()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -145,7 +155,9 @@ CVPVBIConfig::GetConnectInfo(
     LPDWORD pdwNumConnectInfo, 
     IN OUT LPDDVIDEOPORTCONNECT pddVPConnectInfo)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -154,7 +166,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::SetConnectInfo(
     DWORD dwChosenEntry)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -163,7 +177,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::GetVPDataInfo(
     LPAMVPDATAINFO pamvpDataInfo)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -173,7 +189,9 @@ CVPVBIConfig::GetMaxPixelRate(
     LPAMVPSIZE pamvpSize,
     OUT LPDWORD pdwMaxPixelsPerSecond)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -183,7 +201,9 @@ CVPVBIConfig::InformVPInputFormats(
     DWORD dwNumFormats,
     IN LPDDPIXELFORMAT pDDPixelFormats)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -193,7 +213,9 @@ CVPVBIConfig::GetVideoFormats(
     LPDWORD pdwNumFormats, 
     IN OUT LPDDPIXELFORMAT pddPixelFormats)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -202,7 +224,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::SetVideoFormat(
     DWORD dwChosenEntry)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -210,7 +234,9 @@ HRESULT
 STDMETHODCALLTYPE
 CVPVBIConfig::SetInvertPolarity()
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+ #ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -219,7 +245,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::GetOverlaySurface(
     LPDIRECTDRAWSURFACE* ppddOverlaySurface)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -228,7 +256,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::SetDirectDrawKernelHandle(
     ULONG_PTR dwDDKernelHandle)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -237,7 +267,9 @@ STDMETHODCALLTYPE
 CVPVBIConfig::SetVideoPortID(
     IN DWORD dwVideoPortID)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -248,7 +280,9 @@ CVPVBIConfig::SetDDSurfaceKernelHandles(
     DWORD cHandles,
     IN ULONG_PTR *rgDDKernelHandles)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -260,7 +294,9 @@ CVPVBIConfig::SetSurfaceParameters(
     IN DWORD dwXOrigin,
     IN DWORD dwYOrigin)
 {
-    OutputDebugString("UNIMPLEMENTED\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"UNIMPLEMENTED\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -272,7 +308,9 @@ CVPVBIConfig_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CVPVBIConfig_Constructor\n");
+#endif
 
     CVPVBIConfig * handler = new CVPVBIConfig();
 
index 5006b68..965e847 100644 (file)
@@ -103,7 +103,9 @@ CKsDataTypeHandler::KsIsMediaTypeInRanges(
     ULONG Index;
     HRESULT hr = S_FALSE;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsDataTypeHandler::KsIsMediaTypeInRanges\n");
+#endif
 
     DataList = (PKSMULTIPLE_ITEM)DataRanges;
     DataRange = (PKSDATARANGE)(DataList + 1);
@@ -187,7 +189,9 @@ STDMETHODCALLTYPE
 CKsDataTypeHandler::KsSetMediaType(
     IN const AM_MEDIA_TYPE* AmMediaType)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugString("CKsDataTypeHandler::KsSetMediaType\n");
+#endif
 
     if (m_Type)
     {
@@ -228,7 +232,10 @@ CKsDataTypeHandler_Constructor (
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsDataTypeHandler_Constructor\n");
+#endif
+
     CKsDataTypeHandler * handler = new CKsDataTypeHandler();
 
     if (!handler)
index 462ffda..db2c7a0 100644 (file)
@@ -64,13 +64,6 @@ CEnumMediaTypes::QueryInterface(
         return NOERROR;
     }
 
-    WCHAR Buffer[MAX_PATH];
-    LPOLESTR lpstr;
-    StringFromCLSID(refiid, &lpstr);
-    swprintf(Buffer, L"CEnumMediaTypes::QueryInterface: NoInterface for %s\n", lpstr);
-    OutputDebugStringW(Buffer);
-    CoTaskMemFree(lpstr);
-
     return E_NOINTERFACE;
 }
 
@@ -171,7 +164,9 @@ STDMETHODCALLTYPE
 CEnumMediaTypes::Clone(
     IEnumMediaTypes **ppEnum)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CEnumMediaTypes::Clone : NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -189,7 +184,7 @@ CEnumMediaTypes_fnConstructor(
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
     StringFromCLSID(riid, &lpstr);
-    swprintf(Buffer, L"CEnumMediaTypes_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
+    swprintf(Buffer, L"CEnumMediaTypes_fnConstructor riid %s\n", lpstr);
     OutputDebugStringW(Buffer);
 #endif
 
index 5c0f0ec..a6c3bdf 100644 (file)
@@ -64,6 +64,14 @@ CEnumPins::QueryInterface(
         return NOERROR;
     }
 
+    WCHAR Buffer[100];
+    LPOLESTR lpstr;
+    StringFromCLSID(refiid, &lpstr);
+    swprintf(Buffer, L"CEnumPins::QueryInterface: NoInterface for %s\n", lpstr);
+    OutputDebugStringW(Buffer);
+    CoTaskMemFree(lpstr);
+
+DebugBreak();
     return E_NOINTERFACE;
 }
 
@@ -132,7 +140,10 @@ STDMETHODCALLTYPE
 CEnumPins::Clone(
     IEnumPins **ppEnum)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CEnumPins::Clone : NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
index ef1cb54..51b7872 100644 (file)
@@ -62,6 +62,8 @@ class CInputPin : public IPin,
                   public ISpecifyPropertyPages
 {
 public:
+    typedef std::vector<IUnknown *>ProxyPluginVector;
+
     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
 
     STDMETHODIMP_(ULONG) AddRef()
@@ -170,14 +172,15 @@ public:
     HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
     HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
     HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
-    CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication);
+    HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids);
+    HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids);
+    CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication);
     virtual ~CInputPin(){};
 
 protected:
     LONG m_Ref;
     IBaseFilter * m_ParentFilter;
     LPCWSTR m_PinName;
-    HANDLE m_hFilter;
     HANDLE m_hPin;
     ULONG m_PinId;
     IMemAllocator * m_MemAllocator;
@@ -196,17 +199,16 @@ protected:
     LPWSTR m_FilterName;
     FRAMING_PROP m_FramingProp[4];
     PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
+    ProxyPluginVector m_Plugins;
 };
 
 CInputPin::CInputPin(
-    IBaseFilter * ParentFilter, 
+    IBaseFilter * ParentFilter,
     LPCWSTR PinName,
-    HANDLE hFilter,
     ULONG PinId,
     KSPIN_COMMUNICATION Communication) : m_Ref(0),
                                          m_ParentFilter(ParentFilter),
                                          m_PinName(PinName),
-                                         m_hFilter(hFilter),
                                          m_hPin(INVALID_HANDLE_VALUE),
                                          m_PinId(PinId),
                                          m_MemAllocator(0),
@@ -218,13 +220,27 @@ CInputPin::CInputPin(
                                          m_KsAllocatorEx(0),
                                          m_PipeAllocatorFlag(0),
                                          m_bPinBusCacheInitialized(0),
-                                         m_FilterName(0)
+                                         m_FilterName(0),
+                                         m_Plugins()
 {
     ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
     ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
 
+    HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    assert(hr == S_OK);
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+    assert(hFilter);
+
+    KsObjectParent->Release();
+
+
     ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE));
-    HRESULT hr = KsGetMediaType(0, &m_MediaFormat, m_hFilter, m_PinId);
+    hr = KsGetMediaType(0, &m_MediaFormat, hFilter, m_PinId);
     assert(hr == S_OK);
 }
 
@@ -346,7 +362,10 @@ CInputPin::Notify(
     IBaseFilter *pSelf,
     Quality q)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Notify NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -355,7 +374,10 @@ STDMETHODCALLTYPE
 CInputPin::SetSink(
     IQualityControl *piqc)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::SetSink NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -368,7 +390,10 @@ STDMETHODCALLTYPE
 CInputPin::KsAddAggregate(
     IN REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::KsAddAggregate NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -377,7 +402,10 @@ STDMETHODCALLTYPE
 CInputPin::KsRemoveAggregate(
     REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::KsRemoveAggregate NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -401,7 +429,10 @@ CInputPin::Backout(
     IPin *ppinOut, 
     IGraphBuilder *pGraph)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Backout\n");
+#endif
+
     return S_OK;
 }
 
@@ -414,7 +445,10 @@ STDMETHODCALLTYPE
 CInputPin::KsPinFactory(
     ULONG* PinFactory)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::KsPinFactory\n");
+#endif
+
     *PinFactory = m_PinId;
     return S_OK;
 }
@@ -590,7 +624,10 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::GetAllocator(IMemAllocator **ppAllocator)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::GetAllocator\n");
+#endif
+
     return VFW_E_NO_ALLOCATOR;
 }
 
@@ -598,13 +635,16 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
 {
-    WCHAR Buffer[100];
     HRESULT hr;
     ALLOCATOR_PROPERTIES Properties;
 
     hr = pAllocator->GetProperties(&Properties);
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
     swprintf(Buffer, L"CInputPin::NotifyAllocator hr %lx bReadOnly, %u cbAlign %u cbBuffer %u cbPrefix %u cBuffers %u\n", hr, bReadOnly, Properties.cbAlign, Properties.cbBuffer, Properties.cbPrefix, Properties.cBuffers);
     OutputDebugStringW(Buffer);
+#endif
 
     if (pAllocator)
     {
@@ -645,9 +685,11 @@ CInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
     else
         hr = E_NOTIMPL;
 
+#ifdef KSPROXY_TRACE
     WCHAR Buffer[100];
     swprintf(Buffer, L"CInputPin::GetAllocatorRequirements hr %lx m_hPin %p cBuffers %u cbBuffer %u cbAlign %u cbPrefix %u\n", hr, m_hPin, pProps->cBuffers, pProps->cbBuffer, pProps->cbAlign, pProps->cbPrefix);
     OutputDebugStringW(Buffer);
+#endif
 
     return hr;
 }
@@ -656,7 +698,11 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::Receive(IMediaSample *pSample)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");
+    DebugBreak();
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -664,7 +710,11 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");
+    DebugBreak();
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -672,7 +722,11 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::ReceiveCanBlock( void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");
+    DebugBreak();
+#endif
+
     return S_FALSE;
 }
 
@@ -685,7 +739,22 @@ STDMETHODCALLTYPE
 CInputPin::KsQueryMediums(
     PKSMULTIPLE_ITEM* MediumList)
 {
-    return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
+    HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
+    return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
 }
 
 HRESULT
@@ -693,7 +762,22 @@ STDMETHODCALLTYPE
 CInputPin::KsQueryInterfaces(
     PKSMULTIPLE_ITEM* InterfaceList)
 {
-    return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
+    HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
+    return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
 }
 
 HRESULT
@@ -744,8 +828,6 @@ CInputPin::KsPropagateAcquire()
     ULONG BytesReturned;
     HRESULT hr;
 
-    OutputDebugStringW(L"CInputPin::KsPropagateAcquire\n");
-
     assert(m_hPin != INVALID_HANDLE_VALUE);
 
     Property.Set = KSPROPSETID_Connection;
@@ -837,7 +919,11 @@ CInputPin::KsQualityNotify(
     ULONG Proportion,
     REFERENCE_TIME TimeDelta)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");
+#endif
+
+    DebugBreak();
     return E_NOTIMPL;
 }
 
@@ -851,7 +937,9 @@ CInputPin::KsNotifyError(
     IMediaSample* Sample,
     HRESULT hr)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n");
+#endif
 }
 
 
@@ -1024,7 +1112,10 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
+    DebugBreak();
+#endif
     return NOERROR;
 }
 
@@ -1075,7 +1166,10 @@ CInputPin::Disconnect( void)
     m_Pin->Release();
     m_Pin = NULL;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Disconnect\n");
+#endif
+
     return S_OK;
 }
 HRESULT
@@ -1103,7 +1197,11 @@ CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
     if (!m_Pin)
         return VFW_E_NOT_CONNECTED;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n");
+    DebugBreak();
+#endif
+
     return E_NOTIMPL;
 }
 HRESULT
@@ -1155,9 +1253,23 @@ CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
     HRESULT hr;
     ULONG MediaTypeCount = 0, Index;
     AM_MEDIA_TYPE * MediaTypes;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
 
     // query media type count
-    hr = KsGetMediaTypeCount(m_hFilter, m_PinId, &MediaTypeCount);
+    hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
     if (FAILED(hr) || !MediaTypeCount)
         return hr;
 
@@ -1175,7 +1287,7 @@ CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
     for(Index = 0; Index < MediaTypeCount; Index++)
     {
         // get media type
-        hr = KsGetMediaType(Index, &MediaTypes[Index], m_hFilter, m_PinId);
+        hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId);
         if (FAILED(hr))
         {
             // failed
@@ -1191,35 +1303,45 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::EndOfStream( void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::BeginFlush( void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::EndFlush( void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -1233,11 +1355,25 @@ CInputPin::CheckFormat(
     PKSMULTIPLE_ITEM MultipleItem;
     PKSDATAFORMAT DataFormat;
     HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
 
     if (!pmt)
         return E_POINTER;
 
-    hr = KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem);
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
+
+    hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem);
     if (FAILED(hr))
         return S_FALSE;
 
@@ -1250,7 +1386,9 @@ CInputPin::CheckFormat(
         {
             // format is supported
             CoTaskMemFree(MultipleItem);
+#ifdef KSPROXY_TRACE
             OutputDebugStringW(L"CInputPin::CheckFormat format OK\n");
+#endif
             return S_OK;
         }
         DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize);
@@ -1317,7 +1455,9 @@ CInputPin::CreatePin(
             if (FAILED(hr))
             {
                 // failed to load interface handler plugin
+#ifdef KSPROXY_TRACE
                 OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
+#endif
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
 
@@ -1329,7 +1469,9 @@ CInputPin::CreatePin(
             if (FAILED(hr))
             {
                 // failed to load interface handler plugin
+#ifdef KSPROXY_TRACE
                 OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
+#endif
                 InterfaceHandler->Release();
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
@@ -1350,10 +1492,12 @@ CInputPin::CreatePin(
     }
     else
     {
+#ifdef KSPROXY_TRACE
         WCHAR Buffer[100];
         swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName);
         OutputDebugStringW(Buffer);
         DebugBreak();
+#endif
         hr = E_FAIL;
     }
 
@@ -1375,6 +1519,23 @@ CInputPin::CreatePinHandle(
     PKSDATAFORMAT DataFormat;
     ULONG Length;
     HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
+
+    if (!pmt)
+        return E_POINTER;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
 
     if (m_hPin != INVALID_HANDLE_VALUE)
     {
@@ -1423,7 +1584,7 @@ CInputPin::CreatePinHandle(
     }
 
     // create pin
-    hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
+    hr = KsCreatePin(hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
 
     if (SUCCEEDED(hr))
     {
@@ -1432,16 +1593,19 @@ CInputPin::CreatePinHandle(
         CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE));
         CopyMemory(&m_MediaFormat, pmt, sizeof(AM_MEDIA_TYPE));
 
+#ifdef KSPROXY_TRACE
         LPOLESTR pMajor, pSub, pFormat;
         StringFromIID(m_MediaFormat.majortype, &pMajor);
         StringFromIID(m_MediaFormat.subtype , &pSub);
         StringFromIID(m_MediaFormat.formattype, &pFormat);
+
         WCHAR Buffer[200];
         swprintf(Buffer, L"CInputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor, pSub, pFormat, pmt->pbFormat, pmt->cbFormat);
         CoTaskMemFree(pMajor);
         CoTaskMemFree(pSub);
         CoTaskMemFree(pFormat);
         OutputDebugStringW(Buffer);
+#endif
 
         if (pmt->cbFormat)
         {
@@ -1456,6 +1620,35 @@ CInputPin::CreatePinHandle(
             CopyMemory(m_MediaFormat.pbFormat, pmt->pbFormat, pmt->cbFormat);
         }
 
+        LPGUID pGuid;
+        ULONG NumGuids = 0;
+
+        // get all supported sets
+        hr = GetSupportedSets(&pGuid, &NumGuids);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n");
+            DebugBreak();
+#endif
+            return hr;
+        }
+
+        // load all proxy plugins
+        hr = LoadProxyPlugins(pGuid, NumGuids);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
+            DebugBreak();
+#endif
+            return hr;
+        }
+
+        // free sets
+        CoTaskMemFree(pGuid);
+
+
         //TODO
         // connect pin pipes
 
@@ -1467,6 +1660,140 @@ CInputPin::CreatePinHandle(
     return hr;
 }
 
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::GetSupportedSets(
+    LPGUID * pOutGuid,
+    PULONG NumGuids)
+{
+    KSPROPERTY Property;
+    LPGUID pGuid;
+    ULONG NumProperty = 0;
+    ULONG NumMethods = 0;
+    ULONG NumEvents = 0;
+    ULONG Length;
+    ULONG BytesReturned;
+    HRESULT hr;
+
+    Property.Set = GUID_NULL;
+    Property.Id = 0;
+    Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
+
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty);
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods);
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents);
+
+    Length = NumProperty + NumMethods + NumEvents;
+
+    assert(Length);
+
+    // allocate guid buffer
+    pGuid = (LPGUID)CoTaskMemAlloc(Length);
+    if (!pGuid)
+    {
+        // failed
+        return E_OUTOFMEMORY;
+    }
+
+    NumProperty /= sizeof(GUID);
+    NumMethods /= sizeof(GUID);
+    NumEvents /= sizeof(GUID);
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
+    swprintf(Buffer, L"CInputPin::GetSupportedSets NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents);
+    OutputDebugStringW(Buffer);
+#endif
+
+    // get all properties
+    hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned);
+    if (FAILED(hr))
+    {
+        CoTaskMemFree(pGuid);
+        return E_FAIL;
+    }
+    Length -= BytesReturned;
+
+    // get all methods
+    if (Length && NumMethods)
+    {
+        hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned);
+        if (FAILED(hr))
+        {
+            CoTaskMemFree(pGuid);
+            return E_FAIL;
+        }
+        Length -= BytesReturned;
+    }
+
+    // get all events
+    if (Length && NumEvents)
+    {
+        hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned);
+        if (FAILED(hr))
+        {
+            CoTaskMemFree(pGuid);
+            return E_FAIL;
+        }
+        Length -= BytesReturned;
+    }
+
+    *pOutGuid = pGuid;
+    *NumGuids = NumProperty+NumEvents+NumMethods;
+    return S_OK;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::LoadProxyPlugins(
+    LPGUID pGuids,
+    ULONG NumGuids)
+{
+    ULONG Index;
+    LPOLESTR pStr;
+    HKEY hKey, hSubKey;
+    HRESULT hr;
+    IUnknown * pUnknown;
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+    {
+        OutputDebugStringW(L"CInputPin::LoadProxyPlugins failed to open MediaInterfaces key\n");
+        return E_FAIL;
+    }
+
+    // enumerate all sets
+    for(Index = 0; Index < NumGuids; Index++)
+    {
+        // convert to string
+        hr = StringFromCLSID(pGuids[Index], &pStr);
+        if (FAILED(hr))
+            return E_FAIL;
+
+        // now try open class key
+        if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
+        {
+            // no plugin for that set exists
+            CoTaskMemFree(pStr);
+            continue;
+        }
+
+        // try load plugin
+        hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
+        if (SUCCEEDED(hr))
+        {
+            // store plugin
+            m_Plugins.push_back(pUnknown);
+DebugBreak();
+        }
+        // close key
+        RegCloseKey(hSubKey);
+    }
+
+    // close media interfaces key
+    RegCloseKey(hKey);
+    return S_OK;
+}
+
 HRESULT
 WINAPI
 CInputPin_Constructor(
@@ -1478,7 +1805,7 @@ CInputPin_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
-    CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId, Communication);
+    CInputPin * handler = new CInputPin(ParentFilter, PinName, PinId, Communication);
 
     if (!handler)
         return E_OUTOFMEMORY;
index 930f7e0..7eb0fd2 100644 (file)
@@ -35,24 +35,25 @@ public:
     HRESULT STDMETHODCALLTYPE KsProcessMediaSamples(IKsDataTypeHandler *KsDataTypeHandler, IMediaSample** SampleList, PLONG SampleCount, KSIOOPERATION IoOperation, PKSSTREAM_SEGMENT *StreamSegment);
     HRESULT STDMETHODCALLTYPE KsCompleteIo(PKSSTREAM_SEGMENT StreamSegment);
 
-    CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL), m_Pin(0){};
+    CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL), m_Pin(0) {m_PinName[0] = L'\0';};
     virtual ~CKsInterfaceHandler(){};
 
 protected:
     LONG m_Ref;
     HANDLE m_Handle;
     IKsPinEx * m_Pin;
+    WCHAR m_PinName[129];
 };
 
 typedef struct
 {
     KSSTREAM_SEGMENT StreamSegment;
+    OVERLAPPED Overlapped;
     IMediaSample * MediaSample[64];
 
     ULONG SampleCount;
     ULONG ExtendedSize;
     PKSSTREAM_HEADER StreamHeader;
-    OVERLAPPED Overlapped;
 }KSSTREAM_SEGMENT_EXT, *PKSSTREAM_SEGMENT_EXT;
 
 
@@ -118,6 +119,22 @@ CKsInterfaceHandler::KsSetPin(
             Pin->Release();
         }
     }
+#if 1
+    //DBG code
+    PIN_INFO PinInfo;
+    IPin * pPin;
+    if (SUCCEEDED(KsPin->QueryInterface(IID_IPin, (void**)&pPin)))
+    {
+        if (SUCCEEDED(pPin->QueryPinInfo(&PinInfo)))
+        {
+            if (PinInfo.pFilter)
+                PinInfo.pFilter->Release();
+
+            wcscpy(m_PinName, PinInfo.achName);
+        }
+        pPin->Release();
+    }
+#endif
 
     // done
     return hr;
@@ -136,8 +153,6 @@ CKsInterfaceHandler::KsProcessMediaSamples(
     ULONG ExtendedSize, Index, BytesReturned;
     HRESULT hr = S_OK;
 
-    OutputDebugString("CKsInterfaceHandler::KsProcessMediaSamples\n");
-
     // sanity check
     assert(*SampleCount);
 
@@ -237,6 +252,7 @@ CKsInterfaceHandler::KsProcessMediaSamples(
          // query for IMediaSample2 interface
          IMediaSample2 * MediaSample;
          AM_SAMPLE2_PROPERTIES Properties;
+         ZeroMemory(&Properties, sizeof(AM_SAMPLE2_PROPERTIES));
 
          hr = SampleList[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
          if (SUCCEEDED(hr))
@@ -254,7 +270,9 @@ CKsInterfaceHandler::KsProcessMediaSamples(
              hr = SampleList[Index]->GetPointer((BYTE**)&Properties.pbBuffer);
              assert(hr == NOERROR);
              hr = SampleList[Index]->GetTime(&Properties.tStart, &Properties.tStop);
-             assert(hr == NOERROR);
+
+             Properties.cbBuffer = SampleList[Index]->GetSize();
+             assert(Properties.cbBuffer);
 
              Properties.dwSampleFlags = 0;
 
@@ -267,10 +285,11 @@ CKsInterfaceHandler::KsProcessMediaSamples(
              if (SampleList[Index]->IsSyncPoint() == S_OK)
                  Properties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
          }
-
-         WCHAR Buffer[100];
-         swprintf(Buffer, L"BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u\n", Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual);
+#ifdef KSPROXY_TRACE
+         WCHAR Buffer[200];
+         swprintf(Buffer, L"CKsInterfaceHandler::KsProcessMediaSamples PinName %s BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u dwSampleFlags %lx\n", m_PinName, Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual, Properties.dwSampleFlags);
          OutputDebugStringW(Buffer);
+#endif
 
          CurStreamHeader->Size = sizeof(KSSTREAM_HEADER) + ExtendedSize;
          CurStreamHeader->PresentationTime.Denominator = 1;
@@ -336,8 +355,6 @@ CKsInterfaceHandler::KsCompleteIo(
     AM_SAMPLE2_PROPERTIES Properties;
     REFERENCE_TIME Start, Stop;
 
-    OutputDebugStringW(L"CKsInterfaceHandler::KsCompleteIo\n");
-
     // get private stream segment
     StreamSegment = (PKSSTREAM_SEGMENT_EXT)InStreamSegment;
 
@@ -463,7 +480,9 @@ CKsInterfaceHandler_Constructor(
     REFIID riid,
     LPVOID * ppv)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsInterfaceHandler_Constructor\n");
+#endif
 
     CKsInterfaceHandler * handler = new CKsInterfaceHandler();
 
index f79a154..f1e17c9 100644 (file)
@@ -117,7 +117,7 @@ KsOpenDefaultDevice(
     WCHAR Path[MAX_PATH+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)];
 
     /* open device list */
-    hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE  /* | DIGCF_PRESENT*/);
+    hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE  | DIGCF_PRESENT);
 
     if (hList == INVALID_HANDLE_VALUE)
     {
@@ -129,7 +129,7 @@ KsOpenDefaultDevice(
     DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
     DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 
-    if (SetupDiEnumDeviceInterfaces(hList, &DeviceInfoData, &Category, 0, &DeviceInterfaceData))
+    if (SetupDiEnumDeviceInterfaces(hList, NULL, &Category, 0, &DeviceInterfaceData))
     {
         /* setup interface data struct */
         DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)Path;
index 269d986..86cd50a 100644 (file)
@@ -33,6 +33,7 @@
        <file>interface.cpp</file>
        <file>ksproxy.cpp</file>
        <file>ksproxy.rc</file>
+       <file>mediasample.cpp</file>
        <file>node.cpp</file>
        <file>output_pin.cpp</file>
        <file>proxy.cpp</file>
index d2686bb..d308225 100644 (file)
@@ -124,7 +124,9 @@ CKsNode_Constructor(
     HANDLE handle;
     KSNODE_CREATE NodeCreate;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsNode_Constructor\n");
+#endif
 
     //setup request
     NodeCreate.CreateFlags = 0;
index c5d897c..17f0780 100644 (file)
@@ -26,6 +26,8 @@ class COutputPin : public IPin,
 
 {
 public:
+    typedef std::vector<IUnknown *>ProxyPluginVector;
+
     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
 
     STDMETHODIMP_(ULONG) AddRef()
@@ -160,6 +162,13 @@ public:
     HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
     HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
     HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
+    HRESULT WINAPI IoProcessRoutine();
+    HRESULT WINAPI InitializeIOThread();
+    HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids);
+    HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids);
+
+    friend DWORD WINAPI COutputPin_IoThreadStartup(LPVOID lpParameter);
+    friend HRESULT STDMETHODCALLTYPE COutputPin_SetState(IPin * Pin, KSSTATE State);
 
 protected:
     LONG m_Ref;
@@ -167,7 +176,6 @@ protected:
     LPCWSTR m_PinName;
     HANDLE m_hPin;
     ULONG m_PinId;
-    IKsObject * m_KsObjectParent;
     IPin * m_Pin;
     IKsAllocatorEx * m_KsAllocatorEx;
     ULONG m_PipeAllocatorFlag;
@@ -178,21 +186,29 @@ protected:
     PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
 
     IMemAllocator * m_MemAllocator;
+    IMemInputPin * m_MemInputPin;
     LONG m_IoCount;
     KSPIN_COMMUNICATION m_Communication;
     KSPIN_INTERFACE m_Interface;
     KSPIN_MEDIUM m_Medium;
     AM_MEDIA_TYPE m_MediaFormat;
-
-    IMediaSeeking * m_FilterMediaSeeking;
     ALLOCATOR_PROPERTIES m_Properties;
     IKsInterfaceHandler * m_InterfaceHandler;
+
+    HANDLE m_hStartEvent;
+    HANDLE m_hBufferAvailable;
+    HANDLE m_hStopEvent;
+    BOOL m_StopInProgress;
+    BOOL m_IoThreadStarted;
+
+    KSSTATE m_State;
+    CRITICAL_SECTION m_Lock;
+
+    ProxyPluginVector m_Plugins;
 };
 
 COutputPin::~COutputPin()
 {
-    if (m_KsObjectParent)
-        m_KsObjectParent->Release();
 }
 
 COutputPin::COutputPin(
@@ -204,31 +220,39 @@ COutputPin::COutputPin(
                                          m_PinName(PinName),
                                          m_hPin(INVALID_HANDLE_VALUE),
                                          m_PinId(PinId),
-                                         m_KsObjectParent(0),
                                          m_Pin(0),
                                          m_KsAllocatorEx(0),
                                          m_PipeAllocatorFlag(0),
                                          m_bPinBusCacheInitialized(0),
                                          m_FilterName(0),
                                          m_MemAllocator(0),
+                                         m_MemInputPin(0),
                                          m_IoCount(0),
                                          m_Communication(Communication),
-                                         m_FilterMediaSeeking(0),
-                                         m_InterfaceHandler(0)
+                                         m_InterfaceHandler(0),
+                                         m_hStartEvent(0),
+                                         m_hBufferAvailable(0),
+                                         m_hStopEvent(0),
+                                         m_StopInProgress(0),
+                                         m_IoThreadStarted(0),
+                                         m_State(KSSTATE_STOP),
+                                         m_Plugins()
 {
     HRESULT hr;
+    IKsObject * KsObjectParent;
 
-    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent);
-    assert(hr == S_OK);
-
-    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&m_FilterMediaSeeking);
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
     assert(hr == S_OK);
 
     ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
     ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
 
-    hr = KsGetMediaType(0, &m_MediaFormat, m_KsObjectParent->KsGetObjectHandle(), m_PinId);
+    hr = KsGetMediaType(0, &m_MediaFormat, KsObjectParent->KsGetObjectHandle(), m_PinId);
     assert(hr == S_OK);
+
+    InitializeCriticalSection(&m_Lock);
+
+    KsObjectParent->Release();
 };
 
 HRESULT
@@ -241,7 +265,9 @@ COutputPin::QueryInterface(
     if (IsEqualGUID(refiid, IID_IUnknown) ||
         IsEqualGUID(refiid, IID_IPin))
     {
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_IPin\n");
+#endif
         *Output = PVOID(this);
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
@@ -254,8 +280,9 @@ COutputPin::QueryInterface(
             if (FAILED(hr))
                 return hr;
         }
-
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsObject\n");
+#endif
         *Output = (IKsObject*)(this);
         reinterpret_cast<IKsObject*>(*Output)->AddRef();
         return NOERROR;
@@ -292,14 +319,18 @@ COutputPin::QueryInterface(
             if (FAILED(hr))
                 return hr;
         }
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPropertySet\n");
+#endif
         *Output = (IKsPropertySet*)(this);
         reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
         return NOERROR;
     }
     else if (IsEqualGUID(refiid, IID_IKsControl))
     {
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsControl\n");
+#endif
         *Output = (IKsControl*)(this);
         reinterpret_cast<IKsControl*>(*Output)->AddRef();
         return NOERROR;
@@ -314,14 +345,18 @@ COutputPin::QueryInterface(
 #endif
     else if (IsEqualGUID(refiid, IID_IKsPinFactory))
     {
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPinFactory\n");
+#endif
         *Output = (IKsPinFactory*)(this);
         reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
         return NOERROR;
     }
     else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
     {
+#ifdef KSPROXY_TRACE
         OutputDebugStringW(L"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
+#endif
         *Output = (ISpecifyPropertyPages*)(this);
         reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
         return NOERROR;
@@ -351,12 +386,14 @@ COutputPin::QueryInterface(
         return NOERROR;
     }
 
+#ifdef KSPROXY_TRACE
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
     StringFromCLSID(refiid, &lpstr);
     swprintf(Buffer, L"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr, m_PinId, m_PinName);
     OutputDebugStringW(Buffer);
     CoTaskMemFree(lpstr);
+#endif
 
     return E_NOINTERFACE;
 }
@@ -369,7 +406,9 @@ STDMETHODCALLTYPE
 COutputPin::SuggestAllocatorProperties(
     const ALLOCATOR_PROPERTIES *pprop)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::SuggestAllocatorProperties\n");
+#endif
 
     if (m_Pin)
     {
@@ -386,7 +425,9 @@ STDMETHODCALLTYPE
 COutputPin::GetAllocatorProperties(
     ALLOCATOR_PROPERTIES *pprop)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::GetAllocatorProperties\n");
+#endif
 
     if (!m_Pin)
     {
@@ -412,7 +453,9 @@ STDMETHODCALLTYPE
 COutputPin::SetFormat(
     AM_MEDIA_TYPE *pmt)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::SetFormat NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -420,7 +463,9 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::GetFormat(AM_MEDIA_TYPE **ppmt)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::GetFormat NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -430,7 +475,9 @@ COutputPin::GetNumberOfCapabilities(
     int *piCount,
     int *piSize)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::GetNumberOfCapabilities NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -441,7 +488,9 @@ COutputPin::GetStreamCaps(
     AM_MEDIA_TYPE **ppmt,
     BYTE *pSCC)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::GetStreamCaps NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -452,8 +501,14 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::NotifyRelease()
 {
-    OutputDebugStringW(L"COutputPin::NotifyRelease NotImplemented\n");
-    return E_NOTIMPL;
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"COutputPin::NotifyRelease\n");
+#endif
+
+    // notify thread of new available sample
+    SetEvent(m_hBufferAvailable);
+
+    return NOERROR;
 }
 
 //-------------------------------------------------------------------
@@ -464,7 +519,17 @@ STDMETHODCALLTYPE
 COutputPin::GetCapabilities(
     DWORD *pCapabilities)
 {
-    return m_FilterMediaSeeking->GetCapabilities(pCapabilities);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetCapabilities(pCapabilities);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -472,7 +537,17 @@ STDMETHODCALLTYPE
 COutputPin::CheckCapabilities(
     DWORD *pCapabilities)
 {
-    return m_FilterMediaSeeking->CheckCapabilities(pCapabilities);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->CheckCapabilities(pCapabilities);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -480,7 +555,17 @@ STDMETHODCALLTYPE
 COutputPin::IsFormatSupported(
     const GUID *pFormat)
 {
-    return m_FilterMediaSeeking->IsFormatSupported(pFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->IsFormatSupported(pFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -488,7 +573,17 @@ STDMETHODCALLTYPE
 COutputPin::QueryPreferredFormat(
     GUID *pFormat)
 {
-    return m_FilterMediaSeeking->QueryPreferredFormat(pFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->QueryPreferredFormat(pFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -496,7 +591,17 @@ STDMETHODCALLTYPE
 COutputPin::GetTimeFormat(
     GUID *pFormat)
 {
-    return m_FilterMediaSeeking->GetTimeFormat(pFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetTimeFormat(pFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -504,7 +609,17 @@ STDMETHODCALLTYPE
 COutputPin::IsUsingTimeFormat(
     const GUID *pFormat)
 {
-    return m_FilterMediaSeeking->IsUsingTimeFormat(pFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->IsUsingTimeFormat(pFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -512,7 +627,17 @@ STDMETHODCALLTYPE
 COutputPin::SetTimeFormat(
     const GUID *pFormat)
 {
-    return m_FilterMediaSeeking->SetTimeFormat(pFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->SetTimeFormat(pFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -520,7 +645,17 @@ STDMETHODCALLTYPE
 COutputPin::GetDuration(
     LONGLONG *pDuration)
 {
-    return m_FilterMediaSeeking->GetDuration(pDuration);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetDuration(pDuration);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -528,7 +663,17 @@ STDMETHODCALLTYPE
 COutputPin::GetStopPosition(
     LONGLONG *pStop)
 {
-    return m_FilterMediaSeeking->GetStopPosition(pStop);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetStopPosition(pStop);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 
@@ -537,7 +682,17 @@ STDMETHODCALLTYPE
 COutputPin::GetCurrentPosition(
     LONGLONG *pCurrent)
 {
-    return m_FilterMediaSeeking->GetCurrentPosition(pCurrent);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetCurrentPosition(pCurrent);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -548,7 +703,17 @@ COutputPin::ConvertTimeFormat(
     LONGLONG Source,
     const GUID *pSourceFormat)
 {
-    return m_FilterMediaSeeking->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -559,7 +724,17 @@ COutputPin::SetPositions(
     LONGLONG *pStop,
     DWORD dwStopFlags)
 {
-    return m_FilterMediaSeeking->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -568,7 +743,17 @@ COutputPin::GetPositions(
     LONGLONG *pCurrent,
     LONGLONG *pStop)
 {
-    return m_FilterMediaSeeking->GetPositions(pCurrent, pStop);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetPositions(pCurrent, pStop);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -577,7 +762,17 @@ COutputPin::GetAvailable(
     LONGLONG *pEarliest,
     LONGLONG *pLatest)
 {
-    return m_FilterMediaSeeking->GetAvailable(pEarliest, pLatest);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetAvailable(pEarliest, pLatest);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -585,7 +780,17 @@ STDMETHODCALLTYPE
 COutputPin::SetRate(
     double dRate)
 {
-    return m_FilterMediaSeeking->SetRate(dRate);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->SetRate(dRate);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -593,7 +798,17 @@ STDMETHODCALLTYPE
 COutputPin::GetRate(
     double *pdRate)
 {
-    return m_FilterMediaSeeking->GetRate(pdRate);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetRate(pdRate);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 HRESULT
@@ -601,7 +816,17 @@ STDMETHODCALLTYPE
 COutputPin::GetPreroll(
     LONGLONG *pllPreroll)
 {
-    return m_FilterMediaSeeking->GetPreroll(pllPreroll);
+    IMediaSeeking * FilterMediaSeeking;
+    HRESULT hr;
+
+    hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
+    if (FAILED(hr))
+        return hr;
+
+    hr = FilterMediaSeeking->GetPreroll(pllPreroll);
+
+    FilterMediaSeeking->Release();
+    return hr;
 }
 
 //-------------------------------------------------------------------
@@ -613,7 +838,9 @@ COutputPin::Notify(
     IBaseFilter *pSelf,
     Quality q)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::Notify NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -622,7 +849,9 @@ STDMETHODCALLTYPE
 COutputPin::SetSink(
     IQualityControl *piqc)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::SetSink NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -635,7 +864,9 @@ STDMETHODCALLTYPE
 COutputPin::KsAddAggregate(
     IN REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsAddAggregate NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -644,7 +875,9 @@ STDMETHODCALLTYPE
 COutputPin::KsRemoveAggregate(
     REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsRemoveAggregate NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -658,8 +891,24 @@ STDMETHODCALLTYPE
 COutputPin::KsQueryMediums(
     PKSMULTIPLE_ITEM* MediumList)
 {
-    HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
-    return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
+    HRESULT hr;
+    HANDLE hFilter;
+    IKsObject * KsObjectParent;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return E_NOINTERFACE;
+
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    if (hFilter)
+        hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
+    else
+        hr = E_HANDLE;
+
+    KsObjectParent->Release();
+
+    return hr;
 }
 
 HRESULT
@@ -667,9 +916,24 @@ STDMETHODCALLTYPE
 COutputPin::KsQueryInterfaces(
     PKSMULTIPLE_ITEM* InterfaceList)
 {
-    HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
+    HRESULT hr;
+    HANDLE hFilter;
+    IKsObject * KsObjectParent;
+
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
 
-    return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    if (hFilter)
+        hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
+    else
+        hr = E_HANDLE;
+
+    KsObjectParent->Release();
+
+    return hr;
 }
 
 HRESULT
@@ -678,7 +942,9 @@ COutputPin::KsCreateSinkPinHandle(
     KSPIN_INTERFACE& Interface,
     KSPIN_MEDIUM& Medium)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -721,7 +987,9 @@ COutputPin::KsPropagateAcquire()
     ULONG BytesReturned;
     HRESULT hr;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsPropagateAcquire\n");
+#endif
 
     assert(m_hPin != INVALID_HANDLE_VALUE);
 
@@ -732,6 +1000,10 @@ COutputPin::KsPropagateAcquire()
     State = KSSTATE_ACQUIRE;
 
     hr = KsProperty(&Property, sizeof(KSPROPERTY), (LPVOID)&State, sizeof(KSSTATE), &BytesReturned);
+    if (SUCCEEDED(hr))
+    {
+        m_State = State;
+    }
 
     //TODO
     //propagate to connected pin on the pipe
@@ -813,7 +1085,9 @@ COutputPin::KsQualityNotify(
     ULONG Proportion,
     REFERENCE_TIME TimeDelta)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsQualityNotify NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -827,7 +1101,9 @@ COutputPin::KsNotifyError(
     IMediaSample* Sample,
     HRESULT hr)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsNotifyError NotImplemented\n");
+#endif
 }
 
 
@@ -984,7 +1260,9 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::GetPages(CAUUID *pPages)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n");
+#endif
 
     if (!pPages)
         return E_POINTER;
@@ -1004,7 +1282,10 @@ STDMETHODCALLTYPE
 COutputPin::KsPinFactory(
     ULONG* PinFactory)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsPinFactory\n");
+#endif
+
     *PinFactory = m_PinId;
     return S_OK;
 }
@@ -1020,7 +1301,9 @@ COutputPin::Render(
     IPin *ppinOut,
     IGraphBuilder *pGraph)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::Render\n");
+#endif
     return S_OK;
 }
 
@@ -1030,7 +1313,10 @@ COutputPin::Backout(
     IPin *ppinOut, 
     IGraphBuilder *pGraph)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::Backout\n");
+#endif
+
     return S_OK;
 }
 //-------------------------------------------------------------------
@@ -1040,7 +1326,10 @@ HANDLE
 STDMETHODCALLTYPE
 COutputPin::KsGetObjectHandle()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsGetObjectHandle\n");
+#endif
+
     assert(m_hPin != INVALID_HANDLE_VALUE);
     return m_hPin;
 }
@@ -1058,16 +1347,17 @@ COutputPin::KsProperty(
     ULONG* BytesReturned)
 {
     HRESULT hr;
-    WCHAR Buffer[100];
-    LPOLESTR pstr;
 
     assert(m_hPin != INVALID_HANDLE_VALUE);
 
     hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
-
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
+    LPOLESTR pstr;
     StringFromCLSID(Property->Set, &pstr);
     swprintf(Buffer, L"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr, Property->Id, Property->Flags, hr);
     OutputDebugStringW(Buffer);
+#endif
 
     return hr;
 }
@@ -1082,7 +1372,9 @@ COutputPin::KsMethod(
     ULONG* BytesReturned)
 {
     assert(m_hPin != INVALID_HANDLE_VALUE);
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsMethod\n");
+#endif
     return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
 }
 
@@ -1097,7 +1389,9 @@ COutputPin::KsEvent(
 {
     assert(m_hPin != INVALID_HANDLE_VALUE);
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::KsEvent\n");
+#endif
 
     if (EventLength)
         return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
@@ -1202,7 +1496,9 @@ COutputPin::QuerySupported(
     KSPROPERTY Property;
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::QuerySupported\n");
+#endif
 
     Property.Set = guidPropSet;
     Property.Id = dwPropID;
@@ -1220,8 +1516,14 @@ STDMETHODCALLTYPE
 COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 {
     HRESULT hr;
+    ALLOCATOR_PROPERTIES Properties;
+    IMemAllocatorCallbackTemp *pMemCallback;
 
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
     OutputDebugStringW(L"COutputPin::Connect called\n");
+#endif
+
     if (pmt)
     {
         hr = pReceivePin->QueryAccept(pmt);
@@ -1238,54 +1540,184 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
          pmt = &m_MediaFormat;
     }
 
-    //FIXME create pin handle
+    // query for IMemInput interface
+    hr = pReceivePin->QueryInterface(IID_IMemInputPin, (void**)&m_MemInputPin);
+    if (FAILED(hr))
+    {
+#ifdef KSPROXY_TRACE
+        OutputDebugStringW(L"COutputPin::Connect no IMemInputPin interface\n");
+#endif
+
+        DebugBreak();
+        return hr;
+    }
 
-    // receive connection;
-    hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
+    // get input pin allocator properties
+    ZeroMemory(&Properties, sizeof(ALLOCATOR_PROPERTIES));
+    m_MemInputPin->GetAllocatorRequirements(&Properties);
+
+    //FIXME determine allocator properties
+    Properties.cBuffers = 32;
+    Properties.cbBuffer = 2048 * 188; //2048 frames * MPEG2 TS Payload size
+    Properties.cbAlign = 4;
+
+    // get input pin allocator
+#if 0
+    hr = m_MemInputPin->GetAllocator(&m_MemAllocator);
     if (SUCCEEDED(hr))
     {
-        // increment reference count
-        pReceivePin->AddRef();
-        m_Pin = pReceivePin;
-        OutputDebugStringW(L"COutputPin::Connect success\n");
+        // set allocator properties
+        hr = m_MemAllocator->SetProperties(&Properties, &m_Properties);
+        if (FAILED(hr))
+            m_MemAllocator->Release();
     }
+#endif
 
-    return hr;
-}
+    if (1)
+    {
+        hr = CKsAllocator_Constructor(NULL, IID_IMemAllocator, (void**)&m_MemAllocator);
+        if (FAILED(hr))
+            return hr;
 
-HRESULT
-STDMETHODCALLTYPE
-COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
-{
-    OutputDebugStringW(L"COutputPin::ReceiveConnection\n");
-    return E_UNEXPECTED;
-}
-HRESULT
-STDMETHODCALLTYPE
-COutputPin::Disconnect( void)
-{
-   OutputDebugStringW(L"COutputPin::Disconnect\n");
+        // set allocator properties
+        hr = m_MemAllocator->SetProperties(&Properties, &m_Properties);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
+            m_MemAllocator->Release();
+            m_MemInputPin->Release();
+            return hr;
+        }
+    }
 
-    if (!m_Pin)
+    // commit property changes
+    hr = m_MemAllocator->Commit();
+    if (FAILED(hr))
     {
-        // pin was not connected
-        return S_FALSE;
+#ifdef KSPROXY_TRACE
+        swprintf(Buffer, L"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
+        m_MemAllocator->Release();
+        m_MemInputPin->Release();
+        return hr;
     }
 
-    //FIXME
-    //check if filter is active
+    // get callback interface
+    hr = m_MemAllocator->QueryInterface(IID_IMemAllocatorCallbackTemp, (void**)&pMemCallback);
+    if (FAILED(hr))
+    {
+#ifdef KSPROXY_TRACE
+        swprintf(Buffer, L"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
+        m_MemAllocator->Release();
+        m_MemInputPin->Release();
+        return hr;
+    }
+
+    // set notification routine
+    hr = pMemCallback->SetNotify((IMemAllocatorNotifyCallbackTemp*)this);
+
+    // release IMemAllocatorNotifyCallbackTemp interface
+    pMemCallback->Release();
+
+    if (FAILED(hr))
+    {
+#ifdef KSPROXY_TRACE
+        swprintf(Buffer, L"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
+        m_MemAllocator->Release();
+        m_MemInputPin->Release();
+        return hr;
+    }
+
+    // now set allocator
+    hr = m_MemInputPin->NotifyAllocator(m_MemAllocator, TRUE);
+    if (FAILED(hr))
+    {
+#ifdef KSPROXY_TRACE
+        swprintf(Buffer, L"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
+        m_MemAllocator->Release();
+        m_MemInputPin->Release();
+        return hr;
+    }
+
+    if (!m_hPin)
+    {
+        //FIXME create pin handle
+        assert(0);
+    }
+
+    // receive connection;
+    hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
+    if (SUCCEEDED(hr))
+    {
+        // increment reference count
+        pReceivePin->AddRef();
+        m_Pin = pReceivePin;
+#ifdef KSPROXY_TRACE
+        OutputDebugStringW(L"COutputPin::Connect success\n");
+#endif
+    }
+    else
+    {
+        m_MemInputPin->Release();
+        m_MemAllocator->Release();
+    }
+
+    return hr;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
+{
+    return E_UNEXPECTED;
+}
+HRESULT
+STDMETHODCALLTYPE
+COutputPin::Disconnect( void)
+{
+#ifdef KSPROXY_TRACE
+   OutputDebugStringW(L"COutputPin::Disconnect\n");
+#endif
+
+    if (!m_Pin)
+    {
+        // pin was not connected
+        return S_FALSE;
+    }
+
+    //FIXME
+    //check if filter is active
 
     m_Pin->Release();
     m_Pin = NULL;
+    m_MemInputPin->Release();
+    m_MemAllocator->Release();
+
+    CloseHandle(m_hPin);
+    m_hPin = INVALID_HANDLE_VALUE;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::Disconnect\n");
+#endif
     return S_OK;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::ConnectedTo(IPin **pPin)
 {
+#ifdef KSPROXY_TRACE
    OutputDebugStringW(L"COutputPin::ConnectedTo\n");
+#endif
 
     if (!pPin)
         return E_POINTER;
@@ -1305,15 +1737,16 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::ConnectionMediaType called\n");
+#endif
+
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::QueryPinInfo(PIN_INFO *pInfo)
 {
-    OutputDebugStringW(L"COutputPin::QueryPinInfo\n");
-
     wcscpy(pInfo->achName, m_PinName);
     pInfo->dir = PINDIR_OUTPUT;
     pInfo->pFilter = m_ParentFilter;
@@ -1325,8 +1758,6 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::QueryDirection(PIN_DIRECTION *pPinDir)
 {
-    OutputDebugStringW(L"COutputPin::QueryDirection\n");
-
     if (pPinDir)
     {
         *pPinDir = PINDIR_OUTPUT;
@@ -1339,8 +1770,6 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::QueryId(LPWSTR *Id)
 {
-    OutputDebugStringW(L"COutputPin::QueryId\n");
-
     *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR));
     if (!*Id)
         return E_OUTOFMEMORY;
@@ -1352,7 +1781,10 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"COutputPin::QueryAccept called\n");
+#endif
+
     return E_NOTIMPL;
 }
 HRESULT
@@ -1363,23 +1795,22 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
     ULONG MediaTypeCount = 0, Index;
     AM_MEDIA_TYPE * MediaTypes;
     HANDLE hFilter;
+    IKsObject * KsObjectParent;
 
-    OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n");
-
-    if (!m_KsObjectParent)
-    {
-        // no interface
-        return E_NOINTERFACE;
-    }
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
 
     // get parent filter handle
-    hFilter = m_KsObjectParent->KsGetObjectHandle();
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    // release IKsObject
+    KsObjectParent->Release();
 
     // query media type count
     hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
     if (FAILED(hr) || !MediaTypeCount)
     {
-        OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n");
         return hr;
     }
 
@@ -1388,7 +1819,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
     if (!MediaTypes)
     {
         // not enough memory
-        OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n");
         return E_OUTOFMEMORY;
     }
 
@@ -1403,7 +1833,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
         {
             // failed
             CoTaskMemFree(MediaTypes);
-            OutputDebugStringW(L"COutputPin::EnumMediaTypes failed\n");
             return hr;
         }
     }
@@ -1414,36 +1843,40 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
 {
-    OutputDebugStringW(L"COutputPin::QueryInternalConnections called\n");
     return E_NOTIMPL;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::EndOfStream( void)
 {
-    OutputDebugStringW(L"COutputPin::EndOfStream called\n");
-    return E_NOTIMPL;
+    /* should be called only on input pins */
+    return E_UNEXPECTED;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::BeginFlush( void)
 {
-    OutputDebugStringW(L"COutputPin::BeginFlush called\n");
-    return E_NOTIMPL;
+    /* should be called only on input pins */
+    return E_UNEXPECTED;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::EndFlush( void)
 {
-    OutputDebugStringW(L"COutputPin::EndFlush called\n");
-    return E_NOTIMPL;
+    /* should be called only on input pins */
+    return E_UNEXPECTED;
 }
 HRESULT
 STDMETHODCALLTYPE
 COutputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
 {
-    OutputDebugStringW(L"COutputPin::NewSegment called\n");
-    return E_NOTIMPL;
+    if (!m_Pin)
+    {
+        // we are not connected
+        return VFW_E_NOT_CONNECTED;
+    }
+
+    return m_Pin->NewSegment(tStart, tStop, dRate);
 }
 
 //-------------------------------------------------------------------
@@ -1455,12 +1888,26 @@ COutputPin::CheckFormat(
     PKSMULTIPLE_ITEM MultipleItem;
     PKSDATAFORMAT DataFormat;
     HRESULT hr;
+    IKsObject * KsObjectParent;
+    HANDLE hFilter;
 
     if (!pmt)
         return E_POINTER;
 
-    HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
-    assert(hFilter != NULL);
+    // get IKsObject interface
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    // get parent filter handle
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    // release IKsObject
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
+
 
     hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem);
     if (FAILED(hr))
@@ -1475,7 +1922,6 @@ COutputPin::CheckFormat(
         {
             // format is supported
             CoTaskMemFree(MultipleItem);
-            OutputDebugStringW(L"COutputPin::CheckFormat format OK\n");
             return S_OK;
         }
         DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize);
@@ -1539,8 +1985,12 @@ COutputPin::CreatePin(
         hr = CreatePinHandle(Medium, Interface, pmt);
         if (FAILED(hr))
         {
-            m_InterfaceHandler->Release();
-            m_InterfaceHandler = InterfaceHandler;
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"COutputPin::CreatePinHandle failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
+            return hr;
         }
 
         if (!m_InterfaceHandler)
@@ -1550,7 +2000,6 @@ COutputPin::CreatePin(
             if (FAILED(hr))
             {
                 // failed to load interface handler plugin
-                OutputDebugStringW(L"COutputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
 
@@ -1562,7 +2011,6 @@ COutputPin::CreatePin(
             if (FAILED(hr))
             {
                 // failed to load interface handler plugin
-                OutputDebugStringW(L"COutputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
                 InterfaceHandler->Release();
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
@@ -1575,10 +2023,13 @@ COutputPin::CreatePin(
     }
     else
     {
+#ifdef KSPROXY_TRACE
         WCHAR Buffer[100];
         swprintf(Buffer, L"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName);
         OutputDebugStringW(Buffer);
         DebugBreak();
+#endif
+
         hr = E_FAIL;
     }
 
@@ -1600,6 +2051,12 @@ COutputPin::CreatePinHandle(
     PKSDATAFORMAT DataFormat;
     ULONG Length;
     HRESULT hr;
+    HANDLE hFilter;
+    IKsObject * KsObjectParent;
+
+    //KSALLOCATOR_FRAMING Framing;
+    //KSPROPERTY Property;
+    //ULONG BytesReturned;
 
     if (m_hPin != INVALID_HANDLE_VALUE)
     {
@@ -1647,11 +2104,22 @@ COutputPin::CreatePinHandle(
         CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat);
     }
 
-    HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
-    assert(hFilter != NULL);
+    // get IKsObject interface
+    hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
+    if (FAILED(hr))
+        return hr;
+
+    // get parent filter handle
+    hFilter = KsObjectParent->KsGetObjectHandle();
+
+    // release IKsObject
+    KsObjectParent->Release();
+
+    if (!hFilter)
+        return E_HANDLE;
 
     // create pin
-    hr = KsCreatePin(hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
+    hr = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin);
 
     if (SUCCEEDED(hr))
     {
@@ -1660,6 +2128,7 @@ COutputPin::CreatePinHandle(
         CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE));
         CopyMemory(&m_MediaFormat, pmt, sizeof(AM_MEDIA_TYPE));
 
+#ifdef KSPROXY_TRACE
         LPOLESTR pMajor, pSub, pFormat;
         StringFromIID(m_MediaFormat.majortype, &pMajor);
         StringFromIID(m_MediaFormat.subtype , &pSub);
@@ -1670,6 +2139,7 @@ COutputPin::CreatePinHandle(
         CoTaskMemFree(pSub);
         CoTaskMemFree(pFormat);
         OutputDebugStringW(Buffer);
+#endif
 
         if (pmt->cbFormat)
         {
@@ -1683,6 +2153,57 @@ COutputPin::CreatePinHandle(
             }
             CopyMemory(m_MediaFormat.pbFormat, pmt->pbFormat, pmt->cbFormat);
         }
+#if 0
+        Property.Set = KSPROPSETID_Connection;
+        Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
+        Property.Flags = KSPROPERTY_TYPE_GET;
+
+        ZeroMemory(&Framing, sizeof(KSALLOCATOR_FRAMING));
+        hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
+        if (SUCCEEDED(hr))
+        {
+            m_Properties.cbAlign = (Framing.FileAlignment + 1);
+            m_Properties.cbBuffer = Framing.FrameSize;
+            m_Properties.cbPrefix = 0; //FIXME
+            m_Properties.cBuffers = Framing.Frames;
+        }
+        hr = S_OK;
+#endif
+
+        if (FAILED(InitializeIOThread()))
+        {
+            OutputDebugStringW(L"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
+            DebugBreak();
+        }
+
+        LPGUID pGuid;
+        ULONG NumGuids = 0;
+
+        // get all supported sets
+        hr = GetSupportedSets(&pGuid, &NumGuids);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n");
+            DebugBreak();
+#endif
+            return hr;
+        }
+
+        // load all proxy plugins
+        hr = LoadProxyPlugins(pGuid, NumGuids);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
+            DebugBreak();
+#endif
+            return hr;
+        }
+
+        // free sets
+        CoTaskMemFree(pGuid);
+
 
         //TODO
         // connect pin pipes
@@ -1694,6 +2215,486 @@ COutputPin::CreatePinHandle(
     return hr;
 }
 
+HRESULT
+STDMETHODCALLTYPE
+COutputPin::GetSupportedSets(
+    LPGUID * pOutGuid,
+    PULONG NumGuids)
+{
+    KSPROPERTY Property;
+    LPGUID pGuid;
+    ULONG NumProperty = 0;
+    ULONG NumMethods = 0;
+    ULONG NumEvents = 0;
+    ULONG Length;
+    ULONG BytesReturned;
+    HRESULT hr;
+
+    Property.Set = GUID_NULL;
+    Property.Id = 0;
+    Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
+
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty);
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods);
+    KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents);
+
+    Length = NumProperty + NumMethods + NumEvents;
+
+    assert(Length);
+
+    // allocate guid buffer
+    pGuid = (LPGUID)CoTaskMemAlloc(Length);
+    if (!pGuid)
+    {
+        // failed
+        return E_OUTOFMEMORY;
+    }
+
+    NumProperty /= sizeof(GUID);
+    NumMethods /= sizeof(GUID);
+    NumEvents /= sizeof(GUID);
+
+    // get all properties
+    hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned);
+    if (FAILED(hr))
+    {
+        CoTaskMemFree(pGuid);
+        return E_FAIL;
+    }
+    Length -= BytesReturned;
+
+    // get all methods
+    if (Length && NumMethods)
+    {
+        hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned);
+        if (FAILED(hr))
+        {
+            CoTaskMemFree(pGuid);
+            return E_FAIL;
+        }
+        Length -= BytesReturned;
+    }
+
+    // get all events
+    if (Length && NumEvents)
+    {
+        hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned);
+        if (FAILED(hr))
+        {
+            CoTaskMemFree(pGuid);
+            return E_FAIL;
+        }
+        Length -= BytesReturned;
+    }
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
+    swprintf(Buffer, L"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents);
+    OutputDebugStringW(Buffer);
+#endif
+
+    *pOutGuid = pGuid;
+    *NumGuids = NumProperty+NumEvents+NumMethods;
+    return S_OK;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+COutputPin::LoadProxyPlugins(
+    LPGUID pGuids,
+    ULONG NumGuids)
+{
+    ULONG Index;
+    LPOLESTR pStr;
+    HKEY hKey, hSubKey;
+    HRESULT hr;
+    IUnknown * pUnknown;
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+    {
+        OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
+        return E_FAIL;
+    }
+
+    // enumerate all sets
+    for(Index = 0; Index < NumGuids; Index++)
+    {
+        // convert to string
+        hr = StringFromCLSID(pGuids[Index], &pStr);
+        if (FAILED(hr))
+            return E_FAIL;
+
+        // now try open class key
+        if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
+        {
+            // no plugin for that set exists
+            CoTaskMemFree(pStr);
+            continue;
+        }
+
+        // try load plugin
+        hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
+        if (SUCCEEDED(hr))
+        {
+            // store plugin
+            m_Plugins.push_back(pUnknown);
+DebugBreak();
+        }
+        // close key
+        RegCloseKey(hSubKey);
+    }
+
+    // close media interfaces key
+    RegCloseKey(hKey);
+    return S_OK;
+}
+
+
+HRESULT
+WINAPI
+COutputPin::IoProcessRoutine()
+{
+    IMediaSample *Sample;
+    LONG SampleCount;
+    HRESULT hr;
+    PKSSTREAM_SEGMENT StreamSegment;
+    HANDLE hEvent;
+    IMediaSample * Samples[1];
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
+#endif
+
+    // first wait for the start event to signal
+    WaitForSingleObject(m_hStartEvent, INFINITE);
+
+    assert(m_InterfaceHandler);
+    do
+    {
+        if (m_StopInProgress)
+        {
+            // stop io thread
+            break;
+        }
+
+        assert(m_State == KSSTATE_RUN);
+        assert(m_MemAllocator);
+
+        // get buffer
+        hr = m_MemAllocator->GetBuffer(&Sample, NULL, NULL, AM_GBF_NOWAIT);
+
+        if (FAILED(hr))
+        {
+            WaitForSingleObject(m_hBufferAvailable, INFINITE);
+            // now retry again
+            continue;
+        }
+
+        // fill buffer
+        SampleCount = 1;
+        Samples[0] = Sample;
+
+        Sample->SetTime(NULL, NULL);
+        hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */
+                                                       Samples,
+                                                       &SampleCount,
+                                                       KsIoOperation_Read,
+                                                       &StreamSegment);
+        if (FAILED(hr) || !StreamSegment)
+        {
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+            break;
+        }
+
+        // get completion event
+        hEvent = StreamSegment->CompletionEvent;
+
+        // wait for i/o completion
+        WaitForSingleObject(hEvent, INFINITE);
+
+        // perform completion
+        m_InterfaceHandler->KsCompleteIo(StreamSegment);
+
+        // close completion event
+        CloseHandle(hEvent);
+
+        if (SUCCEEDED(hr))
+        {
+            assert(m_MemInputPin);
+
+            // now deliver the sample
+            hr = m_MemInputPin->Receive(Sample);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator);
+            OutputDebugStringW(Buffer);
+#endif
+
+             if (FAILED(hr))
+                 break;
+
+            Sample = NULL;
+        }
+    }while(TRUE);
+
+    // signal end of i/o thread
+    SetEvent(m_hStopEvent);
+
+    m_IoThreadStarted = false;
+
+    return NOERROR;
+}
+
+DWORD
+WINAPI
+COutputPin_IoThreadStartup(
+    LPVOID lpParameter)
+{
+    COutputPin * Pin = (COutputPin*)lpParameter;
+    assert(Pin);
+
+    return Pin->IoProcessRoutine();
+}
+
+
+HRESULT
+WINAPI
+COutputPin::InitializeIOThread()
+{
+    HANDLE hThread;
+
+    if (m_IoThreadStarted)
+        return NOERROR;
+
+    if (!m_hStartEvent)
+        m_hStartEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+    if (!m_hStartEvent)
+        return E_OUTOFMEMORY;
+
+    if (!m_hStopEvent)
+        m_hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+    if (!m_hStopEvent)
+        return E_OUTOFMEMORY;
+
+    if (!m_hBufferAvailable)
+        m_hBufferAvailable = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+    if (!m_hBufferAvailable)
+        return E_OUTOFMEMORY;
+
+    m_StopInProgress = false;
+    m_IoThreadStarted = true;
+
+    // now create the startup thread
+    hThread = CreateThread(NULL, 0, COutputPin_IoThreadStartup, (LPVOID)this, 0, NULL);
+    if (!hThread)
+        return E_OUTOFMEMORY;
+
+
+    // close thread handle
+    CloseHandle(hThread);
+    return NOERROR;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+COutputPin_SetState(
+    IPin * Pin,
+    KSSTATE State)
+{
+    HRESULT hr = S_OK;
+    KSPROPERTY Property;
+    KSSTATE CurState;
+    ULONG BytesReturned;
+    COutputPin * pPin = (COutputPin*)Pin;
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[200];
+#endif
+
+    Property.Set = KSPROPSETID_Connection;
+    Property.Id = KSPROPERTY_CONNECTION_STATE;
+    Property.Flags = KSPROPERTY_TYPE_SET;
+
+    EnterCriticalSection(&pPin->m_Lock);
+
+    if (pPin->m_State <= State)
+    {
+        if (pPin->m_State == KSSTATE_STOP)
+        {
+            hr = pPin->InitializeIOThread();
+            if (FAILED(hr))
+            {
+                // failed to initialize I/O thread
+#ifdef KSPROXY_TRACE
+                OutputDebugStringW(L"Failed to initialize I/O Thread\n");
+#endif
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+            CurState = KSSTATE_ACQUIRE;
+            hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin->m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+
+            pPin->m_State = CurState;
+
+            if (pPin->m_State == State)
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+        }
+        if (pPin->m_State == KSSTATE_ACQUIRE)
+        {
+            CurState = KSSTATE_PAUSE;
+            hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin->m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+
+            pPin->m_State = CurState;
+
+            if (pPin->m_State == State)
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+        }
+        if (State == KSSTATE_RUN && pPin->m_State == KSSTATE_PAUSE)
+        {
+            CurState = KSSTATE_RUN;
+            hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin->m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+
+            if (SUCCEEDED(hr))
+            {
+                pPin->m_State = CurState;
+                // signal start event
+                SetEvent(pPin->m_hStartEvent);
+            }
+        }
+
+        LeaveCriticalSection(&pPin->m_Lock);
+        return hr;
+    }
+    else
+    {
+        if (pPin->m_State == KSSTATE_RUN)
+        {
+            // setting pending stop flag
+            pPin->m_StopInProgress = true;
+
+            // release any waiting threads
+            SetEvent(pPin->m_hBufferAvailable);
+
+            // wait until i/o thread is done
+            WaitForSingleObject(pPin->m_hStopEvent, INFINITE);
+
+            CurState = KSSTATE_PAUSE;
+            hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin->m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+
+            pPin->m_State = CurState;
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+        }
+        if (pPin->m_State == KSSTATE_PAUSE)
+        {
+            CurState = KSSTATE_ACQUIRE;
+            hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin->m_PinName, hr);
+            OutputDebugStringW(Buffer);
+#endif
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+
+            pPin->m_State = CurState;
+
+            if (pPin->m_State == State)
+            {
+                LeaveCriticalSection(&pPin->m_Lock);
+                return hr;
+            }
+        }
+
+        CloseHandle(pPin->m_hStopEvent);
+        CloseHandle(pPin->m_hStartEvent);
+        CloseHandle(pPin->m_hBufferAvailable);
+
+        /* close event handles */
+        pPin->m_hStopEvent = NULL;
+        pPin->m_hStartEvent = NULL;
+        pPin->m_hBufferAvailable = NULL;
+
+        CurState = KSSTATE_STOP;
+        hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
+
+#ifdef KSPROXY_TRACE
+        swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin->m_PinName, hr);
+        OutputDebugStringW(Buffer);
+#endif
+
+        if (SUCCEEDED(hr))
+        {
+            // store state
+            pPin->m_State = CurState;
+        }
+
+        // unset pending stop flag
+        pPin->m_StopInProgress = false;
+
+        LeaveCriticalSection(&pPin->m_Lock);
+        return hr;
+    }
+}
+
 HRESULT
 WINAPI
 COutputPin_Constructor(
index 6df3ddf..eae5de0 100644 (file)
@@ -3,6 +3,7 @@
 #define _FORCENAMELESSUNION
 #define BUILDING_KS
 #define _KSDDK_
+//#define KSPROXY_TRACE
 #include <dshow.h>
 //#include <streams.h>
 #include <ks.h>
@@ -18,6 +19,8 @@
 #include <setupapi.h>
 #include <stdio.h>
 #include <vector>
+#include <stack>
+#include <list>
 #include <assert.h>
 #include <ksmedia.h>
 //#include <debug.h>
@@ -138,6 +141,12 @@ COutputPin_Constructor(
     REFIID riid,
     LPVOID * ppv);
 
+HRESULT
+STDMETHODCALLTYPE
+COutputPin_SetState(
+    IPin * Pin,
+    KSSTATE State);
+
 /* enumpins.cpp */
 HRESULT
 WINAPI
@@ -166,10 +175,30 @@ CKsNode_Constructor(
     REFIID riid,
     LPVOID * ppv);
 
+/* allocator.cpp */
+HRESULT
+WINAPI
+CKsAllocator_Constructor(
+    IUnknown * pUnkOuter,
+    REFIID riid,
+    LPVOID * ppv);
+
+/* mediasample.cpp */
+HRESULT
+WINAPI
+CMediaSample_Constructor(
+    IMemAllocator* Allocator, 
+    BYTE* pBuffer,
+    ULONG BufferSize,
+    REFIID riid,
+    LPVOID * ppv);
+
+
 extern const GUID IID_IKsObject;
 extern const GUID IID_IKsPinEx;
 extern const GUID IID_IKsAggregateControl;
 extern const GUID IID_IKsPinPipe;
 extern const GUID IID_IKsPinFactory;
+extern const GUID IID_IKsAllocatorEx;
 extern KSPIN_INTERFACE StandardPinInterface;
 extern KSPIN_MEDIUM StandardPinMedium;
index 39d6386..bd34ec8 100644 (file)
@@ -63,7 +63,7 @@ public:
         InterlockedDecrement(&m_Ref);
         if (!m_Ref)
         {
-            delete this;
+            //delete this;
             return 0;
         }
         return m_Ref;
@@ -171,7 +171,7 @@ public:
     HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
 
 
-    CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock((IReferenceClock*)this), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0), m_hClock(0) {};
+    CKsProxy();
     ~CKsProxy()
     {
         if (m_hDevice)
@@ -203,8 +203,23 @@ protected:
     LPWSTR m_DevicePath;
     CLSID m_DeviceInterfaceGUID;
     HANDLE m_hClock;
+    CRITICAL_SECTION m_Lock;
 };
 
+CKsProxy::CKsProxy() : m_Ref(0),
+                       m_pGraph(0),
+                       m_ReferenceClock((IReferenceClock*)this),
+                       m_FilterState(State_Stopped),
+                       m_hDevice(0),
+                       m_Plugins(),
+                       m_Pins(),
+                       m_DevicePath(0),
+                       m_hClock(0)
+{
+    InitializeCriticalSection(&m_Lock);
+}
+
+
 HRESULT
 STDMETHODCALLTYPE
 CKsProxy::QueryInterface(
@@ -332,24 +347,26 @@ CKsProxy::QueryInterface(
             HRESULT hr = m_Plugins[Index]->QueryInterface(refiid, Output);
             if (SUCCEEDED(hr))
             {
+#ifdef KSPROXY_TRACE
                 WCHAR Buffer[100];
                 LPOLESTR lpstr;
                 StringFromCLSID(refiid, &lpstr);
                 swprintf(Buffer, L"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index, lpstr);
                 OutputDebugStringW(Buffer);
                 CoTaskMemFree(lpstr);
+#endif
                 return hr;
             }
         }
     }
-
+#ifdef KSPROXY_TRACE
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
     StringFromCLSID(refiid, &lpstr);
     swprintf(Buffer, L"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr);
     OutputDebugStringW(Buffer);
     CoTaskMemFree(lpstr);
-
+#endif
 
     return E_NOINTERFACE;
 }
@@ -362,7 +379,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::GetPages(CAUUID *pPages)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetPages NotImplemented\n");
+#endif
 
     if (!pPages)
         return E_POINTER;
@@ -478,7 +497,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetTime(
     LONGLONG* Time)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_GET, (PVOID)Time, sizeof(LONGLONG));
 }
 
@@ -487,7 +509,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsSetTime(
     LONGLONG Time)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsSetTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_SET, (PVOID)&Time, sizeof(LONGLONG));
 }
 
@@ -496,7 +521,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetPhysicalTime(
     LONGLONG* Time)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_GET, (PVOID)Time, sizeof(LONGLONG));
 }
 
@@ -505,7 +533,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsSetPhysicalTime(
     LONGLONG Time)
 {
-    OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime NotImplemented\n");
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_SET, (PVOID)&Time, sizeof(LONGLONG));
 }
 
@@ -514,7 +545,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetCorrelatedTime(
     KSCORRELATED_TIME* CorrelatedTime)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_GET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
 }
 
@@ -523,7 +557,9 @@ STDMETHODCALLTYPE
 CKsProxy::KsSetCorrelatedTime(
     KSCORRELATED_TIME* CorrelatedTime)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime\n");
+#endif
     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_SET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
 }
 
@@ -532,7 +568,9 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetCorrelatedPhysicalTime(
     KSCORRELATED_TIME* CorrelatedTime)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime\n");
+#endif
     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, KSPROPERTY_TYPE_GET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
 }
 
@@ -541,7 +579,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsSetCorrelatedPhysicalTime(
     KSCORRELATED_TIME* CorrelatedTime)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime\n");
+#endif
+
     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, KSPROPERTY_TYPE_SET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
 }
 
@@ -550,7 +591,9 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetResolution(
     KSRESOLUTION* Resolution)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetResolution\n");
+#endif
     return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION, KSPROPERTY_TYPE_GET, (PVOID)Resolution, sizeof(KSRESOLUTION));
 }
 
@@ -559,7 +602,9 @@ STDMETHODCALLTYPE
 CKsProxy::KsGetState(
     KSSTATE* State)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetState\n");
+#endif
     return PerformClockProperty(KSPROPERTY_CLOCK_STATE, KSPROPERTY_TYPE_GET, (PVOID)State, sizeof(KSSTATE));
 }
 
@@ -575,7 +620,9 @@ CKsProxy::GetTime(
     KSPROPERTY Property;
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetTime\n");
+#endif
 
     if (!pTime)
         return E_POINTER;
@@ -620,7 +667,9 @@ CKsProxy::AdviseTime(
     ULONG BytesReturned;
     PKSEVENT_TIME_MARK Event;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::AdviseTime\n");
+#endif
 
     //
     //FIXME locks
@@ -686,7 +735,9 @@ CKsProxy::AdvisePeriodic(
     ULONG BytesReturned;
     PKSEVENT_TIME_INTERVAL Event;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::AdvisePeriodic\n");
+#endif
 
     //
     //FIXME locks
@@ -748,7 +799,9 @@ CKsProxy::Unadvise(
     HRESULT hr;
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Unadvise\n");
+#endif
 
     if (m_hClock)
     {
@@ -786,7 +839,10 @@ CKsProxy::GetCapabilities(
     Property.Id = KSPROPERTY_MEDIASEEKING_CAPABILITIES;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetCapabilities\n");
+#endif
+
 
     if (!pCapabilities)
         return E_POINTER;
@@ -836,7 +892,9 @@ CKsProxy::CheckCapabilities(
     DWORD Capabilities;
     HRESULT hr;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::CheckCapabilities\n");
+#endif
 
     if (!pCapabilities)
         return E_POINTER;
@@ -914,11 +972,13 @@ CKsProxy::IsFormatSupported(
     ULONG Index;
     HRESULT hr = S_FALSE;
 
+#ifdef KSPROXY_TRACE
     WCHAR Buffer[100];
     LPOLESTR pstr;
     StringFromCLSID(*pFormat, &pstr);
     swprintf(Buffer, L"CKsProxy::IsFormatSupported %s\n",pstr);
     OutputDebugStringW(Buffer);
+#endif
 
     if (!pFormat)
         return E_POINTER;
@@ -927,8 +987,10 @@ CKsProxy::IsFormatSupported(
     hr = GetMediaSeekingFormats(&FormatList);
     if (SUCCEEDED(hr))
     {
+#ifdef KSPROXY_TRACE
         swprintf(Buffer, L"CKsProxy::IsFormatSupported NumFormat %lu\n",FormatList->Count);
         OutputDebugStringW(Buffer);
+#endif
 
         //iterate through format list
         pGuid = (LPGUID)(FormatList + 1);
@@ -961,7 +1023,9 @@ CKsProxy::IsFormatSupported(
         {
             // plugin does not support interface
             hr = S_FALSE;
+#ifdef KSPROXY_TRACE
             OutputDebugStringW(L"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
+#endif
             break;
         }
 
@@ -986,7 +1050,9 @@ CKsProxy::QueryPreferredFormat(
     HRESULT hr;
     ULONG Index;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::QueryPreferredFormat\n");
+#endif
 
     if (!pFormat)
         return E_POINTER;
@@ -1046,7 +1112,9 @@ CKsProxy::GetTimeFormat(
     Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetTimeFormat\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1086,7 +1154,9 @@ CKsProxy::IsUsingTimeFormat(
 {
     GUID Format;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat\n");
+#endif
 
     if (FAILED(QueryPreferredFormat(&Format)))
         return S_FALSE;
@@ -1110,7 +1180,9 @@ CKsProxy::SetTimeFormat(
     Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
     Property.Flags = KSPROPERTY_TYPE_SET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::SetTimeFormat\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1158,7 +1230,9 @@ CKsProxy::GetDuration(
     Property.Id = KSPROPERTY_MEDIASEEKING_DURATION;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetDuration\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pDuration, sizeof(LONGLONG), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1204,7 +1278,9 @@ CKsProxy::GetStopPosition(
     Property.Id = KSPROPERTY_MEDIASEEKING_STOPPOSITION;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetStopPosition\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pStop, sizeof(LONGLONG), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1250,7 +1326,9 @@ CKsProxy::GetCurrentPosition(
     Property.Id = KSPROPERTY_MEDIASEEKING_POSITION;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetCurrentPosition\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pCurrent, sizeof(LONGLONG), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1300,7 +1378,9 @@ CKsProxy::ConvertTimeFormat(
     Property.Property.Id = KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT;
     Property.Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::ConvertTimeFormat\n");
+#endif
 
     if (!pTargetFormat)
     {
@@ -1383,7 +1463,9 @@ CKsProxy::SetPositions(
     Positions.Stop = *pStop;
     Positions.StopFlags = (KS_SEEKING_FLAGS)dwStopFlags;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::SetPositions\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Positions, sizeof(KSPROPERTY_POSITIONS), &BytesReturned);
     if (SUCCEEDED(hr))
@@ -1444,7 +1526,9 @@ CKsProxy::GetPositions(
 {
     HRESULT hr;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetPositions\n");
+#endif
 
     hr = GetCurrentPosition(pCurrent);
     if (SUCCEEDED(hr))
@@ -1468,7 +1552,9 @@ CKsProxy::GetAvailable(
     Property.Id = KSPROPERTY_MEDIASEEKING_AVAILABLE;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetAvailable\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Media, sizeof(KSPROPERTY_MEDIAAVAILABLE), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1512,7 +1598,9 @@ STDMETHODCALLTYPE
 CKsProxy::SetRate(
     double dRate)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::SetRate\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -1521,7 +1609,9 @@ STDMETHODCALLTYPE
 CKsProxy::GetRate(
     double *pdRate)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetRate\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -1538,7 +1628,9 @@ CKsProxy::GetPreroll(
     Property.Id = KSPROPERTY_MEDIASEEKING_PREROLL;
     Property.Flags = KSPROPERTY_TYPE_GET;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetPreroll\n");
+#endif
 
     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pllPreroll, sizeof(LONGLONG), &BytesReturned);
     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
@@ -1584,7 +1676,7 @@ CKsProxy::GetMiscFlags()
     HRESULT hr;
     PIN_DIRECTION PinDirection;
     KSPIN_COMMUNICATION Communication;
-    WCHAR Buffer[100];
+
 
     for(Index = 0; Index < m_Pins.size(); Index++)
     {
@@ -1599,7 +1691,7 @@ CKsProxy::GetMiscFlags()
                 if (SUCCEEDED(GetPinCommunication(Index, //FIXME verify PinId
                                         &Communication)))
                 {
-                    if (Communication == KSPIN_COMMUNICATION_NONE || Communication == KSPIN_COMMUNICATION_BRIDGE)
+                    if (Communication != KSPIN_COMMUNICATION_NONE && Communication != KSPIN_COMMUNICATION_BRIDGE)
                     {
                         Flags |= AM_FILTER_MISC_FLAGS_IS_SOURCE;
                     }
@@ -1608,8 +1700,12 @@ CKsProxy::GetMiscFlags()
         }
     }
 
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
     swprintf(Buffer, L"CKsProxy::GetMiscFlags stub Flags %x\n", Flags);
     OutputDebugStringW(Buffer);
+#endif
+
     return Flags;
 }
 
@@ -1625,8 +1721,11 @@ CKsProxy::KsProperty(
     ULONG DataLength,
     ULONG* BytesReturned)
 {
-    assert(m_hDevice != 0);
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsProperty\n");
+#endif
+
+    assert(m_hDevice != 0);
     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
 }
 
@@ -1639,8 +1738,11 @@ CKsProxy::KsMethod(
     ULONG DataLength,
     ULONG* BytesReturned)
 {
-    assert(m_hDevice != 0);
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsMethod\n");
+#endif
+
+    assert(m_hDevice != 0);
     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
 }
 
@@ -1653,8 +1755,11 @@ CKsProxy::KsEvent(
     ULONG DataLength,
     ULONG* BytesReturned)
 {
-    assert(m_hDevice != 0);
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsEvent\n");
+#endif
+
+    assert(m_hDevice != 0);
     if (EventLength)
         return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
     else
@@ -1677,7 +1782,9 @@ CKsProxy::Set(
 {
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Set\n");
+#endif
 
     if (cbInstanceData)
     {
@@ -1721,7 +1828,9 @@ CKsProxy::Get(
 {
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Get\n");
+#endif
 
     if (cbInstanceData)
     {
@@ -1762,7 +1871,9 @@ CKsProxy::QuerySupported(
     KSPROPERTY Property;
     ULONG BytesReturned;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::QuerySupported\n");
+#endif
 
     Property.Set = guidPropSet;
     Property.Id = dwPropID;
@@ -1787,7 +1898,9 @@ CKsProxy::CreateNodeInstance(
 {
     HRESULT hr;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::CreateNodeInstance\n");
+#endif
 
     *Interface = NULL;
 
@@ -1812,7 +1925,9 @@ STDMETHODCALLTYPE
 CKsProxy::KsAddAggregate(
     IN REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsAddAggregate NotImplemented\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -1821,7 +1936,10 @@ STDMETHODCALLTYPE
 CKsProxy::KsRemoveAggregate(
     REFGUID AggregateClass)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsRemoveAggregate NotImplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -1834,8 +1952,10 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::IsDirty()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n");
     DebugBreak();
+#endif
     return E_NOTIMPL;
 }
 
@@ -1853,7 +1973,9 @@ CKsProxy::Load(
     ULONG PinId;
     LPOLESTR pMajor, pSub, pFormat;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Load\n");
+#endif
 
 #if 0
     ULONG Version = ReadInt(pStm, hr);
@@ -1923,7 +2045,10 @@ CKsProxy::Save(
     IStream *pStm,
     BOOL fClearDirty)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Save Notimplemented\n");
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -1932,8 +2057,11 @@ STDMETHODCALLTYPE
 CKsProxy::GetSizeMax(
     ULARGE_INTEGER *pcbSize)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n");
     DebugBreak();
+#endif
+
     return E_NOTIMPL;
 }
 
@@ -1945,8 +2073,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink)
 {
-
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::DeviceInfo\n");
+#endif
 
     if (!m_DevicePath)
     {
@@ -1971,7 +2100,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::Reassociate(void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Reassociate\n");
+#endif
 
     if (!m_DevicePath || m_hDevice)
     {
@@ -1994,7 +2125,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::Disassociate(void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Disassociate\n");
+#endif
 
     if (!m_hDevice)
         return E_HANDLE;
@@ -2012,7 +2145,10 @@ HANDLE
 STDMETHODCALLTYPE
 CKsProxy::KsGetClockHandle()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetClockHandle\n");
+#endif
+
     return m_hClock;
 }
 
@@ -2025,7 +2161,10 @@ HANDLE
 STDMETHODCALLTYPE
 CKsProxy::KsGetObjectHandle()
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::KsGetObjectHandle\n");
+#endif
+
     return m_hDevice;
 }
 
@@ -2036,7 +2175,10 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::InitNew( void)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::InitNew\n");
+#endif
+
     return S_OK;
 }
 
@@ -2323,7 +2465,6 @@ CKsProxy::CreatePins()
     KSPIN_DATAFLOW DataFlow;
     KSPIN_COMMUNICATION Communication;
     HRESULT hr;
-    WCHAR Buffer[100];
     LPWSTR PinName;
     IPin * pPin;
     ULONG InputPin = 0;
@@ -2390,8 +2531,12 @@ CKsProxy::CreatePins()
         // store pins
         m_Pins.push_back(pPin);
 
+#ifdef KSPROXY_TRACE
+        WCHAR Buffer[100];
         swprintf(Buffer, L"Index %lu DataFlow %lu Name %s\n", Index, DataFlow, PinName);
         OutputDebugStringW(Buffer);
+#endif
+
     }
 
     return S_OK;
@@ -2402,14 +2547,16 @@ STDMETHODCALLTYPE
 CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
 {
     HRESULT hr;
-    WCHAR Buffer[100];
     VARIANT varName;
     LPGUID pGuid;
     ULONG NumGuids = 0;
     HDEVINFO hList;
     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
 
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
     OutputDebugStringW(L"CKsProxy::Load\n");
+#endif
 
     // read device path
     varName.vt = VT_BSTR;
@@ -2417,14 +2564,18 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
 
     if (FAILED(hr))
     {
+#ifdef KSPROXY_TRACE
         swprintf(Buffer, L"CKsProxy::Load Read %lx\n", hr);
         OutputDebugStringW(Buffer);
+#endif
         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
     }
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"DevicePath: ");
     OutputDebugStringW(varName.bstrVal);
     OutputDebugStringW(L"\n");
+#endif
 
     // create device list
     hList = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
@@ -2453,9 +2604,10 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
     if (m_hDevice == INVALID_HANDLE_VALUE)
     {
         // failed to open device
+#ifdef KSPROXY_TRACE
         swprintf(Buffer, L"CKsProxy:: failed to open device with %lx\n", GetLastError());
         OutputDebugStringW(Buffer);
-
+#endif
         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
     }
 
@@ -2493,7 +2645,9 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Save\n");
+#endif
     return E_NOTIMPL;
 }
 
@@ -2506,7 +2660,9 @@ STDMETHODCALLTYPE
 CKsProxy::GetClassID(
     CLSID *pClassID)
 {
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetClassID\n");
+#endif
     CopyMemory(pClassID, &CLSID_Proxy, sizeof(GUID));
 
     return S_OK;
@@ -2516,8 +2672,21 @@ HRESULT
 STDMETHODCALLTYPE
 CKsProxy::Stop()
 {
-    OutputDebugStringW(L"CKsProxy::Stop : NotImplemented\n");
-    return E_NOTIMPL;
+    HRESULT hr;
+
+#ifdef KSPROXY_TRACE
+    OutputDebugStringW(L"CKsProxy::Stop\n");
+#endif
+
+    EnterCriticalSection(&m_Lock);
+
+    hr = SetPinState(KSSTATE_STOP);
+    if (SUCCEEDED(hr))
+        m_FilterState = State_Stopped;
+
+    LeaveCriticalSection(&m_Lock);
+
+    return hr;
 }
 
 HRESULT
@@ -2526,17 +2695,28 @@ CKsProxy::Pause()
 {
     HRESULT hr = S_OK;
 
+#ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::Pause\n");
+#endif
 
-    if (m_FilterState == State_Stopped)
-    {
-        hr = SetPinState(KSSTATE_PAUSE);
-        if (FAILED(hr))
-            return hr;
+    EnterCriticalSection(&m_Lock);
 
+    if (m_FilterState == State_Running)
+    {
+        hr = SetPinState(KSSTATE_STOP);
     }
+    if (SUCCEEDED(hr))
+    {
+        if (m_FilterState == State_Stopped)
+        {
+            hr = SetPinState(KSSTATE_PAUSE);
+        }
+    }
+
+    if (SUCCEEDED(hr))
+        m_FilterState = State_Paused;
 
-    m_FilterState = State_Paused;