Firewall exception code just works for outgoing connections - c++

I took this code from the web to add a firewall exception for my application:
STDAPI AddApplicationToExceptionListW( const WCHAR* strGameExeFullPath, const WCHAR* strFriendlyAppName )
{
HRESULT hr = E_FAIL;
bool bCleanupCOM = false;
BSTR bstrFriendlyAppName = NULL;
BSTR bstrGameExeFullPath = NULL;
INetFwAuthorizedApplication* pFwApp = NULL;
INetFwAuthorizedApplications* pFwApps = NULL;
INetFwProfile* pFwProfile = NULL;
#ifdef SHOW_DEBUG_MSGBOXES
WCHAR sz[1024];
StringCchPrintf( sz, 1024, L"strFriendlyAppName='%s' strGameExeFullPath='%s'", strFriendlyAppName, strGameExeFullPath );
MessageBox( NULL, sz, L"AddApplicationToExceptionListW", MB_OK );
#endif
if( strGameExeFullPath == NULL || strFriendlyAppName == NULL )
{
assert( false );
return E_INVALIDARG;
}
bstrGameExeFullPath = SysAllocString( strGameExeFullPath );
bstrFriendlyAppName = SysAllocString( strFriendlyAppName );
if( bstrGameExeFullPath == NULL || bstrFriendlyAppName == NULL )
{
hr = E_OUTOFMEMORY;
goto LCleanup;
}
hr = CoInitialize( 0 );
bCleanupCOM = SUCCEEDED( hr );
pFwProfile = GetFirewallProfile();
if( pFwProfile == NULL )
{
hr = E_FAIL;
goto LCleanup;
}
hr = pFwProfile->get_AuthorizedApplications( &pFwApps );
if( FAILED( hr ) )
goto LCleanup;
// Create an instance of an authorized application.
hr = CoCreateInstance( __uuidof( NetFwAuthorizedApplication ), NULL,
CLSCTX_INPROC_SERVER, __uuidof( INetFwAuthorizedApplication ), ( void** )&pFwApp );
if( FAILED( hr ) )
goto LCleanup;
// Set the process image file name.
hr = pFwApp->put_ProcessImageFileName( bstrGameExeFullPath );
if( FAILED( hr ) )
goto LCleanup;
// Set the application friendly name.
hr = pFwApp->put_Name( bstrFriendlyAppName );
if( FAILED( hr ) )
goto LCleanup;
// Add the application to the collection.
hr = pFwApps->Add( pFwApp );
LCleanup:
if( bstrFriendlyAppName ) SysFreeString( bstrFriendlyAppName );
if( bstrGameExeFullPath ) SysFreeString( bstrGameExeFullPath );
if( pFwApp ) pFwApp->Release();
if( pFwApps ) pFwApps->Release();
if( pFwProfile ) pFwProfile->Release();
if( bCleanupCOM ) CoUninitialize();
return hr;
}
Everything works great when I try to send data through the Windows firewall, but incoming connections are still blocked. So I have to disable my firewall to recieve data. I thought, that exception would allow all connections (outgoing and incoming)...
Does somebody know what I should add to this code so I can recieve incoming data?

It is not enough to just add the application by itself. The firewall has no way of discovering which port(s) the application is listening on for inbound connections. You have to tell the firewall which port(s) the application is using. You do that via the INetFwProfile::GloballyOpenPorts collection, eg:
INetFwOpenPorts *pFwPorts = NULL;
INetFwOpenPort *pFWPort = NULL;
...
hr = pFwProfile->get_GloballyOpenPorts( &pFwPorts );
if( FAILED( hr ) )
goto LCleanup;
// Create an instance of an open port.
hr = CoCreateInstance( __uuidof( NetFwOpenPort ), NULL, CLSCTX_INPROC_SERVER, __uuidof( INetFwOpenPort ), ( void** )&pFwPort );
if( FAILED( hr ) )
goto LCleanup;
// Set the port number.
hr = pFWPort->put_Port( ... );
if( FAILED( hr ) )
goto LCleanup;
// Add the port to the collection.
hr = pFwPorts->Add( pFwPort );
...
if( pFwPort ) pFwPort->Release();
if( pFwPorts ) pFwPorts->Release();

