ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
June 2009
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
21 participants
496 discussions
Start a n
N
ew thread
[cgutman] 41345: - Register the adapter shutdown handler if it is specified in the miniport characteristics
by cgutman@svn.reactos.org
Author: cgutman Date: Mon Jun 8 05:14:19 2009 New Revision: 41345 URL:
http://svn.reactos.org/svn/reactos?rev=41345&view=rev
Log: - Register the adapter shutdown handler if it is specified in the miniport characteristics Modified: trunk/reactos/drivers/network/ndis/ndis/miniport.c Modified: trunk/reactos/drivers/network/ndis/ndis/miniport.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/ndis/ndis/…
============================================================================== --- trunk/reactos/drivers/network/ndis/ndis/miniport.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/ndis/ndis/miniport.c [iso-8859-1] Mon Jun 8 05:14:19 2009 @@ -2528,6 +2528,15 @@ Adapter->NdisMiniportBlock.CheckForHangSeconds = CheckForHangTimeInSeconds; if (AttributeFlags & NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER) NDIS_DbgPrint(MAX_TRACE, ("Intermediate drivers not supported yet.\n")); + + + if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.AdapterShutdownHandler) + { + NDIS_DbgPrint(MAX_TRACE, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n")); + NdisMRegisterAdapterShutdownHandler(Adapter, + Adapter->NdisMiniportBlock.MiniportAdapterContext, + Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.AdapterShutdownHandler); + } }
15 years, 5 months
1
0
0
0
[hyperion] 41344: Fix no-op code for UNIX hosts
by hyperion@svn.reactos.org
Author: hyperion Date: Mon Jun 8 03:39:15 2009 New Revision: 41344 URL:
http://svn.reactos.org/svn/reactos?rev=41344&view=rev
Log: Fix no-op code for UNIX hosts Modified: trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp Modified: trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/backend/mingw…
============================================================================== --- trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp [iso-8859-1] Mon Jun 8 03:39:15 2009 @@ -2268,6 +2268,10 @@ // TODO? attempt to support Microsoft tools on non-Windows? #if !defined(WIN32) +#include "../../pch.h" + +#include "mingw.h" + bool MingwBackend::DetectMicrosoftCompiler ( std::string& ) {
15 years, 5 months
2
1
0
0
[hyperion] 41343: modified tools/rbuild/backend/mingw/mingw.cpp modified tools/rbuild/backend/mingw/mingw.h From now on, the MinGW back-end will also support the Microsoft command line C/C++ compiler (cl) and incremental linker (link). Support is currently limited to detecting the tools, and invoking them with the wrong arguments. Only Windows hosts are currently supported added tools/rbuild/backend/mingw/mstools_detection.cpp modified tools/rbuild/rbuild.mak Auto-detection of Microsoft compiler
by hyperion@svn.reactos.org
Author: hyperion Date: Mon Jun 8 03:33:42 2009 New Revision: 41343 URL:
http://svn.reactos.org/svn/reactos?rev=41343&view=rev
Log: modified tools/rbuild/backend/mingw/mingw.cpp modified tools/rbuild/backend/mingw/mingw.h From now on, the MinGW back-end will also support the Microsoft command line C/C++ compiler (cl) and incremental linker (link). Support is currently limited to detecting the tools, and invoking them with the wrong arguments. Only Windows hosts are currently supported added tools/rbuild/backend/mingw/mstools_detection.cpp modified tools/rbuild/rbuild.mak Auto-detection of Microsoft compiler and linker: if rbuild finds them in the path, it will use those. Otherwise, it will look for the highest version installed by any of the supported Microsoft products. Supported Microsoft products are Visual Studio 2005 and higher, Visual C++ Express and Windows DDK version 6001 and higher. Optimizing versions of the compiler will take precedence over "standard edition" compilers, regardless of version number modified tools/rbuild/configuration.cpp modified tools/rbuild/rbuild.cpp modified tools/rbuild/rbuild.h New command line options for rbuild to choose the tools set for the MinGW back-end: -Mc<compiler set>, -Ml<linker set>, -M<build tools set>. Defaults to -Mgnu, so that support for Microsoft tools has to be opted into Added: trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp (with props) Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp trunk/reactos/tools/rbuild/backend/mingw/mingw.h trunk/reactos/tools/rbuild/configuration.cpp trunk/reactos/tools/rbuild/rbuild.cpp trunk/reactos/tools/rbuild/rbuild.h trunk/reactos/tools/rbuild/rbuild.mak Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/backend/mingw…
============================================================================== --- trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -726,32 +726,47 @@ printf ( "Detecting compiler..." ); bool detectedCompiler = false; - const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" ); - if ( ROS_PREFIXValue.length () > 0 ) - { - compilerPrefix = ROS_PREFIXValue; - compilerCommand = compilerPrefix + "-gcc"; - detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); - } + bool supportedCompiler = false; + string compilerVersion; + + if ( ProjectNode.configuration.Compiler == GnuGcc ) + { + const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" ); + if ( ROS_PREFIXValue.length () > 0 ) + { + compilerPrefix = ROS_PREFIXValue; + compilerCommand = compilerPrefix + "-gcc"; + detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); + } #if defined(WIN32) - if ( !detectedCompiler ) - { - compilerPrefix = ""; - compilerCommand = "gcc"; - detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); - } + if ( !detectedCompiler ) + { + compilerPrefix = ""; + compilerCommand = "gcc"; + detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); + } #endif - if ( !detectedCompiler ) - { - compilerPrefix = "mingw32"; - compilerCommand = compilerPrefix + "-gcc"; - detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); + if ( !detectedCompiler ) + { + compilerPrefix = "mingw32"; + compilerCommand = compilerPrefix + "-gcc"; + detectedCompiler = TryToDetectThisCompiler ( compilerCommand ); + } + + if ( detectedCompiler ) + compilerVersion = GetCompilerVersion ( compilerCommand ); + + supportedCompiler = IsSupportedCompilerVersion ( compilerVersion ); + } + else if ( ProjectNode.configuration.Compiler == MicrosoftC ) + { + detectedCompiler = DetectMicrosoftCompiler ( compilerVersion ); + supportedCompiler = true; // TODO } if ( detectedCompiler ) { - string compilerVersion = GetCompilerVersion ( compilerCommand ); - if ( IsSupportedCompilerVersion ( compilerVersion ) ) + if ( supportedCompiler ) printf ( "detected (%s %s)\n", compilerCommand.c_str (), compilerVersion.c_str() ); else { @@ -953,34 +968,50 @@ printf ( "Detecting binutils..." ); bool detectedBinutils = false; - const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" ); - - if ( ROS_PREFIXValue.length () > 0 ) - { - binutilsPrefix = ROS_PREFIXValue; - binutilsCommand = binutilsPrefix + "-ld"; - manualBinutilsSetting = true; - detectedBinutils = true; - } + bool supportedBinutils = false; + string binutilsVersion; + + if ( ProjectNode.configuration.Linker == GnuLd ) + { + const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" ); + + if ( ROS_PREFIXValue.length () > 0 ) + { + binutilsPrefix = ROS_PREFIXValue; + binutilsCommand = binutilsPrefix + "-ld"; + manualBinutilsSetting = true; + detectedBinutils = true; + } #if defined(WIN32) - if ( !detectedBinutils ) - { - binutilsPrefix = ""; - binutilsCommand = "ld"; - detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); - } + if ( !detectedBinutils ) + { + binutilsPrefix = ""; + binutilsCommand = "ld"; + detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); + } #endif - if ( !detectedBinutils ) - { - binutilsPrefix = "mingw32"; - binutilsCommand = binutilsPrefix + "-ld"; - detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); - } + if ( !detectedBinutils ) + { + binutilsPrefix = "mingw32"; + binutilsCommand = binutilsPrefix + "-ld"; + detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); + } + if ( detectedBinutils ) + { + binutilsVersion = GetBinutilsVersionDate ( binutilsCommand ); + supportedBinutils = IsSupportedBinutilsVersion ( binutilsVersion ); + } + } + else if ( ProjectNode.configuration.Linker == MicrosoftLink ) + { + detectedBinutils = DetectMicrosoftLinker ( binutilsVersion ); + supportedBinutils = true; // TODO + } + if ( detectedBinutils ) { - string binutilsVersion = GetBinutilsVersionDate ( binutilsCommand ); - if ( IsSupportedBinutilsVersion ( binutilsVersion ) ) - printf ( "detected (%s %s)\n", binutilsCommand.c_str (), GetBinutilsVersion( binutilsCommand ).c_str() ); + if ( supportedBinutils ) + printf ( "detected (%s %s)\n", binutilsCommand.c_str (), binutilsVersion.c_str() ); else { printf ( "detected (%s), but with unsupported version (%s)\n", @@ -1022,33 +1053,36 @@ void MingwBackend::DetectPipeSupport () { - printf ( "Detecting compiler -pipe support..." ); - - string pipe_detection = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pipe_detection.c"; - string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection, - ".o" ); - string command = ssprintf ( - "%s -pipe -c %s -o %s 1>%s 2>%s", - FixSeparatorForSystemCommand(compilerCommand).c_str (), - pipe_detection.c_str (), - pipe_detectionObjectFilename.c_str (), - NUL, - NUL ); - int exitcode = system ( command.c_str () ); - FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" ); - if ( f ) - { - usePipe = (exitcode == 0); - fclose ( f ); - unlink ( pipe_detectionObjectFilename.c_str () ); - } - else - usePipe = false; - - if ( usePipe ) - printf ( "detected\n" ); - else - printf ( "not detected\n" ); + if ( ProjectNode.configuration.Compiler == GnuGcc ) + { + printf ( "Detecting compiler -pipe support..." ); + + string pipe_detection = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pipe_detection.c"; + string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection, + ".o" ); + string command = ssprintf ( + "%s -pipe -c %s -o %s 1>%s 2>%s", + FixSeparatorForSystemCommand(compilerCommand).c_str (), + pipe_detection.c_str (), + pipe_detectionObjectFilename.c_str (), + NUL, + NUL ); + int exitcode = system ( command.c_str () ); + FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" ); + if ( f ) + { + usePipe = (exitcode == 0); + fclose ( f ); + unlink ( pipe_detectionObjectFilename.c_str () ); + } + else + usePipe = false; + + if ( usePipe ) + printf ( "detected\n" ); + else + printf ( "not detected\n" ); + } } void @@ -1056,7 +1090,7 @@ { printf ( "Detecting compiler pre-compiled header support..." ); - if ( configuration.PrecompiledHeadersEnabled ) + if ( configuration.PrecompiledHeadersEnabled && ProjectNode.configuration.Compiler == GnuGcc ) { string path = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pch_detection.h"; string cmd = ssprintf ( Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/backend/mingw…
============================================================================== --- trunk/reactos/tools/rbuild/backend/mingw/mingw.h [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/backend/mingw/mingw.h [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -45,10 +45,12 @@ std::string AddDirectoryTarget ( const std::string& directory, Directory* directoryTree ); const Module& GetAliasedModuleOrModule ( const Module& module ) const; + bool compilerNeedsHelper; std::string compilerPrefix; std::string compilerCommand; std::string nasmCommand; std::string binutilsPrefix; + bool binutilsNeedsHelper; std::string binutilsCommand; bool usePipe, manualBinutilsSetting; Directory* intermediateDirectory; @@ -115,6 +117,8 @@ void GenerateDirectoryTargets (); FILE* fMakefile; bool use_pch; + bool DetectMicrosoftCompiler ( std::string& version ); + bool DetectMicrosoftLinker ( std::string& version ); }; Added: trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/backend/mingw…
============================================================================== --- trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp (added) +++ trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -1,0 +1,2285 @@ +/* + * Copyright (C) 2009 KJK::Hyperion + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if defined(WIN32) + +#define UNICODE +#define _UNICODE + +#include "../../pch.h" + +#include "mingw.h" + +#ifndef ARRAYSIZE +#define ARRAYSIZE(X_) (sizeof(X_) / sizeof((X_)[0])) +#endif + +#include <ole2.h> + +#include <assert.h> +#include <stdlib.h> +#include <tchar.h> + +#include <string> +#include <istream> +#include <streambuf> +#include <ios> +#include <iostream> +#include <iterator> +#include <functional> +#include <locale> +#include <vector> +#include <algorithm> +#include <limits> +#include <sstream> + +#if defined(_CPPLIB_VER) +#include <fstream> +typedef std::filebuf stdio_filebuf; +#elif defined(__GLIBCXX__) +#include <ext/stdio_sync_filebuf.h> +typedef __gnu_cxx::stdio_sync_filebuf<char> stdio_filebuf; +#else +#error Unknown or unsupported C++ standard library +#endif + +namespace +{ + +#if 1 +HRESULT dispPropGet(IDispatch * object, DISPID dispid, VARIANTARG * args, UINT ccArgs, VARTYPE vt, VARIANT& result) +{ + HRESULT hr; + + DISPPARAMS params = {}; + params.rgvarg = args; + params.cArgs = ccArgs; + + hr = object->Invoke(dispid, IID_NULL, 0, DISPATCH_PROPERTYGET | (ccArgs ? DISPATCH_METHOD : 0), ¶ms, &result, NULL, NULL); + + if(SUCCEEDED(hr)) + hr = VariantChangeType(&result, &result, 0, vt); + + return hr; +} + +HRESULT dispPropGet(IDispatch * object, const OLECHAR * name, VARIANTARG * args, UINT ccArgs, VARTYPE vt, VARIANT& result) +{ + HRESULT hr; + + DISPID dispid; + hr = object->GetIDsOfNames(IID_NULL, const_cast<OLECHAR **>(&name), 1, 0, &dispid); + + if(SUCCEEDED(hr)) + hr = dispPropGet(object, dispid, args, ccArgs, vt, result); + + return hr; +} + +VARIANT dispPropGet(HRESULT& hr, IDispatch * object, DISPID dispid, VARTYPE vt) +{ + VARIANT ret; + VariantInit(&ret); + + if(SUCCEEDED(hr)) + hr = dispPropGet(object, dispid, 0, 0, vt, ret); + + return ret; +} + +VARIANT dispPropGet(HRESULT& hr, IDispatch * object, const OLECHAR * name, VARTYPE vt) +{ + VARIANT ret; + VariantInit(&ret); + + if(SUCCEEDED(hr)) + hr = dispPropGet(object, name, 0, 0, vt, ret); + + return ret; +} + +HRESULT dispInvoke(IDispatch * object, DISPID dispid, VARIANTARG * args, UINT ccArgs, VARTYPE vt, VARIANT& result) +{ + HRESULT hr; + + DISPPARAMS params = {}; + params.rgvarg = args; + params.cArgs = ccArgs; + + hr = object->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, ¶ms, &result, NULL, NULL); + + if(SUCCEEDED(hr)) + hr = VariantChangeType(&result, &result, 0, vt); + + return hr; +} + +HRESULT dispInvoke(IDispatch * object, DISPID dispid, const VARIANTARG& arg, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, dispid, const_cast<VARIANTARG *>(&arg), 1, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, DISPID dispid, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, dispid, NULL, 0, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, VARIANTARG * args, UINT ccArgs, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, DISPID_VALUE, args, ccArgs, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, DISPID_VALUE, NULL, 0, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, const VARIANTARG& arg, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, DISPID_VALUE, const_cast<VARIANTARG *>(&arg), 1, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, const OLECHAR * name, VARIANTARG * args, UINT ccArgs, VARTYPE vt, VARIANT& result) +{ + HRESULT hr; + + DISPID dispid; + hr = object->GetIDsOfNames(IID_NULL, const_cast<OLECHAR **>(&name), 1, 0, &dispid); + + if(SUCCEEDED(hr)) + hr = dispInvoke(object, dispid, args, ccArgs, vt, result); + + return hr; +} + +HRESULT dispInvoke(IDispatch * object, const OLECHAR * name, const VARIANTARG& arg, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, name, const_cast<VARIANTARG *>(&arg), 1, vt, result); +} + +HRESULT dispInvoke(IDispatch * object, const OLECHAR * name, VARTYPE vt, VARIANT& result) +{ + return dispInvoke(object, name, NULL, 0, vt, result); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, DISPID dispid, VARIANTARG * args, UINT ccArgs, VARTYPE vt) +{ + VARIANT ret; + VariantInit(&ret); + + if(SUCCEEDED(hr)) + hr = dispInvoke(object, dispid, args, ccArgs, vt, ret); + + return ret; +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, const OLECHAR * name, VARIANTARG * args, UINT ccArgs, VARTYPE vt) +{ + VARIANT ret; + VariantInit(&ret); + + if(SUCCEEDED(hr)) + hr = dispInvoke(object, name, args, ccArgs, vt, ret); + + return ret; +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, DISPID dispid, const VARIANTARG& arg, VARTYPE vt) +{ + return dispInvoke(hr, object, dispid, const_cast<VARIANTARG *>(&arg), 1, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, DISPID dispid, VARTYPE vt) +{ + return dispInvoke(hr, object, dispid, NULL, 0, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, VARIANTARG * args, UINT ccArgs, VARTYPE vt) +{ + return dispInvoke(hr, object, DISPID(DISPID_VALUE), args, ccArgs, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, VARTYPE vt) +{ + return dispInvoke(hr, object, DISPID(DISPID_VALUE), NULL, 0, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, const VARIANTARG& arg, VARTYPE vt) +{ + return dispInvoke(hr, object, DISPID(DISPID_VALUE), const_cast<VARIANTARG *>(&arg), 1, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, const OLECHAR * name, const VARIANTARG& arg, VARTYPE vt) +{ + return dispInvoke(hr, object, name, const_cast<VARIANTARG *>(&arg), 1, vt); +} + +VARIANT dispInvoke(HRESULT& hr, IDispatch * object, const OLECHAR * name, VARTYPE vt) +{ + return dispInvoke(hr, object, name, NULL, 0, vt); +} + +VARIANT oleString(HRESULT& hr, const OLECHAR * sz) +{ + VARIANT v; + VariantInit(&v); + + if(SUCCEEDED(hr)) + { + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = SysAllocString(sz); + + if(!V_BSTR(&v)) + hr = E_OUTOFMEMORY; + } + + if(FAILED(hr)) + { + V_VT(&v) = VT_ERROR; + V_ERROR(&v) = hr; + } + + return v; +} + +#endif + +#if 1 +namespace knuth_morris_pratt +{ + +namespace details +{ + +template<class Iter> +typename std::iterator_traits<Iter>::iterator_category iterator_category(const Iter&) +{ + return typename std::iterator_traits<Iter>::iterator_category(); +} + +template<typename TypeX, typename TypeY> +struct type_equals +{ + enum { value = 0 }; +}; + +template<typename TypeX> +struct type_equals<TypeX, TypeX> +{ + enum { value = 1 }; +}; + +template<class Iter, class diff_type> +void advance_substr(Iter& pos, Iter, diff_type, diff_type rel, const std::bidirectional_iterator_tag&) +{ + std::advance(pos, rel); +} + +template<class Iter, class diff_type> +void advance_substr(Iter& pos, Iter begin, diff_type absol, diff_type rel, const std::forward_iterator_tag&) +{ + if(rel > 0) + std::advance(pos, rel); + else + { + pos = begin; + std::advance(pos, absol); + } +} + +template<class Iter, class diff_type> +void advance_substr(Iter& pos, Iter begin, diff_type absol, diff_type rel) +{ + advance_substr(pos, begin, absol, rel, iterator_category(pos)); +} + +template<class T, size_t N> +struct fixed_table +{ +public: + typedef typename std::iterator_traits<T *>::difference_type value_type; + typedef value_type * pointer; + typedef value_type& reference; + typedef const value_type * const_pointer; + typedef const value_type& const_reference; + typedef typename std::allocator<value_type>::difference_type difference_type; + typedef typename std::allocator<value_type>::size_type size_type; + +private: + value_type m_table[(N)]; + +public: + static pointer address(reference r) { return &r; } + static const_pointer address(const_reference r) { return &r; } + static size_type max_size() { return (N); } + static void construct(pointer p, const T& v) { p->T(v); } + static void destroy(pointer p) { p->~T(); } + template<class Other> struct rebind { typedef fixed_table<Other, N> other; }; + + template<class Other> pointer allocate(size_type n, const Other * hint) + { + assert(n <= (N)); + assert(hint == 0); + return m_table; + } + + pointer allocate(size_type n) + { + assert(n <= (N)); + return m_table; + } + + void deallocate(pointer p, size_type n) const + { + assert(p == m_table); + assert(n <= (N)); + } +}; + +void validate_range_iterator_category(const std::input_iterator_tag&) { } +void validate_substr_iterator_category(const std::forward_iterator_tag&) { } + +template<class RangeIter, class SubstrIter> +RangeIter search_cornercase_neg(RangeIter, RangeIter end, SubstrIter) +{ + return end; +} + +template<class RangeIter, class SubstrIter> +RangeIter search_cornercase0(RangeIter begin, RangeIter, SubstrIter) +{ + return begin; +} + +template<class RangeIter, class SubstrIter> +RangeIter search_cornercase1(RangeIter begin, RangeIter end, SubstrIter substrBegin) +{ + RangeIter pos = std::find(begin, end, *substrBegin); + + if(type_equals<typename std::iterator_traits<RangeIter>::iterator_category, std::input_iterator_tag>::value && pos != end) + ++ pos; + + return pos; +} + +template<class SubstrIter, class TableType, class TableSize> +void search_createtable_dynamic +( + SubstrIter beginSubstr, + typename std::iterator_traits<SubstrIter>::difference_type substrSize, + TableType table, + TableSize +) +{ + typedef typename std::iterator_traits<SubstrIter>::difference_type substr_diff_type; + typedef typename TableType::pointer table_type; + typedef TableSize table_size_type; + + substr_diff_type i(2); + SubstrIter pi = beginSubstr; + std::advance(pi, substr_diff_type(1)); + + substr_diff_type j(0); + SubstrIter pj = beginSubstr; + std::advance(pj, substr_diff_type(0)); + + while(i < substrSize) + { + if(*pi == *pj) + { + substr_diff_type new_j = j; + ++ new_j; + + table[static_cast<table_size_type>(i)] = new_j; + + ++ i; ++ pi; + ++ j; ++ pj; + } + else if(j > 0) + { + substr_diff_type new_j = table[i]; + details::advance_substr(pj, beginSubstr, new_j, new_j - j); + j = new_j; + } + else + { + table[i] = 0; + ++ i; ++ pi; + } + } +} + +template<class D, class S, size_t N> +void search_createtable_static +( + const S (& substr)[N], + D (& table)[N] +) +{ + typedef std::ptrdiff_t substr_diff_type; + + table[0] = substr_diff_type(-1); + table[1] = substr_diff_type(0); + + substr_diff_type pos = 2; + substr_diff_type cnd = 0; + + while(pos < static_cast<substr_diff_type>(N)) + { + if(substr[pos - 1] == substr[cnd]) + { + table[pos] = cnd + 1; + ++ pos; + ++ cnd; + } + else if(cnd > 0) + cnd = table[cnd]; + else + { + table[pos] = 0; + ++ pos; + } + } +} + +template<class RangeIter, class SubstrIter, class Table, class TableSize> +RangeIter search +( + const RangeIter& begin, + const RangeIter& end, + const SubstrIter beginSubstr, + typename std::iterator_traits<SubstrIter>::difference_type substrSize, + Table table, + TableSize +) +{ + details::validate_range_iterator_category(details::iterator_category(begin)); + details::validate_substr_iterator_category(details::iterator_category(beginSubstr)); + + typedef typename std::iterator_traits<SubstrIter>::difference_type substr_diff_type; + typedef Table table_type; + typedef TableSize table_size_type; + + // Find the next match + substr_diff_type iSubstr(0); // i + RangeIter pCurMatch = begin; // m + RangeIter pCurElem = begin; // m + i + SubstrIter pCurSubstrElem = beginSubstr; // i + + while(pCurElem != end) + { + if(*pCurSubstrElem == *pCurElem) + { + ++ iSubstr; // ++ i + + if(iSubstr == substrSize) + { + // For input iterators, we return the end of the match + if(type_equals<typename std::iterator_traits<RangeIter>::iterator_category, std::input_iterator_tag>::value) + ++ pCurElem; // return m + i + 1 + // For all other iterators, we return the beginning of the match + else + pCurElem = pCurMatch; // return m + + break; + } + + ++ pCurElem; // ++ i + ++ pCurSubstrElem; // ++ i + } + else + { + substr_diff_type table_iSubstr = table[static_cast<table_size_type>(iSubstr)]; // T[i] + substr_diff_type iSubstr_backtracked = iSubstr - table_iSubstr; // i - T[i] + assert(iSubstr_backtracked >= substr_diff_type(0)); + + if(!type_equals<typename std::iterator_traits<RangeIter>::iterator_category, std::input_iterator_tag>::value) + std::advance(pCurMatch, iSubstr_backtracked); // m = m + i - T[i] + + if(iSubstr > substr_diff_type(0)) // i > 0 + { + iSubstr = table_iSubstr; // i = T[i] + pCurSubstrElem = beginSubstr; + std::advance(pCurSubstrElem, iSubstr); // i = T[i] + } + else + std::advance(pCurElem, iSubstr_backtracked); + } + } + + return pCurElem; +} + +}; + +template<class RangeIter, class SubstrIter, class AllocTable> +RangeIter search(RangeIter begin, RangeIter end, SubstrIter beginSubstr, SubstrIter endSubstr, AllocTable& allocTable) +{ + typename std::iterator_traits<SubstrIter>::difference_type substrSize = std::distance(beginSubstr, endSubstr); + + if(substrSize < 0) + return knuth_morris_pratt::details::search_cornercase_neg(begin, end, beginSubstr); + + if(substrSize == 0) + return knuth_morris_pratt::details::search_cornercase0(begin, end, beginSubstr); + + if(substrSize == 1) + return knuth_morris_pratt::details::search_cornercase1(begin, end, beginSubstr); + + typedef typename AllocTable::size_type table_size; + typedef typename AllocTable::pointer table_type; + + table_size tableSize = static_cast<table_size>(substrSize); + table_type table = allocTable.allocate(tableSize); + + RangeIter pos = knuth_morris_pratt::details::search(begin, end, beginSubstr, substrSize, table, tableSize); + + allocTable.deallocate(table, tableSize); + + return pos; +} + +template<class RangeIter, class SubstrIter> +RangeIter search(RangeIter begin, RangeIter end, SubstrIter beginSubstr, SubstrIter endSubstr) +{ + std::allocator<typename std::iterator_traits<SubstrIter>::difference_type> allocTable; + return knuth_morris_pratt::search(begin, end, beginSubstr, endSubstr, allocTable); +} + +template<class RangeIter, class SubstrElem, size_t N> +RangeIter search(RangeIter begin, RangeIter end, const SubstrElem (& substr)[(N)]) +{ + if((N) == 0) + return knuth_morris_pratt::details::search_cornercase0(begin, end, substr); + + if((N) == 1) + return knuth_morris_pratt::details::search_cornercase1(begin, end, substr); + + if((N) * sizeof(SubstrElem) <= 4096) + { + ptrdiff_t table[N]; + knuth_morris_pratt::details::search_createtable_static(substr, table); + return knuth_morris_pratt::details::search(begin, end, substr, (N), table, sizeof(table)); + } + else + return knuth_morris_pratt::search(begin, end, substr, substr + (N)); +} + +} +#endif + +#if 1 +template<class CharT, class Traits, class Alloc, size_t N, class ReplIter> +std::basic_string<CharT, Traits, Alloc> replace(const std::basic_string<CharT, Traits, Alloc>& str, const CharT (& substr)[(N)], ReplIter replBegin, ReplIter replEnd) +{ + if((N) == 0) + return str; + + std::basic_string<CharT, Traits, Alloc> newStr; + typename std::basic_string<CharT, Traits, Alloc>::const_iterator cur = str.begin(); + typename std::basic_string<CharT, Traits, Alloc>::const_iterator end = str.end(); + + while(cur != end) + { + typename std::basic_string<CharT, Traits, Alloc>::const_iterator found = knuth_morris_pratt::search(cur, end, *reinterpret_cast<const CharT (*)[(N) - 1]>(&substr)); + + newStr.append(cur, found); + cur = found; + + if(found != end) + { + newStr.append(replBegin, replEnd); + advance(cur, (N) - 1); + } + } + + return newStr; +} + +template<class CharT, class Traits, class Alloc, size_t N, size_t M> +std::basic_string<CharT, Traits, Alloc> replace(const std::basic_string<CharT, Traits, Alloc>& str, const CharT (& substr)[(N)], const CharT (& repl)[(M)]) +{ + return replace(str, substr, repl, repl + ((M) - 1)); +} + +template<class CharT, class Traits, class Alloc, size_t N, class Traits2, class Alloc2> +std::basic_string<CharT, Traits, Alloc> replace(const std::basic_string<CharT, Traits, Alloc>& str, const CharT (& substr)[(N)], const std::basic_string<CharT, Traits2, Alloc2>& repl) +{ + return replace(str, substr, repl.begin(), repl.end()); +} + +template<class CharT, class Traits, class Alloc, size_t M, class Traits2, class Alloc2> +std::basic_string<CharT, Traits, Alloc> replace(const std::basic_string<CharT, Traits, Alloc>& str, const std::basic_string<CharT, Traits2, Alloc2>& substr, const CharT (& repl)[(M)]) +{ + return replace(str, substr.begin(), substr.end(), repl, repl + ((M) - 1)); +} + +template<class CharT, class Traits, class Alloc, class Traits2, class Alloc2, class Traits3, class Alloc3> +std::basic_string<CharT, Traits, Alloc> replace(const std::basic_string<CharT, Traits, Alloc>& str, const std::basic_string<CharT, Traits2, Alloc2>& substr, const std::basic_string<CharT, Traits3, Alloc3>& repl) +{ + return replace(str, substr.begin(), substr.end(), repl.begin(), repl.end()); +} + +template<typename TypeX, typename TypeY> +struct type_equals +{ + enum { value = 0 }; +}; + +template<typename TypeX> +struct type_equals<TypeX, TypeX> +{ + enum { value = 1 }; +}; + +template<class InIter, class Dist> +bool advance_between_impl(InIter& cur, const InIter& begin, const InIter& end, Dist off, const std::input_iterator_tag&) +{ + if(Dist(0) < off) + for(; off != Dist(0) && cur != end; -- off) + ++ cur; + + return off == Dist(0); +} + +template<class InIter, class Dist> +bool advance_between_impl(InIter& cur, const InIter& begin, const InIter& end, Dist off, const std::bidirectional_iterator_tag&) +{ + if(Dist(0) < off) + for(; off != Dist(0) && cur != end; -- off) + ++ cur; + else + for(; off != Dist(0) && cur != begin; ++ off) + ++ cur; + + return off == Dist(0); +} + +template<class InIter, class Dist> +bool advance_between_impl(InIter& cur, const InIter& begin, const InIter& end, Dist off, const std::random_access_iterator_tag&) +{ + bool ret; + + if(Dist(0) < off) + { + Dist max = distance(cur, end); + ret = off == max || off < max; + } + else + { + Dist max = distance(cur, end); + ret = abs(off) == max || abs(off) < max; + } + + if(ret) + advance(cur, off); + + return ret; +} + +template<class InIter, class Dist> +bool advance_between(InIter& cur, const InIter& begin, const InIter& end, Dist off) +{ + return advance_between_impl(cur, begin, end, off, typename std::iterator_traits<InIter>::iterator_category()); +} + +template<class InIter, class Elem, class Traits, class InIterTag> +class range_streambuf_base: public std::basic_streambuf<Elem, Traits> +{ +public: + typedef typename std::basic_streambuf<Elem, Traits>::int_type int_type; + typedef typename std::basic_streambuf<Elem, Traits>::pos_type pos_type; + typedef typename std::basic_streambuf<Elem, Traits>::off_type off_type; + +protected: + InIter m_cur; + InIter m_end; + int_type m_ungetc; + int_type m_putbackc; + + int_type get_char() + { + int_type c = m_ungetc; + + if(c == Traits::eof()) + { + if(m_cur != m_end) + { + c = *m_cur; + ++ m_cur; + } + } + else + m_ungetc = Traits::eof(); + + return c; + } + + int_type unget_char(int_type c) + { + if(c == Traits::eof()) + return c; + + if(m_ungetc == Traits::eof()) + m_ungetc = c; + else + return Traits::eof(); + + return c; + } + +protected: + range_streambuf_base(const InIter& begin, const InIter& end): + m_cur(begin), + m_end(end), + m_ungetc(Traits::eof()), + m_putbackc(Traits::eof()) + { + } + +public: + virtual int_type pbackfail(int_type c) + { + int_type ret; + + if(Traits::eq_int_type(c, Traits::eof())) + { + if(!Traits::eq_int_type(m_putbackc, Traits::eof())) + ret = unget_char(m_putbackc); + else + ret = Traits::eof(); + } + else + ret = unget_char(c); + + m_putbackc = Traits::eof(); + return ret; + } + + virtual std::streamsize showmanyc() const + { + return std::streamsize(-1); + } + + virtual int_type underflow() + { + return unget_char(get_char()); + } + + virtual int_type uflow() + { + m_putbackc = get_char(); + return m_putbackc; + } + + virtual std::streamsize xsgetn(Elem * p, std::streamsize n) + { + return _Xsgetn_s(p, std::numeric_limits<size_t>::max(), n); + } + + virtual std::streamsize _Xsgetn_s(Elem * p, size_t cb, std::streamsize n) + { + std::streamsize i; + size_t ib; + + for(i = 0, ib = 0; i < n && ib < cb; ++ i, ++ ib, ++ p) + { + int_type c = get_char(); + + if(c == Traits::eof()) + break; + + *p = Traits::to_char_type(c); + } + + if(i > 0) + m_putbackc = p[-1]; + else + m_putbackc = Traits::eof(); + + return i; + } + + virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode) + { + if(((off == 0 && dir == std::ios_base::end) || (off >= 0 && dir == std::ios_base::cur)) && !(mode & std::ios_base::out)) + { + m_ungetc = Traits::eof(); + + if(dir == std::ios_base::end) + m_cur = m_end; + + advance_between(m_cur, m_cur, m_end, off); + } + + return pos_type(-1); + } +}; + +template<class InIter, class Elem, class Traits> +class range_streambuf_base<InIter, Elem, Traits, std::forward_iterator_tag>: + public range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag> +{ +public: + typedef typename range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag>::int_type int_type; + typedef typename range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag>::pos_type pos_type; + typedef typename range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag>::off_type off_type; + +private: + typedef range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag> super; + InIter m_begin; + +protected: + range_streambuf_base(const InIter& begin, const InIter& end): + m_begin(begin), + range_streambuf_base<InIter, Elem, Traits, std::input_iterator_tag>(begin, end) + { + } + +public: + virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode) + { + if(!(mode & std::ios_base::out) && off >= 0) + { + if(dir == std::ios_base::beg) + super::m_cur = m_begin; + else if(dir != std::ios_base::cur) + super::m_cur = super::m_end; + + advance_between(super::m_cur, m_begin, super::m_end, off); + } + + return pos_type(-1); + } +}; + +template<class InIter, class Elem, class Traits> +class range_streambuf_base<InIter, Elem, Traits, std::bidirectional_iterator_tag>: public std::basic_streambuf<Elem, Traits> +{ +public: + typedef typename std::basic_streambuf<Elem, Traits>::int_type int_type; + typedef typename std::basic_streambuf<Elem, Traits>::pos_type pos_type; + typedef typename std::basic_streambuf<Elem, Traits>::off_type off_type; + +protected: + InIter m_begin; + InIter m_cur; + InIter m_end; + +protected: + range_streambuf_base(const InIter& begin, const InIter& end): + m_begin(begin), + m_cur(begin), + m_end(end) + { + } + +public: + virtual int_type pbackfail(int_type c) + { + int_type ret = Traits::eof(); + + if(m_cur != m_begin) + { + InIter prev = m_cur; + -- prev; + + if(Traits::eq_int_type(c, Traits::eof()) || Traits::eq_int_type(c, Traits::to_int_type(*prev))) + { + -- m_cur; + ret = Traits::to_int_type(*m_cur); + } + } + + return ret; + } + + virtual std::streamsize showmanyc() const + { + return std::streamsize(-1); + } + + virtual int_type underflow() + { + if(m_cur != m_end) + return *m_cur; + else + return Traits::eof(); + } + + virtual int_type uflow() + { + int_type c = Traits::eof(); + + if(m_cur != m_end) + { + c = *m_cur; + ++ m_cur; + } + + return c; + } + + virtual std::streamsize xsgetn(Elem * p, std::streamsize n) + { + return _Xsgetn_s(p, std::numeric_limits<size_t>::max(), n); + } + + virtual std::streamsize _Xsgetn_s(Elem * p, size_t cb, std::streamsize n) + { + std::streamsize i; + size_t ib; + + for(i = 0, ib = 0; i < n && ib < cb && m_cur != m_end; ++ i, ++ ib, ++ p, ++ m_cur) + *p = Traits::to_char_type(*m_cur); + + return i; + } + + virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode) + { + if(mode & std::ios_base::out) + return pos_type(-1); + + if(dir == std::ios_base::beg) + m_cur = m_begin; + else if(dir != std::ios_base::cur) + m_cur = m_end; + + if(!advance_between(m_cur, m_begin, m_end, off)) + return pos_type(-1); + + return m_cur - m_begin; + } +}; + +template<class InIter, class Elem, class Traits> +class range_streambuf_base<InIter, Elem, Traits, std::random_access_iterator_tag>: + public range_streambuf_base<InIter, Elem, Traits, std::bidirectional_iterator_tag> +{ +private: + typedef range_streambuf_base<InIter, Elem, Traits, std::bidirectional_iterator_tag> super; + +protected: + range_streambuf_base(const InIter& begin, const InIter& end): + range_streambuf_base<InIter, Elem, Traits, std::bidirectional_iterator_tag>(begin, end) + { + } + +public: + virtual std::streamsize showmanyc() const + { + return distance(super::m_cur, super::m_end); + } + + virtual std::streamsize _Xsgetn_s(Elem * p, size_t cb, std::streamsize n) + { + std::streamsize maxn = showmanyc(); + + if(n > maxn) + n = maxn; + + if(cb > static_cast<size_t>(n)) + cb = static_cast<size_t>(n); + + std::copy(super::m_cur, super::m_cur + cb, p); + return cb; + } +}; + +template<class InIter, class Elem = typename std::iterator_traits<InIter>::value_type, class Traits = typename std::char_traits<Elem> > +class range_streambuf: + public range_streambuf_base<InIter, Elem, Traits, typename std::iterator_traits<InIter>::iterator_category> +{ +public: + range_streambuf(const InIter& begin, const InIter& end): + range_streambuf_base<InIter, Elem, Traits, typename std::iterator_traits<InIter>::iterator_category>(begin, end) { } +}; + +#endif + +struct version_tuple +{ +private: + unsigned short m_fields[4]; + +public: + version_tuple(): m_fields() {} + + version_tuple(unsigned short major, unsigned short minor, unsigned short build_major = 0, unsigned short build_minor = 0) + { + m_fields[0] = major; + m_fields[1] = minor; + m_fields[2] = build_major; + m_fields[3] = build_minor; + } + + version_tuple(const version_tuple& That) + { + m_fields[0] = That.m_fields[0]; + m_fields[1] = That.m_fields[1]; + m_fields[2] = That.m_fields[2]; + m_fields[3] = That.m_fields[3]; + } + + const version_tuple& operator=(const version_tuple& That) + { + m_fields[0] = That.m_fields[0]; + m_fields[1] = That.m_fields[1]; + m_fields[2] = That.m_fields[2]; + m_fields[3] = That.m_fields[3]; + return *this; + } + + unsigned short get_major() const + { + return m_fields[0]; + } + + unsigned short get_minor() const + { + return m_fields[1]; + } + + unsigned short get_build_major() const + { + return m_fields[2]; + } + + unsigned short get_build_minor() const + { + return m_fields[3]; + } + + bool operator==(const version_tuple& That) const + { + return memcmp(this->m_fields, That.m_fields, sizeof(this->m_fields)) == 0; + } + + bool operator<(const version_tuple& That) const + { + return std::lexicographical_compare + ( + &(this->m_fields[0]) + 0, + &(this->m_fields[0]) + ARRAYSIZE(this->m_fields), + &(That.m_fields[0]) + 0, + &(That.m_fields[0]) + ARRAYSIZE(That.m_fields) + ); + } + + bool operator<=(const version_tuple& That) const + { + return (*this == That) || (*this < That); + } + + bool operator>(const version_tuple& That) const + { + return !(*this <= That); + } + + bool operator>=(const version_tuple& That) const + { + return !(*this < That); + } +}; + +template<class Elem, class Tr> std::basic_ostream<Elem, Tr>& operator<<(std::basic_ostream<Elem, Tr>& ostr, const version_tuple& v) +{ + std::ios_base::fmtflags flags = ostr.flags(); + ostr.flags(std::ios_base::dec); + ostr << v.get_major(); + ostr << Tr::to_char_type('.'); + ostr << v.get_minor(); + ostr << Tr::to_char_type('.'); + ostr << v.get_build_major(); + ostr << Tr::to_char_type('.'); + ostr << v.get_build_minor(); + ostr.flags(flags); + return ostr; +} + +template<class Elem, class Tr> std::basic_istream<Elem, Tr>& operator>>(std::basic_istream<Elem, Tr>& istr, version_tuple& v) +{ + const std::ctype<Elem>& ct = std::use_facet<std::ctype<Elem> >(istr.getloc()); + unsigned short a = 0, b = 0, c = 0, d = 0; + Elem ch; + + std::ios_base::fmtflags flags = istr.setf(std::ios_base::dec); + + if(istr >> a) + { + istr >> ch; + + if(ch == ct.widen('.')) + { + if(istr >> b) + { + istr >> ch; + + if(ch == ct.widen('.')) + { + if(istr >> c) + { + istr >> ch; + + if(ch == ct.widen('.')) + istr >> d; + else + istr.putback(ch); + } + } + else + istr.putback(ch); + + if(istr) + { + v = version_tuple(a, b, c, d); + istr.flags(flags); + return istr; + } + } + } + else + istr.putback(ch); + } + + istr.flags(flags); + istr.setstate(std::ios_base::failbit); + return istr; +} + +struct cl_version: public version_tuple +{ +private: + bool m_optimizing; + +public: + cl_version(): m_optimizing() {} + + cl_version(const version_tuple& version_number, bool optimizing = false): + version_tuple(version_number), m_optimizing(optimizing) {} + + cl_version + ( + unsigned short major, + unsigned short minor, + unsigned short build_major = 0, + unsigned short build_minor = 0, + bool optimizing = false, + bool analyze = false + ): + version_tuple(major, minor, build_major, build_minor), m_optimizing(optimizing) {} + + cl_version(const cl_version& That): version_tuple(That), m_optimizing(That.m_optimizing) {} + + const cl_version& operator=(const cl_version& That) + { + version_tuple::operator=(That); + m_optimizing = That.m_optimizing; + return *this; + } + + bool is_optimizing() const + { + return m_optimizing; + } + + bool operator==(const cl_version& That) const + { + return this->m_optimizing == That.m_optimizing && this->version_tuple::operator==(That); + } + + bool operator<(const cl_version& That) const + { + return (!this->m_optimizing && That.m_optimizing) || this->version_tuple::operator<(That); + } + + bool operator<=(const cl_version& That) const + { + return (*this == That) || (*this < That); + } + + bool operator>(const cl_version& That) const + { + return !(*this <= That); + } + + bool operator>=(const cl_version& That) const + { + return !(*this < That); + } + + operator bool() const + { + return get_major() || get_minor() || get_build_major() || get_build_minor(); + } +}; + +struct link_version: public version_tuple +{ +public: + link_version() {} + + link_version(const version_tuple& version_number): version_tuple(version_number) {} + + link_version + ( + unsigned short major, + unsigned short minor, + unsigned short build_major = 0, + unsigned short build_minor = 0 + ): + version_tuple(major, minor, build_major, build_minor) {} + + link_version(const link_version& That): version_tuple(That) {} + + const link_version& operator=(const link_version& That) + { + version_tuple::operator=(That); + return *this; + } + + bool operator==(const cl_version& That) const + { + return this->version_tuple::operator==(That); + } + + bool operator<(const cl_version& That) const + { + return this->version_tuple::operator<(That); + } + + bool operator<=(const cl_version& That) const + { + return (*this == That) || (*this < That); + } + + bool operator>(const cl_version& That) const + { + return !(*this <= That); + } + + bool operator>=(const cl_version& That) const + { + return !(*this < That); + } + + operator bool() const + { + return get_major() || get_minor() || get_build_major() || get_build_minor(); + } +}; + +template<typename T> +struct type_holder +{ + typedef T type; +}; + +template<class Elem, class Traits, class Ax> +std::basic_string<Elem, Traits, Ax> get_env(const Elem * name, const type_holder<Traits>&, const type_holder<Ax>&) +{ + DWORD cchValue = 0; + std::vector<Elem, Ax> value; + + for(;;) + { + value.resize(cchValue); + + if(type_equals<Elem, CHAR>::value) + cchValue = GetEnvironmentVariableA(reinterpret_cast<const CHAR *>(name), reinterpret_cast<CHAR *>(cchValue ? &(value[0]) : NULL), cchValue); + else if(type_equals<Elem, WCHAR>::value) + cchValue = GetEnvironmentVariableW(reinterpret_cast<const WCHAR *>(name), reinterpret_cast<WCHAR *>(cchValue ? &(value[0]) : NULL), cchValue); + + if(cchValue == 0) + return std::basic_string<Elem, Traits, Ax>(); + + if(cchValue <= value.size()) + break; + } + + value.resize(cchValue); + return std::basic_string<Elem, Traits, Ax>(value.begin(), value.end()); +} + +template<class Traits, class Ax, class Elem> +std::basic_string<Elem, Traits, Ax> get_env(const Elem * name) +{ + return get_env(name, type_holder<Traits>(), type_holder<Ax>()); +} + +template<class Traits, class Elem> +std::basic_string<Elem, Traits> get_env(const Elem * name) +{ + return get_env(name, type_holder<Traits>(), type_holder<typename std::basic_string<Elem>::allocator_type>()); +} + +template<class Elem> +std::basic_string<Elem> get_env(const Elem * name) +{ + return get_env(name, type_holder<typename std::basic_string<Elem>::traits_type>(), type_holder<typename std::basic_string<Elem>::allocator_type>()); +} + +template<class Elem> +void set_env(const Elem * name, const Elem * value) +{ + if(type_equals<Elem, CHAR>::value) + SetEnvironmentVariableA(reinterpret_cast<const CHAR *>(name), reinterpret_cast<const CHAR *>(value)); + else if(type_equals<Elem, WCHAR>::value) + SetEnvironmentVariableW(reinterpret_cast<const WCHAR *>(name), reinterpret_cast<const WCHAR *>(value)); +} + +template<class CharT> +FILE * pipe_open(const CharT * commandLine, const CharT * mode) +{ + if(type_equals<CharT, char>::value) + return _popen(reinterpret_cast<const char *>(commandLine), reinterpret_cast<const char *>(mode)); + else if(type_equals<CharT, wchar_t>::value) + return _wpopen(reinterpret_cast<const wchar_t *>(commandLine), reinterpret_cast<const wchar_t *>(mode)); + else + return NULL; +} + +template<class CharT, class CharT2> +FILE * pipe_open_override_path(const CharT * commandLine, const CharT * mode, const CharT2 * newPath) +{ + FILE * pipe = NULL; + const CharT2 path[] = { 'P', 'A', 'T', 'H', 0 }; + + std::basic_string<CharT2> oldPath; + + if(newPath) + { + oldPath = get_env(path); + set_env(path, newPath); + } + + try + { + pipe = pipe_open(commandLine, mode); + } + catch(...) + { + if(pipe != NULL) + fclose(pipe); + + if(newPath) + set_env(path, oldPath.c_str()); + + throw; + } + + if(newPath) + set_env(path, oldPath.c_str()); + + return pipe; +} + +template<class InIter, class IsSep> +std::pair<InIter, InIter> tokenize(InIter begin, InIter end, IsSep isSeparator) +{ + InIter beginToken = std::find_if(begin, end, std::not1(isSeparator)); + InIter endToken = std::find_if(beginToken, end, isSeparator); + return std::make_pair(beginToken, endToken); +} + +std::locale clocale("C"); +const std::ctype<char>& cctype = std::use_facet<std::ctype<char> >(clocale); + +template<const std::ctype_base::mask Mask> +struct is_ctype_l: public std::binary_function<std::locale, char, bool> +{ +public: + result_type operator()(const first_argument_type& locale, second_argument_type c) const + { + return std::use_facet<std::ctype<char> >(locale).is(Mask, c); + } +}; + +typedef is_ctype_l<std::ctype_base::space> is_space_l; + +template<const std::ctype_base::mask Mask> +struct is_ctype: public std::unary_function<char, bool> +{ +private: + const std::locale& m_locale; + is_ctype_l<Mask> m_is_ctype_l; + +public: + is_ctype(const std::locale& locale): m_locale(locale) {} + + result_type operator()(argument_type c) const + { + return m_is_ctype_l(m_locale, c); + } +}; + +typedef is_ctype<std::ctype_base::space> is_space; + +template<class Elem, size_t N> +std::pair<const Elem *, const Elem *> string_literal_token(const Elem (& lit)[N]) +{ + return std::make_pair(lit, lit + ((N) - 1)); +} + +template<class Iter, class Iter2> +bool token_equals(const std::pair<Iter, Iter>& tokenX, const std::pair<Iter2, Iter2>& tokenY) +{ + return std::distance(tokenX.first, tokenX.second) == std::distance(tokenY.first, tokenY.second) && std::equal(tokenX.first, tokenX.second, tokenY.first); +} + +std::pair<const char *, const char *> GetClArchToken(const std::string& arch) +{ + if(arch == "i386") + return string_literal_token("80x86"); + else if(arch == "amd64") + return string_literal_token("x64"); + else if(arch == "arm") + return string_literal_token("ARM"); + else + return string_literal_token(""); +} + +template<class Elem> +cl_version CheckClVersion(const std::string& arch, const Elem * pathOverride) +{ + stdio_filebuf clVersionInfoBuf(pipe_open_override_path(_T("cl /nologo- 2>&1 >nul <nul"), _T("rt"), pathOverride)); + std::istream clVersionInfo(&clVersionInfoBuf); + + std::pair<const char *, const char *> archToken = GetClArchToken(arch); + + version_tuple clVersionNumber; + bool clOptimizing = false; + bool clTargetArch = false; + + std::string clVersionLine; + getline(clVersionInfo, clVersionLine); + + for + ( + std::pair<std::string::iterator, std::string::iterator> token = tokenize(clVersionLine.begin(), clVersionLine.end(), is_space(clocale)); + token.first != token.second; + token = tokenize(token.second, clVersionLine.end(), is_space(clocale)) + ) + { + // Is the compiler optimizing? + if(token_equals(token, string_literal_token("Optimizing"))) + { + clOptimizing = true; + continue; + } + + // Is this the version number? + range_streambuf<std::string::const_iterator> tokenBuf(token.first, token.second); + std::istream tokenStream(&tokenBuf); + + if(tokenStream >> clVersionNumber) + continue; + + // Does the compiler support the target architecture? + if(token_equals(token, archToken)) + { + clTargetArch = true; + continue; + } + } + + if(clTargetArch) + return cl_version(clVersionNumber, clOptimizing); + else + return cl_version(); +} + +cl_version CheckClVersion(const std::string& arch) +{ + return CheckClVersion(arch, (const char *)0); +} + +std::pair<const _TCHAR *, const _TCHAR *> GetLinkArchToken(const std::string& arch) +{ + if(arch == "i386") + return string_literal_token(_T("X86")); + else if(arch == "amd64") + return string_literal_token(_T("X64")); + else if(arch == "arm") + return string_literal_token(_T("ARM")); + else + return string_literal_token(_T("")); +} + +template<class Elem> +link_version CheckLinkVersion(const std::string& arch, const Elem * pathOverride) +{ + std::pair<const _TCHAR *, const _TCHAR *> archToken = GetLinkArchToken(arch); + + std::basic_string<_TCHAR> linkCmdLine; + linkCmdLine.append(_T("link /nologo- /machine:\"")); + linkCmdLine.append(archToken.first, archToken.second); + linkCmdLine.append(_T("\" <nul 2>nul")); + + stdio_filebuf linkOutputBuf(pipe_open_override_path(linkCmdLine.c_str(), _T("rt"), pathOverride)); + std::istream linkOutput(&linkOutputBuf); + + link_version linkVersion; + + std::string linkOutputLine; + + if(getline(linkOutput, linkOutputLine)) + { + for + ( + std::pair<std::string::iterator, std::string::iterator> token = tokenize(linkOutputLine.begin(), linkOutputLine.end(), is_space(clocale)); + token.first != token.second; + token = tokenize(token.second, linkOutputLine.end(), is_space(clocale)) + ) + { + range_streambuf<std::string::const_iterator> tokenBuf(token.first, token.second); + std::istream tokenStream(&tokenBuf); + + version_tuple linkVersionNumber; + + if(tokenStream >> linkVersionNumber) + { + linkVersion = linkVersionNumber; + break; + } + } + } + + if(linkVersion) + { + bool linkArchCheckFail = false; + + while(!linkArchCheckFail && getline(linkOutput, linkOutputLine)) + { + linkArchCheckFail = + knuth_morris_pratt::search(linkOutputLine.begin(), linkOutputLine.end(), "LNK4012") != linkOutputLine.end() || + knuth_morris_pratt::search(linkOutputLine.begin(), linkOutputLine.end(), "LNK1146") != linkOutputLine.end(); + } + + if(linkArchCheckFail) + linkVersion = link_version(); + } + + return linkVersion; +} + +link_version CheckLinkVersion(const std::string& arch) +{ + return CheckLinkVersion(arch, (const char *)0); +} + +template<class Elem, class Traits, class Ax> +void CharsToString(HRESULT& hr, std::basic_string<Elem, Traits, Ax>& str, const Elem * beginChars, const Elem * endChars) +{ + if(SUCCEEDED(hr)) + str = std::basic_string<Elem, Traits, Ax>(beginChars, endChars); +} + +template<class Traits, class Ax> +void CharsToString(HRESULT& hr, std::basic_string<CHAR, Traits, Ax>& str, const WCHAR * beginChars, const WCHAR * endChars) +{ + if(!SUCCEEDED(hr)) + return; + + UINT cchChars = endChars - beginChars; + int cch = WideCharToMultiByte(CP_ACP, 0, beginChars, cchChars, NULL, 0, NULL, NULL); + + if(cch <= 0) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + return; + } + + CHAR * psz = new CHAR[cch]; + + if(psz == NULL) + { + hr = E_OUTOFMEMORY; + return; + } + + cch = WideCharToMultiByte(CP_ACP, 0, beginChars, cchChars, psz, cch, NULL, NULL); + + if(cch <= 0) + hr = HRESULT_FROM_WIN32(GetLastError()); + else + str = std::basic_string<CHAR, Traits, Ax>(psz, psz + cch); + + delete[] psz; +} + +template<class Traits, class Ax> +void CharsToString(HRESULT& hr, std::basic_string<WCHAR, Traits, Ax>& str, const CHAR * beginChars, const CHAR * endChars) +{ + if(!SUCCEEDED(hr)) + return; + + UINT cchChars = endChars - beginChars; + int cch = MultiByteToWideChar(CP_ACP, 0, beginChars, cchChars, NULL, 0); + + if(cch <= 0) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + return; + } + + WCHAR * psz = new WCHAR[cch]; + + if(psz == NULL) + { + hr = E_OUTOFMEMORY; + return; + } + + cch = MultiByteToWideChar(CP_ACP, 0, beginChars, cchChars, psz, cch); + + if(cch <= 0) + hr = HRESULT_FROM_WIN32(GetLastError()); + else + str = std::basic_string<WCHAR, Traits, Ax>(psz, psz + cch); + + delete[] psz; +} + +template<class Elem, class Traits, class Ax> +void BSTRToString(HRESULT& hr, std::basic_string<Elem, Traits, Ax>& str, BSTR bstr) +{ + CharsToString(hr, str, bstr, bstr + SysStringLen(bstr)); +} + +std::vector<std::string> SplitPath(const std::string& strPath) +{ + std::vector<std::string> path; + std::string::const_iterator cur = strPath.begin(); + std::string::const_iterator end = strPath.end(); + + while(!(cur == end)) + { + std::string::const_iterator itemBegin = cur; + std::string::const_iterator itemEnd = std::find(cur, end, ';'); + + if(!(itemBegin == itemEnd)) + path.push_back(std::string(itemBegin, itemEnd)); + + cur = itemEnd; + + if(!(cur == end)) + ++ cur; + } + + return path; +} + +std::vector<std::string> ParsePlatformPath(HRESULT& hr, IDispatch * pPlatform, BSTR bstrPath) +{ + std::vector<std::string> path; + + if(FAILED(hr)) + return path; + + VARIANT varPath; + VariantInit(&varPath); + V_VT(&varPath) = VT_BSTR; + V_BSTR(&varPath) = bstrPath; + + VARIANT varRet = dispInvoke(hr, pPlatform, OLESTR("Evaluate"), varPath, VT_BSTR); + + std::string strPath; + BSTRToString(hr, strPath, V_BSTR(&varRet)); + + VariantClear(&varRet); + + path = SplitPath(strPath); + return path; +} + +VARIANT GetDTEProjectEngine(HRESULT& hr, IDispatch * pDTE) +{ + VARIANT varVCProjects = oleString(hr, OLESTR("VCProjects")); + VARIANT varVCProjectEngine = oleString(hr, OLESTR("VCProjectEngine")); + VARIANT varProjects = dispInvoke(hr, pDTE, OLESTR("GetObject"), varVCProjects, VT_DISPATCH); + VARIANT varProjectsProperties = dispPropGet(hr, V_DISPATCH(&varProjects), OLESTR("Properties"), VT_DISPATCH); + VARIANT varProjectEngineProperty = dispInvoke(hr, V_DISPATCH(&varProjectsProperties), varVCProjectEngine, VT_DISPATCH); + VARIANT varRet = dispPropGet(hr, V_DISPATCH(&varProjectEngineProperty), OLESTR("Object"), VT_DISPATCH); + VariantClear(&varProjectEngineProperty); + VariantClear(&varProjectsProperties); + VariantClear(&varProjects); + VariantClear(&varVCProjectEngine); + VariantClear(&varVCProjects); + return varRet; +} + +VARIANT GetDTEPlatformPath(HRESULT& hr, IDispatch * pDTE, BSTR bstrPlatformName, const OLECHAR * pszPathName) +{ + VARIANTARG argsProperties[2] = { oleString(hr, OLESTR("VCDirectories")), oleString(hr, OLESTR("Projects")) }; + + VARIANT varProperties; + VariantInit(&varProperties); + + if(SUCCEEDED(hr)) + hr = dispPropGet(pDTE, OLESTR("Properties"), argsProperties, ARRAYSIZE(argsProperties), VT_DISPATCH, varProperties); + + VARIANT varPathName = oleString(hr, pszPathName); + VARIANT varPath = dispInvoke(hr, V_DISPATCH(&varProperties), varPathName, VT_BSTR); + + VARIANT varRet; + VariantInit(&varRet); + + if(SUCCEEDED(hr)) + { + const OLECHAR * pCur = V_BSTR(&varPath); + const OLECHAR * pEnd = V_BSTR(&varPath) + SysStringLen(V_BSTR(&varPath)); + + while(!(pCur == pEnd)) + { + const OLECHAR * pBeginName = pCur; + const OLECHAR * pEndName = std::find(pBeginName, pEnd, OLESTR('|')); + const OLECHAR * pBeginValue = pEndName == pEnd ? pEndName : pEndName + 1; + const OLECHAR * pEndValue = std::find(pBeginValue, pEnd, OLESTR('|')); + + pCur = pEndValue; + + if(!(pCur == pEnd)) + ++ pCur; + + BSTR bstrName = SysAllocStringLen(pBeginName, pEndName - pBeginName); + + if(bstrName) + { + hr = VarBstrCmp(bstrName, bstrPlatformName, 0, NORM_IGNORECASE); + + if(hr == VARCMP_EQ) + { + BSTR bstrRet = SysAllocStringLen(pBeginValue, pEndValue - pBeginValue); + + if(bstrRet) + { + V_VT(&varRet) = VT_BSTR; + V_BSTR(&varRet) = bstrRet; + } + else + hr = E_OUTOFMEMORY; + } + + SysFreeString(bstrName); + + if(FAILED(hr) || hr == VARCMP_EQ) + break; + } + else + { + hr = E_OUTOFMEMORY; + break; + } + } + } + + VariantClear(&varPath); + VariantClear(&varPathName); + VariantClear(&varProperties); + VariantClear(&argsProperties[1]); + VariantClear(&argsProperties[0]); + + if(SUCCEEDED(hr) && V_VT(&varRet) != VT_BSTR) + { + VariantClear(&varRet); + varRet = oleString(hr, OLESTR("")); + } + + return varRet; +} + +cl_version msCompilerVersion; +std::string msCompilerPath; +std::vector<std::string> msCompilerIncludeDirs; // TODO: use this +std::string msCompilerSource; // TODO: use this + +link_version msLinkerVersion; +std::string msLinkerPath; +std::vector<std::string> msLinkerLibDirs; // TODO: use this +std::string msLinkerSource; // TODO: use this + +void ProcessVCPlatform(HRESULT& hr, const std::string& arch, bool wantCompiler, bool wantLinker, IDispatch * pVCProjectEngine, IDispatch * pPlatform, BSTR bstrPath, BSTR bstrInclude, BSTR bstrLib) +{ + if(FAILED(hr)) + return; + + std::basic_string<OLECHAR> strPath = replace(std::basic_string<OLECHAR>(bstrPath, SysStringLen(bstrPath)), OLESTR("$(PATH)"), OLESTR("%PATH%")); + + VARIANT varPath; + VariantInit(&varPath); + V_VT(&varPath) = VT_BSTR; + V_BSTR(&varPath) = SysAllocStringLen(strPath.c_str(), strPath.size()); + + if(!V_BSTR(&varPath)) + hr = E_OUTOFMEMORY; + + VARIANT varRet = dispInvoke(hr, pPlatform, OLESTR("Evaluate"), varPath, VT_BSTR); + + if(SUCCEEDED(hr)) + { + std::basic_string<OLECHAR> strPathOverride = replace + ( + std::basic_string<OLECHAR>(V_BSTR(&varRet), V_BSTR(&varRet) + SysStringLen(V_BSTR(&varRet))), + OLESTR("%PATH%"), + get_env(OLESTR("PATH")) + ); + + cl_version clVersion; + link_version linkVersion; + + if(wantCompiler) + clVersion = CheckClVersion(arch, strPathOverride.c_str()); + + if(wantLinker) + linkVersion = CheckLinkVersion(arch, strPathOverride.c_str()); + + // TODO: need a way to choose the desired tools and which version + // BUGBUG: for now, only set the new version if both tools are the highest version yet + if((!wantCompiler || (clVersion && clVersion > msCompilerVersion)) && (!wantLinker || (linkVersion && linkVersion > msLinkerVersion))) + { + std::string strPath; + BSTRToString(hr, strPath, V_BSTR(&varRet)); + strPath = replace(strPath, "%PATH%", "$(PATH)"); + + std::vector<std::string> include = ParsePlatformPath(hr, pPlatform, bstrInclude); + std::vector<std::string> lib = ParsePlatformPath(hr, pPlatform, bstrLib); + + if(SUCCEEDED(hr)) + { + if(wantCompiler) + { + msCompilerVersion = clVersion; + msCompilerPath = strPath; + msCompilerIncludeDirs = include; + //msCompilerSource; // TODO: fill this in + } + + if(wantLinker) + { + msLinkerVersion = linkVersion; + msLinkerPath = strPath; + msLinkerLibDirs = lib; + //msLinkerSource; // TODO: fill this in + } + } + } + } + + VariantClear(&varPath); + VariantClear(&varRet); +} + +bool IsVCPlatformSupported(HRESULT& hr, const std::string& arch, IDispatch * pPlatform) +{ + bool ret = false; + + VARIANT varPlatformName = dispPropGet(hr, pPlatform, OLESTR("Name"), VT_BSTR); + + if(arch == "i386") + { + VARIANT varWin32 = oleString(hr, OLESTR("Win32")); + + if(SUCCEEDED(hr)) + { + hr = VarBstrCmp(V_BSTR(&varWin32), V_BSTR(&varPlatformName), 0, NORM_IGNORECASE); + ret = hr == VARCMP_EQ; + } + + VariantClear(&varWin32); + } + else if(arch == "amd64") + { + VARIANT varX64 = oleString(hr, OLESTR("x64")); + + if(SUCCEEDED(hr)) + { + hr = VarBstrCmp(V_BSTR(&varX64), V_BSTR(&varPlatformName), 0, NORM_IGNORECASE); + ret = hr == VARCMP_EQ; + } + + VariantClear(&varX64); + } + else if(arch == "arm") + { + VARIANT varARM = oleString(hr, OLESTR("ARM")); + VARIANT varARCHFAM = oleString(hr, OLESTR("ARCHFAM")); + VARIANT varArchFamily = dispInvoke(hr, pPlatform, OLESTR("GetMacroValue"), varARCHFAM, VT_BSTR); + + if(SUCCEEDED(hr)) + { + hr = VarBstrCmp(V_BSTR(&varARM), V_BSTR(&varArchFamily), 0, NORM_IGNORECASE); + ret = hr == VARCMP_EQ; + } + + VariantClear(&varArchFamily); + VariantClear(&varARCHFAM); + VariantClear(&varARM); + } + + VariantClear(&varPlatformName); + + return SUCCEEDED(hr) && ret; +} + +void EnumerateVCTools(const std::string& arch, bool wantCompiler, bool wantLinker, const OLECHAR * szProductTag) +{ + size_t cchProductTag = std::wcslen(szProductTag); + HRESULT hr; + + hr = OleInitialize(NULL); + + if(SUCCEEDED(hr)) + { + std::basic_string<TCHAR> strProductKey; + CharsToString(hr, strProductKey, szProductTag, szProductTag + cchProductTag); + + if(SUCCEEDED(hr)) + { + strProductKey = TEXT("SOFTWARE\\Microsoft\\") + strProductKey; + + HKEY hkVisualStudio; + hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_LOCAL_MACHINE, strProductKey.c_str(), 0, KEY_ENUMERATE_SUB_KEYS, &hkVisualStudio)); + + if(SUCCEEDED(hr)) + { + for(DWORD i = 0; ; ++ i) + { + TCHAR szProductVersion[255 + 1]; + DWORD cchProductVersion = ARRAYSIZE(szProductVersion); + + hr = HRESULT_FROM_WIN32(RegEnumKeyEx(hkVisualStudio, i, szProductVersion, &cchProductVersion, NULL, NULL, NULL, NULL)); + + if(SUCCEEDED(hr)) + { + std::basic_string<OLECHAR> strProductVersion; + CharsToString(hr, strProductVersion, szProductVersion, szProductVersion + cchProductVersion); + + if(SUCCEEDED(hr)) + { + std::basic_string<OLECHAR> strDTEProgId(szProductTag, szProductTag + cchProductTag); + strDTEProgId += OLESTR(".DTE."); + strDTEProgId += strProductVersion; + + CLSID clsidDTE; + hr = CLSIDFromProgID(strDTEProgId.c_str(), &clsidDTE); + + if(SUCCEEDED(hr)) + { + IDispatch * pDTE; + hr = CoCreateInstance(clsidDTE, NULL, CLSCTX_ALL, IID_IDispatch, (void **)(void *)&pDTE); + + if(SUCCEEDED(hr)) + { + VARIANT varProjectEngine = GetDTEProjectEngine(hr, pDTE); + VARIANT varPlatforms = dispPropGet(hr, V_DISPATCH(&varProjectEngine), OLESTR("Platforms"), VT_DISPATCH); + VARIANT varCount = dispPropGet(hr, V_DISPATCH(&varPlatforms), OLESTR("Count"), VT_I4); + VARIANT varI; + VariantInit(&varI); + V_VT(&varI) = VT_I4; + + for(V_I4(&varI) = 1; V_I4(&varI) <= V_I4(&varCount); ++ V_I4(&varI)) + { + VARIANT varPlatform = dispInvoke(hr, V_DISPATCH(&varPlatforms), varI, VT_DISPATCH); + + if(IsVCPlatformSupported(hr, arch, V_DISPATCH(&varPlatform))) + { + VARIANT varPlatformName = dispPropGet(hr, V_DISPATCH(&varPlatform), OLESTR("Name"), VT_BSTR); + VARIANT varPath = GetDTEPlatformPath(hr, pDTE, V_BSTR(&varPlatformName), OLESTR("ExecutableDirectories")); + VARIANT varInclude = GetDTEPlatformPath(hr, pDTE, V_BSTR(&varPlatformName), OLESTR("IncludeDirectories")); + VARIANT varLib = GetDTEPlatformPath(hr, pDTE, V_BSTR(&varPlatformName), OLESTR("LibraryDirectories")); + + ProcessVCPlatform(hr, arch, wantCompiler, wantLinker, V_DISPATCH(&varProjectEngine), V_DISPATCH(&varPlatform), V_BSTR(&varPath), V_BSTR(&varInclude), V_BSTR(&varLib)); + + VariantClear(&varLib); + VariantClear(&varInclude); + VariantClear(&varPath); + VariantClear(&varPlatformName); + } + + VariantClear(&varPlatform); + } + + VariantClear(&varI); + VariantClear(&varCount); + VariantClear(&varPlatforms); + VariantClear(&varProjectEngine); + + pDTE->Release(); + } + } + + // TODO: print an error message here + } + + hr = S_OK; + } + else if(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) + { + hr = S_OK; + break; + } + else + break; + } + } + } + + OleUninitialize(); + } +} + +const TCHAR * GetDDKArchPath(const std::string& arch) +{ + if(arch == "i386") + return TEXT("x86"); + else if(arch == "amd64") + return TEXT("amd64"); + else + return NULL; +} + +void EnumerateDDKTools(const std::string& arch, bool wantCompiler, bool wantLinker) +{ + const TCHAR * pszArchPath = GetDDKArchPath(arch); + + if(pszArchPath == NULL) + return; + + HRESULT hr; + + HKEY hkDDK; + hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\WINDDK"), 0, KEY_ENUMERATE_SUB_KEYS, &hkDDK)); + + if(SUCCEEDED(hr)) + { + for(DWORD i = 0; ; ++ i) + { + TCHAR szDDKVersion[255 + ARRAYSIZE(TEXT("\\Setup"))]; + DWORD cchDDKVersion = ARRAYSIZE(szDDKVersion); + + hr = HRESULT_FROM_WIN32(RegEnumKeyEx(hkDDK, i, szDDKVersion, &cchDDKVersion, NULL, NULL, NULL, NULL)); + + if(SUCCEEDED(hr)) + { + memcpy(szDDKVersion + cchDDKVersion, TEXT("\\Setup"), sizeof(TEXT("\\Setup"))); + + HKEY hkDDKVersion; + hr = HRESULT_FROM_WIN32(RegOpenKeyEx(hkDDK, szDDKVersion, 0, KEY_QUERY_VALUE, &hkDDKVersion)); + + if(SUCCEEDED(hr)) + { + TCHAR szDDKPath[MAX_PATH]; + DWORD cbDDKPath = sizeof(szDDKPath); + DWORD dwType = 0; + + hr = HRESULT_FROM_WIN32(RegQueryValueEx(hkDDKVersion, TEXT("BUILD"), NULL, &dwType, reinterpret_cast<BYTE *>(szDDKPath), &cbDDKPath)); + + if(SUCCEEDED(hr) && dwType == REG_SZ) + { +#if defined(_X86_) + static const TCHAR * const a_szBinPaths[] = { TEXT("x86") }; +#elif defined(_AMD64_) + // Prefer native tools, fall back on x86 if necessary + static const TCHAR * const a_szBinPaths[] = { TEXT("amd64"), TEXT("x86") }; +#elif defined(_IA64_) + // Prefer native tools, fall back on x86 if necessary + static const TCHAR * const a_szBinPaths[] = { TEXT("ia64"), TEXT("x86") }; +#endif + szDDKPath[cbDDKPath / sizeof(TCHAR)] = 0; + std::basic_string<TCHAR> strDDKPath(szDDKPath); + strDDKPath += TEXT("\\bin\\"); + + std::basic_string<TCHAR>::size_type cchCutoff = strDDKPath.length(); + + for(unsigned i = 0; i < ARRAYSIZE(a_szBinPaths); ++ i) + { + strDDKPath.resize(cchCutoff); + strDDKPath += a_szBinPaths[i]; + strDDKPath += TEXT("\\"); + strDDKPath += pszArchPath; + + cl_version clVersion; + link_version linkVersion; + + if(wantCompiler) + clVersion = CheckClVersion(arch, strDDKPath.c_str()); + + if(wantLinker) + linkVersion = CheckLinkVersion(arch, strDDKPath.c_str()); + + if((!wantCompiler || (clVersion && clVersion > msCompilerVersion)) && (!wantLinker || (linkVersion && linkVersion > msLinkerVersion))) + { + std::string strPath; + CharsToString(hr, strPath, strDDKPath.c_str(), strDDKPath.c_str() + strDDKPath.length()); + + if(SUCCEEDED(hr)) + { + if(wantCompiler) + { + msCompilerVersion = clVersion; + msCompilerPath = strPath; + msCompilerIncludeDirs.clear(); + //msCompilerSource; // TODO: fill this in + } + + if(wantLinker) + { + msLinkerVersion = linkVersion; + msLinkerPath = strPath; + msLinkerLibDirs.clear(); + //msLinkerSource; // TODO: fill this in + } + } + else + break; + } + } + } + + RegCloseKey(hkDDKVersion); + } + } + else if(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) + { + hr = S_OK; + break; + } + + if(FAILED(hr)) + break; + } + + RegCloseKey(hkDDK); + } +} + +void DetectEnvironmentVCTools(const std::string& arch, bool wantCompiler, bool wantLinker) +{ + cl_version clVersion; + link_version linkVersion; + + if(wantCompiler) + clVersion = CheckClVersion(arch); + + if(wantLinker) + linkVersion = CheckLinkVersion(arch); + + if((!wantCompiler || (clVersion && clVersion > msCompilerVersion)) && (!wantLinker || (linkVersion && linkVersion > msLinkerVersion))) + { + if(wantCompiler) + { + msCompilerVersion = clVersion; + msCompilerPath.clear(); + msCompilerIncludeDirs = SplitPath(get_env("INCLUDE")); + msCompilerSource = "environment"; + } + + if(wantLinker) + { + msLinkerVersion = linkVersion; + msLinkerPath.clear(); + msLinkerLibDirs = SplitPath(get_env("LIB")); + msLinkerSource = "environment"; + } + } +} + +void EnumerateMicrosoftTools(const std::string& arch, bool wantCompiler, bool wantLinker) +{ + DetectEnvironmentVCTools(arch, wantCompiler, wantLinker); + + if(!msCompilerVersion || !msLinkerVersion) + { + EnumerateVCTools(arch, wantCompiler, wantLinker, OLESTR("VisualStudio")); + EnumerateVCTools(arch, wantCompiler, wantLinker, OLESTR("VCExpress")); + EnumerateDDKTools(arch, wantCompiler, wantLinker); + } +} + +} + +bool +MingwBackend::DetectMicrosoftCompiler ( std::string& version ) +{ + bool wantCompiler = ProjectNode.configuration.Compiler == MicrosoftC; + bool wantLinker = ProjectNode.configuration.Linker == MicrosoftLink; + + if ( wantCompiler && !msCompilerVersion ) + EnumerateMicrosoftTools ( Environment::GetArch(), wantCompiler, wantLinker ); + + bool ret = wantCompiler && msCompilerVersion; + + if ( ret ) + { + compilerNeedsHelper = true; + compilerCommand = "cl"; + + std::ostringstream compilerVersion; + compilerVersion << msCompilerVersion; + version = compilerVersion.str(); + } + + return ret; +} + +bool +MingwBackend::DetectMicrosoftLinker ( std::string& version ) +{ + bool wantCompiler = ProjectNode.configuration.Compiler == MicrosoftC; + bool wantLinker = ProjectNode.configuration.Linker == MicrosoftLink; + + if ( wantLinker && !msLinkerVersion ) + EnumerateMicrosoftTools ( Environment::GetArch(), wantCompiler, wantLinker ); + + bool ret = wantLinker && msLinkerVersion; + + if ( ret ) + { + binutilsNeedsHelper = msLinkerPath.length() != 0; + binutilsCommand = "link"; + + std::ostringstream linkerVersion; + linkerVersion << msLinkerVersion; + version = linkerVersion.str(); + } + + return ret; +} + +#endif + +// TODO? attempt to support Microsoft tools on non-Windows? +#if !defined(WIN32) + +bool +MingwBackend::DetectMicrosoftCompiler ( std::string& ) +{ + return false; +} + +bool +MingwBackend::DetectMicrosoftLinker ( std::string& ) +{ + return false; +} + +#endif + +// EOF Propchange: trunk/reactos/tools/rbuild/backend/mingw/mstools_detection.cpp ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/reactos/tools/rbuild/configuration.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/configuration…
============================================================================== --- trunk/reactos/tools/rbuild/configuration.cpp [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/configuration.cpp [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -33,6 +33,8 @@ InstallFiles = false; UseConfigurationInPath = false; UseVSVersionInPath = false; + Compiler = GnuGcc; + Linker = GnuLd; } Configuration::~Configuration () Modified: trunk/reactos/tools/rbuild/rbuild.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/rbuild.cpp?re…
============================================================================== --- trunk/reactos/tools/rbuild/rbuild.cpp [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/rbuild.cpp [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -161,6 +161,58 @@ } bool +ParseMingwSwitch ( char* switchStart ) +{ + switchStart += 2; + + if ( *switchStart == 'c' ) + { + ++ switchStart; + + if ( strcmp ( switchStart, "msc" ) == 0 ) + configuration.Compiler = MicrosoftC; + else if ( strcmp ( switchStart, "gcc" ) == 0 ) + configuration.Compiler = GnuGcc; + else + { + printf ( "Unknown value of -Mc: %s\n", switchStart ); + return false; + } + } + else if ( *switchStart == 'l' ) + { + ++ switchStart; + + if ( strcmp ( switchStart, "mslink" ) == 0 ) + configuration.Linker = MicrosoftLink; + else if ( strcmp ( switchStart, "ld" ) == 0 ) + configuration.Linker = GnuLd; + else + { + printf ( "Unknown value of -Ml: %s\n", switchStart ); + return false; + } + } + else if ( strcmp ( switchStart, "microsoft" ) == 0 ) + { + configuration.Compiler = MicrosoftC; + configuration.Linker = MicrosoftLink; + } + else if ( strcmp ( switchStart, "gnu" ) == 0 ) + { + configuration.Compiler = GnuGcc; + configuration.Linker = GnuLd; + } + else + { + printf ( "Unknown value of -M: %s\n", switchStart ); + return false; + } + + return true; +} + +bool ParseMakeSwitch ( char switchChar2 ) { switch ( switchChar2 ) @@ -252,6 +304,8 @@ break; case 'm': return ParseMakeSwitch ( switchChar2 ); + case 'M': + return ParseMingwSwitch ( argv[index] ); case 'p': return ParseProxyMakefileSwitch ( switchChar2 ); case 'D': @@ -309,6 +363,14 @@ printf ( " tree.\n" ); printf ( " -vs{version} Version of MS VS project files. Default is %s.\n", MS_VS_DEF_VERSION ); printf ( " -vo{version|configuration} Adds subdirectory path to the default Intermediate-Outputdirectory.\n" ); + printf ( " -Mc{compiler} Compiler to use for mingw backend. Can be one of:\n" ); + printf ( " %-10s %s (default)\n", "gcc", "GNU compiler collection (gcc, g++)\n"); + printf ( " %-10s %s\n", "msc", "Microsoft Visual C++ (cl)\n"); + printf ( " -Ml{compiler} Linker to use for mingw backend. Can be one of:\n" ); + printf ( " %-10s %s (default)\n", "ld", "GNU binutils (ld, dlltool)\n"); + printf ( " %-10s %s\n", "mslink", "Microsoft Linker (link, lib)\n"); + printf ( " -Mmicrosoft Same as -Mcmsc -Mlmslink\n" ); + printf ( " -Mgnu Same as -Mcgcc -Mlld\n" ); printf ( " -Dvar=val Set the value of 'var' variable to 'val'.\n" ); printf ( "\n" ); printf ( " buildsystem Target build system. Can be one of:\n" ); Modified: trunk/reactos/tools/rbuild/rbuild.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/rbuild.h?rev=…
============================================================================== --- trunk/reactos/tools/rbuild/rbuild.h [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/rbuild.h [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -155,6 +155,18 @@ FullDependencies }; +enum CompilerSet +{ + GnuGcc, + MicrosoftC +}; + +enum LinkerSet +{ + GnuLd, + MicrosoftLink +}; + class Configuration { public: @@ -174,6 +186,8 @@ bool MakeHandlesInstallDirectories; bool GenerateProxyMakefilesInSourceTree; bool InstallFiles; + CompilerSet Compiler; + LinkerSet Linker; }; class Environment Modified: trunk/reactos/tools/rbuild/rbuild.mak URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rbuild/rbuild.mak?re…
============================================================================== --- trunk/reactos/tools/rbuild/rbuild.mak [iso-8859-1] (original) +++ trunk/reactos/tools/rbuild/rbuild.mak [iso-8859-1] Mon Jun 8 03:33:42 2009 @@ -199,6 +199,7 @@ RBUILD_BACKEND_MINGW_BASE_SOURCES = $(addprefix $(RBUILD_MINGW_BASE_), \ mingw.cpp \ modulehandler.cpp \ + mstools_detection.cpp \ proxymakefile.cpp \ rule.cpp \ ) @@ -349,6 +350,10 @@ RBUILD_HOST_LFLAGS = $(TOOLS_LFLAGS) +ifeq ($(HOST),mingw32-windows) +RBUILD_HOST_LFLAGS += -loleaut32 -lole32 -luuid +endif + .PHONY: rbuild rbuild: $(RBUILD_TARGET) host_gpp += -g @@ -474,6 +479,10 @@ ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ $(RBUILD_MINGW_INT_)modulehandler.o: $(RBUILD_MINGW_BASE_)modulehandler.cpp $(RBUILD_HEADERS) | $(RBUILD_MINGW_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + +$(RBUILD_MINGW_INT_)mstools_detection.o: $(RBUILD_MINGW_BASE_)mstools_detection.cpp $(RBUILD_HEADERS) | $(RBUILD_MINGW_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
15 years, 5 months
1
0
0
0
[janderwald] 41342: - Disable debugging flood
by janderwald@svn.reactos.org
Author: janderwald Date: Sun Jun 7 22:24:50 2009 New Revision: 41342 URL:
http://svn.reactos.org/svn/reactos?rev=41342&view=rev
Log: - Disable debugging flood Modified: trunk/reactos/drivers/ksfilter/ks/priv.h trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h Modified: trunk/reactos/drivers/ksfilter/ks/priv.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/priv.h…
============================================================================== --- trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] Sun Jun 7 22:24:50 2009 @@ -3,7 +3,7 @@ #include <ntifs.h> #include <ntddk.h> -#define YDEBUG +#define NDEBUG #include <debug.h> #include <portcls.h> #include <ks.h> Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sun Jun 7 22:24:50 2009 @@ -9,7 +9,7 @@ #include <ntddk.h> #include <portcls.h> -#define YDEBUG +#define NDEBUG #include <debug.h> #include <dmusicks.h> Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Sun Jun 7 22:24:50 2009 @@ -5,7 +5,7 @@ #include <ntddk.h> #include <portcls.h> #include <ks.h> -#define YDEBUG +#define NDEBUG #include <debug.h> #include <ksmedia.h> #include <mmsystem.h> Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Sun Jun 7 22:24:50 2009 @@ -7,7 +7,7 @@ #include <ks.h> #include <ksmedia.h> #include <math.h> -#define YDEBUG +#define NDEBUG #include <debug.h> #include <stdio.h>
15 years, 5 months
1
0
0
0
[janderwald] 41341: - Also Store audio filter object header in FsContext member - Create the pin on the correct filter by using the filters object class - Remove filter object class before performing actual create request - Remove object header from audio filter when closing - Retrieve internal object class name with internal IOCTL_KS_OBJECT_CLASS - Avoid using interface name as ReactOS doesn't support it - Store object class name when creating the object header for the audio sub device - Implem
by janderwald@svn.reactos.org
Author: janderwald Date: Sun Jun 7 22:22:24 2009 New Revision: 41341 URL:
http://svn.reactos.org/svn/reactos?rev=41341&view=rev
Log: - Also Store audio filter object header in FsContext member - Create the pin on the correct filter by using the filters object class - Remove filter object class before performing actual create request - Remove object header from audio filter when closing - Retrieve internal object class name with internal IOCTL_KS_OBJECT_CLASS - Avoid using interface name as ReactOS doesn't support it - Store object class name when creating the object header for the audio sub device - Implement IPortFilterTopology interface - Activate pin property handle for port topology driver - There is no need to create a handle to sysaudio for each application opening wdmaud, use only one connection per driver basis - Pass object create class to pin creation method by duplicating KsCreatePin - Audio devices should now be accessible again Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c (with props) Modified: trunk/reactos/drivers/ksfilter/ks/irp.c trunk/reactos/drivers/ksfilter/ks/priv.h trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h trunk/reactos/drivers/wdm/audio/sysaudio/control.c trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c trunk/reactos/drivers/wdm/audio/sysaudio/main.c trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h Modified: trunk/reactos/drivers/ksfilter/ks/irp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?…
============================================================================== --- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -352,7 +352,7 @@ } /* was the request for a pin/clock/node */ - if (IoStack->FileObject) + if (IoStack->FileObject->FileName.Buffer) { /* store the object in the file object */ ASSERT(IoStack->FileObject->FsContext == NULL); @@ -360,9 +360,10 @@ } else { - /* the object header is for device */ + /* the object header is for a audio filter */ ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems); DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader; + IoStack->FileObject->FsContext = ObjectHeader; } /* store result */ @@ -720,7 +721,7 @@ IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - //PIO_STACK_LOCATION IoStack; + PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; ULONG Index; @@ -729,7 +730,7 @@ DPRINT("KS / CREATE\n"); /* get current stack location */ - //IoStack = IoGetCurrentIrpStackLocation(Irp); + IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ @@ -756,11 +757,41 @@ return Status; } } + else if (DeviceHeader->ItemList[Index].bCreated && IoStack->FileObject->FileName.Buffer != NULL) + { + ULONG Length = wcslen(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer); + + /* filter for that type has already exists */ + if (!_wcsnicmp(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer, + IoStack->FileObject->FileName.Buffer, + Length)) + { + if (IoStack->FileObject->FileName.Buffer[0] != L'{') + { + RtlMoveMemory(IoStack->FileObject->FileName.Buffer, &IoStack->FileObject->FileName.Buffer[Length+1], + IoStack->FileObject->FileName.Length - Length * sizeof(WCHAR)); + + IoStack->FileObject->FileName.Length -= Length * sizeof(WCHAR); + } + + + KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem; + Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp); + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + return Status; + } + } + } /* release lock */ KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - return Status; + + Irp->IoStatus.Information = 0; + /* set return status */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; } static NTAPI @@ -771,9 +802,17 @@ { PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + ULONG Index; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + DPRINT("KS / CLOSE\n"); @@ -782,11 +821,20 @@ ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (DeviceHeader->ItemList[Index].ObjectHeader == ObjectHeader) + { + DeviceHeader->ItemList[Index].ObjectHeader = NULL; + } + } return ObjectHeader->DispatchTable.Close(DeviceObject, Irp); } else { - DPRINT1("Expected Object Header\n"); + DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext); + KeBugCheckEx(0, 0, 0, 0, 0); return STATUS_SUCCESS; } } @@ -809,6 +857,15 @@ ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS) + { + *((LPWSTR*)Irp->UserBuffer) = ObjectHeader->CreateItem->ObjectClass.Buffer; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(LPWSTR); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp); } else Modified: trunk/reactos/drivers/ksfilter/ks/priv.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/priv.h…
============================================================================== --- trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -3,7 +3,7 @@ #include <ntifs.h> #include <ntddk.h> -#define NDEBUG +#define YDEBUG #include <debug.h> #include <portcls.h> #include <ks.h> @@ -16,6 +16,6 @@ #define TAG_DEVICE_HEADER TAG('H','D','S','K') - +#define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) #endif Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -288,7 +288,7 @@ */ Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject, &SubDeviceDescriptor->Interfaces[Index], - &RefName, + NULL, //&RefName, &SymbolicLinkName); if (NT_SUCCESS(Status)) { Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -211,7 +211,8 @@ NTAPI NewDispatchObject( IN PIRP Irp, - IN IIrpTarget * Target) + IN IIrpTarget * Target, + IN LPWSTR Name) { NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; @@ -223,6 +224,7 @@ return STATUS_INSUFFICIENT_RESOURCES; CreateItem->Context = (PVOID)Target; + RtlInitUnicodeString(&CreateItem->ObjectClass, Name); IoStack = IoGetCurrentIrpStackLocation(Irp); ASSERT(IoStack->FileObject); Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c (added) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -1,0 +1,364 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_topology.c + * PURPOSE: portcls topology filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.h" + +typedef struct +{ + IPortFilterTopologyVtbl *lpVtbl; + + LONG ref; + + IPortTopology* Port; + SUBDEVICE_DESCRIPTOR * Descriptor; + +}IPortFilterTopologyImpl; + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnQueryInterface( + IPortFilterTopology* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, &IID_IPort)) + { + *Output = This->Port; + This->Port->lpVtbl->AddRef(This->Port); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterTopology_fnAddRef( + IPortFilterTopology* iface) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + return InterlockedIncrement(&This->ref); +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterTopology_fnRelease( + IPortFilterTopology* iface) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + return This->ref; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnNewIrpTarget( + IN IPortFilterTopology* iface, + OUT struct IIrpTarget **OutTarget, + IN WCHAR * Name, + IN PUNKNOWN Unknown, + IN POOL_TYPE PoolType, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN KSOBJECT_CREATE *CreateObject) +{ + DPRINT("IPortFilterTopology_fnNewIrpTarget entered\n"); + + return STATUS_NOT_SUPPORTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnDeviceIoControl( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + ISubdevice *SubDevice = NULL; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice); + ASSERT(Status == STATUS_SUCCESS); + ASSERT(SubDevice != NULL); + + Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor); + ASSERT(Status == STATUS_SUCCESS); + ASSERT(Descriptor != NULL); + + SubDevice->lpVtbl->Release(SubDevice); + + return PcPropertyHandler(Irp, Descriptor); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnRead( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnWrite( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnFlush( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnClose( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + //PMINIPORTTOPOLOGY Miniport; + //IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; + + /* release reference to port */ + //This->Port->lpVtbl->Release(This->Port); + + /* get the miniport driver */ + //Miniport = GetTopologyMiniport(This->Port); + /* release miniport driver */ + //Miniport->lpVtbl->Release(Miniport); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnQuerySecurity( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnSetSecurity( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastDeviceIoControl( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastRead( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastWrite( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +static +NTSTATUS +NTAPI +IPortFilterTopology_fnInit( + IN IPortFilterTopology* iface, + IN IPortTopology* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + /* get our private interface */ + Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + /* get the subdevice descriptor */ + Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor); + + /* release subdevice interface */ + ISubDevice->lpVtbl->Release(ISubDevice); + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + /* save descriptor */ + This->Descriptor = Descriptor; + + /* increment reference count */ + Port->lpVtbl->AddRef(Port); + + /* store port object */ + This->Port = Port; + + return STATUS_SUCCESS; +} + +static IPortFilterTopologyVtbl vt_IPortFilterTopology = +{ + IPortFilterTopology_fnQueryInterface, + IPortFilterTopology_fnAddRef, + IPortFilterTopology_fnRelease, + IPortFilterTopology_fnNewIrpTarget, + IPortFilterTopology_fnDeviceIoControl, + IPortFilterTopology_fnRead, + IPortFilterTopology_fnWrite, + IPortFilterTopology_fnFlush, + IPortFilterTopology_fnClose, + IPortFilterTopology_fnQuerySecurity, + IPortFilterTopology_fnSetSecurity, + IPortFilterTopology_fnFastDeviceIoControl, + IPortFilterTopology_fnFastRead, + IPortFilterTopology_fnFastWrite, + IPortFilterTopology_fnInit +}; + +NTSTATUS +NewPortFilterTopology( + OUT IPortFilterTopology ** OutFilter) +{ + IPortFilterTopologyImpl * This; + + This = AllocateItem(NonPagedPool, sizeof(IPortFilterTopologyImpl), TAG_PORTCLASS); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize IPortFilterTopology */ + This->ref = 1; + This->lpVtbl = &vt_IPortFilterTopology; + + /* return result */ + *OutFilter = (IPortFilterTopology*)&This->lpVtbl; + + return STATUS_SUCCESS; +} Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -248,7 +248,9 @@ /* release reference to port */ This->Port->lpVtbl->Release(This->Port); + /* get the miniport driver */ Miniport = GetWaveCyclicMiniport(This->Port); + /* release miniport driver */ Miniport->lpVtbl->Release(Miniport); @@ -256,7 +258,7 @@ Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; } /* Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -687,4 +687,26 @@ #undef INTERFACE +/***************************************************************************** + * IPortFilterTopology + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IPortFilterTopology + +DECLARE_INTERFACE_(IPortFilterTopology, IIrpTarget) +{ + DEFINE_ABSTRACT_UNKNOWN() + + DEFINE_ABSTRACT_IRPTARGET() + + STDMETHOD_(NTSTATUS, Init)(THIS_ + IN PPORTTOPOLOGY Port)PURE; +}; + +typedef IPortFilterTopology *PPORTFILTERTOPOLOGY; + +#undef INTERFACE + #endif Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -23,6 +23,7 @@ PPCFILTER_DESCRIPTOR pDescriptor; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; + IPortFilterTopology * Filter; }IPortTopologyImpl; typedef struct @@ -44,27 +45,26 @@ } }; -#if 0 -static -KSPROPERTY_SET PinPropertySet = -{ - &KSPROPSETID_Pin, - 0, - NULL, - 0, - NULL +DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET TopologyPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet, + 0, + NULL + } }; - -static -KSPROPERTY_SET TopologyPropertySet = -{ - &KSPROPSETID_Topology, - 4, - NULL, - 0, - NULL -}; -#endif //--------------------------------------------------------------- @@ -223,13 +223,13 @@ } /* create the subdevice descriptor */ - Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, + Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, 2, InterfaceGuids, 0, NULL, - 0, - NULL, + 2, + TopologyPropertySet, 0, 0, 0, @@ -339,10 +339,45 @@ IN PIRP Irp, IN KSOBJECT_CREATE *CreateObject) { - //IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + NTSTATUS Status; + IPortFilterTopology * Filter; + IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); + + /* is there already an instance of the filter */ + if (This->Filter) + { + /* it is, let's return the result */ + *OutTarget = (IIrpTarget*)This->Filter; + + /* increment reference */ + This->Filter->lpVtbl->AddRef(This->Filter); + return STATUS_SUCCESS; + } + + /* create new instance of filter */ + Status = NewPortFilterTopology(&Filter); + if (!NT_SUCCESS(Status)) + { + /* not enough memory */ + return Status; + } + + /* initialize the filter */ + Status = Filter->lpVtbl->Init(Filter, (IPortTopology*)This); + if (!NT_SUCCESS(Status)) + { + /* destroy filter */ + Filter->lpVtbl->Release(Filter); + /* return status */ + return Status; + } + + /* store result */ + *OutTarget = (IIrpTarget*)Filter; + /* store for later re-use */ + This->Filter = Filter; + /* return status */ + return Status; } static @@ -366,7 +401,7 @@ { IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - DPRINT("ISubDevice_GetDescriptor this %p\n", This); + DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", This, This->SubDeviceDescriptor); *Descriptor = This->SubDeviceDescriptor; return STATUS_SUCCESS; } @@ -477,7 +512,7 @@ if (NT_SUCCESS(Status)) { /* create the dispatch object */ - Status = NewDispatchObject(WorkerContext->Irp, Pin); + Status = NewDispatchObject(WorkerContext->Irp, Pin, NULL); DPRINT("Pin %p\n", Pin); } @@ -573,7 +608,7 @@ if (IoStack->FileObject->FileName.Buffer == NULL) { /* create the dispatch object */ - Status = NewDispatchObject(Irp, Filter); + Status = NewDispatchObject(Irp, Filter, CreateItem->ObjectClass.Buffer); DPRINT1("Filter %p\n", Filter); } @@ -645,3 +680,11 @@ return STATUS_SUCCESS; } + +PMINIPORTTOPOLOGY +GetTopologyMiniport( + PPORTTOPOLOGY Port) +{ + IPortTopologyImpl * This = (IPortTopologyImpl*)Port; + return This->pMiniport; +} Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -593,28 +593,40 @@ DPRINT("ISubDevice_NewIrpTarget this %p\n", This); + /* is there already an instance of the filter */ if (This->Filter) { + /* it is, let's return the result */ *OutTarget = (IIrpTarget*)This->Filter; + + /* increment reference */ + This->Filter->lpVtbl->AddRef(This->Filter); return STATUS_SUCCESS; } - + /* create new instance of filter */ Status = NewPortFilterWaveCyclic(&Filter); if (!NT_SUCCESS(Status)) { + /* not enough memory */ return Status; } + /* initialize the filter */ Status = Filter->lpVtbl->Init(Filter, (IPortWaveCyclic*)This); if (!NT_SUCCESS(Status)) { + /* destroy filter */ Filter->lpVtbl->Release(Filter); + /* return status */ return Status; } + /* store result */ *OutTarget = (IIrpTarget*)Filter; + /* store for later re-use */ This->Filter = Filter; + /* return status */ return Status; } Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -19,6 +19,7 @@ <file>dma_slave.c</file> <file>drm.c</file> <file>drm_port.c</file> + <file>filter_topology.c</file> <file>filter_dmus.c</file> <file>filter_wavecyclic.c</file> <file>filter_wavepci.c</file> Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -9,7 +9,7 @@ #include <ntddk.h> #include <portcls.h> -#define NDEBUG +#define YDEBUG #include <debug.h> #include <dmusicks.h> @@ -147,11 +147,20 @@ #endif +NTSTATUS +NewPortFilterTopology( + OUT IPortFilterTopology ** OutFilter); + +PMINIPORTTOPOLOGY +GetTopologyMiniport( + PPORTTOPOLOGY Port); + NTSTATUS NTAPI NewDispatchObject( IN PIRP Irp, - IN IIrpTarget * Target); + IN IIrpTarget * Target, + IN LPWSTR Name); PMINIPORTWAVECYCLIC GetWaveCyclicMiniport( Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -44,6 +44,7 @@ NTSTATUS Status; KSPIN_COMMUNICATION Communication; KSPIN_DATAFLOW DataFlow; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) { @@ -55,7 +56,9 @@ Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT; Pin.Property.Flags = KSPROPERTY_TYPE_GET; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); if (!NT_SUCCESS(Status)) return STATUS_UNSUCCESSFUL; @@ -69,7 +72,7 @@ Pin.Property.Id = KSPROPERTY_PIN_CTYPES; Pin.PinId = 0; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); if (NT_SUCCESS(Status)) { /* enumerate now all pins */ @@ -80,13 +83,13 @@ Communication = KSPIN_COMMUNICATION_NONE; /* get pin communication type */ - KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW; DataFlow = 0; /* get pin dataflow type */ - KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); + KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) { @@ -132,6 +135,7 @@ IN PWDMAUD_CLIENT ClientInfo) { PSYSAUDIO_INSTANCE_INFO InstanceInfo; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; ULONG BytesReturned; NTSTATUS Status; ACCESS_MASK DesiredAccess = 0; @@ -169,7 +173,9 @@ InstanceInfo->Flags = 0; InstanceInfo->DeviceNumber = FilterId; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); if (!NT_SUCCESS(Status)) { @@ -204,7 +210,7 @@ PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; PinConnect->Medium.Flags = 0; PinConnect->PinId = PinId; - PinConnect->PinToHandle = ClientInfo->hSysAudio; + PinConnect->PinToHandle = DeviceExtension->hSysAudio; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = 1; @@ -231,7 +237,7 @@ /* ros specific pin creation request */ InstanceInfo->Property.Id = (ULONG)-1; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); if (NT_SUCCESS(Status)) { PHANDLE Handels; @@ -283,8 +289,9 @@ NTSTATUS Status; KSPIN_COMMUNICATION Communication; KSPIN_DATAFLOW DataFlow; - - if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + + if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE && DeviceInfo->DeviceType != MIXER_DEVICE_TYPE) { DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); @@ -294,7 +301,8 @@ Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT; Pin.Property.Flags = KSPROPERTY_TYPE_GET; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); if (!NT_SUCCESS(Status)) { DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status); @@ -311,7 +319,7 @@ Pin.Property.Id = KSPROPERTY_PIN_CTYPES; Pin.PinId = 0; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); if (NT_SUCCESS(Status)) { /* enumerate now all pins */ @@ -322,13 +330,17 @@ Communication = KSPIN_COMMUNICATION_NONE; /* get pin communication type */ - KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + if (!NT_SUCCESS(Status)) + continue; Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW; DataFlow = 0; /* get pin dataflow type */ - KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); + if (!NT_SUCCESS(Status)) + continue; if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) { @@ -432,6 +444,7 @@ IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { + PWDMAUD_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status = STATUS_UNSUCCESSFUL; KSP_PIN PinProperty; KSCOMPONENTID ComponentId; @@ -462,7 +475,8 @@ RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID)); - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); if (NT_SUCCESS(Status)) { DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7; @@ -476,7 +490,7 @@ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; BytesReturned = 0; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); if (Status != STATUS_BUFFER_TOO_SMALL) { return SetIrpIoStatus(Irp, Status, 0); @@ -489,7 +503,7 @@ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { ExFreePool(MultipleItem); Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -94,6 +94,8 @@ LPWSTR SymbolicLinkList; SYSAUDIO_ENTRY * Entry; ULONG Length; + HANDLE hSysAudio; + PFILE_OBJECT FileObject; UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio"); if (DeviceExtension->DeviceInterfaceSupport) @@ -135,7 +137,28 @@ InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); DeviceExtension->NumSysAudioDevices++; - } + + DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer); + Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open sysaudio %x\n", Status); + return Status; + } + + /* get the file object */ + Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to reference FileObject %x\n", Status); + ZwClose(hSysAudio); + return Status; + } + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DeviceExtension->hSysAudio = hSysAudio; + DeviceExtension->FileObject = FileObject; + } + return Status; } @@ -180,10 +203,6 @@ IN PWDMAUD_CLIENT *pClient) { PWDMAUD_CLIENT Client; - NTSTATUS Status; - HANDLE hSysAudio; - PSYSAUDIO_ENTRY SysEntry; - PFILE_OBJECT FileObject; PWDMAUD_DEVICE_EXTENSION DeviceExtension; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -200,34 +219,6 @@ } RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT)); - - - /* open the first sysaudio device available */ - SysEntry = (PSYSAUDIO_ENTRY)DeviceExtension->SysAudioDeviceList.Flink; - - DPRINT1("Opening device %S\n", SysEntry->SymbolicLink.Buffer); - Status = WdmAudOpenSysAudioDevice(SysEntry->SymbolicLink.Buffer, &hSysAudio); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to open sysaudio %x\n", Status); - ExFreePool(Client); - return Status; - } - - /* get the file object */ - Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to reference FileObject %x\n", Status); - ExFreePool(Client); - ZwClose(hSysAudio); - return Status; - } - - Client->hSysAudio = hSysAudio; - Client->FileObject = FileObject; - Client->hProcess = PsGetCurrentProcessId(); - *pClient = Client; return STATUS_SUCCESS; Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -215,8 +215,6 @@ ExFreePool(pClient->hPins); } - ObDereferenceObject(pClient->FileObject); - ZwClose(pClient->hSysAudio); ExFreePool(pClient); IoStack->FileObject->FsContext = NULL; } Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -5,7 +5,7 @@ #include <ntddk.h> #include <portcls.h> #include <ks.h> -#define NDEBUG +#define YDEBUG #include <debug.h> #include <ksmedia.h> #include <mmsystem.h> @@ -15,8 +15,6 @@ typedef struct { HANDLE hProcess; - HANDLE hSysAudio; - PFILE_OBJECT FileObject; ULONG NumPins; HANDLE * hPins; @@ -38,6 +36,8 @@ KSPIN_LOCK Lock; ULONG NumSysAudioDevices; LIST_ENTRY SysAudioDeviceList; + HANDLE hSysAudio; + PFILE_OBJECT FileObject; }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -19,11 +19,93 @@ NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_DEVICE_ENTRY Entry, + IN PKSAUDIO_SUBDEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat); + + +NTSTATUS +NTAPI +KspCreateObjectType( + IN HANDLE ParentHandle, + IN LPWSTR ObjectType, + PVOID CreateParameters, + UINT CreateParametersSize, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE NodeHandle) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + + Name.Length = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize; + Name.MaximumLength += sizeof(WCHAR); + Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); + + if (!Name.Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + wcscpy(Name.Buffer, ObjectType); + Name.Buffer[wcslen(ObjectType)] = '\\'; + + RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize); + + Name.Buffer[Name.Length / 2] = L'\0'; + InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); + + + Status = IoCreateFile(NodeHandle, + DesiredAccess, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + 0, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0, + CreateFileTypeNone, + NULL, + IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); + + return Status; +} + +KSDDKAPI +NTSTATUS +NTAPI +KsoCreatePin( + IN HANDLE FilterHandle, + IN PKSPIN_CONNECT Connect, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE ConnectionHandle, + IN LPWSTR ObjectClass) +{ + WCHAR szBuffer[100]; + UINT ConnectSize = sizeof(KSPIN_CONNECT); + + PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); + if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) || + Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX)) + { + ConnectSize += Format->DataFormat.FormatSize; + } + + swprintf(szBuffer, L"%s\\{146F1A80-4791-11D0-A5D6-28DB04C10000}", ObjectClass); + + return KspCreateObjectType(FilterHandle, + szBuffer, + (PVOID)Connect, + ConnectSize, + DesiredAccess, + ConnectionHandle); +} NTSTATUS @@ -46,20 +128,39 @@ } -PKSAUDIO_DEVICE_ENTRY +PKSAUDIO_SUBDEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index) { - PLIST_ENTRY Entry = Head->Flink; - - while(Index-- && Entry != Head) + PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; + PLIST_ENTRY SubEntry, Entry = Head->Flink; + + DPRINT1("device index %u\n", Index); + while(Entry != Head) + { + DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); + if (Index < DeviceEntry->NumSubDevices) + { + SubEntry = DeviceEntry->SubDeviceList.Flink; + while(SubEntry != &DeviceEntry->SubDeviceList && Index--) + SubEntry = SubEntry->Flink; + + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + return SubDeviceEntry; + } + else + { + Index -= DeviceEntry->NumSubDevices; + } + Entry = Entry->Flink; - if (Entry == Head) - return NULL; - - return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); + } + DPRINT1("Not Found index %u\n", Index); + DbgBreakPoint(); + return NULL; } NTSTATUS @@ -69,7 +170,7 @@ PSYSAUDIODEVEXT DeviceExtension) { PSYSAUDIO_CLIENT ClientInfo; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PKSOBJECT_CREATE_ITEM CreateItem; /* access the create item */ @@ -98,9 +199,6 @@ /* get device context */ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber); ASSERT(Entry != NULL); - - /* increase usage count */ - Entry->NumberOfClients++; return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); } @@ -217,13 +315,12 @@ ASSERT(WorkerContext->Entry->Pins); ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); - /* Fetch input format */ InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1); /* Let's try to create the audio irp pin */ - Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); + Status = KsoCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); if (!NT_SUCCESS(Status)) { @@ -260,7 +357,7 @@ } /* Retry with Mixer format */ - Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); + Status = KsoCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); if (!NT_SUCCESS(Status)) { /* This should not fail */ @@ -432,7 +529,7 @@ { PIO_STACK_LOCATION IoStack; NTSTATUS Status; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; ULONG BytesReturned; PKSP_PIN Pin; @@ -519,7 +616,7 @@ NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_DEVICE_ENTRY Entry, + IN PKSAUDIO_SUBDEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, @@ -653,7 +750,7 @@ NTSTATUS GetPinInstanceCount( - PKSAUDIO_DEVICE_ENTRY Entry, + PKSAUDIO_SUBDEVICE_ENTRY Entry, PKSPIN_CINSTANCES PinInstances, PKSPIN_CONNECT PinConnect) { @@ -723,7 +820,7 @@ PDEVICE_OBJECT DeviceObject) { ULONG Length; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PIO_STACK_LOCATION IoStack; PSYSAUDIO_INSTANCE_INFO InstanceInfo; @@ -886,7 +983,7 @@ PULONG Index; PKSPROPERTY Property; PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PSYSAUDIO_INSTANCE_INFO InstanceInfo; ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -11,13 +11,14 @@ const GUID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}}; const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}}; const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KS_CATEGORY_TOPOLOGY = {0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}}; const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +#define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) + VOID -NTAPI -FilterPinWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) +QueryFilterRoutine( + IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry) { KSPROPERTY PropertyRequest; KSP_PIN PinRequest; @@ -27,14 +28,18 @@ ULONG Count, Index; NTSTATUS Status; ULONG BytesReturned; - PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY DeviceEntry; - PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context; - - DeviceEntry = Ctx->DeviceEntry; - + ULONG NumWaveOutPin, NumWaveInPin; DPRINT("Querying filter...\n"); + + Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &DeviceEntry->ObjectClass, sizeof(LPWSTR), &BytesReturned); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to query object class Status %x\n", Status); + return; + } + + DPRINT("ObjectClass %S\n", DeviceEntry->ObjectClass); PropertyRequest.Set = KSPROPSETID_Pin; PropertyRequest.Flags = KSPROPERTY_TYPE_GET; @@ -45,13 +50,13 @@ if (!NT_SUCCESS(Status)) { DPRINT1("Failed to query number of pins Status %x\n", Status); - goto cleanup; + return; } if (!Count) { DPRINT1("Filter has no pins!\n"); - goto cleanup; + return; } /* allocate pin array */ @@ -60,12 +65,14 @@ { /* no memory */ DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO)); - goto cleanup; + return; } /* clear array */ RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count); DeviceEntry->NumberOfPins = Count; + NumWaveInPin = 0; + NumWaveOutPin = 0; for(Index = 0; Index < Count; Index++) { /* get max instance count */ @@ -97,20 +104,41 @@ } if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) - DeviceEntry->NumWaveOutPin++; + NumWaveOutPin++; if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) - DeviceEntry->NumWaveInPin++; - - } - - DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin, DeviceEntry->NumWaveOutPin); - /* fetch device extension */ - DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - /* insert new audio device */ - ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); - /* increment audio device count */ - InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); + NumWaveInPin++; + + } + + DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin); +} + + + + +VOID +NTAPI +FilterPinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; + PLIST_ENTRY ListEntry; + + PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context; + + DeviceEntry = Ctx->DeviceEntry; + + ListEntry = DeviceEntry->SubDeviceList.Flink; + while(ListEntry != &DeviceEntry->SubDeviceList) + { + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(ListEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + QueryFilterRoutine(SubDeviceEntry); + ListEntry = ListEntry->Flink; + } + /* free work item */ IoFreeWorkItem(Ctx->WorkItem); @@ -118,14 +146,6 @@ ExFreePool(Ctx); return; -cleanup: - - ObDereferenceObject(DeviceEntry->FileObject); - ZwClose(DeviceEntry->Handle); - ExFreePool(DeviceEntry->DeviceName.Buffer); - ExFreePool(DeviceEntry); - IoFreeWorkItem(Ctx->WorkItem); - ExFreePool(Ctx); } NTSTATUS @@ -184,6 +204,7 @@ NTSTATUS Status = STATUS_SUCCESS; PSYSAUDIODEVEXT DeviceExtension; PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PIO_WORKITEM WorkItem = NULL; PFILTER_WORKER_CONTEXT Ctx = NULL; PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context; @@ -195,6 +216,7 @@ if (IsEqualGUIDAligned(&Event->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) { + /* a new device has arrived */ DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); if (!DeviceEntry) @@ -226,7 +248,7 @@ /* set device name */ DeviceEntry->DeviceName.Length = 0; - DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR); + DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR); DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); if (!DeviceEntry->DeviceName.Buffer) @@ -247,17 +269,41 @@ goto cleanup; } - Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateFile failed with %x\n", Status); - goto cleanup; - } - - DPRINT("Successfully opened audio device %u handle %p file object %p device object %p\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->Handle, DeviceEntry->FileObject, DeviceEntry->FileObject->DeviceObject); + /* FIXME Ros does not support device interface strings */ + /* Workarround: repeatly call IoCreateFile untill ks wont find a create item which has no object header attached */ + + InitializeListHead(&DeviceEntry->SubDeviceList); + do + { + SubDeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); + if (SubDeviceEntry) + { + RtlZeroMemory(SubDeviceEntry, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); + Status = OpenDevice(&DeviceEntry->DeviceName, &SubDeviceEntry->Handle, &SubDeviceEntry->FileObject); + if (NT_SUCCESS(Status)) + { + InsertTailList(&DeviceEntry->SubDeviceList, &SubDeviceEntry->Entry); + DeviceEntry->NumSubDevices++; + /* increment audio device count */ + InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); + } + else + { + ExFreePool(SubDeviceEntry); + break; + } + } + }while(NT_SUCCESS(Status) && SubDeviceEntry != NULL); + + DPRINT("Successfully opened audio device %u Device %S NumberOfSubDevices %u\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer, DeviceEntry->NumSubDevices); Ctx->DeviceEntry = DeviceEntry; Ctx->WorkItem = WorkItem; + + /* fetch device extension */ + DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + /* insert new audio device */ + ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx); return Status; Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -74,7 +74,7 @@ PIRP Irp) { PSYSAUDIO_CLIENT Client; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PIO_STACK_LOCATION IoStatus; ULONG Index, SubIndex; PSYSAUDIODEVEXT DeviceExtension; Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -34,8 +34,9 @@ IN PIRP Irp) { PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PSYSAUDIODEVEXT DeviceExtension; - PLIST_ENTRY Entry; + PLIST_ENTRY Entry, SubEntry; DPRINT1("SysAudio_Shutdown called\n"); @@ -48,9 +49,17 @@ DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName); RtlFreeUnicodeString(&DeviceEntry->DeviceName); - ZwClose(DeviceEntry->Handle); - ObDereferenceObject(DeviceEntry->FileObject); - ExFreePool(DeviceEntry->Pins); + + while(!IsListEmpty(&DeviceEntry->SubDeviceList)) + { + SubEntry = RemoveHeadList(&DeviceEntry->SubDeviceList); + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + + ZwClose(SubDeviceEntry->Handle); + ObDereferenceObject(SubDeviceEntry->FileObject); + ExFreePool(SubDeviceEntry->Pins); + ExFreePool(SubDeviceEntry); + } ExFreePool(DeviceEntry); } Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Sun Jun 7 22:22:24 2009 @@ -7,8 +7,9 @@ #include <ks.h> #include <ksmedia.h> #include <math.h> -#define NDEBUG +#define YDEBUG #include <debug.h> +#include <stdio.h> typedef struct { @@ -43,20 +44,27 @@ KSPIN_COMMUNICATION Communication; // pin type }PIN_INFO; +typedef struct +{ + LIST_ENTRY Entry; // linked list entry to KSAUDIO_DEVICE_ENTRY + + HANDLE Handle; // handle to audio sub device + PFILE_OBJECT FileObject; // file objecto to audio sub device + + ULONG NumberOfPins; // number of pins of audio device + PIN_INFO * Pins; // array of PIN_INFO + + LPWSTR ObjectClass; // object class of sub device + +}KSAUDIO_SUBDEVICE_ENTRY, *PKSAUDIO_SUBDEVICE_ENTRY; typedef struct { LIST_ENTRY Entry; // device entry for KsAudioDeviceList - HANDLE Handle; // handle to audio device - PFILE_OBJECT FileObject; // file object for audio device UNICODE_STRING DeviceName; // symbolic link of audio device - ULONG NumberOfClients; // number of clients referenced audio device - ULONG NumberOfPins; // number of pins of audio device - PIN_INFO * Pins; // array of PIN_INFO - - ULONG NumWaveOutPin; // number of wave out pins - ULONG NumWaveInPin; // number of wave in pins + ULONG NumSubDevices; // number of subdevices + LIST_ENTRY SubDeviceList; // audio sub device list }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; @@ -88,7 +96,7 @@ HANDLE Handle; // audio irp pin handle PFILE_OBJECT FileObject; // audio irp pin file object ULONG PinId; // pin id of device - PKSAUDIO_DEVICE_ENTRY AudioEntry; // pointer to audio device entry + PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry HANDLE hMixerPin; // handle to mixer pin PFILE_OBJECT MixerFileObject; // mixer file object @@ -104,7 +112,7 @@ PIRP Irp; BOOL CreateRealPin; BOOL CreateMixerPin; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PDISPATCH_CONTEXT DispatchContext; PSYSAUDIO_CLIENT AudioClient; @@ -148,7 +156,7 @@ IN PHANDLE HandleOut, IN PFILE_OBJECT * FileObjectOut); -PKSAUDIO_DEVICE_ENTRY +PKSAUDIO_SUBDEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index);
15 years, 5 months
1
0
0
0
[cwittich] 41340: revert a part of r41339 as it break ppc port
by cwittich@svn.reactos.org
Author: cwittich Date: Sun Jun 7 21:42:41 2009 New Revision: 41340 URL:
http://svn.reactos.org/svn/reactos?rev=41340&view=rev
Log: revert a part of r41339 as it break ppc port Modified: trunk/reactos/include/psdk/winnt.h Modified: trunk/reactos/include/psdk/winnt.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winnt.h?rev=4…
============================================================================== --- trunk/reactos/include/psdk/winnt.h [iso-8859-1] (original) +++ trunk/reactos/include/psdk/winnt.h [iso-8859-1] Sun Jun 7 21:42:41 2009 @@ -2936,8 +2936,7 @@ ULONGLONG QuadPart; } ULARGE_INTEGER, *PULARGE_INTEGER; typedef struct _LUID { - DWORD LowPart; - LONG HighPart; + LARGE_INTEGER_ORDER(LONG) } LUID, *PLUID; #pragma pack(push,4) typedef struct _LUID_AND_ATTRIBUTES {
15 years, 5 months
1
0
0
0
[cwittich] 41339: fix definition of LUID
by cwittich@svn.reactos.org
Author: cwittich Date: Sun Jun 7 21:27:44 2009 New Revision: 41339 URL:
http://svn.reactos.org/svn/reactos?rev=41339&view=rev
Log: fix definition of LUID Modified: trunk/reactos/include/psdk/winnt.h trunk/reactos/include/reactos/idl/lsa.idl Modified: trunk/reactos/include/psdk/winnt.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winnt.h?rev=4…
============================================================================== --- trunk/reactos/include/psdk/winnt.h [iso-8859-1] (original) +++ trunk/reactos/include/psdk/winnt.h [iso-8859-1] Sun Jun 7 21:27:44 2009 @@ -2936,7 +2936,8 @@ ULONGLONG QuadPart; } ULARGE_INTEGER, *PULARGE_INTEGER; typedef struct _LUID { - LARGE_INTEGER_ORDER(LONG) + DWORD LowPart; + LONG HighPart; } LUID, *PLUID; #pragma pack(push,4) typedef struct _LUID_AND_ATTRIBUTES { Modified: trunk/reactos/include/reactos/idl/lsa.idl URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/idl/lsa.id…
============================================================================== --- trunk/reactos/include/reactos/idl/lsa.idl [iso-8859-1] (original) +++ trunk/reactos/include/reactos/idl/lsa.idl [iso-8859-1] Sun Jun 7 21:27:44 2009 @@ -11,7 +11,7 @@ cpp_quote("#ifndef _WINNT_H") typedef struct _LUID { - ULONG LowPart; + DWORD LowPart; LONG HighPart; } LUID, *PLUID; cpp_quote("#endif")
15 years, 5 months
1
0
0
0
[cwittich] 41338: partial wine sync
by cwittich@svn.reactos.org
Author: cwittich Date: Sun Jun 7 19:36:25 2009 New Revision: 41338 URL:
http://svn.reactos.org/svn/reactos?rev=41338&view=rev
Log: partial wine sync Modified: trunk/reactos/dll/win32/user32/windows/dialog.c Modified: trunk/reactos/dll/win32/user32/windows/dialog.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/d…
============================================================================== --- trunk/reactos/dll/win32/user32/windows/dialog.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/windows/dialog.c [iso-8859-1] Sun Jun 7 19:36:25 2009 @@ -323,7 +323,7 @@ while (items--) { - template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info, + template = (LPCSTR)DIALOG_GetControl32( (const WORD *)template, &info, dlgTemplate->dialogEx ); /* Is this it? */ if (info.style & WS_BORDER) @@ -842,14 +842,14 @@ return 0; } -// dlgInfo->hwndFocus = 0; + dlgInfo->hwndFocus = 0; dlgInfo->hUserFont = hUserFont; dlgInfo->hMenu = hMenu; dlgInfo->xBaseUnit = xBaseUnit; dlgInfo->yBaseUnit = yBaseUnit; -// dlgInfo->idResult = 0; + dlgInfo->idResult = 0; dlgInfo->flags = flags; -// dlgInfo->hDialogHeap = 0; + /* dlgInfo->hDialogHeap = 0; */ if (template.helpId) SetWindowContextHelpId( hwnd, template.helpId ); @@ -864,6 +864,7 @@ if (DIALOG_CreateControls32( hwnd, dlgTemplate, &template, hInst, unicode )) { /* Send initialisation messages and set focus */ + if (dlgProc) { if (SendMessageW( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ) && @@ -889,6 +890,7 @@ return 0; } + /*********************************************************************** * DEFDLG_SetFocus * @@ -909,6 +911,7 @@ SetFocus( hwndCtrl ); } + /*********************************************************************** * DEFDLG_SaveFocus */ @@ -922,6 +925,7 @@ infoPtr->hwndFocus = hwndFocus; /* Remove default button */ } + /*********************************************************************** * DEFDLG_RestoreFocus @@ -946,6 +950,7 @@ sometimes losing focus when receiving WM_SETFOCUS messages. */ } + /*********************************************************************** * DEFDLG_FindDefButton * @@ -973,6 +978,7 @@ } return hwndChild; } + /*********************************************************************** * DEFDLG_SetDefId @@ -1005,6 +1011,7 @@ } return TRUE; } + /*********************************************************************** * DEFDLG_SetDefButton @@ -1042,6 +1049,7 @@ } return TRUE; } + /*********************************************************************** * DEFDLG_Proc @@ -1084,7 +1092,7 @@ /* Window clean-up */ return DefWindowProcA( hwnd, msg, wParam, lParam ); - case WM_SHOWWINDOW: + case WM_SHOWWINDOW: if (!wParam) DEFDLG_SaveFocus( hwnd ); return DefWindowProcA( hwnd, msg, wParam, lParam ); @@ -1157,7 +1165,7 @@ // TODO: where's wine's WM_CTLCOLOR from? if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) || - msg == WM_CTLCOLOR || msg == WM_COMPAREITEM || + msg == WM_CTLCOLOR || msg == WM_COMPAREITEM || msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM || msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG) return fResult; @@ -1226,7 +1234,6 @@ retWnd = DIALOG_GetNextTabItem(hwndMain,hwndMain,NULL,fPrevious ); } return retWnd ? retWnd : hwndCtrl; - } /********************************************************************** @@ -1529,13 +1536,12 @@ WPARAM wParam, LPARAM lParam) { + DIALOGINFO *dlgInfo; WNDPROC dlgproc; BOOL result = FALSE; - DIALOGINFO * dlgInfo; - - /* if there's no dialog info property then call default windows proc?? */ - if (!(dlgInfo = DIALOG_get_info(hDlg, TRUE))) - return DefWindowProcA( hDlg, Msg, wParam, lParam ); + + /* Perform DIALOGINFO initialization if not done */ + if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return -1; SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 ); @@ -1590,13 +1596,12 @@ WPARAM wParam, LPARAM lParam) { + DIALOGINFO *dlgInfo; WNDPROC dlgproc; BOOL result = FALSE; - DIALOGINFO * dlgInfo; - - /* if there's no dialog info property then call default windows proc?? */ - if (!(dlgInfo = DIALOG_get_info(hDlg, TRUE))) - return DefWindowProcW( hDlg, Msg, wParam, lParam ); + + /* Perform DIALOGINFO initialization if not done */ + if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return -1; SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 ); @@ -1713,7 +1718,7 @@ LPCDLGTEMPLATE ptr; if (!(hrsrc = FindResourceA( hInstance, lpTemplateName, (LPCSTR)RT_DIALOG )) || - !(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) + !(ptr = LoadResource(hInstance, hrsrc))) { SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); return -1; @@ -1746,7 +1751,7 @@ LPCDLGTEMPLATE ptr; if (!(hrsrc = FindResourceW( hInstance, lpTemplateName, (LPCWSTR)RT_DIALOG )) || - !(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) + !(ptr = LoadResource(hInstance, hrsrc))) { SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); return -1;
15 years, 5 months
1
0
0
0
[cwittich] 41337: add missing newline at eof
by cwittich@svn.reactos.org
Author: cwittich Date: Sun Jun 7 19:34:48 2009 New Revision: 41337 URL:
http://svn.reactos.org/svn/reactos?rev=41337&view=rev
Log: add missing newline at eof Modified: trunk/reactos/dll/win32/user32/misc/resources.c Modified: trunk/reactos/dll/win32/user32/misc/resources.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/reso…
============================================================================== --- trunk/reactos/dll/win32/user32/misc/resources.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/resources.c [iso-8859-1] Sun Jun 7 19:34:48 2009 @@ -197,4 +197,4 @@ return TRUE; } -/* EOF */ +/* EOF */
15 years, 5 months
1
0
0
0
[cwittich] 41336: sync kernel32 lzexpand to wine 1.1.23
by cwittich@svn.reactos.org
Author: cwittich Date: Sun Jun 7 18:10:13 2009 New Revision: 41336 URL:
http://svn.reactos.org/svn/reactos?rev=41336&view=rev
Log: sync kernel32 lzexpand to wine 1.1.23 Added: trunk/reactos/dll/win32/kernel32/misc/lzexpand.c - copied, changed from r41335, trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c Removed: trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c Modified: trunk/reactos/dll/win32/kernel32/kernel32.rbuild trunk/reactos/media/doc/README.WINE Modified: trunk/reactos/dll/win32/kernel32/kernel32.rbuild URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/kernel3…
============================================================================== --- trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] Sun Jun 7 18:10:13 2009 @@ -75,7 +75,7 @@ <file>handle.c</file> <file>lang.c</file> <file>ldr.c</file> - <file>lzexpand_main.c</file> + <file>lzexpand.c</file> <file>muldiv.c</file> <file>nls.c</file> <file>perfcnt.c</file> Copied: trunk/reactos/dll/win32/kernel32/misc/lzexpand.c (from r41335, trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c) URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/lz…
============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/lzexpand.c [iso-8859-1] Sun Jun 7 18:10:13 2009 @@ -1,5 +1,5 @@ /* $Id$ - * + * * LZ Decompression functions * * Copyright 1996 Marcus Meissner @@ -16,10 +16,22 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * FIXME: return values might be wrong + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * NOTES + * + * The LZ (Lempel Ziv) decompression was used in win16 installation programs. + * It is a simple tabledriven decompression engine, the algorithm is not + * documented as far as I know. WINE does not contain a compressor for + * this format. + * + * The implementation is complete and there have been no reports of failures + * for some time. + * + * TODO: + * + * o Check whether the return values are correct + * */ //#include "config.h" @@ -36,14 +48,19 @@ */ #define GETLEN 2048 +#define LZ_MAGIC_LEN 8 +#define LZ_HEADER_LEN 14 + /* Format of first 14 byte of LZ compressed file */ struct lzfileheader { - BYTE magic[8]; + BYTE magic[LZ_MAGIC_LEN]; BYTE compressiontype; CHAR lastchar; DWORD reallength; }; -static BYTE LZMagic[8]={'S','Z','D','D',0x88,0xf0,0x27,0x33}; +static const BYTE LZMagic[LZ_MAGIC_LEN]={'S','Z','D','D',0x88,0xf0,0x27,0x33}; + +#define LZ_TABLE_SIZE 0x1000 struct lzstate { HFILE realfd; /* the real filedescriptor */ @@ -53,7 +70,7 @@ DWORD realcurrent; /* the position the decompressor currently is */ DWORD realwanted; /* the position the user wants to read from */ - BYTE table[0x1000]; /* the rotating LZ table */ + BYTE table[LZ_TABLE_SIZE]; /* the rotating LZ table */ UINT curtabent; /* CURrent TABle ENTry */ BYTE stringlen; /* length and position of current string */ @@ -70,8 +87,9 @@ #define MAX_LZSTATES 16 static struct lzstate *lzstates[MAX_LZSTATES]; -#define IS_LZ_HANDLE(h) (((h) >= 0x400) && ((h) < 0x400+MAX_LZSTATES)) -#define GET_LZ_STATE(h) (IS_LZ_HANDLE(h) ? lzstates[(h)-0x400] : NULL) +#define LZ_MIN_HANDLE 0x400 +#define IS_LZ_HANDLE(h) (((h) >= LZ_MIN_HANDLE) && ((h) < LZ_MIN_HANDLE+MAX_LZSTATES)) +#define GET_LZ_STATE(h) (IS_LZ_HANDLE(h) ? lzstates[(h)-LZ_MIN_HANDLE] : NULL) /* reads one compressed byte, including buffering */ #define GET(lzs,b) _lzget(lzs,&b) @@ -102,7 +120,7 @@ */ static INT read_header(HFILE fd,struct lzfileheader *head) { - BYTE buf[14]; + BYTE buf[LZ_HEADER_LEN]; if (_llseek(fd,0,SEEK_SET)==-1) return LZERROR_BADINHANDLE; @@ -110,16 +128,16 @@ /* We can't directly read the lzfileheader struct due to * structure element alignment */ - if (_hread(fd,buf,14)<14) + if (_hread(fd,buf,LZ_HEADER_LEN)<LZ_HEADER_LEN) return 0; - memcpy(head->magic,buf,8); - memcpy(&(head->compressiontype),buf+8,1); - memcpy(&(head->lastchar),buf+9,1); + memcpy(head->magic,buf,LZ_MAGIC_LEN); + memcpy(&(head->compressiontype),buf+LZ_MAGIC_LEN,1); + memcpy(&(head->lastchar),buf+LZ_MAGIC_LEN+1,1); /* FIXME: consider endianess on non-intel architectures */ - memcpy(&(head->reallength),buf+10,4); - - if (memcmp(head->magic,LZMagic,8)) + memcpy(&(head->reallength),buf+LZ_MAGIC_LEN+2,4); + + if (memcmp(head->magic,LZMagic,LZ_MAGIC_LEN)) return 0; if (head->compressiontype!='A') return LZERROR_UNKNOWNALG; @@ -128,9 +146,7 @@ /*********************************************************************** - * LZStart (LZ32.@) - * - * @unimplemented + * LZStart (KERNEL32.@) */ INT WINAPI LZStart(void) { @@ -140,7 +156,7 @@ /*********************************************************************** - * LZInit (LZ32.@) + * LZInit (KERNEL32.@) * * initializes internal decompression buffers, returns lzfiledescriptor. * (return value the same as hfSrc, if hfSrc is not compressed) @@ -149,22 +165,19 @@ * * since _llseek uses the same types as libc.lseek, we just use the macros of * libc - * - * @implemented */ HFILE WINAPI LZInit( HFILE hfSrc ) { struct lzfileheader head; struct lzstate *lzs; - DWORD ret; - int i; + int i, ret; DPRINT("(%d)\n",hfSrc); ret=read_header(hfSrc,&head); if (ret<=0) { _llseek(hfSrc,0,SEEK_SET); - return ret?(HFILE)ret:hfSrc; + return ret?ret:hfSrc; } for (i = 0; i < MAX_LZSTATES; i++) if (!lzstates[i]) break; if (i == MAX_LZSTATES) return LZERROR_GLOBALLOC; @@ -186,18 +199,15 @@ } /* Yes, preinitialize with spaces */ - memset(lzs->table,' ',0x1000); + memset(lzs->table,' ',LZ_TABLE_SIZE); /* Yes, start 16 byte from the END of the table */ lzs->curtabent = 0xff0; - return 0x400 + i; -} - - -/*********************************************************************** - * LZDone (LZEXPAND.9) - * LZDone (LZ32.@) - * - * @unimplemented + return LZ_MIN_HANDLE + i; +} + + +/*********************************************************************** + * LZDone (KERNEL32.@) */ void WINAPI LZDone(void) { @@ -206,7 +216,7 @@ /*********************************************************************** - * GetExpandedNameA (LZ32.@) + * GetExpandedNameA (KERNEL32.@) * * gets the full filename of the compressed file 'in' by opening it * and reading the header @@ -214,8 +224,6 @@ * "file." is being translated to "file" * "file.bl_" (with lastchar 'a') is being translated to "file.bla" * "FILE.BL_" (with lastchar 'a') is being translated to "FILE.BLA" - * - * @implemented */ INT WINAPI GetExpandedNameA( LPSTR in, LPSTR out ) @@ -265,9 +273,9 @@ } if (isalpha(head.lastchar)) { if (fnislowercased) - head.lastchar=(CHAR)tolower(head.lastchar); + head.lastchar=tolower(head.lastchar); else - head.lastchar=(CHAR)toupper(head.lastchar); + head.lastchar=toupper(head.lastchar); } /* now look where to replace the last character */ @@ -286,9 +294,7 @@ /*********************************************************************** - * GetExpandedNameW (LZ32.@) - * - * @implemented + * GetExpandedNameW (KERNEL32.@) */ INT WINAPI GetExpandedNameW( LPWSTR in, LPWSTR out ) { @@ -315,9 +321,7 @@ /*********************************************************************** - * LZRead (LZ32.@) - * - * @implemented + * LZRead (KERNEL32.@) */ INT WINAPI LZRead( HFILE fd, LPSTR vbuf, INT toread ) { @@ -383,12 +387,12 @@ */ if (lzs->realcurrent>lzs->realwanted) { /* flush decompressor state */ - _llseek(lzs->realfd,14,SEEK_SET); + _llseek(lzs->realfd,LZ_HEADER_LEN,SEEK_SET); GET_FLUSH(lzs); lzs->realcurrent= 0; lzs->bytetype = 0; lzs->stringlen = 0; - memset(lzs->table,' ',0x1000); + memset(lzs->table,' ',LZ_TABLE_SIZE); lzs->curtabent = 0xFF0; } while (lzs->realcurrent<lzs->realwanted) { @@ -408,9 +412,7 @@ /*********************************************************************** - * LZSeek (LZ32.@) - * - * @implemented + * LZSeek (KERNEL32.@) */ LONG WINAPI LZSeek( HFILE fd, LONG off, INT type ) { @@ -432,7 +434,7 @@ newwanted = off; break; } - if (newwanted>(LONG)lzs->reallength) + if (newwanted>lzs->reallength) return LZERROR_BADVALUE; if (newwanted<0) return LZERROR_BADVALUE; @@ -442,22 +444,19 @@ /*********************************************************************** - * LZCopy (LZ32.@) + * LZCopy (KERNEL32.@) * * Copies everything from src to dest * if src is a LZ compressed file, it will be uncompressed. * will return the number of bytes written to dest or errors. - * - * @implemented */ LONG WINAPI LZCopy( HFILE src, HFILE dest ) { - int usedlzinit=0,ret,wret; + int usedlzinit = 0, ret, wret; LONG len; HFILE oldsrc = src, srcfd; FILETIME filetime; struct lzstate *lzs; - #define BUFLEN 1000 CHAR buf[BUFLEN]; /* we need that weird typedef, for i can't seem to get function pointer @@ -476,7 +475,7 @@ /* not compressed? just copy */ if (!IS_LZ_HANDLE(src)) - xread=(_readfun)_hread; + xread=_lread; else xread=(_readfun)LZRead; len=0; @@ -497,8 +496,8 @@ /* Maintain the timestamp of source file to destination file */ srcfd = (!(lzs = GET_LZ_STATE(src))) ? src : lzs->realfd; - GetFileTime((HANDLE)srcfd, NULL, NULL, &filetime); - SetFileTime((HANDLE)dest, NULL, NULL, &filetime); + GetFileTime( LongToHandle(srcfd), NULL, NULL, &filetime ); + SetFileTime( LongToHandle(dest), NULL, NULL, &filetime ); /* close handle */ if (usedlzinit) @@ -511,8 +510,7 @@ static LPSTR LZEXPAND_MangleName( LPCSTR fn ) { char *p; - char *mfn = (char *)RtlAllocateHeap( GetProcessHeap(), 0, - strlen(fn) + 3 ); /* "._" and \0 */ + char *mfn = RtlAllocateHeap( GetProcessHeap(), 0, strlen(fn) + 3 ); /* "._" and \0 */ if(mfn == NULL) return NULL; strcpy( mfn, fn ); if (!(p = strrchr( mfn, '\\' ))) p = mfn; @@ -526,12 +524,11 @@ return mfn; } -/*********************************************************************** - * LZOpenFileA (LZ32.@) + +/*********************************************************************** + * LZOpenFileA (KERNEL32.@) * * Opens a file. If not compressed, open it as a normal file. - * - * @implemented */ HFILE WINAPI LZOpenFileA( LPSTR fn, LPOFSTRUCT ofs, WORD mode ) { @@ -557,9 +554,7 @@ /*********************************************************************** - * LZOpenFileW (LZ32.@) - * - * @implemented + * LZOpenFileW (KERNEL32.@) */ HFILE WINAPI LZOpenFileW( LPWSTR fn, LPOFSTRUCT ofs, WORD mode ) { @@ -574,9 +569,7 @@ /*********************************************************************** - * LZClose (LZ32.@) - * - * @implemented + * LZClose (KERNEL32.@) */ void WINAPI LZClose( HFILE fd ) { @@ -587,23 +580,9 @@ else { if (lzs->get) RtlFreeHeap( GetProcessHeap(), 0, lzs->get ); - CloseHandle((HANDLE)lzs->realfd); - lzstates[fd - 0x400] = NULL; + CloseHandle( LongToHandle(lzs->realfd) ); + lzstates[fd - LZ_MIN_HANDLE] = NULL; RtlFreeHeap( GetProcessHeap(), 0, lzs ); } } - -/*********************************************************************** - * CopyLZFile (LZ32.@) - * - * Copy src to dest (including uncompressing src). - * NOTE: Yes. This is exactly the same function as LZCopy. - * - * @implemented - */ -LONG WINAPI CopyLZFile( HFILE src, HFILE dest ) -{ - DPRINT("(%d,%d)\n",src,dest); - return LZCopy(src,dest); -} Removed: trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/lz…
============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/lzexpand_main.c (removed) @@ -1,609 +1,0 @@ -/* $Id$ - * - * LZ Decompression functions - * - * Copyright 1996 Marcus Meissner - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * FIXME: return values might be wrong - */ - -//#include "config.h" - -#include <k32.h> -#define NDEBUG -#include <debug.h> -#include "lzexpand.h" - -#define HFILE_ERROR ((HFILE)-1) - -/* The readahead length of the decompressor. Reading single bytes - * using _hread() would be SLOW. - */ -#define GETLEN 2048 - -/* Format of first 14 byte of LZ compressed file */ -struct lzfileheader { - BYTE magic[8]; - BYTE compressiontype; - CHAR lastchar; - DWORD reallength; -}; -static BYTE LZMagic[8]={'S','Z','D','D',0x88,0xf0,0x27,0x33}; - -struct lzstate { - HFILE realfd; /* the real filedescriptor */ - CHAR lastchar; /* the last char of the filename */ - - DWORD reallength; /* the decompressed length of the file */ - DWORD realcurrent; /* the position the decompressor currently is */ - DWORD realwanted; /* the position the user wants to read from */ - - BYTE table[0x1000]; /* the rotating LZ table */ - UINT curtabent; /* CURrent TABle ENTry */ - - BYTE stringlen; /* length and position of current string */ - DWORD stringpos; /* from stringtable */ - - - WORD bytetype; /* bitmask within blocks */ - - BYTE *get; /* GETLEN bytes */ - DWORD getcur; /* current read */ - DWORD getlen; /* length last got */ -}; - -#define MAX_LZSTATES 16 -static struct lzstate *lzstates[MAX_LZSTATES]; - -#define IS_LZ_HANDLE(h) (((h) >= 0x400) && ((h) < 0x400+MAX_LZSTATES)) -#define GET_LZ_STATE(h) (IS_LZ_HANDLE(h) ? lzstates[(h)-0x400] : NULL) - -/* reads one compressed byte, including buffering */ -#define GET(lzs,b) _lzget(lzs,&b) -#define GET_FLUSH(lzs) lzs->getcur=lzs->getlen; - -static int -_lzget(struct lzstate *lzs,BYTE *b) { - if (lzs->getcur<lzs->getlen) { - *b = lzs->get[lzs->getcur++]; - return 1; - } else { - int ret = _hread(lzs->realfd,lzs->get,GETLEN); - if (ret==HFILE_ERROR) - return HFILE_ERROR; - if (ret==0) - return 0; - lzs->getlen = ret; - lzs->getcur = 1; - *b = *(lzs->get); - return 1; - } -} -/* internal function, reads lzheader - * returns BADINHANDLE for non filedescriptors - * return 0 for file not compressed using LZ - * return UNKNOWNALG for unknown algorithm - * returns lzfileheader in *head - */ -static INT read_header(HFILE fd,struct lzfileheader *head) -{ - BYTE buf[14]; - - if (_llseek(fd,0,SEEK_SET)==-1) - return LZERROR_BADINHANDLE; - - /* We can't directly read the lzfileheader struct due to - * structure element alignment - */ - if (_hread(fd,buf,14)<14) - return 0; - memcpy(head->magic,buf,8); - memcpy(&(head->compressiontype),buf+8,1); - memcpy(&(head->lastchar),buf+9,1); - - /* FIXME: consider endianess on non-intel architectures */ - memcpy(&(head->reallength),buf+10,4); - - if (memcmp(head->magic,LZMagic,8)) - return 0; - if (head->compressiontype!='A') - return LZERROR_UNKNOWNALG; - return 1; -} - - -/*********************************************************************** - * LZStart (LZ32.@) - * - * @unimplemented - */ -INT WINAPI LZStart(void) -{ - DPRINT("(void)\n"); - return 1; -} - - -/*********************************************************************** - * LZInit (LZ32.@) - * - * initializes internal decompression buffers, returns lzfiledescriptor. - * (return value the same as hfSrc, if hfSrc is not compressed) - * on failure, returns error code <0 - * lzfiledescriptors range from 0x400 to 0x410 (only 16 open files per process) - * - * since _llseek uses the same types as libc.lseek, we just use the macros of - * libc - * - * @implemented - */ -HFILE WINAPI LZInit( HFILE hfSrc ) -{ - - struct lzfileheader head; - struct lzstate *lzs; - DWORD ret; - int i; - - DPRINT("(%d)\n",hfSrc); - ret=read_header(hfSrc,&head); - if (ret<=0) { - _llseek(hfSrc,0,SEEK_SET); - return ret?(HFILE)ret:hfSrc; - } - for (i = 0; i < MAX_LZSTATES; i++) if (!lzstates[i]) break; - if (i == MAX_LZSTATES) return LZERROR_GLOBALLOC; - lzstates[i] = lzs = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct lzstate) ); - if(lzs == NULL) return LZERROR_GLOBALLOC; - - lzs->realfd = hfSrc; - lzs->lastchar = head.lastchar; - lzs->reallength = head.reallength; - - lzs->get = RtlAllocateHeap( GetProcessHeap(), 0, GETLEN ); - lzs->getlen = 0; - lzs->getcur = 0; - - if(lzs->get == NULL) { - RtlFreeHeap(GetProcessHeap(), 0, lzs); - lzstates[i] = NULL; - return LZERROR_GLOBALLOC; - } - - /* Yes, preinitialize with spaces */ - memset(lzs->table,' ',0x1000); - /* Yes, start 16 byte from the END of the table */ - lzs->curtabent = 0xff0; - return 0x400 + i; -} - - -/*********************************************************************** - * LZDone (LZEXPAND.9) - * LZDone (LZ32.@) - * - * @unimplemented - */ -void WINAPI LZDone(void) -{ - DPRINT("(void)\n"); -} - - -/*********************************************************************** - * GetExpandedNameA (LZ32.@) - * - * gets the full filename of the compressed file 'in' by opening it - * and reading the header - * - * "file." is being translated to "file" - * "file.bl_" (with lastchar 'a') is being translated to "file.bla" - * "FILE.BL_" (with lastchar 'a') is being translated to "FILE.BLA" - * - * @implemented - */ - -INT WINAPI GetExpandedNameA( LPSTR in, LPSTR out ) -{ - struct lzfileheader head; - HFILE fd; - OFSTRUCT ofs; - INT fnislowercased,ret,len; - LPSTR s,t; - - DPRINT("(%s)\n",in); - fd=OpenFile(in,&ofs,OF_READ); - if (fd==HFILE_ERROR) - return (INT)(INT16)LZERROR_BADINHANDLE; - strcpy(out,in); - ret=read_header(fd,&head); - if (ret<=0) { - /* not a LZ compressed file, so the expanded name is the same - * as the input name */ - _lclose(fd); - return 1; - } - - - /* look for directory prefix and skip it. */ - s=out; - while (NULL!=(t=strpbrk(s,"/\\:"))) - s=t+1; - - /* now mangle the basename */ - if (!*s) { - /* FIXME: hmm. shouldn't happen? */ - DPRINT("Specified a directory or what? (%s)\n",in); - _lclose(fd); - return 1; - } - /* see if we should use lowercase or uppercase on the last char */ - fnislowercased=1; - t=s+strlen(s)-1; - while (t>=out) { - if (!isalpha(*t)) { - t--; - continue; - } - fnislowercased=islower(*t); - break; - } - if (isalpha(head.lastchar)) { - if (fnislowercased) - head.lastchar=(CHAR)tolower(head.lastchar); - else - head.lastchar=(CHAR)toupper(head.lastchar); - } - - /* now look where to replace the last character */ - if (NULL!=(t=strchr(s,'.'))) { - if (t[1]=='\0') { - t[0]='\0'; - } else { - len=strlen(t)-1; - if (t[len]=='_') - t[len]=head.lastchar; - } - } /* else no modification necessary */ - _lclose(fd); - return 1; -} - - -/*********************************************************************** - * GetExpandedNameW (LZ32.@) - * - * @implemented - */ -INT WINAPI GetExpandedNameW( LPWSTR in, LPWSTR out ) -{ - INT ret; - DWORD len; - char *xin, *xout; - len = WideCharToMultiByte( CP_ACP, 0, in, -1, NULL, 0, NULL, NULL ); - xin = RtlAllocateHeap( RtlGetProcessHeap(), 0, len ); - if (xin == NULL) - return LZERROR_BADVALUE; - xout = RtlAllocateHeap( RtlGetProcessHeap(), 0, len+3 ); - if (xout == NULL) - { - RtlFreeHeap( RtlGetProcessHeap(), 0, xin ); - return LZERROR_BADVALUE; - } - WideCharToMultiByte( CP_ACP, 0, in, -1, xin, len, NULL, NULL ); - if ((ret = GetExpandedNameA( xin, xout )) > 0) - MultiByteToWideChar( CP_ACP, 0, xout, -1, out, wcslen(in)+4 ); - RtlFreeHeap( RtlGetProcessHeap(), 0, xin ); - RtlFreeHeap( RtlGetProcessHeap(), 0, xout ); - return ret; -} - - -/*********************************************************************** - * LZRead (LZ32.@) - * - * @implemented - */ -INT WINAPI LZRead( HFILE fd, LPSTR vbuf, INT toread ) -{ - int howmuch; - BYTE b,*buf; - struct lzstate *lzs; - - buf=(LPBYTE)vbuf; - DPRINT("(%d,%p,%d)\n",fd,buf,toread); - howmuch=toread; - if (!(lzs = GET_LZ_STATE(fd))) return _hread(fd,buf,toread); - -/* The decompressor itself is in a define, cause we need it twice - * in this function. (the decompressed byte will be in b) - */ -#define DECOMPRESS_ONE_BYTE \ - if (lzs->stringlen) { \ - b = lzs->table[lzs->stringpos]; \ - lzs->stringpos = (lzs->stringpos+1)&0xFFF; \ - lzs->stringlen--; \ - } else { \ - if (!(lzs->bytetype&0x100)) { \ - if (1!=GET(lzs,b)) \ - return toread-howmuch; \ - lzs->bytetype = b|0xFF00; \ - } \ - if (lzs->bytetype & 1) { \ - if (1!=GET(lzs,b)) \ - return toread-howmuch; \ - } else { \ - BYTE b1,b2; \ - \ - if (1!=GET(lzs,b1)) \ - return toread-howmuch; \ - if (1!=GET(lzs,b2)) \ - return toread-howmuch; \ - /* Format: \ - * b1 b2 \ - * AB CD \ - * where CAB is the stringoffset in the table\ - * and D+3 is the len of the string \ - */ \ - lzs->stringpos = b1|((b2&0xf0)<<4); \ - lzs->stringlen = (b2&0xf)+2; \ - /* 3, but we use a byte already below ... */\ - b = lzs->table[lzs->stringpos];\ - lzs->stringpos = (lzs->stringpos+1)&0xFFF;\ - } \ - lzs->bytetype>>=1; \ - } \ - /* store b in table */ \ - lzs->table[lzs->curtabent++]= b; \ - lzs->curtabent &= 0xFFF; \ - lzs->realcurrent++; - - /* if someone has seeked, we have to bring the decompressor - * to that position - */ - if (lzs->realcurrent!=lzs->realwanted) { - /* if the wanted position is before the current position - * I see no easy way to unroll ... We have to restart at - * the beginning. *sigh* - */ - if (lzs->realcurrent>lzs->realwanted) { - /* flush decompressor state */ - _llseek(lzs->realfd,14,SEEK_SET); - GET_FLUSH(lzs); - lzs->realcurrent= 0; - lzs->bytetype = 0; - lzs->stringlen = 0; - memset(lzs->table,' ',0x1000); - lzs->curtabent = 0xFF0; - } - while (lzs->realcurrent<lzs->realwanted) { - DECOMPRESS_ONE_BYTE; - } - } - - while (howmuch) { - DECOMPRESS_ONE_BYTE; - lzs->realwanted++; - *buf++ = b; - howmuch--; - } - return toread; -#undef DECOMPRESS_ONE_BYTE -} - - -/*********************************************************************** - * LZSeek (LZ32.@) - * - * @implemented - */ -LONG WINAPI LZSeek( HFILE fd, LONG off, INT type ) -{ - struct lzstate *lzs; - LONG newwanted; - - DPRINT("(%d,%ld,%d)\n",fd,off,type); - /* not compressed? just use normal _llseek() */ - if (!(lzs = GET_LZ_STATE(fd))) return _llseek(fd,off,type); - newwanted = lzs->realwanted; - switch (type) { - case 1: /* SEEK_CUR */ - newwanted += off; - break; - case 2: /* SEEK_END */ - newwanted = lzs->reallength-off; - break; - default:/* SEEK_SET */ - newwanted = off; - break; - } - if (newwanted>(LONG)lzs->reallength) - return LZERROR_BADVALUE; - if (newwanted<0) - return LZERROR_BADVALUE; - lzs->realwanted = newwanted; - return newwanted; -} - - -/*********************************************************************** - * LZCopy (LZ32.@) - * - * Copies everything from src to dest - * if src is a LZ compressed file, it will be uncompressed. - * will return the number of bytes written to dest or errors. - * - * @implemented - */ -LONG WINAPI LZCopy( HFILE src, HFILE dest ) -{ - int usedlzinit=0,ret,wret; - LONG len; - HFILE oldsrc = src, srcfd; - FILETIME filetime; - struct lzstate *lzs; - -#define BUFLEN 1000 - CHAR buf[BUFLEN]; - /* we need that weird typedef, for i can't seem to get function pointer - * casts right. (Or they probably just do not like WINAPI in general) - */ - typedef UINT (WINAPI *_readfun)(HFILE,LPVOID,UINT); - - _readfun xread; - - DPRINT("(%d,%d)\n",src,dest); - if (!IS_LZ_HANDLE(src)) { - src = LZInit(src); - if ((INT)src <= 0) return 0; - if (src != oldsrc) usedlzinit=1; - } - - /* not compressed? just copy */ - if (!IS_LZ_HANDLE(src)) - xread=(_readfun)_hread; - else - xread=(_readfun)LZRead; - len=0; - while (1) { - ret=xread(src,buf,BUFLEN); - if (ret<=0) { - if (ret==0) - break; - if (ret==-1) - return LZERROR_READ; - return ret; - } - len += ret; - wret = _hwrite(dest,buf,ret); - if (wret!=ret) - return LZERROR_WRITE; - } - - /* Maintain the timestamp of source file to destination file */ - srcfd = (!(lzs = GET_LZ_STATE(src))) ? src : lzs->realfd; - GetFileTime((HANDLE)srcfd, NULL, NULL, &filetime); - SetFileTime((HANDLE)dest, NULL, NULL, &filetime); - - /* close handle */ - if (usedlzinit) - LZClose(src); - return len; -#undef BUFLEN -} - -/* reverses GetExpandedPathname */ -static LPSTR LZEXPAND_MangleName( LPCSTR fn ) -{ - char *p; - char *mfn = (char *)RtlAllocateHeap( GetProcessHeap(), 0, - strlen(fn) + 3 ); /* "._" and \0 */ - if(mfn == NULL) return NULL; - strcpy( mfn, fn ); - if (!(p = strrchr( mfn, '\\' ))) p = mfn; - if ((p = strchr( p, '.' ))) - { - p++; - if (strlen(p) < 3) strcat( p, "_" ); /* append '_' */ - else p[strlen(p)-1] = '_'; /* replace last character */ - } - else strcat( mfn, "._" ); /* append "._" */ - return mfn; -} - -/*********************************************************************** - * LZOpenFileA (LZ32.@) - * - * Opens a file. If not compressed, open it as a normal file. - * - * @implemented - */ -HFILE WINAPI LZOpenFileA( LPSTR fn, LPOFSTRUCT ofs, WORD mode ) -{ - HFILE fd,cfd; - - DPRINT("(%s,%p,%d)\n",fn,ofs,mode); - /* 0x70 represents all OF_SHARE_* flags, ignore them for the check */ - fd=OpenFile(fn,ofs,mode); - if (fd==HFILE_ERROR) - { - LPSTR mfn = LZEXPAND_MangleName(fn); - fd = OpenFile(mfn,ofs,mode); - RtlFreeHeap( GetProcessHeap(), 0, mfn ); - } - if ((mode&~0x70)!=OF_READ) - return fd; - if (fd==HFILE_ERROR) - return HFILE_ERROR; - cfd=LZInit(fd); - if ((INT)cfd <= 0) return fd; - return cfd; -} - - -/*********************************************************************** - * LZOpenFileW (LZ32.@) - * - * @implemented - */ -HFILE WINAPI LZOpenFileW( LPWSTR fn, LPOFSTRUCT ofs, WORD mode ) -{ - HFILE ret; - DWORD len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL ); - LPSTR xfn = RtlAllocateHeap( GetProcessHeap(), 0, len ); - WideCharToMultiByte( CP_ACP, 0, fn, -1, xfn, len, NULL, NULL ); - ret = LZOpenFileA(xfn,ofs,mode); - RtlFreeHeap( GetProcessHeap(), 0, xfn ); - return ret; -} - - -/*********************************************************************** - * LZClose (LZ32.@) - * - * @implemented - */ -void WINAPI LZClose( HFILE fd ) -{ - struct lzstate *lzs; - - DPRINT("(%d)\n",fd); - if (!(lzs = GET_LZ_STATE(fd))) _lclose(fd); - else - { - if (lzs->get) RtlFreeHeap( GetProcessHeap(), 0, lzs->get ); - CloseHandle((HANDLE)lzs->realfd); - lzstates[fd - 0x400] = NULL; - RtlFreeHeap( GetProcessHeap(), 0, lzs ); - } -} - - -/*********************************************************************** - * CopyLZFile (LZ32.@) - * - * Copy src to dest (including uncompressing src). - * NOTE: Yes. This is exactly the same function as LZCopy. - * - * @implemented - */ -LONG WINAPI CopyLZFile( HFILE src, HFILE dest ) -{ - DPRINT("(%d,%d)\n",src,dest); - return LZCopy(src,dest); -} Modified: trunk/reactos/media/doc/README.WINE URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sun Jun 7 18:10:13 2009 @@ -207,6 +207,7 @@ reactos/dll/win32/kernel32/misc/errormsg.c # Out of sync reactos/dll/win32/kernel32/misc/profile.c # Out of sync reactos/dll/win32/kernel32/misc/lcformat.c # Out of sync + reactos/dll/win32/kernel32/misc/lzexpand.c # Synced to Wine-1_1_23 msvcrt - reactos/lib/sdk/crt/except/cpp.c # Synced at 20071111
15 years, 5 months
1
0
0
0
← Newer
1
...
36
37
38
39
40
41
42
...
50
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Results per page:
10
25
50
100
200