Disable prevent windows log event - c++

I'm using WMI (Windows Management Instrumentation) to try to collect some information from a allot of remote computers.
The issue is that every time I try to initiate a connection to a remote computer/resource using:
//IWbemLocator::ConnectServer method (wbemcli.h)
m_pLoc->ConnectServer ....
where
IWbemLocator *m_pLoc;
(You can assume m_pLoc is correctly initialized)
, if the remote resource is unavailable, Windows generates a log event in the Windows Event Viewer:
DCOM was unable to communicate with the computer ....using any of the
configured protocols; requested by PID .....
The problem is that given a huge number of remotes that at some point are not accessible the logs get flooded.
Is there any way to control or to prevent Windows from pushing a event in the Event Viewer every time I try to initiate a connection?
Seems that arguments for :
IWbemLocator::ConnectServer method (wbemcli.h)
or
CoCreateInstance used to intialize an IWbemLocator do not permit this sort of very custom configuration I'm looking for.
Any suggestion or alternatives?
Thank you!

Looking at the message logged in EventViewer more closely, I can see that this is a DCOM thing, and it looks like you can turn DCOM error logging off by (as usual) tweaking the registry.
The key you want is:
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Ole
And then create a DWORD value in there called ActivationFailureLoggingLevel and set it to 2.
Info gleaned from here. I haven't tested this myself but it looks like it should work.

Related

Is it possible to get a event in C++ program if Windows firewall status changes

I need to write a C++ application that should read firewall status of Windows, and then need to keep an eye continuously if admin/someuser
changes the firewall status (lets say when my program was started firewall was disabled and after sometime Admin enabled it).
To implement this, I have created a thread that periodically(10 seconds) poll the code that checks Windows firewall status, but this doesn't look an efficient solution to me as continuous polling is required.
Is there a way to get event automatically in my program if firewall status changes (for example, FindFirstChangeNotification, using this I can get notification if any change in directory)? This will avoid continuous polling and will make program more efficient I think.
Any help is appreciated.
I know there is Windows ETW which anti-viruses use and which has all the info you need. It is a big system log where you subscribe to log/event providers. Pretty much everything that happens in system gets reported there via event which you can listen/wait for. I don't know the links to more useful pages with a list of loggers connected to ETW so here is the more general page: https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-. You need to find out how to use C++ ETW API and the name/ID of the firewall events provider with a list of event types, then using API subscribe to this provider and setup a callback for when an event that interests you (here change of firewall status) occurs and that is it.

How to get a C++ Windows service to be properly notified when user log on/off or PC enters sleep/hibernation

I have a C++ Windows service which starts a TCP server when booted.
The problem is that when the user logs on/off the service no longer responses to client requests, also when returns from hibernation. So I need to get notified about the power modes so that I suspend/resume the server the proper way.
I tried ServiceBase.OnPowerEvent() but visual studio says it is undefined. is this method available only for C#? is there a counterpart in C++?
It is worth mentioned that the service template I used have downloaded it from an online tutorial, not the default template that comes with VS.
ServiceBase.OnPowerEvent is for .Net services based on ServiceBase. It is a wrapper of SERVICE_CONTROL_POWEREVENT.Services are also notified of log on and log off events via SERVICE_CONTROL_SESSIONCHANGE.
For a list of notification code, check HandlerEx callback function

DCOM interoperability between Windows XP and Windows 7

I am facing a rather strange and very specific DCOM related problem and I am hoping someone might have encountered it and solved it.
I am trying to instantiate a COM object in an EXE server on a Windows 7 machine (call it W7). The client resides on a Windows XP machine (call it WXP). On WXP the logged-in user is a domain user. On W7 the user is a local user. I have (afaik) correctly set all the DCOM rights, authentication and account privileges. There is no firewall involved.
All I get is that the COM EXE server process is started on W7, with the username I expect, but does not seem to even reach its WinMain function and remains hanging and never dies unless I kill it. I can attach a remote debugger (Visual Studio 2010) to it which will warn me that the process might be deadlocked, and when I break it, it stops in a message queue loop (GetMessage/Dispatch).
The client gets a (seemingly valid) pointer but any attempt to use it, results in E_ACCESSDENIED.
If anything from the scenario above is changed, the instantiation of the COM object succeeds and the object behaves correctly.
I know the chance is slight to find an answer but any tip is extremely welcome.
Thanks.
DCOM client and server either needs to be both the same local administrator on workgroup, or domain users on the same domain.
You can use this test app to check if your two machines are configured correctly:
http://support.microsoft.com/kb/259011
This way you make sure that your machine's permission and firewall are setup properly first without your own code.
Answering my own question...
It turns out that in the client CoInitializeSecurity didn't have all credentials it needed after all... It was called too early, before the credentials were known.
I discovered this after using CoSetProxyBlanket (as described here: How does impersonation in DCOM work?) on each component I was instantiating. Every component on which I called CoSetProxyBlanket was correctly working. This triggered me to go and double check the CoInitializeSecurity.
It remains strange that the reverse connection (from W7 to WXP) worked, but this is another research I need to do. The current question can be closed.