In my case the solution was deleting the firewall rules that blocked my application. I don't know where these rules came from, but now it finally works.

Related

Getting output of Async SAPI call?

I have a working example using the Windows text-to-speech API, but the problem is it freezes when given a large amount of text.
To solve this I want to make the process asynchronous. I've found the SpeechVoiceSpeakFlags::SVSFlagsAsync flag, but how do I get the results of a previously-submitted request?
Here is my code:
char* TextToWavInner( const wchar_t* voiceRequiredAttributes, const wchar_t* voiceOptionalAttributes, long rate, const wchar_t* textToRender, ULONG* pBytesRead )
{
HRESULT hr;
CComPtr<ISpVoice> cpVoice; //Will send data to ISpStream
CComPtr<ISpStream> cpStream; //Will contain IStream
CComPtr<IStream> cpBaseStream; //raw data
ISpObjectToken* cpToken( NULL ); //Will set voice characteristics
GUID guidFormat;
WAVEFORMATEX* pWavFormatEx = nullptr;
hr = cpVoice.CoCreateInstance( CLSID_SpVoice );
if ( FAILED( hr ) )
return NULL;
hr = SpFindBestToken( SPCAT_VOICES, voiceRequiredAttributes, voiceOptionalAttributes, &cpToken );
if ( FAILED( hr ) )
return NULL;
hr = cpVoice->SetVoice( cpToken );
cpToken->Release();
if ( FAILED( hr ) )
return NULL;
cpVoice->SetRate( rate );
hr = cpStream.CoCreateInstance( CLSID_SpStream );
if ( FAILED( hr ) )
return NULL;
hr = CreateStreamOnHGlobal( NULL, true, &cpBaseStream );
if ( FAILED( hr ) )
return NULL;
hr = SpConvertStreamFormatEnum( SPSF_44kHz16BitMono, &guidFormat, &pWavFormatEx );
if ( FAILED( hr ) )
return NULL;
hr = cpStream->SetBaseStream( cpBaseStream, guidFormat, pWavFormatEx );
if ( FAILED( hr ) )
return NULL;
hr = cpVoice->SetOutput( cpStream, false );
if ( FAILED( hr ) )
return NULL;
SpeechVoiceSpeakFlags voiceFlags = ( SpeechVoiceSpeakFlags ) ( SpeechVoiceSpeakFlags::SVSFlagsAsync | SpeechVoiceSpeakFlags::SVSFPurgeBeforeSpeak );
hr = cpVoice->Speak( textToRender, voiceFlags, NULL );
if ( FAILED( hr ) )
return NULL;
LARGE_INTEGER a = { 0 };
hr = cpStream->Seek( a, STREAM_SEEK_SET, NULL );
if ( FAILED( hr ) )
return NULL;
STATSTG stats;
cpStream->Stat( &stats, STATFLAG_NONAME );
ULONG sSize = stats.cbSize.LowPart;
char* pBuffer = new char[ sSize ];
cpStream->Read( pBuffer, sSize, pBytesRead );
return pBuffer;
}

Shell Extension: IShellExtInit::Initialize called 4 times

