Semaphore for Multiple Users - c++

What I want to achieve:
I would like to count the instances of my application to a fixed number.
if more instances of the application are started, it should only work as a "Viewer"
Her is the code of the sample application
boost named_semaphore example
The problem:
it works fine if all processe are started from only one user
But I get a Security exception if I start the application with another user!!
(Access not allowed)
Somebody can point me in the right direction, the boost documentation is a little bit lacking on this topic ;-)
What permissions must be set to allow access from every other logged on user?

I found the solution
Looks like the docu for Boost isn't that bad :-/
http://www.boost.org/doc/libs/1_47_0/doc/html/boost/interprocess/permissions.html
Just have to pass the permission and set it to "unrestricted"
boost::interprocess::permissions permtest;
permtest.set_unrestricted();
_getch();
boost::interprocess::named_semaphore
the_semphore(boost::interprocess::open_or_create,"test_semaphore",3,permtest);

Unfortunately boost uses default security attributes for semaphore and there is no way to change it. Use ATL::CSemaphore or CSemaphore from MFC or even CreateSemaphore from WinApi and construct security descriptor which allows access for everyone.

I'm not exactly a Windows expert, so I can't tell you the answer by heart, but you need to know how named_semaphores are implemented (see "Some basic explanations" documentation of boost.interprocess) and then look up the permission policy for this resource to grant system-wide access. So, read the boost.named_semaphore code, and if they use a file, update that file's permissions, and if they use a system call, read the Windows API documentation for that system call.

Related

Writing to the Windows Security Log with C++

I have been tasked with writing entries to the Windows security log. The entire project is Win32 C++ code. I have already written (with help from various online resources) a logging class that handles registration, deregistration, and code for executing the ReportEvent() call. Also, I've done the mc.exe and rc.exe steps for my event logging, if that helps establish where I'm at in the project.
My question is a multi-parter:
I've noticed at Filling Windows XP Security Event Log that there are some who believe this is not allowed by Windows. Others ( How to write log to SECURITY event Log in C#? ) imply otherwise. Possible or not?
If it is possible, how to get it to write to the security log. Is it as simple as specifying "Security" as my source name when calling RegisterEventSource()?
As far as deregistration, when should that occur? When the app is uninstalled? When the app closes? When the log entry is written?
How do I look up my log entries? I look in the Windows Event Viewer, but I don't see the entries I add with my test app, despite all the appropriate return values from the system calls. Where would I look up the events that I specified with a source name of "yarp" when I made my call to RegisterEventSource()?
For the moment, I'll just deal with the first question, because the answer to that probably renders the rest irrelevant.
Only Local Security Authority (lsass.exe) can write to the security log. This isn't a matter that something else attempting to get the privilege will fail -- it's a matter of there not being a way for anything else to even request the privilege at all (and this is by design).
From there, about the only answer to your other questions is "Sorry!"

Monitor registry using C++

I want to monitor when a key is changed/added/deleted to the registry whenever application is being installed or removed. I have tested the sample code from the msdn(link) and it works fine.
But the problem is that it does not tell me which key has actually been modified/added/deleted. How can i retrieve this information using c++?
There are only 3 ways, none of which is both easy and adequate:
RegNotifyChangeKeyValue:
Doesn't give you the info you need, but is very easy to use.
EVENT_TRACE_FLAG_REGISTRY which is part of Event Tracing for Windows
which is what ProcMon uses. It works well, but it's quite difficult to use.
I'm not sure exactly how to use it myself, but if I figure it out I'll post it here.
CmRegisterCallback:
Requires kernel-mode driver, which is a pain in 64-bit.
But it's the most perfect solution otherwise.
Unfortunately Event Tracing for Windows (EWT) does not allow to see full key path in the event. You get only a partial key name and a strange handle with is actually a key control block. It's not so simple to get information from this block.
Yes the process monitor uses EWT, but it does not use Windows Kernel Trace as a provider.

How to find out if hibernation is available for a Windows user (with C++)

