I have a very basic question about windows services, I have this main
function which install I can use it to install my service, And also there are some configuration data that are loaded inside main function:
int
wmain(int argc, WCHAR* argv[])
{
// it reads config and fill a global struct.
ReadConfig();
// if command == 'install'
install_service();
}
and here is the service main function:
void WINAPI ServiceMain(DWORD argc, WCHAR* argv[])
{
// this method retrieves the global config object.
auto config_data = GetConfigData();
// service stuff
}
and here is another function which is called in my wmain
function if it is run without any arguments (argc = 0 !):
bool
ServiceRunAsService()
{
static const SERVICE_TABLE_ENTRY table[] = {
{ SERVICE_NAME, ServiceMain },
{ NULL, NULL }
};
g_hStopService = CreateEvent(0, TRUE, FALSE, 0);
return StartServiceCtrlDispatcher(table) && GetLastError() != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
}
My question is that when windows wants to run my service(after the PC has been shut down and turn on again), Does it call my wmain
function (and hence call the ReadConfig
function) or call the registered ServiceMain
function?
I want to point that the install_service
method, finds the path of executable by GetModuleFileName
and pass that to CreateService
and ScmManager
when executable is started, no matter for what reason, the exe entry point is called (if process not crashed or hooked before). so in your case always wmainCRTStartup
(or what is name of your exe real entry point) which call your wmain
. so yes - your wamin
will be called every time when your executable file start.
and system simply can not just call ServiceMain
anyway. it simply don't know it address. and it not registered. when you register exe service you register the command line for your service, but not any exported name inside exe. your executable became service and register ServiceMain
only after StartServiceCtrlDispatcher
, which must be called from your wmain
even in case dll form service which work with svchost.exe
- you register exported function which must be called from your dll as service entry point, or ServiceMain
by default. but anyway even in this case first your DllMain
(dll entry point) will be called (if exist). in case exe - entry point is mandatory and always will be called