I've run into a situation that is not so unique (others have been asking exact same question) Offsite similar question..
Basically, for some reason, the code in IShellExtInit::Initialize implementation that is supposed to be invoked once after each right-click on a file, ends up being invoked 4 times.
STDMETHODIMP My_ShellExtInit::Initialize (LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID ) {
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT,
-1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;
if ( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
return E_INVALIDARG;
hDrop = (HDROP) GlobalLock ( stg.hGlobal );
if ( NULL == hDrop )
return E_INVALIDARG;
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
HRESULT hr = S_OK;
if ( 0 == uNumFiles ) {
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}
if ( 0 == DragQueryFile ( hDrop, 0, m_szFile, MAX_PATH ) )
hr = E_INVALIDARG;
system("echo INVOKED >> log.txt");
// QMessageBox::warning(NULL, "Foo!", TCHARToQString(m_szFile));
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return hr;
}
Depending on the file/type, your context menu handler is called multiple times:
for the file/folder itself
for the parent folder of the file
for the folder background
in case of a *.lnk file also for the target it points to
And if explorer shows the tree view, then that part also calls your handler.

enumerate forms in BeforeNavigate2 event

I'm writing an IE BHO, I'd like to know how to enumerate forms in event callback.
here's the code that enumerates forms in BeforeNavigate2 event, but the length is always 0.
STDMETHODIMP CEventSink::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
HRESULT hr;
char bf[1024];
if(!IsEqualIID(riid, IID_NULL))
return DISP_E_UNKNOWNINTERFACE;
if(dispIdMember == DISPID_BEFORENAVIGATE2) {
IWebBrowser2* pSite = (IWebBrowser2*)pDispParams->rgvarg[6].pdispVal;
IDispatch* pHtmlDocDispatch;
hr = pSite->get_Document(&pHtmlDocDispatch);
if (FAILED(hr) || !pHtmlDocDispatch)
return S_OK;
IHTMLDocument2* pHtmlDoc = 0;
hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);
if(SUCCEEDED(hr) && pHtmlDoc) {
CComPtr<IHTMLElementCollection> pColl=NULL;
hr = pHtmlDoc->get_forms(&pColl);
if (SUCCEEDED (hr) && (pColl != NULL))
{
long nLength = 0;
hr = pColl->get_length (&nLength);
if(SUCCEEDED(hr)) {
sprintf(bf, "len = %d", nLength);
OutputDebugString(bf); // always 0
}
}
}
}
return S_OK;
}
Why it always output 0?
Thanks.
I just copy/pasted your code in my BHO and got a non-zero length collection.
Try that URL: http://linuxfr.org/ Use random user/password values and try to connect. That will trigger a DISPID_BEFORENAVIGATE2 and you will get 3 forms.
So, it seems there is no form in the page your are navigating away.
Also, your code leaks memory and is not quite correct in using COM interfaces (ag: you should QueryInterface for obtaining an IWebBrowser2 from a IDispatch.
Rewritten:
CComPtr<IDispatch> spIDispatch( pDispParams->rgvarg[6].pdispVal );
CComPtr<IWebBrowser2> spIWebBrowser2;
HRESULT hr = spIDispatch.QueryInterface<IWebBrowser2>( &spIWebBrowser2 );
if ( SUCCEEDED( hr ) && spIWebBrowser2 ) {
CComPtr<IDispatch> spIDispatchDoc;
hr = spIWebBrowser2->get_Document( &spIDispatchDoc );
if ( SUCCEEDED( hr ) && spIDispatchDoc ) {
CComPtr<IHTMLDocument2> spIHTMLDocument2;
hr = spIDispatchDoc.QueryInterface<IHTMLDocument2>( &spIHTMLDocument2 );
if ( SUCCEEDED( hr ) && spIHTMLDocument2 ) {
CComPtr<IHTMLElementCollection> spIHTMLElementCollection;
hr = spIHTMLDocument2->get_forms( &spIHTMLElementCollection );
if ( SUCCEEDED( hr ) && spIHTMLElementCollection ) {
[...]
}
}
}
}

How to pin Application icon to the metro start screen in windows 8 programmatically

How can I pin application icon to metro start screen in win8 programmatically(c++)? I know how to do it manually. I also know that it will be added automatically once I launch that application.
I found this solution here
BOOL PinToStart( LPCWSTR szFilePath )
{
BOOL bSuccess = FALSE;
// break into file name and path
WCHAR lpszDirectoryName[ MAX_PATH ] = { 0 };
LPCWSTR lpszFileName = ::PathFindFileName( szFilePath );
wcscpy_s( lpszDirectoryName, szFilePath );
::PathRemoveFileSpec( lpszDirectoryName );
// load shell32.dll
HMODULE hShell32 = LoadLibrary( L"SHELL32" );
if( hShell32 != NULL )
{
// get the localized translation of 'Pin to Start' verb
WCHAR szPinToStartLocalized[ MAX_PATH ] = { 0 };
int nPinToStartLocalizedLength = LoadString( (HINSTANCE)hShell32, 51201, szPinToStartLocalized, MAX_PATH );
if( nPinToStartLocalizedLength > 0 )
{
// create the shell object
IShellDispatch *pShellDispatch = NULL;
HRESULT hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&pShellDispatch);
if( SUCCEEDED( hr ) )
{
Folder *pFolder = NULL;
variant_t vaDirectory( lpszDirectoryName );
// get the namespace
if( SUCCEEDED( pShellDispatch->NameSpace( vaDirectory, &pFolder ) ) )
{
FolderItem *pItem = NULL;
bstr_t vaFileName( lpszFileName );
// parse the name
if( SUCCEEDED( pFolder->ParseName( vaFileName, &pItem ) ) )
{
FolderItemVerbs* pVerbs = NULL;
// get the verbs
if( SUCCEEDED( pItem->Verbs(&pVerbs) ) )
{
long nCount = 0;
if( SUCCEEDED ( pVerbs->get_Count( &nCount ) ) )
{
variant_t vaIndex;
vaIndex.vt = VT_I4;
// iterate through verbs
for( vaIndex.lVal = 0; vaIndex.lVal<nCount; vaIndex.lVal++ )
{
FolderItemVerb* pVerb = NULL;
if( SUCCEEDED( pVerbs->Item( vaIndex, &pVerb ) ) )
{
BSTR bstrVerbName = NULL;
// check for 'Pin to Start' verb
if( SUCCEEDED( pVerb->get_Name( &bstrVerbName ) ) )
{
if( 0 == wcscmp( bstrVerbName, szPinToStartLocalized ) )
{
bSuccess = SUCCEEDED( pVerb->DoIt() );
vaIndex.lVal = nCount; // break for
}
::SysFreeString( bstrVerbName );
}
pVerb->Release();
} // if
} // for
}
pVerbs->Release();
}
pItem->Release();
}
pFolder->Release();
}
pShellDispatch->Release();
}
}
::FreeLibrary( hShell32 );
}
return bSuccess;
}
Hope it's help you

