My service can't set WinXP sound mixer props on remote computer when launched from a remote login session - windows

The title didn't scare you off. Great!
This is what I'm trying to do:
I have a service that at some point in time plays a very important sound. Because it is so important, I make sure that the mixer is ummuted and that the volume is at a proper level at startup.
This works fine when I start the service logged on locally to the computer where it's executing.
However, when I start the service from a remote desktop session it fails to get the volume control if I select "Play on this computer" when logging on.
The obvious solution is "Select 'Play on remote computer' when logging on" but for various usability reasons this is not feasible.
So; the M$ question is: "how can a service launched from remote desktop session set the local mixer main volume if 'Play on this computer' was selected at log on?"
The service runs on WinXP and I use the horrible Mixer* API from C++.
Thanks,
Rickard

The problem is that as an OS service, you can't control the volume for a TS user unless you have code running in the TS user's session. In order to remote audio from the server to the client, the TS service virtualizes all the audio APIs. Those virtualized controls aren't accessible from Windows services.
In order to solve your program, you'll need come code running in the user's session. I might suggest a scheduled task which is triggered on user logon. The task scheduler APIs allow you to create a task which causes a COM object to be created upon user logon. From that COM object, you can communicate with your service and then perform the mute operation on behalf of the user.

Related

SendInput or similar from windows service (session 0) in Windows 8 to login screen

As I understand, when we start windows it starts Session 0 which does not connect to any GUI, etc. and runs all windows services. So my task is, after windows was started, emulate windows input for selecting user and login to is session. I know that for sending input from service I should run desktop app and through it send input, show GUI, so on, but how can I do it before any user session was start? (for example I see that TeamViewer can do it)
WTSGetActiveConsoleSessionId() will tell you which session is attached to the physical console.
You can then duplicate your security token with DuplicateTokenEx(), change the new token's session with SetTokenInformation() and the TokenSessionId option, and launch a process with CreateProcessAsUser().
The new process should then be running in the right session, but it may also need to attach itself to the right desktop before it can interact with the logon interface. You can use EnumDesktops() to list the available desktops, and trial and error to determine which one the logon interface runs in. (Note that this may be different in different versions of Windows.)

WNetGetConnection and run as admin

I need to call WNetGetConnection to get the UNC path and it works good when application run as standard user but it returns 1201(ERROR_CONNECTION_UNAVAIL) error code when application run as admin. According to the documentation its working as expected.
If the network connection was made using the Microsoft LAN Manager
network, and the calling application is running in a different logon
session than the application that made the connection, a call to the
WNetGetConnection function for the associated local device will fail.
The function fails with ERROR_NOT_CONNECTED or
ERROR_CONNECTION_UNAVAIL. This is because a connection made using
Microsoft LAN Manager is visible only to applications running in the
same logon session as the application that made the connection. (To
prevent the call to WNetGetConnection from failing it is not
sufficient for the application to be running in the user account that
created the connection.)
that means its not possible at all to get the UNC path from the app running as admin ? Is there some other way ?
This is by design. Network shares created by a non-elevated account are not visible under elevation, and vice versa.
See this question on Super User for discussion of the issue. There is apparently a registry setting that enables mapped drives to be shared between elevated and non-elevated accounts but I've never tried it myself.
Network connections cannot normally be shared across different Windows login sessions. This is regardless of admin account / elevation level. Each Windows login or impersonation session needs to create its own network connections.

remote login a windows user knowing it's name and password

