// svc_main() is ServiceMain() as in MSDN document.
It calls RegisterServiceCtrlHandlerExW() immediately after setting
SERVICE_WIN32_OWN_PROCESS and Win32ExitCode = NO_ERROR. W means Unicode variant.
Then it calls svc_init(). That does not seem like an system API.
h_svc_events = CreateEvent(NULL, TRUE, FALSE, NULL)
if h_svc_events is NULL -> set_svc_status(stopped, no_error, 0)
Use RegisterWaitForSingleObject to check if cleaned up? Not sure.
If OK, set_svc_status(running, no_error, 0)
set_svc_status() handles
SetServiceStatus// TODO-Doc
CreateThread with start_gdipp_rpc_server, and if can't create, stop the service.
CreateThread// TODO-Doc
start_gdipp_rpc_server() is in rpc_server.cpp
check if heap is ok (process_heap = GetProcessHeap())
scoped_rw_lock::init() // is in ./lib/scoped_rw_lock.cpp. TODO-Code
set server_cache_size
glyph_cache_instance.initialize()
initialize_freetype()
multiple rpc_status initializations // TODO-Doc
RpcServerUseProtseqEp()RpcServerRegisterIf()RpcServerListen()RpcMgmtWaitServerListen()// if any of these fails, stop starting rpc server
return 0 back to svc_init()
If all clear, call WTSGetActiveConsoleSessionId() (probably a WTL function) for active_session_id.
If active_session_id clear, start_hook(active_session_id).
// Set the event handle inheritable.
SECURITY_ATTRIBUTES inheritable_sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}
Check WTSQueryUserToken(session_id, &h_user_token).
if not, hook failure,
goto post_hook
// Use linked token if exist, which facilitates UAC and Run As Admin.
GetTokenInformation(h_user_token, TokenLinkedToken, &linked_token, sizeof(TOKEN_LINKED_TOKEN), &token_info_len)
if yes,
CloseHandle(h_user_token)h_user_token=linked_token.LinkedToken
Record service process id using GetCurrentProcessId().
Check config_instance.get_number(L"/gdipp/hook/include/proc_32_bit/text()", static_cast<int>(gdipp::hook_config::PROC_32_BIT))
if yes, set
gdipp_hook_nameto L"gdipp_hook_32.exe" check (hook_proc(h_user_token, hook_env_str, gdipp_hook_name_32, pi))if yes, pi_hooks_32[session_id] = pi else, hook failure
Run a 64-bit version of above check.
get_dir_file_path(NULL, gdipp_hook_name, gdipp_hook_path) // is in ./lib/helper.cpp, appends hook_name after the module's dir
return CreateProcessAsUserW(h_user_token, gdipp_hook_path, NULL, NULL, NULL, TRUE, NULL, hook_env_str, NULL, &si, &pi)
post_hook:
if hook success, set h_user_tokens[session_id] = h_user_token
else, if have h_user_token, CloseHandle(h_user_token)
Return whether we have token.
[start_gdipp_rpc_server]:
- WTL Windows Template Library
- RPC Remote Procedure Call
- SCM Service Controller Manager