GmfBridge doesn't connect sink filter with source filter

I am trying to use GmfBridge library to dynamically change source filters from cam to file and vice versa. All functions return S_OK (well, almost all - pMediaControlOutput->Run() returns S_FALSE actually, but in msdn said that this can be ok too), so I've assumed that all is ok but data isn't transfered to the other side of the bridge. I use GraphStudio to connect to remote graph and all seems to be ok - all filters in both graph are connected as it should be. But while playing I receive following messages in bridge log file:
0: Started 2011-09-10 15:58:38
0: Buffer minimum 100
0: Added stream 1: 畡楤o, Decompressed Only, Discard mode
1: Sink 0x7ae0ca8 has 1 pins
1: Sink filter 0x7ae0cf8 in graph 0x193bf0
2: Source 0x7ae1030 has 1 pins
2: Source filter 0x7ae1080 in graph 0x194c18
14: ReceiveConnection Aware: false
14: Bridging 0x194c18 to 0x193bf0
14: Pin 0x7ae3438 disconnect
25: Source 0x7ae1030 pause from 0
25: Source pin 0x7ae3618 active
2234: Pin 0x7ae3438 receive 0x721ec68
2234: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3389: Pin 0x7ae3438 receive 0x721ec68
3389: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3940: Pin 0x7ae3438 receive 0x721ec68
3940: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
4440: Pin 0x7ae3438 receive 0x721ec68
So as you can see, left graph isn't connected to right one despite BridgeGraphs() returned S_OK and media sample is discarded. Below there is my code. Where am I going wrong?
// Create graphs
HRESULT hr = m_graphInput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );
// Get IMediaControl interfaces
hr = m_graphInput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlOutput );
ATLASSERT( SUCCEEDED( hr ) );
// Get builder interfaces
hr = m_graphInput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderOutput );
ATLASSERT( SUCCEEDED( hr ) );
// Load source filter (on sink side)
LocateFilter( SOURCE_FILTER_NAME, CLSID_LegacyAmFilterCategory, &inputDevice );
hr = m_graphInput->AddFilter( inputDevice, SOURCE_FILTER_NAME );
ATLASSERT( SUCCEEDED( hr ) );
// Load render filter (on bridge's source side)
LocateFilter( _T( "Default DirectSound Device" ), CLSID_AudioRendererCategory, &audioOutputPreview );
hr = m_graphOutput->AddFilter( audioOutputPreview, _T( "Default DirectSound Device" ) );
ATLASSERT( SUCCEEDED( hr ) );
// Init bridge
bridge.CreateInstance( __uuidof(GMFBridgeController) );
hr = bridge->SetBufferMinimum( 100 );
ATLASSERT( SUCCEEDED( hr ) );
hr = bridge->AddStream( false, eUncompressed, false );
ATLASSERT( SUCCEEDED( hr ) );
// Add sink filter and connect to input graph
IUnknownPtr pSinkFilter;
{
hr = bridge->InsertSinkFilter( m_graphInput, (IUnknown**)&pSinkFilter );
ATLASSERT( SUCCEEDED( hr ) );
// Using own functions get pins
IPin* pInAudio = CPinController::getOutputPin( inputDevice, _T("Audio"));
IPin* pOutAudio = CPinController::getInputPin( pSinkFilter );
hr = pBuilderInput->Connect( pOutAudio, pInAudio );
ATLASSERT( SUCCEEDED( hr ) );
}
// Add output filter and connect to output graph
IUnknownPtr pFeederFilter;
{
hr = bridge->InsertSourceFilter( pSinkFilter, m_graphOutput, &pFeederFilter );
ATLASSERT( SUCCEEDED( hr ) );
// Get pins
IPin* pInAudio = CPinController::getOutputPin( pFeederFilter/*, _T("Audio")*/);
IPin* pOutAudio = CPinController::getInputPin( audioOutputPreview );
hr = pBuilderOutput->Connect( pInAudio, pOutAudio );
ATLASSERT( SUCCEEDED( hr ) );
}
// Run left
hr = pMediaControlInput->Run();
ATLASSERT( SUCCEEDED( hr ) );
// Run right
hr = pMediaControlOutput->Run();
ATLASSERT( SUCCEEDED( hr ) );
hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );
ATLASSERT( SUCCEEDED( hr ) );
It's really ridiculous but about a few minutes ago after a day of searching we have found the answer. All deal was about really huge hole in GmfBridge. I was giving wrong interfaces here (there are graphs instead of bridge's sink and source filters) 'coz function needed pointers to IUnknown:
hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );
And in GmfBridge library this situation wasn't handled properly - there is no "else" brunch to handle error and function returns hr which was set in begin to S_OK:
HRESULT STDMETHODCALLTYPE BridgeGraphs(
/* [in] */ IUnknown *pSourceGraphSinkFilter,
/* [in] */ IUnknown *pRenderGraphSourceFilter)
{
HRESULT hr = S_OK;
...
// if we are not given both filters, then
// we need do nothing
IBridgeSinkPtr pSink = pSourceGraphSinkFilter;
IBridgeSourcePtr pSource = pRenderGraphSourceFilter;
if ((pSink != NULL) && (pSource != NULL))
{
...
}
return hr;
}
So as you can see it just says there is nothing wrong and then it just do nothing! I think it's good idea to notify authors of the lib about this bug.
Hope this info will help someone.