-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
311 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/****************************** Module Header ******************************\ | ||
* Module Name: CppWindowsService.cpp | ||
* Project: CppWindowsService | ||
* Copyright (c) Microsoft Corporation. | ||
* | ||
* The file defines the entry point of the application. According to the | ||
* arguments in the command line, the function installs or uninstalls or | ||
* starts the service by calling into different routines. | ||
* | ||
* This source is subject to the Microsoft Public License. | ||
* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL. | ||
* All other rights reserved. | ||
* | ||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, | ||
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. | ||
\***************************************************************************/ | ||
|
||
#pragma region Includes | ||
#include <cstdio> | ||
#include <windows.h> | ||
#include "ServiceInstaller.h" | ||
#include "ServiceBase.h" | ||
#include "SampleService.h" | ||
#pragma endregion | ||
|
||
|
||
#include <filesystem> | ||
#include "../../devlog.h" | ||
#include "../../forte_stringFunctions.h" | ||
|
||
int _main(int argc, char *arg[]); | ||
|
||
|
||
// | ||
// Settings of the service | ||
// | ||
|
||
// Internal name of the service | ||
#define SERVICE_NAME (PWSTR)L"4diac-forte" | ||
|
||
// Displayed name of the service | ||
#define SERVICE_DISPLAY_NAME (PWSTR)L"4diac FORTE Runtime for Windows" | ||
|
||
// Service start options. | ||
#define SERVICE_START_TYPE SERVICE_DEMAND_START | ||
|
||
// List of service dependencies - "dep1\0dep2\0\0" | ||
#define SERVICE_DEPENDENCIES (PWSTR)L"" | ||
|
||
// The name of the account under which the service should run | ||
#define SERVICE_ACCOUNT (PWSTR)L"NT AUTHORITY\\LocalService" | ||
|
||
// The password to the service account name | ||
#define SERVICE_PASSWORD NULL | ||
|
||
|
||
// User can edit forte command line arguments in | ||
// HKLM\SYSTEM\CurrentControlSet\Services\4diac-forte\ImagePath | ||
static void convertArguments(int argc, wchar_t *argw[], std::vector<std::string> &args) | ||
{ | ||
for (int i = 0; i < argc; ++i) | ||
{ | ||
std::string str = forte_wstringToString(argw[i]); | ||
args.push_back(str); | ||
if (str.compare("-service") == 0 || str.compare("-s") == 0) | ||
{ | ||
if ((argc & 1) == 0) // forte always expect an argument pair | ||
{ | ||
// log redirection enabled by default | ||
args.push_back("log"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
// | ||
// FUNCTION: wmain(int, wchar_t *[]) | ||
// | ||
// PURPOSE: entrypoint for the application. | ||
// | ||
// PARAMETERS: | ||
// argc - number of command line arguments | ||
// argv - array of command line arguments | ||
// | ||
// RETURN VALUE: | ||
// none | ||
// | ||
// COMMENTS: | ||
// wmain() either performs the command line task, or run the service. | ||
// | ||
int wmain(int argc, wchar_t *argv[]) | ||
{ | ||
int ret = -1; | ||
|
||
// Convert command line arguments from wide to narrow string | ||
std::vector<std::string> l_argvBuff; | ||
convertArguments(argc, argv, l_argvBuff); | ||
|
||
// Reconstruct command line arguments fort FORTE process | ||
std::vector<const char*> l_argv; | ||
for (size_t i = 0; i < l_argvBuff.size(); ++i) | ||
{ | ||
// Pointer to string | ||
l_argv.push_back(l_argvBuff[i].data()); | ||
} | ||
|
||
if ((argc > 1) && ((*argv[1] == L'-' || (*argv[1] == L'/')))) | ||
{ | ||
if (_wcsicmp(L"install", argv[1] + 1) == 0) | ||
{ | ||
// Install the service when the command is | ||
// "-install" or "/install". | ||
InstallService( | ||
SERVICE_NAME, // Name of service | ||
SERVICE_DISPLAY_NAME, // Name to display | ||
SERVICE_START_TYPE, // Service start type | ||
SERVICE_DEPENDENCIES, // Dependencies | ||
SERVICE_ACCOUNT, // Service running account | ||
SERVICE_PASSWORD // Password of the account | ||
); | ||
} | ||
else if (_wcsicmp(L"remove", argv[1] + 1) == 0) | ||
{ | ||
// Uninstall the service when the command is | ||
// "-remove" or "/remove". | ||
UninstallService(SERVICE_NAME); | ||
} | ||
else if (_wcsicmp(L"service", argv[1] + 1) == 0 || _wcsicmp(L"s", argv[1] + 1) == 0) | ||
{ | ||
CSampleService service(SERVICE_DISPLAY_NAME, static_cast<int>(l_argv.size()), (char **)l_argv.data()); | ||
|
||
// Start setup stdout/stderr redirection | ||
wchar_t szPath[MAX_PATH]; | ||
if (GetModuleFileNameW(NULL, szPath, ARRAYSIZE(szPath)) == 0) { | ||
DEVLOG_ERROR("GetModuleFileNameW failed w/err 0x%08lx\n", GetLastError()); | ||
} | ||
|
||
std::filesystem::path fullpath(szPath); | ||
// Disable logging with "-service nolog" argument | ||
if (std::filesystem::exists(fullpath) && _wcsicmp(L"nolog", argv[2]) != 0) { | ||
auto path = fullpath.replace_extension("log"); | ||
std::string logfile = forte_wstringToString(path); | ||
service.StartLogRedirection(logfile.c_str(), stdout); | ||
path = fullpath.replace_extension("err"); | ||
logfile = forte_wstringToString(path); | ||
service.StartLogRedirection(logfile.c_str(), stderr); | ||
} | ||
|
||
if (!CServiceBase::Run(service)) | ||
{ | ||
DEVLOG_ERROR("Service failed to run w/err 0x%08lx\n", GetLastError()); | ||
} | ||
|
||
// Stop stdout/stderr redirection in reverse order | ||
service.StopLogRedirection(stderr); | ||
service.StopLogRedirection(stdout); | ||
} | ||
else | ||
{ | ||
ret = _main(static_cast<int>(l_argv.size()), (char **)l_argv.data()); | ||
} | ||
} | ||
else | ||
{ | ||
ret = _main(static_cast<int>(l_argv.size()), (char **)l_argv.data()); | ||
} | ||
|
||
// Clear the char vector and then the string vector | ||
l_argv.clear(); | ||
l_argvBuff.clear(); | ||
|
||
return ret; | ||
} |
Oops, something went wrong.