QueryInterface fails with E_ACCESSDENIED

The following method is a DCOM server method. The COM client and server is running in different WinXP machines. The COM client calls RegisterClient method to register callback interface. The problem is QueryInterface method fails with error code E_ACCESSDENIED. What could be the reason for the issue?
STDMETHODIMP CGEMExtension::RegisterClient(IUnknown** ppGEMExtensionEvents, int* nClientId, int* nResult)
{
HRESULT hRes = (*ppGEMExtensionEvents)->QueryInterface(IID_IGEMExtension,(void**)&pUnknown);
return hRes;
}
When you get an E_ACCESSDENIED, it means you have a permissions problem (don't waist your time on firewalls or registrations - the former will raise errors telling you the service is not available, and the latter will tell you the class is not registered or so). COM relies on Windows permissions, so this is what you should focus on.
In your case, if I understand the case correctly, the server actually calls the client, in order to get the right interface. For that, the user running the server should have the right permissions on the client side. A few suggestions:
As daramarak suggests, have the server and the client use the same domain user, or the same local user with the same password.
On the client, set this setting to "classic".
Give the server's user, if known to the client, additional permissions using DCOMCNFG.
This might be because the correct permissions is wrong on the other computer. Simplest way to check this is to turn on logging with secpol (Local Policies, Audit policy, turn on logging of logon events and object access) then you can see if you are trying to access the other machine.
If you are just testing then I would suggest to use the setting "run as interactive user" on the com object in component services and make sure that you have the same user with the same password on both machines. Then you must be running as the common user on the client machine. Spesifically setting the user to the common user is also possible.
As a general advice to debugging DCOM connectivity: Turn off all firewalls and such to make sure that the connection is working, then turn on security measures one by one, making sure that you leave the correct ports open and that the correct users have the correct permissions.
I give you my experience even if it may not apply directly to your specific case.
On Windows 7 at 64bit I have an exe compiled with x64 and a dll compiled at 32 bit.
A COM object lives inside the dll.
The exe (launched by the "normal" user) creates the COM object (on the same computer) asking for IUnknown and the creation is successful. Then the exe asks for a different interface through QueryInterface and it fails with E_ACCESSDENIED.
If I launch the exe "as administrator" then the QueryInterface will return with S_OK.
I did not investigate further, I suspect there is some policy about the 32 bit - 64 bit interaction.

Can you use WMI to create an MSMQ message queue (PRIVATE queue)?

I need to create a PRIVATE message queue on a remote machine and I have resolved to fact that I can't do this with the .NET Framework in a straight forward manner. I can create a public message queue on a remote machine, but not a PRIVATE one. I can create a message queue (public or private) locally.
I am wondering if anyone knows how to access MSMQ through WMI.
Edit: I don't see anything to do it with using the MSMQ Provider. May have to get tricky and use PSExec to log onto a remote server and execute some code.
Yes, queue creation is simple in .NET, however you cannot create a private queue on a remote machine this way.
I have been thinking about adding queue creation to the MSMQ WMI provider for some time... If you need it for a real product / customer, you can contact me and I will consider giving this feature a priority.
All the best,
Yoel Arnon
A blog post about MSMQ and WMI is here: http://msmq.spaces.live.com/blog/cns!393534E869CE55B7!210.entry
It says there is a provider here: http://www.msmq.biz/Blog/MSMQWmiSetup.msi
It also says there is a reference here: http://www.msmq.biz/Blog/MSMQ%20WMI%20Provider%20Objects.doc
Hope this helps.
WMI can't do this out-of-box. The previous answer has some obsucre WMI provider, but it doesn't even seem to support Queue creation.
This is very simple in .NET however! I wouldn't go so far as PSExec.
MessageQueue.Create
I was wanting to create remote private queues also, but since .NET doesn't support it, we decided we will just use remote public queues instead. If we set Send and Receive permissions on the queues as desired, this should be fine.
One idea for a work around would be to write your own Windows service or web service that runs on the same machine where the queue needs to reside. You could call this service remotely through a socket or over http, and your locally-running code could create the local private queue.
If you use the direct name format to reference the queue, you can Send and Receive from a remote private queue.
set qinfo = CreateObject("MSMQ.MSMQQueueInfo")
qinfo.PathName = ".\Private$\TestQueue"
qinfo.Label = ".\Private$\TestQueue"
qinfo.Journal = "1"
qinfo.Create
Copy the code in a text editor, save the file as .vbs and execute.