Here's what I want to do:
a program that listens in the network for a message, and when that message is received, if the user is not logged in (for example the computer just powered on and windows displays the classic login screen), it automatically logs in a certain user accordingly to the message. the username and password are known and stored safely inside the computer in a configuration for the program i'm talking about.
What I had in mind was a windows service that starts with the computer and also listens to those messages, and if one is received, then it does it's job
but I have no idea of where to start
(basically i'm trying to login a user without having to type the password, which I said is stored and known - need something mostly like the fingerprint software windows 7 comes with, and the ones that you had to install in vista/xp so that fingerprint login would work (fingerprint was only an example) )
There's two methods to pursue depending upon which operating system you're looking to run under.
For Windows XP, Windows 2000, and Windows Server 2003 you need to create a GINA.DLL. This is a replacement DLL which must follow specific rules which handles the authentication process. In your case your replacement DLL would be known by the service which was listening for your start signal, and it would make a call into the DLL with the username and password as appropriate.
MSDN Magazine article on customizing GINA.DLL
MSDN entry on GINA
For Windows Vista/7 and above you'll need to look into the Credential Provider API.
MSDN Magazine article on Credential Provider API in Vista.
MSDN entry on Credential Provider API
You can use windows auto logon feature to do this.
Create a service which waits for the required data on a network socket. Make sure this service is started after the network service (Tcpip). Modify winlogon service properties (manually) so that it depends on your service. By depends, I mean that winlogon service is started after your service.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon to 1
Once you receive the data on your network socket, set the following registry keys:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword
Once the registry settings are in place, then the winlogon service can read those values and proceed with the login process.
For more details on setting the registry values refer: http://support.microsoft.com/kb/315231
I want clarify a little the suggestion of Vikram.exe.
Of cause the usage of AutoAdminLogon seems native for the problem, but saving of the password in registry as a clear text under HKLM\...\Winlogon\DefaultPassword is not good. Since Windows 2000 it is supported the usage of the secrets DefaultPassword which makes the same effect as the DefaultPassword registry value (see Protecting the Automatic Logon Password for the code example).
Another way to force user login or to do any other actions on the login screen is switching to the Winlogon desktop (full name WinSta0\Winlogon). You can use SwitchDesktop and SetProcessWindowStation to do this (see Window Stations and Desktops). If the service run under System account you will have all rights to do this. Depend on the configuration of your service it could be also needed to use SetTokenInformation with TokenSessionId to change the current session id. After the service process will run on the WinSta0\Winlogon desktop you can use functions like FindWindow and other GUI API to place any information in controls of the window (user name, password and so on) of other process. So you can implement more complex scenarios.
Firstly let me just say im not 100% sure how to fully complete such a application but I have a few tips.
you will need to create a Windows Service that starts during the Pre-Login, you can create a service in C#, An example of creating a C# Service is linked below:
http://msdn.microsoft.com/en-us/library/zt39148a(VS.80).aspx
Within your application you would set the property Startup Type to Automatic, This will automatically start your service on boot.
You should know that windows services run under a secure context by account so you will have to get your service to run with privs do do this.
In your Service Properties you can Click Log On and you can
To specify that the service uses the Local Service account, click This account, and then type the following NT AUTHORITY\LocalService.
To specify that the service uses the Network Service account, click This account, and then type the following NT AUTHORITY\NetworkService.
As your trying to do this remotly you will have to look at WMI (Windows Management Instrumentation) and you will be able to start/stop and send commands to your service.
Your service then would send a command to the Login Management (Not Sure of the name).
you may also wish to check this WOL class which will switch the computer on remotely as long as it supports Wake On LAN, If this is for a corporate environment then I advise you to check your network cards to make sure they are supported
http://www.codeproject.com/KB/IP/wolclass.aspx
I know of some education software that I use for schools that's called CC4 ( http://www.rm.com/shops/rmshop/story.aspx?cref=PS1026195 ) and we can do exactly what you need within this system, I'm not fully sure of how it works fully but i believe it takes the same principles described above.

How to automatically open a session after a Windows 2003 SP2 reboot?

i'm using a Windows 2003 Server.
I have a session with my username on it and i have a windows application (not service) opened on it. I want this application to always be running.
The problem is, when Security updates force Windows to reboot, my session is closed and i need to reconnect to the session to get my application working again ..
How can i do to automaticaly force the opening of my user's session upon server's reboot ? (application launch is in the startup of my session)
Thanks
If you want to have the program running consistently, I would highly recommend making it into a Windows service (see also this page). Then you can set the username that the service logs on with (this is particularly important if the app needs to access networked resources), and even set the stability values to have the service restart itself if the EXE crashes for some reason.
Otherwise, if you really want the computer to login as your user and run the program, you could set the autologon parameters to your username and password, and put the shortcut to your program in the user's Start Menu Startup folder. (But this does not provide you any of the stability benefits that a service would.)
Add a startup script, http://technet.microsoft.com/en-us/library/cc779329(WS.10).aspx

How can I get my Windows Service to display in the system tray?

I have a Windows Service that runs in the background when the PC starts. I want to display an Icon on the system tray to allow configuration after a user has logged in but can't find how to do this.
Is there an event I should be looking for which tells me that a user has logged in?
As I understand Windows Services can't have a UI so do I need to start an app to display the sys tray icon? How can I pass configuration updates to my service.
You will want a seperate "agent" application for this. A Windows service is global, running at the system level. There can be multiple desktops running on the system at once, so while there are ways of allowing services to interact with the desktop layer, it is far from trivial to interact with the "users desktop" in the same manner that you do with an application already bound to a specific login/desktop environment.
There are also security risks involved with having a service tunnel into the desktop environment (it opens up a pathway to a system account unless the service runs on a more restricted one), which is why interacting with the desktop is disabled by default.
You will need a separate application to show the tray icon. You can communicate with your service either through WCF letting the service host a WCF service or through ServiceController.
I would create a second application that runs and displays itself in the system tray when the user logs in.
You can open remoting to the windows service, and pass the configuration updates through exposed methods from the app in the system tray.
Actually, I don't think you CAN show a service in the system tray. Applications doing this are always using an agent or other mangement tool.
Most of the time the application running in the tray is a very small app giving access to the settings for the service.
Configuration options could be stored in the registry, ini file or anyother storage option. After the configuration changes, all you need to do is make sure you restart your service, so it can reload it's new settings.

Resources