1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00
Files
MeshAgent/meshservice/ServiceMain.c
2017-10-12 14:28:03 -07:00

1276 lines
41 KiB
C

/*
Copyright 2006 - 2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#endif
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winhttp.h>
#include <shlobj.h>
#include "resource.h"
#include "meshcore/signcheck.h"
#include "meshcore/meshdefines.h"
#include "meshcore/meshinfo.h"
#include "microstack/ILibParsers.h"
#include "microstack/ILibCrypto.h"
#include "meshcore/agentcore.h"
#ifndef _MINCORE
// #include "../kvm/kvm.h"
int SetupWindowsFirewall(wchar_t* processname);
int ClearWindowsFirewall(wchar_t* processname);
#endif
#if defined(WIN32) && defined (_DEBUG) && !defined(_MINCORE)
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
#endif
TCHAR* serviceFile = TEXT("Mesh Agent v2");
TCHAR* serviceName = TEXT("Mesh Agent v2 background service");
TCHAR* serviceDesc = TEXT("Remote monitoring and management service.");
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
INT_PTR CALLBACK DialogHandler(HWND, UINT, WPARAM, LPARAM);
MeshAgentHostContainer *agent = NULL;
/*
extern int g_TrustedHashSet;
extern char g_TrustedHash[32];
extern char NullNodeId[32];
extern struct PolicyInfoBlock* g_TrustedPolicy;
extern char g_selfid[UTIL_HASHSIZE];
extern struct sockaddr_in6 g_ServiceProxy;
extern char* g_ServiceProxyHost;
extern int g_ServiceConnectFlags;
*/
#if defined(_LINKVM)
extern DWORD WINAPI kvm_server_mainloop(LPVOID Param);
#endif
BOOL IsAdmin()
{
BOOL admin;
PSID AdministratorsGroup;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if ((admin = AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) != 0)
{
if (!CheckTokenMembership( NULL, AdministratorsGroup, &admin)) admin = FALSE;
FreeSid(AdministratorsGroup);
}
return admin;
}
void WINAPI ServiceControlHandler( DWORD controlCode )
{
switch (controlCode)
{
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus( serviceStatusHandle, &serviceStatus );
if (agent != NULL) { MeshAgent_Stop(agent); }
return;
default:
break;
}
SetServiceStatus( serviceStatusHandle, &serviceStatus );
}
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
CONTEXT winException;
size_t len = 0;
WCHAR str[_MAX_PATH];
char selfexe[_MAX_PATH];
char *selfexe_ptr[] = { selfexe };
UNREFERENCED_PARAMETER( argc );
UNREFERENCED_PARAMETER( argv );
// Initialise service status
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwControlsAccepted = 0;
serviceStatus.dwWin32ExitCode = NO_ERROR;
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
if (serviceStatusHandle)
{
// Service is starting
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
// Service running
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus( serviceStatusHandle, &serviceStatus);
// Get our own executable name
if (GetModuleFileNameW(NULL, str, _MAX_PATH) > 5)
{
wcstombs_s(&len, selfexe, _MAX_PATH, str, _MAX_PATH);
}
#ifndef _MINCORE
// Setup firewall
SetupWindowsFirewall(str);
#endif
// Run the mesh agent
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
__try
{
agent = MeshAgent_Create();
MeshAgent_Start(agent, 1, selfexe_ptr);
agent = NULL;
}
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException))
{
ILib_WindowsExceptionDebug(&winException);
}
CoUninitialize();
// Service was stopped
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
// Service is now stopped
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
}
int RunService()
{
SERVICE_TABLE_ENTRY serviceTable[2];
serviceTable[0].lpServiceName = serviceName;
serviceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
serviceTable[1].lpServiceName = NULL;
serviceTable[1].lpServiceProc = NULL;
return StartServiceCtrlDispatcher( serviceTable );
}
BOOL InstallService()
{
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
SERVICE_DESCRIPTION sd;
SERVICE_DELAYED_AUTO_START_INFO as;
SERVICE_FAILURE_ACTIONS fa;
SC_ACTION failactions[3];
BOOL r = FALSE;
if ( serviceControlManager )
{
char path[1024];
if (GetModuleFileName( 0, (LPTSTR)path, 1024) > 0)
{
// Install the service
SC_HANDLE service = CreateService(
serviceControlManager,
serviceFile,
serviceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_IGNORE,
(LPCTSTR)path,
0, 0, 0, 0, 0 );
if (service)
{
// Update the service description
sd.lpDescription = serviceDesc;
ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sd);
// Update the service auto-start
as.fDelayedAutostart = FALSE;
ChangeServiceConfig2(service, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &as);
// Update the faliure action
failactions[0].Type = SC_ACTION_RESTART;
failactions[0].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
failactions[1].Type = SC_ACTION_RESTART;
failactions[1].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
failactions[2].Type = SC_ACTION_NONE;
failactions[2].Delay = 120000;
memset(&fa, 0, sizeof(SERVICE_FAILURE_ACTIONS));
fa.dwResetPeriod = 86400; // After 1 days, reset the faliure counters (seconds)
fa.cActions = 3;
fa.lpsaActions = failactions;
r = ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &fa);
// Cleanup
CloseServiceHandle( service );
#ifdef _DEBUG
//ILIBMESSAGE("Mesh service installed successfully");
#endif
}
else
{
#ifdef _DEBUG
if(GetLastError() == ERROR_SERVICE_EXISTS)
{
ILIBMESSAGE("Mesh service already exists.");
}
else
{
ILIBMESSAGE2("Mesh service was not Installed Successfully. Error Code %d", (int)GetLastError());
}
#endif
}
}
CloseServiceHandle( serviceControlManager );
}
return r;
}
int UninstallService()
{
int r = 0;
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT);
if (serviceControlManager)
{
SC_HANDLE service = OpenService( serviceControlManager, serviceFile, SERVICE_QUERY_STATUS | DELETE );
if (service)
{
SERVICE_STATUS serviceStatusEx;
if ( QueryServiceStatus( service, &serviceStatusEx ) )
{
if ( serviceStatusEx.dwCurrentState == SERVICE_STOPPED )
{
if (DeleteService(service))
{
#ifdef _DEBUG
//ILIBMESSAGE("Mesh service removed successfully");
#endif
r = 1;
}
else
{
#ifdef _DEBUG
DWORD dwError = GetLastError();
if(dwError == ERROR_ACCESS_DENIED) {
ILIBMESSAGE("Access denied while trying to remove mesh service");
}
else if(dwError == ERROR_INVALID_HANDLE) {
ILIBMESSAGE("Handle invalid while trying to remove mesh service");
}
else if(dwError == ERROR_SERVICE_MARKED_FOR_DELETE) {
ILIBMESSAGE("Mesh service already marked for deletion");
}
#endif
}
}
else
{
r = 2;
#ifdef _DEBUG
ILIBMESSAGE("Mesh service is still running");
#endif
}
}
CloseServiceHandle( service );
}
CloseServiceHandle( serviceControlManager );
}
return r;
}
// SERVICE_STOPPED 1 The service is not running.
// SERVICE_START_PENDING 2 The service is starting.
// SERVICE_STOP_PENDING 3 The service is stopping.
// SERVICE_RUNNING 4 The service is running.
// SERVICE_CONTINUE_PENDING 5 The service continue is pending.
// SERVICE_PAUSE_PENDING 6 The service pause is pending.
// SERVICE_PAUSED 7 The service is paused.
// SERVICE_NOT_INSTALLED 100 The service is not installed.
int GetServiceState(LPCSTR servicename)
{
int r = 0;
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
if (serviceControlManager)
{
SC_HANDLE service = OpenService( serviceControlManager, servicename, SERVICE_QUERY_STATUS | DELETE );
if (service)
{
SERVICE_STATUS serviceStatusEx;
if ( QueryServiceStatus( service, &serviceStatusEx) )
{
r = serviceStatusEx.dwCurrentState;
}
CloseServiceHandle( service );
}
else
{
r = 100;
}
CloseServiceHandle( serviceControlManager );
}
return r;
}
int LaunchService(LPCSTR servicename)
{
int r = 0;
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SERVICE_QUERY_STATUS | SERVICE_START);
if (serviceControlManager)
{
SC_HANDLE service = OpenService( serviceControlManager, servicename, SERVICE_QUERY_STATUS | SERVICE_START );
if (service)
{
SERVICE_STATUS serviceStatusEx;
if ( QueryServiceStatus( service, &serviceStatusEx) )
{
if (serviceStatusEx.dwCurrentState == SERVICE_STOPPED ) { if (StartService(service, 0, NULL) == TRUE) { r = 1; } } else { r = 2; }
}
CloseServiceHandle( service );
}
CloseServiceHandle( serviceControlManager );
}
return r;
}
int StopService(LPCSTR servicename)
{
int r = 0;
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SERVICE_QUERY_STATUS | SERVICE_STOP);
if (serviceControlManager)
{
SC_HANDLE service = OpenService( serviceControlManager, servicename, SERVICE_QUERY_STATUS | SERVICE_STOP );
if (service)
{
SERVICE_STATUS serviceStatusEx;
if ( QueryServiceStatus( service, &serviceStatusEx) )
{
if (serviceStatusEx.dwCurrentState != SERVICE_STOPPED )
{
if (ControlService(service, SERVICE_CONTROL_STOP, &serviceStatusEx) == FALSE)
{
// TODO: Unable to stop service
#ifdef _DEBUG
ILIBMESSAGE("Unable to stop service");
#endif
}
else
{
Sleep(3000);
r = 1;
}
}
}
CloseServiceHandle( service );
}
CloseServiceHandle( serviceControlManager );
}
return r;
}
int RunProcess(char* exe)
{
BOOL r;
int count = 50;
DWORD exitcode;
STARTUPINFOA info = {sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcessA(NULL, exe, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &info, &processInfo) == 0) return 0;
do
{
Sleep(100);
r = GetExitCodeProcess(processInfo.hProcess, &exitcode);
if (exitcode == STILL_ACTIVE) r = 0;
}
while (r == 0 && count-- > 0);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return r;
}
/*
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
return _tmain( 0, NULL );
}
*/
#ifndef _MINCORE
void fullinstall(int uninstallonly, char* proxy, int proxylen, char* tag, int taglen)
{
int r = 0;
int loops = 0;
char targetexe2[_MAX_PATH + 40];
char *targetexe = targetexe2 + 1;
size_t targetexelen = 0;
char selfexe[_MAX_PATH];
size_t selfexelen = 0;
char setup1[_MAX_PATH];
char setup2[_MAX_PATH];
int setup1len;
int setup2len;
// Stop and remove the service
StopService(serviceFile);
UninstallService();
// Get our own executable
selfexelen = GetModuleFileNameA(NULL, selfexe, _MAX_PATH);
// Get the target executable
if (SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, targetexe) != S_FALSE)
{
targetexe2[0] = '\"';
targetexelen = strnlen_s(targetexe, _MAX_PATH + 40);
if (targetexelen <= MAX_PATH) memcpy_s(targetexe + targetexelen, _MAX_PATH + 40 - targetexelen, "\\Mesh Agent\\MeshAgent.exe\" -uninstall", 38);
targetexelen += 25;
}
// Call uninstall, this will remove the firewall rules.
RunProcess(targetexe2);
#ifdef _MINCORE
// Remove the MeshAgent registry keys
RegDeleteKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", KEY_WOW64_32KEY, 0);
RegDeleteKeyEx(HKEY_CURRENT_USER, "Software\\Open Source\\MeshAgent2", KEY_WOW64_32KEY, 0);
#else
// Remove the MeshAgent registry keys
RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2");
RegDeleteKey(HKEY_CURRENT_USER, "Software\\Open Source\\MeshAgent2");
#endif
// Check if selfexe is already located at the target, if so, skip to copy steps.
if (targetexelen != selfexelen || memcmp(selfexe, targetexe, targetexelen) != 0)
{
// Remove the target executable.
targetexe[targetexelen] = 0;
remove(targetexe);
// Remove "[Executable].msh" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "msh", 4);
setup2[setup2len] = 0;
remove(setup2);
// Remove "[Executable].proxy" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 257) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "proxy", 6);
setup2[setup2len + 2] = 0;
remove(setup2);
if (uninstallonly != 0) {
// Remove "[Executable].tag" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "tag", 4);
setup2[setup2len] = 0;
remove(setup2);
// Remove "[Executable].log" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "log", 4);
setup2[setup2len] = 0;
remove(setup2);
// Remove "[Executable].db" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 256) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "db", 3);
setup2[setup2len] = 0;
remove(setup2);
}
// Remove the folder.
targetexe[targetexelen - 14] = 0;
RemoveDirectoryA(targetexe);
if (uninstallonly != 0) return;
// Get the target executable, create folders if needed
if (!CreateDirectoryA(targetexe, NULL) && GetLastError() == ERROR_ACCESS_DENIED) { ILIBMESSAGE("Access denied (1)"); return; }
targetexe[targetexelen - 14] = '\\';
// Attempt to copy our own exe over the original exe
loops = 0;
while (!util_CopyFile(selfexe, targetexe, TRUE))
{
if (GetLastError() == ERROR_ACCESS_DENIED) { ILIBMESSAGE("Access denied (2)"); return; }
if (loops++ > 5) { ILIBMESSAGE("Error copying executable file"); return; }
Sleep(5000);
}
// Try to copy "[Executable].msh" file to target directory
if ((setup1len = (int)strnlen_s(selfexe, sizeof(selfexe))) < 4) return;
memcpy_s(setup1, sizeof(setup1), selfexe, setup1len);
memcpy_s(setup1 + (setup1len - 3), sizeof(setup1) - setup1len - 3, "msh", 4);
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "msh", 4);
util_CopyFile(setup1, setup2, TRUE);
// Write the tag if one was passed
if (tag != NULL)
{
FILE *SourceFile = NULL;
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "tag", 4);
if (taglen > 0) {
fopen_s(&SourceFile, setup2, "wb");
if (SourceFile != NULL)
{
if (fwrite(tag, sizeof(char), taglen, SourceFile)) {}
fclose(SourceFile);
}
}
else
{
remove(setup2);
}
}
// Setup proxy filenames
if ((setup1len = (int)strnlen_s(selfexe, sizeof(selfexe))) < 4) return;
memcpy_s(setup1, sizeof(setup1), selfexe, setup1len);
memcpy_s(setup1 + (setup1len - 3), sizeof(setup1) - setup1len - 3, "proxy", 6);
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "proxy", 6);
if (proxy != NULL && proxylen > 0)
{
// Use the specified proxy in the command line switch
FILE *SourceFile = NULL;
fopen_s(&SourceFile, setup2, "wb");
if (SourceFile != NULL)
{
if (fwrite(proxy, sizeof(char), proxylen, SourceFile)) {}
fclose(SourceFile);
}
}
else
{
// Try to copy "[Executable].proxy" file to target directory
if (util_CopyFile(setup1, setup2, TRUE) == FALSE)
{
// Failed to copy proxy file, lets try to create one.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyEx;
if (WinHttpGetIEProxyConfigForCurrentUser(&proxyEx))
{
if (proxyEx.lpszProxy != NULL)
{
FILE *SourceFile = NULL;
size_t len;
if (wcstombs_s(&len, ILibScratchPad, 4095, proxyEx.lpszProxy, 2000) == 0)
{
char* ptr = strstr(ILibScratchPad, "https=");
if (ptr != NULL) {
char* ptr2 = strstr(ptr, ";");
ptr += 6;
if (ptr2 != NULL) ptr2[0] = 0;
} else {
ptr = ILibScratchPad;
}
fopen_s(&SourceFile, setup2, "wb");
if (SourceFile != NULL)
{
if (fwrite(ptr, sizeof(char), strnlen_s(ptr, sizeof(ILibScratchPad)), SourceFile)) {}
fclose(SourceFile);
}
}
GlobalFree(proxyEx.lpszProxy);
}
// Release the rest of the proxy settings
if (proxyEx.lpszAutoConfigUrl != NULL) GlobalFree(proxyEx.lpszAutoConfigUrl);
if (proxyEx.lpszProxyBypass != NULL) GlobalFree(proxyEx.lpszProxyBypass);
}
}
}
}
/*
#if defined(_LINKVM)
// Setup the SendSAS permission
kvm_setupSasPermissions();
#endif
*/
// Attempt to start the updated service up again
memcpy(targetexe + targetexelen, "\" -install", 11);
r = RunProcess(targetexe2);
memcpy(targetexe + targetexelen, "\" -start", 9);
r = RunProcess(targetexe2);
}
#endif
ILibTransport_DoneState kvm_serviceWriteSink(char *buffer, int bufferLen, void *reserved)
{
DWORD len;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, bufferLen, &len, NULL);
return ILibTransport_DoneState_COMPLETE;
}
BOOL CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
{
if (agent != NULL) { MeshAgent_Stop(agent); }
return TRUE;
}
default:
return FALSE;
}
}
int main(int argc, char* argv[])
{
int i;
size_t str2len = 0;// , proxylen = 0, taglen = 0;
wchar_t str[_MAX_PATH];
char str2[_MAX_PATH];
char* proxyarg = NULL;
char* tagarg = NULL;
CONTEXT winException;
int retCode = 0;
/*
#ifndef NOMESHCMD
// Check if this is a Mesh command operation
if (argc >= 1 && strlen(argv[0]) >= 7 && strcasecmp(argv[0] + strlen(argv[0]) - 7, "meshcmd") == 0) return MeshCmd_ProcessCommand(argc, argv, 1);
if (argc >= 2 && strcasecmp(argv[1], "meshcmd") == 0) return MeshCmd_ProcessCommand(argc, argv, 2);
#endif
*/
//CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (argc > 2 && memcmp(argv[1], "-faddr", 6) == 0)
{
uint64_t addrOffset;
util_hexToBuf(argv[2] + 2, strnlen_s(argv[2], 130) - 2, (char*)&addrOffset);
ILibChain_DebugOffset(ILibScratchPad, sizeof(ILibScratchPad), addrOffset);
printf("%s", ILibScratchPad);
return(0);
}
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Process extra switches
for (i = 0; i < argc; i++)
{
str2len = strnlen_s(argv[i], _MAX_PATH - 1);
if (str2len > 7 && memcmp(argv[i], "-proxy:", 7) == 0) { proxyarg = argv[i] + 7; } // Set the HTTPS proxy
else if (str2len >= 5 && memcmp(argv[i], "-tag:", 5) == 0) { tagarg = argv[i] + 5; } // Set the TAG
}
/*
#ifdef _MINCORE
if (argc == 2 && ((strcasecmp(argv[1], "-?") == 0) || (strcasecmp(argv[1], "/?") == 0)))
{
printf("Mesh Agent v%d available switches:\r\n start Start the service.\r\n restart Restart the service.\r\n stop Stop the service.\r\n -signcheck Perform self-check.\r\n -install Install the service from this location.\r\n -uninstall Remove the service from this location.\r\n -nodeidhex Return the current agent identifier.\r\n -proxy:host:port Specifiy an HTTPS proxy (after -fullinstall only).\r\n -tag:xxx Specifiy a agent tag (after -fullinstall only).\r\n\r\n -resetnodeid Reset the NodeID next time the service is started.", MESH_AGENT_VERSION);
return 0;
}
#else
if (argc == 2 && ((strcasecmp(argv[1], "-?") == 0) || (strcasecmp(argv[1], "/?") == 0)))
{
//printf("Mesh Agent v%d available switches:\r\n start Start the service.\r\n restart Restart the service.\r\n stop Stop the service.\r\n -proxy:host:port Specifiy an HTTPS proxy.\r\n -leader Force the agent to always be a leader.\r\n -signcheck Perform self-check.\r\n -install Install the service from this location.\r\n -uninstall Remove the service from this location.\r\n -nodeidhex Return the current agent identifier.\r\n -fullinstall Copy agent into program files, install and launch.\r\n -fulluninstall Stop agent and clean up the program files location.\r\n -loadcert:c.pem Load a pem cert as node certificate.\r\n", MESH_AGENT_VERSION);
printf("Mesh Agent v%d available switches:\r\n start Start the service.\r\n restart Restart the service.\r\n stop Stop the service.\r\n -signcheck Perform self-check.\r\n -install Install the service from this location.\r\n -uninstall Remove the service from this location.\r\n -nodeidhex Return the current agent identifier.\r\n -fullinstall Copy agent into program files, install and launch.\r\n -fulluninstall Stop agent and clean up the program files location.\r\n -proxy:host:port Specifiy an HTTPS proxy (after -fullinstall only).\r\n -tag:xxx Specifiy a agent tag (after -fullinstall only).\r\n -resetnodeid Reset the NodeID next time the service is started.", MESH_AGENT_VERSION);
return 0;
}
#endif
*/
#if defined(_LINKVM)
if (argc > 1 && strcasecmp(argv[1], "-kvm0") == 0)
{
void **parm = (void**)ILibMemory_Allocate(3 * sizeof(void*), 0, 0, NULL);
parm[0] = kvm_serviceWriteSink;
((int*)&(parm[2]))[0] = 0;
kvm_server_mainloop((void*)parm);
return 0;
}
else if (argc > 1 && strcasecmp(argv[1], "-kvm1") == 0)
{
void **parm = (void**)ILibMemory_Allocate(3 * sizeof(void*), 0, 0, NULL);
parm[0] = kvm_serviceWriteSink;
((int*)&(parm[2]))[0] = 1;
kvm_server_mainloop((void*)parm);
return 0;
}
#endif
#ifdef _MINCORE
if (argc > 1 && strcasecmp(argv[1], "-signcheck") == 0)
{
// Check the signature of out own executable
util_openssl_init();
printf("%d", signcheck_verifysign(argv[0], 0));
util_openssl_uninit();
return 0;
}
#else
else if (argc > 1 && ((strcasecmp(argv[1], "run") == 0) || (strcasecmp(argv[1], "--slave") == 0)))
{
// Run the mesh agent in console mode, since the agent is compiled for windows service, the KVM will not work right. This is only good for testing.
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); // Set SIGNAL on windows to listen for Ctrl-C
__try
{
agent = MeshAgent_Create();
MeshAgent_Start(agent, argc, argv);
retCode = agent->exitCode;
MeshAgent_Destroy(agent);
}
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException))
{
ILib_WindowsExceptionDebug(&winException);
}
return(retCode);
}
else if (argc > 1 && (strcasecmp(argv[1], "state") == 0))
{
// SERVICE_STOPPED 1 The service is not running.
// SERVICE_START_PENDING 2 The service is starting.
// SERVICE_STOP_PENDING 3 The service is stopping.
// SERVICE_RUNNING 4 The service is running.
// SERVICE_CONTINUE_PENDING 5 The service continue is pending.
// SERVICE_PAUSE_PENDING 6 The service pause is pending.
// SERVICE_PAUSED 7 The service is paused.
// SERVICE_NOT_INSTALLED 100 The service is not installed.
int serviceState = GetServiceState(serviceFile);
if (serviceState == 1) { printf("Stopped"); }
else if (serviceState == 2) { printf("Start Pending"); }
else if (serviceState == 3) { printf("Stop Pending"); }
else if (serviceState == 4) { printf("Running"); }
else if (serviceState == 5) { printf("Continue Pending"); }
else if (serviceState == 6) { printf("Pause Pending"); }
else if (serviceState == 7) { printf("Paused"); }
else if (serviceState == 100) { printf("Not installed"); }
return serviceState;
}
else if (argc > 1 && strcasecmp(argv[1], "-signcheck") == 0 && GetModuleFileNameA(NULL, str2, _MAX_PATH) > 5)
{
// Check the signature of out own executable
util_openssl_init();
printf("%d", signcheck_verifysign(str2, 0));
util_openssl_uninit();
return 0;
}
#endif
else if (argc > 1 && (strcasecmp(argv[1], "start") == 0 || strcasecmp(argv[1], "-start") == 0))
{
// Ask the service manager to launch the service
int r = LaunchService(serviceFile);
if (r == 0) { printf("Failed to start mesh agent"); }
else if (r == 1) { printf("Started the mesh agent"); }
else if (r == 2) { printf("Mesh agent already running"); }
}
else if (argc > 1 && (strcasecmp(argv[1], "stop") == 0 || strcasecmp(argv[1], "-stop") == 0))
{
// Ask the service manager to stop the service
if (StopService(serviceFile) == 1) { printf("Stopped mesh agent"); } else { printf("Failed to stop mesh agent"); }
}
else if (argc > 1 && (strcasecmp(argv[1], "restart") == 0 || strcasecmp(argv[1], "-restart") == 0))
{
// Ask the service manager to stop and start the service
StopService(serviceFile);
{
int r = LaunchService(serviceFile);
if (r == 0) { printf("Failed to restart mesh agent"); }
else if (r == 1) { printf("Restarted the mesh agent"); }
else if (r == 2) { printf("Mesh agent failed to stop"); }
}
}
else if (argc > 1 && strcasecmp(argv[1], "-install") == 0)
{
// Setup the service
StopService(serviceFile);
UninstallService();
if (InstallService() == TRUE) { printf("Mesh agent installed"); } else { printf("Failed to install mesh agent"); }
#ifndef _MINCORE
// Setup the Windows firewall
if (GetModuleFileNameW(NULL, str, _MAX_PATH) > 5)
{
ClearWindowsFirewall(str);
if (SetupWindowsFirewall(str) != 0)
{
#ifdef _DEBUG
ILIBMESSAGE("Firewall rules added successfully");
#endif
}
else
{
#ifdef _DEBUG
ILIBMESSAGE("Unable to add firewall rules");
#endif
}
}
#endif
}
else if (argc > 1 && ((strcasecmp(argv[1], "-remove") == 0) || (strcasecmp(argv[1], "-uninstall") == 0)))
{
// Ask the service manager to stop the service
StopService(serviceFile);
// Remove the service
i = UninstallService();
if (i == 0) { printf("Failed to uninstall mesh agent"); }
else if (i == 1) { printf("Mesh agent uninstalled"); }
else if (i == 2) { printf("Mesh agent still running"); }
#ifndef _MINCORE
// Remove the MeshAgent registry keys
RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2");
RegDeleteKey(HKEY_CURRENT_USER, "Software\\Open Source\\MeshAgent2");
// Cleanup the firewall rules
if (GetModuleFileNameW( NULL, str, _MAX_PATH ) > 5)
{
if (ClearWindowsFirewall(str) != 0)
{
#ifdef _DEBUG
ILIBMESSAGE("Firewall rules removed successfully");
#endif
}
else
{
#ifdef _DEBUG
ILIBMESSAGE("Unable to remove firewall rules");
#endif
}
}
#endif
}
#ifdef _MINCORE
else if (argc > 1 && memcmp(argv[1], "-update:", 8) == 0)
{
// Attempt to copy our own exe over the original exe
while (util_CopyFile(argv[0], argv[1] + 8, FALSE) == FALSE) { Sleep(5000); }
// Attempt to start the updated service up again
LaunchService();
}
#endif
#ifndef _MINCORE
else if (argc > 1 && memcmp(argv[1], "-update:", 8) == 0)
{
// Attempt to copy our own exe over the original exe
while (util_CopyFile(argv[0], argv[1] + 8, FALSE) == FALSE) Sleep(5000);
// Attempt to start the updated service up again
LaunchService(serviceFile);
}
else if (argc > 1 && (strcasecmp(argv[1], "-netinfo") == 0))
{
char* data;
int len = MeshInfo_GetSystemInformation(&data);
if (len > 0) { printf(data); }
}
else if (argc > 1 && (strcasecmp(argv[1], "-fullinstall") == 0))
{
fullinstall( 0, proxyarg, (int)strnlen_s(proxyarg, _MAX_PATH), tagarg, (int)strnlen_s(tagarg, _MAX_PATH));
}
else if (argc > 1 && (strcasecmp(argv[1], "-fulluninstall") == 0))
{
fullinstall(1, NULL, 0, NULL, 0);
}
else if (argc > 1 && (strcasecmp(argv[1], "-setfirewall") == 0))
{
// Reset the firewall rules
GetModuleFileNameW(NULL, str, _MAX_PATH);
if (IsAdmin() == FALSE) { printf("Must run as administrator"); } else { ClearWindowsFirewall(str); SetupWindowsFirewall(str); printf("Done"); }
}
else if (argc > 1 && (strcasecmp(argv[1], "-clearfirewall") == 0))
{
// Clear the firewall rules
GetModuleFileNameW(NULL, str, _MAX_PATH);
if (IsAdmin() == FALSE) { printf("Must run as administrator"); } else { ClearWindowsFirewall(str); printf("Done"); }
}
#endif
else if (argc == 2 && (strcasecmp(argv[1], "-nodeidhex") == 0))
{
// Get the NodeID from the registry
HKEY hKey;
DWORD len = 0;
char* strEx = NULL;
#ifndef _WIN64
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS )
#else
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS )
#endif
{
if (RegQueryValueExA(hKey, "NodeId", NULL, NULL, NULL, &len ) == ERROR_SUCCESS && len > 0)
{
if ((strEx = (char*)malloc(len)) == NULL) ILIBCRITICALEXIT(254);
if (RegQueryValueExA(hKey, "NodeId", NULL, NULL, (LPBYTE)strEx, &len ) != ERROR_SUCCESS || len == 0) { free(strEx); strEx = NULL; len = 0;}
}
RegCloseKey(hKey);
}
if (strEx != NULL) printf(strEx); else printf("Not defined, start the mesh service to create a nodeid.");
return 0;
}
else if (argc == 2 && (strcasecmp(argv[1], "-info") == 0))
{
// Display agent information from the registry
HKEY hKey;
DWORD len = 0;
char* strEx = NULL;
#ifndef _WIN64
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS)
#else
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
#endif
{
// Display NodeId
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "NodeId", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len == 0) printf("NodeId: (none)"); else printf("NodeId: %s", ILibScratchPad2);
// Display MeshId
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "MeshId", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nMeshId: %s", ILibScratchPad2);
// Display AgentHash
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "AgentHash", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nAgentHash: %s", ILibScratchPad2);
// Display MeshServerId
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "MeshServerId", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nServerId: %s", ILibScratchPad2);
// Display MeshServerUrl
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "MeshServerUrl", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nServerUrl: %s", ILibScratchPad2);
// Display Proxy
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "Proxy", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nProxy: %s", ILibScratchPad2);
// Display Tag
len = sizeof(ILibScratchPad2);
if (RegQueryValueExA(hKey, "Tag", NULL, NULL, (LPBYTE)ILibScratchPad2, &len) != ERROR_SUCCESS) { len = 0; }
if (len > 0) printf("\r\nTag: %s", ILibScratchPad2);
RegCloseKey(hKey);
}
return 0;
}
else if (argc == 2 && (strcasecmp(argv[1], "-resetnodeid") == 0))
{
// Set "resetnodeid" in registry
HKEY hKey;
#ifndef _WIN64
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_WRITE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS )
#else
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Open Source\\MeshAgent2", 0, KEY_WRITE, &hKey) == ERROR_SUCCESS )
#endif
{
i = 1;
DWORD err = RegSetValueEx(hKey, "ResetNodeId", 0, REG_DWORD, (BYTE*)&i, (DWORD)4);
if (err == ERROR_SUCCESS) { printf("NodeID will be reset next time the Mesh Agent service is started."); }
RegCloseKey(hKey);
}
else
{
printf("Error writing to registry, try running this as administrator.");
}
return 0;
}
else
{
if (argc > 1)
{
// See if we need to run as a script engine
if (argc >= 2 && ILibString_EndsWith(argv[1], -1, ".js", 3) != 0)
{
__try
{
agent = MeshAgent_Create();
MeshAgent_Start(agent, argc, argv);
MeshAgent_Destroy(agent);
}
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException))
{
ILib_WindowsExceptionDebug(&winException);
}
}
else
{
#ifdef _MINCORE
printf("Mesh Agent available switches:\r\n start Start the service.\r\n restart Restart the service.\r\n stop Stop the service.\r\n state Display the running state of the service.\r\n -signcheck Perform self-check.\r\n -install Install the service from this location.\r\n -uninstall Remove the service from this location.\r\n -nodeidhex Return the current agent identifier.\r\n -proxy:host:port Specifiy an HTTPS proxy (after -fullinstall only).\r\n -tag:xxx Specifiy a agent tag (after -fullinstall only).\r\n\r\n -resetnodeid Reset the NodeID next time the service is started.");
#else
printf("Mesh Agent available switches:\r\n start Start the service.\r\n restart Restart the service.\r\n stop Stop the service.\r\n state Display the running state of the service.\r\n -signcheck Perform self-check.\r\n -install Install the service from this location.\r\n -uninstall Remove the service from this location.\r\n -nodeidhex Return the current agent identifier.\r\n -fullinstall Copy agent into program files, install and launch.\r\n -fulluninstall Stop agent and clean up the program files location.\r\n -proxy:host:port Specifiy an HTTPS proxy (after -fullinstall only).\r\n -tag:xxx Specifiy a agent tag (after -fullinstall only).\r\n -resetnodeid Reset the NodeID next time the service is started.");
#endif
}
}
else
{
#ifndef _MINCORE
if (RunService() == 0 && GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
FreeConsole();
if (IsAdmin() == FALSE)
{
MessageBox(NULL, TEXT("Must run as administrator"), TEXT("Mesh Agent"), MB_OK | MB_ICONERROR);
}
else
{
DialogBox(NULL, MAKEINTRESOURCE(IDD_INSTALLDIALOG), NULL, DialogHandler);
}
}
}
#else
RunService();
#endif
}
CoUninitialize();
return 0;
}
char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serverid, char** serverurl)
{
char* importFile;
int eq, importFileLen;
parser_result *pr;
parser_result_field *f;
*meshname = *meshid = *serverid = *serverurl = NULL;
importFileLen = ILibReadFileFromDiskEx(&importFile, fileName);
if (importFile == NULL) return NULL;
pr = ILibParseString(importFile, 0, importFileLen, "\n", 1);
f = pr->FirstResult;
while (f != NULL)
{
f->datalength = ILibTrimString(&(f->data), f->datalength);
if (f->data[0] != 35) // Checking to see if this line is commented out
{
eq = ILibString_IndexOf(f->data, f->datalength, "=", 1);
if (eq > 0)
{
char *key, *val;
int keyLen, valLen;
key = f->data;
keyLen = eq;
key[keyLen] = 0;
val = key + keyLen + 1;
valLen = f->datalength - keyLen - 1;
if (val[valLen - 1] == 13) { --valLen; }
valLen = ILibTrimString(&val, valLen);
val[valLen] = 0;
if (keyLen == 8 && memcmp("MeshName", key, keyLen) == 0) { *meshname = val; }
if (keyLen == 6 && memcmp("MeshID", key, keyLen) == 0) { *meshid = val; }
if (keyLen == 8 && memcmp("ServerID", key, keyLen) == 0) { *serverid = val; }
if (keyLen == 10 && memcmp("MeshServer", key, keyLen) == 0) { *serverurl = val; }
}
}
f = f->NextResult;
}
ILibDestructParserResults(pr);
return importFile;
}
#ifndef _MINCORE
// Message handler for dialog box.
INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
char *fileName = NULL, *meshname = NULL, *meshid = NULL, *serverid = NULL, *serverurl = NULL, *mshfile = NULL;
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
// Get the current service running state
int r = GetServiceState(serviceFile);
char* txt = "";
char selfexe[_MAX_PATH];
switch (r)
{
case 0:
txt = "Error";
break;
case SERVICE_STOPPED:
txt = "Stopped";
break;
case SERVICE_START_PENDING:
txt = "Start Pending";
break;
case SERVICE_STOP_PENDING:
txt = "Stop Pending";
break;
case SERVICE_RUNNING:
txt = "Running";
break;
case SERVICE_CONTINUE_PENDING:
txt = "Continue Pending";
break;
case SERVICE_PAUSE_PENDING:
txt = "Pause Pending";
break;
case SERVICE_PAUSED:
txt = "Paused";
break;
case 100:
txt = "Not Installed";
break;
}
SetWindowTextA( GetDlgItem( hDlg, IDC_STATUSTEXT ), txt);
// Get current executable path
GetModuleFileNameA(NULL, selfexe, MAX_PATH);
fileName = MeshAgent_MakeAbsolutePath(selfexe, ".msh");
{
DWORD dwSize = 0;
BYTE *pVersionInfo = NULL;
VS_FIXEDFILEINFO *pFileInfo = NULL;
UINT pLenFileInfo = 0;
int major, minor, hotfix, other;
if ((dwSize = GetFileVersionInfoSize(selfexe, NULL)))
{
pVersionInfo = malloc(dwSize);
if (GetFileVersionInfo(selfexe, 0, dwSize, pVersionInfo))
{
if (VerQueryValue(pVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &pLenFileInfo))
{
// Display the version of this software
major = (pFileInfo->dwFileVersionMS >> 16) & 0xffff;
minor = (pFileInfo->dwFileVersionMS) & 0xffff;
hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff;
other = (pFileInfo->dwFileVersionLS) & 0xffff;
#ifdef _WIN64
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "v%d.%d.%d, 64bit", major, minor, hotfix);
#else
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "v%d.%d.%d", major, minor, hotfix);
#endif
SetWindowTextA(GetDlgItem(hDlg, IDC_VERSIONTEXT), ILibScratchPad);
}
}
free(pVersionInfo);
}
}
if ((mshfile = getMshSettings(fileName, &meshname, &meshid, &serverid, &serverurl)) != NULL)
{
// Set text in the dialog box
if (strlen(meshid) > 50) { meshid += 2; meshid[42] = 0; }
if (strlen(serverid) > 50) { serverid[42] = 0; }
SetWindowTextA(GetDlgItem(hDlg, IDC_POLICYTEXT), (meshid != NULL) ? meshname : "(None)");
SetWindowTextA(GetDlgItem( hDlg, IDC_HASHTEXT), (meshid != NULL) ? meshid : "(None)");
SetWindowTextA(GetDlgItem(hDlg, IDC_SERVERLOCATION), (serverurl != NULL) ? serverurl : "(None)");
SetWindowTextA(GetDlgItem(hDlg, IDC_SERVERID), (serverid != NULL) ? serverid : "(None)");
free(mshfile);
}
return (INT_PTR)TRUE;
}
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
#ifdef _DEBUG
_CrtCheckMemory();
_CrtDumpMemoryLeaks();
#endif
return (INT_PTR)TRUE;
}
else if (LOWORD(wParam) == IDC_INSTALLBUTTON || LOWORD(wParam) == IDC_UNINSTALLBUTTON)
{
EnableWindow( GetDlgItem( hDlg, IDC_INSTALLBUTTON ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_UNINSTALLBUTTON ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDCANCEL ), FALSE );
if (LOWORD(wParam) == IDC_INSTALLBUTTON) fullinstall( 0, NULL, 0, NULL, 0 ); else fullinstall( 1, NULL, 0, NULL, 0 );
EndDialog(hDlg, LOWORD(wParam));
#ifdef _DEBUG
_CrtCheckMemory();
_CrtDumpMemoryLeaks();
#endif
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
#endif
#ifdef _MINCORE
BOOL WINAPI AreFileApisANSI(void) { return FALSE; }
VOID WINAPI FatalAppExitA(_In_ UINT uAction, _In_ LPCSTR lpMessageText) {}
HANDLE WINAPI CreateSemaphoreW(_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, _In_ LONG lInitialCount, _In_ LONG lMaximumCount, _In_opt_ LPCWSTR lpName)
{
return 0;
}
#endif