I have a network critical Windows 7 service. It must start before any network related service on the system, or that network service may fail. My service requires that Winsock is fully initialized by the time it runs.
How can I coerce Windows to load my service at the appropriate time? i.e. Immediately after Winsock is available.
I used the LoadOrder utility by MS Sysinternals. Found out the group should be "NetworkProvider". Also, since the loader loads in lexicographical alphabetical order, I named my process prefixing "Z" so it will load last in the "NetworkProvider" LoadOrderGroup.
You can make your service depend on other services using the depends option. To make other services dependent on your service, you'd need to set their dependencies.
Related
I've got the following totally reproducible scenario, which I'm unable to understand:
There is a very simple application, which does nothing else than calling CreateObject("Word.Application"), that is creating an instance of MS Word for COM interop. This application is located on a Windows Terminal Server. The test case is to connect via RDP, execute the application and the application will output the time taken for the CreateObject call.
The problem now is that the execution time is significantly longer, if I connect from a specific notebook (HP Spectre): It takes 1,7s (+/- 0.1s).
If I connect from any other machine (notebook or desktop computer), then the execution time is between 0,2-0,4s.
The execution times don't depend on the used RDP account, or screen resolution, or local printers. I even did a fresh install of Windows on that HP notebook to rule out any other side-effects. It doesn't matter if the HP notebook is connected via WLAN or an USB network card. I'm at a loss understanding the 4x to 8x execution time difference to any other machine.
Which reason (component/setting) could explain this big difference in execution time?
Some additional information: I tried debugging the process using an API monitor and could see that >90% of the execution time is actually being spent between a call to RpcSend and RpcReceive. Unfortunately I can't make sense of this information.
It could be the credential management somehow being in the way.
Open the .rdp file with notepad and add
enablecredsspsupport:i:0
This setting determines whether RDP will use the Credential Security Support Provider (CredSSP) for authentication if it is available
Related documentation
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff393716%28v%3dws.10%29
According to your information about RpcSend and RpcReceive time consumption, it could be the case you have some service stopped on your client machine, like DCOM server or some other COM-related (they usually have "COM" or "transaction" in their names).
Some of that services could be started/stopped (if Manually mode selected) by system to/after transfer your request, but there is a time delay to starting service.
I suggest you to open Computer Management - Services or run -> services.msc and compare COM-related services running on your "slow" client and on your "fast" clients, and try to set Automatically running instead Manually or Disabled.
Also, try to run API Monitor on such processes to determine the time-consuming place more precisely.
I have some .NET code in a COM+/Enterprise Services serviced component. I communicate with this component from a WPF application and also from a legacy VBA application.
This arrangement works well when only one user is logged on to a machine. The component starts in its own process when either the .NET or the legacy application instantiates one of its COM objects.
The system also works for the first user to try to run it on a terminal server installation. However, when another user logs on, he/she is unable to use the application. I had hoped that each session would run in isolation, and that one host process would run per session. Am I wrong in this expectation?
In Component Services on the Activation tab my application is configured to run as a "Server application". On the Identity tab, "Interactive user" is selected. On the Security tab, "Enforce access checks for this application" is unchecked.
There isn't session isolation as you describe, instead process ownership limits what you have access to.
Your conclusion seems correct & you will need to determine a suitable mechanism to exchange data with the service.
I used WCF to create a service with a net named pipe listener https://learn.microsoft.com/en-us/dotnet/framework/wcf/index
The idea of using proxies to make rpc calls is attractive, but I found the proxy definitions and stubs to link it all together quite clumsy to use.
If you have events that may be triggered at either end then keeping client/service in sync becomes problematic.
AIUI you cannot invoke a rpc method that ends up invoking an rpc back at the originating end, although that could be a named pipe limitation.
If I was doing this again I would use a socket server in the service & the websocket protocol for biderectional data transfer, even though you might need to implement some thread handling to avoid the listener thread blocking whilst servicing requests.
Hard to find anything authoritative on this. For standard COM you can set the identity to 'Launching user'. The same is not available for COM+.
According to this archived post,
A COM+ application can be configured to run under the logged in account, or
a specified account. Under the application properties, see the Identity tab.
...
Once set however, it remains under that account until the application shuts
down, so you can't have multiple users using the same COM+ application under
different IDs.
That seems to match what is said in this knowledge base article too.
My conclusion is, I should probably accept that my component must run once per machine rather than once per session. It will need to be modified to accommodate this. Since it needs to start new processes in individual sessions, it will have to run as a Windows service under the Local System account (giving due attention to the security implications).
I have a COM server LocalServer32 EXE started when a client application calls c_com_ptr::CreateInstance (using ATL wrappers.)
On Windows 7, when a second client application running under the same user account also calls c_com_ptr::CreateInstance, a second copy of the EXE is launched running under the same user account. I was under the impression, from a past life, that the second client would share the first EXE.
Is the LocalServer32 process shared, or not? When, or when not? Googling for an answer gives me a huge noise to signal ratio and I can't find the answer.
My CLSID registry key has the LocalServer32 value giving the EXE path, ProgID, Programmable (empty string), TypeLib (GUID), and a VersionIndependentProgId. I have an AppID key.
I do not want to run the EXE as a service, and I don't mind that the process is not shared. I just want to know the rules so I know what to expect (on Windows Server 2003 onwards.)
EDIT: Following Chris' answer below, I examined the CoRegisterClassObject call in my server. I'm using ATL, and I overrode MyServer::RegisterClassObjects to hook into the calling chain to CAtlExeModuleT::RegisterClassObjects and see that ATL is using CLSCTX_LOCAL_SERVER and REGCLS_MULTIPLEUSE.
Changing this to CLSCTX_LOCAL_SERVER and REGCLS_SINGLEUSE causes more processes to be started, depending on the number of COM objects created by the client, as expected.
Still, going back to REGCLS_MULTIPLEUSE, I get one COM server process per COM client process, each server process containing all of the COM objects for its client, as expected, except that if two COM clients are running under the same user account, they each get their own server which is not how I understood REGCLS_MULTIPLEUSE.
Could the difference be that the clients themselves are actually Windows services? (They are.) When a Windows service process running as a user account creates a COM object under REGCLS_MULTIPLEUSE, is this treated differently, causing the observed behavior? Why am I getting more than one process? (And just to clarify, I do not want my COM server to run as a Windows service, but the clients that use it do run as Windows services.)
Also, running the clients as either Local System, or Network Service, REGCLS_MULTIPLEUSE works as I would have expected: only a single COM server EXE process is started. The multiple processes are started when the COM clients are Windows services running under user accounts.
The routing of out-of-process activation requests is controlled by the registration of class objects with the COM Service Control Manager. If the SCM has a usable registered class object, that will be used to service the request. If it doesn't, it will start an exe process instance of the COM server to get one. Whether multiple activation requests are routed to a single COM server exe process therefore depends on the following factors at least (I'm not sure if this is a complete list):
the activation flags specified by the COM server when it calls CoRegisterClassObject to register with the SCM can cause future activation requests to result in a new exe process instance being started, the simplest and commonest case being the use of the flag REGCLS_SINGLEUSE, which allows the registered class object to be used for a single activation only.
Depending on how the class is registered, activation requests from different security contexts may be serviced by different COM server exe instances (it seems this won't apply in your scenario as your client applications run under the same security contexts).
I always set my drivers Imagepath directly.(C:\Windows\System32\drivers\abc.sys)
But I just knew many device drivers set their ImagePath to %SystemRoot%\system32\svchost.exe -k netsvcs
This is Lanmanworkstation driver's registry hive.
I guess Lanmanworkstation driver's image file is mrxsmb.sys
But they didn't put 'System32\drivers\mrxsmb.sys'. Why.
What does svchost.exe -k netsvcs mean?
Even though there is no certain path, StartService function works well.
How does Service Manager(? i'm not sure) find the driver's image path?
Is there an advantage using this?
What if I decide to use this way, are there my driver codes should modify?
You are confusing between device drivers and services.
svchost.exe is used to share the same process between multiple services. The implementation is internal to Windows so use outside of Windows is not supported.
If you write a device driver (for hardware, or a filter driver) or do not work for Microsoft, you cannot use svchost.
The reason for the confusion is because old style (NT4), non-plug-and-play drivers can be started using the Service Control Manager APIs.
svchost is a host process for other services, contained in DLLs. The part after the "-k" indicates the service group. You can find the service DLL path in HKLM\System\CurrentControlSet\Services\LanmanWorkstation\Parameters in the ServiceDll value. I'm guessing the reason it still starts correctly if you remove the image path is because the service type is set to SERVICE_WIN32_SHARE_PROCESS, and the SCM probably ignores the image path (not sure about this).
svchost.exe is a "multi-purpose" service. It incorporates multiple services in one single exe file, each of which can be seperately controlled using e.g. services management console. The parameters to svchost.exe states the "subservice" inside the exe file.
As startService() is not a control message to the service itself but instead only the request to start a certain executable (which itself must "know" that it is a service (and wich service) and will then register with service control manager), windows will simply execute the binary that ImagePath points to.
In this case (LanManWorkstation) this binary is svchost.exe, the parameter given to it is -k netsvc. This lets svchost.exe know which of the many service it provides should be started.
As usual, the binary doesn't need to contain all the function in itself but can also load additional libraries. mrxsmb.sys may well be such a library, though I'm not sure of this point.
So this answer is more of a "how does it work in general" than a "yes, netsvc and mrxsmb.sys are LanManWorkstation".
When a machine reboots, do all the services which are run under the accounts (system/service/network service) get run before a user logs on?
JD.
Services have a "start type" defined per-service, those types are boot, system, auto, demand, disabled. Services also have dependencies on each other, defined in the registry.
Services with boot and system start type are started during the time period when only NT Native binaries can run (the Win32 API is not yet ready). For example, these services include such as csrss.exe which provides some of the Win32 API.
Once Win32 has been initialized, the services with start type automatic are started. During this time, the service which allows the user to log in runs -- this displays the login prompt and does allow the user to log in.
In every case, if the service being start depends on other services, then the other services will be started in advance.
So, yes, it is possible for users to log in prior to the execution of a service. However, if the login service were to depend on your service... Better, though, if you detect that your service has started. Considering using a named global event with CreateEvent() api. Your service creates the event, your application awaits the event before calling the service. Also, your app can use the ServiceControl API to start the service only when in use.
The windows "Services.msc" management plug-in hides the boot and system services. To learn more about these startup types, refer to this API documentation: MSDN: ChangeServiceConfig Function .
Yes, using (by default) a built-in Windows account. In Services (run services.msc) there is a "Log On As" column that tells you the user that the service logs in as.
I do not think so. This should be asynchronous. If you are fast enough to log on, some of the services will still be coming up. This does not include "system" services