I know that one can call the following API to hibernate the system:
SetSuspendState(TRUE, FALSE, FALSE);
But is there any way to find out if "real" hibernation is available for the current Windows user?
Here's what I mean:
If an admin calls:
powercfg.exe /hibernate off
the API above will put system into a Sleep mode. So how do you know (from a C++ program) that this will happen instead of hibernation?
I'm not sure if there's a group policy that can prohibit a user from hibernating a computer connected to an Active Directory?
Edit I am aware of the (dated) IsPwrHibernateAllowed API. I find that it doesn't work: it still returns the same result even if powercfg.exe /hibernate off was called. Am I doing something wrong there? Can someone explain why IsPwrHibernateAllowed doesn't work for me?
Take a look at SYSTEM_POWER_CAPABILITIES structure that can be obtained with CallNtPowerInformation. Specifically, look at HiberFilePresent field.

How do you use SECURITY_ATTRIBUTES with CreateProcess()?

Greetings!
When I try to use GetThreadContext() on a thread that I've started with CreateProcess(), I receive an error of 998: ERROR_NOACCESS
You can find a contrived but functional code example of this problem here: http://pastebin.com/tamDhYza
Based on the MSDN article regarding "Thread Security and Access Rights", my assumption is that I need to first pass the THREAD_GET_CONTEXT property into the lpThreadAttributes parameter of CreateProcess(). The type required by this argument is LPSECURITY_ATTRIBUTES, which appears to be a long pointer to the struct SECURITY_ATTRIBUTES. Unfortunately, I've not had much luck in figuring out how to add rights to this structure.
Could anyone help point me in the right direction?
I think you probably need to adjust the privileges of the calling code so that you can access the remote process. I suspect that you need to enable the SE_DEBUG_NAME privilege (see here) before you try and get the remote thread context. I'm not sure though as I usually use the debug API and call CreateProcess() with DEBUG_PROCESS which requires SE_DEBUG_NAME anyway...
If you do need to create a security descriptor then what you're doing is creating a DACL (discretionary access control list) which is a SECURITY_ATTRIBUTES structure that's populated with ACLs (access control lists) which allow or deny access to the resource by various principals (users, computers, etc). This used to be quite complex with lots of complicated API calls to make but now it's much easier, see http://msdn.microsoft.com/en-us/library/ms717798(VS.85).aspx for details.

Login to a remote machine & accessing network resources

I want to access a file on remote machine(win2k3, 10.10.20.30), but i couldn't understand how to login to that machine in my program. is there any simple win api that takes network path, credentials and returns the handle?
i just want to access \10.10.20.30\c$\test.txt,
WNetAddConnection2, WNetAddConnection3 are little confusing. Any suggestion will be helpful.
sorry for not being very clear. I want to access a computer on same network(LAN).
I wanted to access a file that is not shared on other computer.
If you have administrator rights, the solution is fairly simple. The C$ administrative share is available. You can call WNetAddConnection2 to create a local driveletter pointing to it. NETRESOURCE.dwType = RESOURCETYPE_DISK of course, .lpLocalName = NULL as you don't need it, .lpRemoteName = _T("\\\\10.10.20.30\\c$") (note the escaping of \ in C strings, it really starts with 4 of them). .lpProvider = NULL - let Windows figure the provider out.
Leave the username/password empty, and Windows will use your current user credentials. If those are indeed (network) administrator credentials, they're sufficient.
dwFlags should include CONNECT_TEMPORARY, as you're only interested in one file.
However, I think that (given sufficient credentials) it's easier to just call CreateFile("\\\\10.10.20.30\\c$\\test.txt") and let Windows deal with the details.
Normal c++ file access functions and libraries should work as is, just put the full network path to the file where you would put the file name, and you should be able to access. Good tutorials with sample code available at this link: http://www.cplusplus.com/doc/tutorial/files/
If you are getting errors, check that the user you are logged in as has file permissions set on the shared folder, as well as sharing permissions.
Execute mstsc.exe from your code using createprocess... Rest of thing it will handle...