diff options
author | Bernard Normier <bernard@zeroc.com> | 2007-10-23 11:40:45 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2007-10-23 11:40:45 -0400 |
commit | a8d3f69603a074010e415143918ed1f5a047bec8 (patch) | |
tree | ae06e54883d21da7b488f5fb382b271a35ffb5e8 /cpp/src | |
parent | Fixed unescaped keyword bug. (diff) | |
download | ice-a8d3f69603a074010e415143918ed1f5a047bec8.tar.bz2 ice-a8d3f69603a074010e415143918ed1f5a047bec8.tar.xz ice-a8d3f69603a074010e415143918ed1f5a047bec8.zip |
New iceserviceinstall tool
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Makefile.mak | 1 | ||||
-rw-r--r-- | cpp/src/iceserviceinstall/.depend | 0 | ||||
-rwxr-xr-x | cpp/src/iceserviceinstall/Install.cpp | 853 | ||||
-rw-r--r-- | cpp/src/iceserviceinstall/Makefile.mak | 56 | ||||
-rwxr-xr-x | cpp/src/iceserviceinstall/security.manifest | 11 |
5 files changed, 921 insertions, 0 deletions
diff --git a/cpp/src/Makefile.mak b/cpp/src/Makefile.mak index 92b0272a119..04cb6872dee 100644 --- a/cpp/src/Makefile.mak +++ b/cpp/src/Makefile.mak @@ -38,6 +38,7 @@ SUBDIRS = $(SUBDIRS) IceUtil \ FreezeScript \ IceStorm \ IceGrid \ + iceserviceinstall \ ca $(EVERYTHING):: diff --git a/cpp/src/iceserviceinstall/.depend b/cpp/src/iceserviceinstall/.depend new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cpp/src/iceserviceinstall/.depend diff --git a/cpp/src/iceserviceinstall/Install.cpp b/cpp/src/iceserviceinstall/Install.cpp new file mode 100755 index 00000000000..f64a3363663 --- /dev/null +++ b/cpp/src/iceserviceinstall/Install.cpp @@ -0,0 +1,853 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution.que +// +// ********************************************************************** + +#define _WIN32_WINNT 0x0500 + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define _CRT_SECURE_NO_DEPRECATE 1 // C4996 '<C function>' was declared deprecated +#endif + +#include <Ice/Application.h> +#include <IceUtil/Options.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include <Aclapi.h> +#include <AccCtrl.h> +#include <Sddl.h> + +using namespace std; +using namespace Ice; + +class Install : public Application +{ +public: + virtual int run(int, char*[]); + + Install(); + virtual ~Install(); + +private: + + void usage() const; + + void initializeSid(const string&); + + bool fileExists(const string&) const; + void checkService(const string&, string&, string&) const; + void grantPermissions(const string& path, SE_OBJECT_TYPE type = SE_FILE_OBJECT, + bool inherit = false, bool fullControl = false) const; + bool mkdir(const string&) const; + string formatMessage(DWORD) const; + + void uninstallService(const string&) const; + void installService(const string&, const string&, const string&, const string&, + const string&, const string&, const string&) const; + + void addEventLogKey(const string&, const string&) const; + void removeEventLogKey(const string&) const; + string mangleKey(const string&) const; + string createEventLogKey(const string&) const; + string getIceDLLPath(const string&) const; + + string _icegridInstanceName; + string _nodeName; + string _glacier2InstanceName; + + SID* _sid; + string _sidName; + + bool _debug; +}; + +int +main(int argc, char* argv[]) +{ + Install app; + int status = app.main(argc, argv); + + system("pause"); + + return status; +} + +int +Install::run(int argc, char* argv[]) +{ + IceUtil::Options opts; + opts.addOpt("h", "help"); + opts.addOpt("v", "version"); + opts.addOpt("u", "uninstall"); + opts.addOpt("", "debug"); + + const string propNames[] = { "ImagePath", "DisplayName", "ObjectName", "Password", + "Description", "DependOnRegistry" }; + const int propCount = 6; + + for(int i = 0; i < propCount; ++i) + { + opts.addOpt("", propNames[i], IceUtil::Options::NeedArg); + } + + vector<string> commands; + try + { + commands = opts.parse(argc, argv); + } + catch(const IceUtil::BadOptException& e) + { + cerr << "Error:" << e.reason << endl; + usage(); + return EXIT_FAILURE; + } + + if(opts.isSet("help")) + { + usage(); + return EXIT_SUCCESS; + } + if(opts.isSet("version")) + { + cout << ICE_STRING_VERSION << endl; + return EXIT_SUCCESS; + } + + _debug = opts.isSet("debug"); + + PropertiesPtr properties = communicator()->getProperties(); + + for(int i = 0; i < propCount; ++i) + { + if(opts.isSet(propNames[i])) + { + properties->setProperty(propNames[i], opts.optArg(propNames[i])); + } + } + + if(commands.size() != 2) + { + usage(); + return EXIT_FAILURE; + } + + initializeSid(properties->getPropertyWithDefault("ObjectName", + "NT Authority\\LocalService")); + + string service = commands[0]; + string configFile = commands[1]; + + try + { + PropertiesPtr serviceProperties = createProperties(); + serviceProperties->load(configFile); + + string serviceName; + LocatorPrx defaultLocator = LocatorPrx::uncheckedCast( + communicator()->stringToProxy( + serviceProperties->getProperty("Ice.Default.Locator"))); + + if(service == "icegridregistry") + { + _icegridInstanceName = + serviceProperties->getPropertyWithDefault("IceGrid.InstanceName", "IceGrid"); + serviceName = service + "." + _icegridInstanceName; + } + else + { + if(defaultLocator != 0) + { + _icegridInstanceName = defaultLocator->ice_getIdentity().category; + } + + if(service == "icegridnode") + { + if(_icegridInstanceName == "") + { + throw string("Ice.Default.Locator must be set in " + configFile); + } + _nodeName = serviceProperties->getProperty("IceGrid.Node.Name"); + if(_nodeName == "") + { + throw string("IceGrid.Node.Name must be set in " + configFile); + } + serviceName = service + "." + _icegridInstanceName + "." + _nodeName; + } + else if(service == "glacier2router") + { + _glacier2InstanceName = + serviceProperties->getPropertyWithDefault("Glacier2.InstanceName", + "Glacier2"); + serviceName = service + "." + _glacier2InstanceName; + } + } + + string displayName; + string description; + checkService(service, displayName, description); + displayName = properties->getPropertyWithDefault("DisplayName", displayName); + description = properties->getPropertyWithDefault("Description", description); + + if(opts.isSet("uninstall")) + { + uninstallService(serviceName); + return EXIT_SUCCESS; + } + + string imagePath = properties->getProperty("ImagePath"); + if(imagePath == "") + { + char buffer[MAX_PATH]; + DWORD size = GetModuleFileName(0, buffer, MAX_PATH); + if(size == 0) + { + throw "Can't get full path to self: " + formatMessage(GetLastError()); + } + imagePath = string(buffer, size); + imagePath.replace(imagePath.rfind('\\'), string::npos, string("\\") + + service + ".exe"); + } + if(!fileExists(imagePath)) + { + throw imagePath + ": not found"; + } + + string dependencies = "netprofm"; + + if(service == "icegridregistry") + { + if(properties->getPropertyAsInt("DependOnRegistry") != 0) + { + throw string("The IceGrid registry service can't depend on itself"); + } + + string registryDataDir = serviceProperties->getProperty("IceGrid.Registry.Data"); + if(registryDataDir == "") + { + throw string("IceGrid.Registry.Data must be set in " + configFile); + } + if(!mkdir(registryDataDir)) + { + grantPermissions(registryDataDir, SE_FILE_OBJECT, true, true); + } + } + else if(service == "icegridnode") + { + string nodeDataDir = serviceProperties->getProperty("IceGrid.Node.Data"); + if(nodeDataDir == "") + { + throw string("IceGrid.Node.Data must be set in " + configFile); + } + if(!mkdir(nodeDataDir)) + { + grantPermissions(nodeDataDir, SE_FILE_OBJECT, true, true); + } + + grantPermissions( + "MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib", + SE_REGISTRY_KEY, true); + + if(properties->getPropertyAsInt("DependOnRegistry") != 0) + { + dependencies = "icegridregistry." + _icegridInstanceName; + } + } + else if(service == "glacier2router") + { + if(properties->getPropertyAsInt("DependOnRegistry") != 0) + { + if(_icegridInstanceName == "") + { + throw string("Ice.Default.Locator must be set in " + configFile + + " when DependOnRegistry is not zero"); + } + dependencies = "icegridregistry." + _icegridInstanceName; + } + } + dependencies += '\0'; // must be double-null terminated + + grantPermissions(configFile); + + installService(serviceName, imagePath, configFile, displayName, description, + dependencies, properties->getProperty("Password")); + } + catch(const string& msg) + { + cerr << "Error: " << msg << endl; + return EXIT_FAILURE; + } + catch(const Ice::Exception& ex) + { + cerr << "Error: " << ex << endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +Install::Install() : + _sid(0) +{ +} + +Install::~Install() +{ + free(_sid); +} + +void +Install::usage() const +{ + cerr << "Usage: " << appName() + << " [options] service config-file [property] [property]\n"; + cerr << + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\n" + "-u, --uninstall Uninstall the Windows service.\n" + "\n" + "service must be icegridregistry, icegridnode or glacier2router.\n" + "\n" + "config-file Path to the Ice configuration file for this service.\n" + "\n" + "Valid properties:\n" + "ImagePath Full path to <service>.exe. The default value is\n" + " <directory of " << appName() << ">\\<service>.exe\n" + "DisplayName Display name for the service\n" + "Description Description for the service\n" + "ObjectName Account used to run the service. Defaults to\n" + " NT Authority\\LocalService\n" + "Password Password for ObjectName\n" + "DependOnRegistry When non 0, the service depends on the IceGrid registry\n" + " service (the IceGrid registry service name is computed\n" + " using Ice.Default.Locator in <config-file>).\n" + ; +} + +void +Install::initializeSid(const string& name) +{ + { + DWORD sidSize = 32; + _sid = static_cast<SID*>(malloc(sidSize)); + memset(_sid, 0, sidSize); + + DWORD domainNameSize = 32; + char* domainName = static_cast<char*>(malloc(domainNameSize)); + memset(domainName, 0, domainNameSize); + + SID_NAME_USE nameUse; + while(LookupAccountName(0, name.c_str(), _sid, &sidSize, domainName, &domainNameSize, &nameUse) == false) + { + DWORD res = GetLastError(); + + if(res == ERROR_INSUFFICIENT_BUFFER) + { + _sid = static_cast<SID*>(realloc(_sid, sidSize)); + memset(_sid, 0, sidSize); + domainName = static_cast<char*>(realloc(domainName, domainNameSize)); + memset(domainName, 0, domainNameSize); + } + else + { + free(_sid); + _sid = 0; + free(domainName); + + throw string("Could not retrieve Security ID for ") + name + ": " + + formatMessage(res); + } + } + free(domainName); + } + + // + // Now store in _sidName a 'normalized' name (for the CreateService call) + // + { + char accountName[1024]; + DWORD accountNameLen = 1024; + + char domainName[1024]; + DWORD domainLen = 1024; + + SID_NAME_USE nameUse; + if(LookupAccountSid(0, _sid, accountName, &accountNameLen, domainName, + &domainLen, &nameUse) == false) + { + DWORD res = GetLastError(); + throw string("Could not retrieve 'normalized' account name for ") + name + ": " + + formatMessage(res); + } + + _sidName = string(domainName) + "\\" + accountName; + } + + if(_debug) + { + char* sidString = 0; + ConvertSidToStringSid(_sid, &sidString); + + Trace trace(communicator()->getLogger(), appName()); + trace << "SID: " << sidString << "; Normalized name: " << _sidName; + + LocalFree(sidString); + } +} + +bool +Install::fileExists(const string& path) const +{ + struct _stat buffer = { 0 }; + int err = _stat(path.c_str(), &buffer); + + if(err == 0) + { + if((buffer.st_mode & _S_IFREG) == 0) + { + throw path + " is not a regular file"; + } + return true; + } + else + { + if(errno == ENOENT) + { + return false; + } + else + { + const char* msg = strerror(errno); + throw string("Problem with ") + path + ": " + msg; + } + } +} + +void +Install::checkService(const string& service, string& displayName, string& description) const +{ + if(service == "icegridregistry") + { + displayName = string("IceGrid registry (") + _icegridInstanceName + ")"; + description = "Location and deployment service for Ice applications"; + } + else if(service == "icegridnode") + { + displayName = string("IceGrid node (") + _nodeName + " within " + + _icegridInstanceName + ")"; + description = "Starts and monitors Ice servers"; + } + else if(service == "glacier2router") + { + displayName = string("Glacier2 router (") + _glacier2InstanceName + ")"; + description = "Ice Firewall traversal service"; + } + else + { + throw string("Invalid service"); + } +} + +void +Install::grantPermissions(const string& path, SE_OBJECT_TYPE type, bool inherit, bool fullControl) const +{ + // + // First retrieve the ACL for our file/directory/key + // + PACL acl = 0; + PACL newAcl = 0; + PSECURITY_DESCRIPTOR sd = 0; + DWORD res = GetNamedSecurityInfo(const_cast<char*>(path.c_str()), type, + DACL_SECURITY_INFORMATION, + 0, 0, &acl, 0, &sd); + if(res != ERROR_SUCCESS) + { + throw string("Could not retrieve securify info for ") + path + ": " + + formatMessage(res); + } + + try + { + // + // Now check if _sid can read this file/dir/key + // + TRUSTEE trustee; + BuildTrusteeWithSid(&trustee, _sid); + + ACCESS_MASK accessMask = 0; + res = GetEffectiveRightsFromAcl(acl, &trustee, &accessMask); + + if(res != ERROR_SUCCESS) + { + throw string("Could not retrieve effective rights for ") + _sidName + + " on " + path + ": " + formatMessage(res); + } + + bool done = false; + + if(type == SE_FILE_OBJECT) + { + if(fullControl) + { + done = (accessMask & READ_CONTROL) && (accessMask & SYNCHRONIZE) + && (accessMask & 0x1F) == 0x1F; + } + else + { + done = (accessMask & READ_CONTROL) && (accessMask & SYNCHRONIZE); + } + } + else + { + done = (accessMask & READ_CONTROL); + } + + if(done) + { + if(_debug) + { + Trace trace(communicator()->getLogger(), appName()); + trace << _sidName << " had already the desired permissions on " << path; + } + } + else + { + EXPLICIT_ACCESS ea = { 0 }; + + if(type == SE_FILE_OBJECT && fullControl) + { + ea.grfAccessPermissions = (accessMask | FILE_ALL_ACCESS); + } + else + { + ea.grfAccessPermissions = (accessMask | GENERIC_READ); + } + ea.grfAccessMode = GRANT_ACCESS; + if(inherit) + { + ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; + } + else + { + ea.grfInheritance = NO_INHERITANCE; + } + ea.Trustee = trustee; + + // + // Create new ACL + // + PACL newAcl = 0; + res = SetEntriesInAcl(1, &ea, acl, &newAcl); + if(res != ERROR_SUCCESS) + { + throw string("Could not modify ACL for ") + path + ": " + formatMessage(res); + } + + res = SetNamedSecurityInfo(const_cast<char*>(path.c_str()), type, + DACL_SECURITY_INFORMATION, + 0, 0, newAcl, 0); + if(res != ERROR_SUCCESS) + { + throw string("Could not grant access to ") + _sidName + + " on " + path + ": " + formatMessage(res); + } + + if(_debug) + { + Trace trace(communicator()->getLogger(), appName()); + trace << "Granted access on " << path << " to " << _sidName; + } + } + } + catch(...) + { + LocalFree(acl); + LocalFree(newAcl); + throw; + } + + LocalFree(acl); + LocalFree(newAcl); +} + +bool +Install::mkdir(const string& path) const +{ + if(CreateDirectory(path.c_str(), 0) == 0) + { + DWORD res = GetLastError(); + if(res == ERROR_ALREADY_EXISTS) + { + return false; + } + else if(res == ERROR_PATH_NOT_FOUND) + { + string parentPath = path; + parentPath.erase(parentPath.rfind('\\')); + mkdir(parentPath); + return mkdir(path); + } + else + { + throw "Could not create directory " + path + ": " + formatMessage(res); + } + } + else + { + grantPermissions(path, SE_FILE_OBJECT, true, true); + return true; + } +} + +string +Install::formatMessage(DWORD err) const +{ + ostringstream os; + char* msgBuf = 0; + DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + 0, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + reinterpret_cast<char*>(&msgBuf), + 0, + 0); + + if(ok) + { + os << msgBuf; + LocalFree(msgBuf); + } + else + { + os << "unknown error"; + } + + return os.str(); +} + +void +Install::uninstallService(const string& serviceName) const +{ + SC_HANDLE scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); + if(scm == 0) + { + DWORD res = GetLastError(); + throw string("Cannot open SCM: ") + formatMessage(res); + } + + SC_HANDLE service = OpenService(scm, serviceName.c_str(), SERVICE_ALL_ACCESS); + if(service == 0) + { + DWORD res = GetLastError(); + CloseServiceHandle(scm); + throw string("Cannot open service: ") + formatMessage(res); + } + + if(!DeleteService(service)) + { + DWORD res = GetLastError(); + CloseServiceHandle(scm); + CloseServiceHandle(service); + throw string("Cannot open service: ") + formatMessage(res); + } + + CloseServiceHandle(scm); + CloseServiceHandle(service); + + removeEventLogKey(serviceName); +} + +void +Install::installService(const string& serviceName, const string& imagePath, + const string& configFile, const string& displayName, + const string& description, const string& dependencies, + const string& password) const +{ + + addEventLogKey(serviceName, getIceDLLPath(imagePath)); + + SC_HANDLE scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); + if(scm == 0) + { + DWORD res = GetLastError(); + throw string("Cannot open SCM: ") + formatMessage(res); + } + + string command = "\"" + imagePath + "\" --service " + serviceName + + " --Ice.Config=\"" + configFile + "\""; + + SC_HANDLE service = CreateService( + scm, + serviceName.c_str(), + displayName.c_str(), + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + command.c_str(), + 0, + 0, + dependencies.c_str(), + _sidName.c_str(), + password.c_str()); + + if(service == 0) + { + DWORD res = GetLastError(); + CloseServiceHandle(scm); + throw string("Cannot create service: ") + formatMessage(res); + } + + // + // Set description + // + + SERVICE_DESCRIPTION sd = { const_cast<char*>(description.c_str()) }; + + if(!ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sd)) + { + DWORD res = GetLastError(); + CloseServiceHandle(scm); + CloseServiceHandle(service); + throw string("Cannot set description: ") + formatMessage(res); + } + + + CloseServiceHandle(scm); + CloseServiceHandle(service); +} + +void +Install::addEventLogKey(const string& serviceName, const string& resourceFile) const +{ + HKEY key = 0; + DWORD disposition = 0; + LONG res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, createEventLogKey(serviceName).c_str(), + 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, + &key, &disposition); + if(res != ERROR_SUCCESS) + { + throw "Could not create Event Log key in registry: " + formatMessage(res); + } + + // + // The event resources are bundled into this DLL, therefore + // the "EventMessageFile" key should contain the path to this + // DLL. + // + res = RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ, + reinterpret_cast<const BYTE*>(resourceFile.c_str()), + resourceFile.length() + 1); + + if(res == ERROR_SUCCESS) + { + // + // The "TypesSupported" key indicates the supported event + // types. + // + DWORD typesSupported = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE + | EVENTLOG_INFORMATION_TYPE; + res = RegSetValueEx(key, "TypesSupported", 0, REG_DWORD, + reinterpret_cast<BYTE*>(&typesSupported), sizeof(typesSupported)); + } + + if(res != ERROR_SUCCESS) + { + RegCloseKey(key); + throw "Could not set registry key: " + formatMessage(res); + } + + res = RegCloseKey(key); + if(res != ERROR_SUCCESS) + { + throw "Could not close registry key handle: " + formatMessage(res); + } +} + +void +Install::removeEventLogKey(const string& serviceName) const +{ + LONG res = RegDeleteKey(HKEY_LOCAL_MACHINE, createEventLogKey(serviceName).c_str()); + if(res != ERROR_SUCCESS) + { + throw "Could not remove registry key: " + formatMessage(res); + } +} + +string +Install::mangleKey(const string& name) const +{ + string result = name; + // + // The service name cannot contain backslashes. + // + string::size_type pos = 0; + while((pos = result.find('\\', pos)) != string::npos) + { + result[pos] = '/'; + } + return result; +} + +string +Install::createEventLogKey(const string& name) const +{ + // + // The registry key is: + // + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application. + // + return "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + mangleKey(name); +} + +string +Install::getIceDLLPath(const string& imagePath) const +{ + string imagePathDir = imagePath; + imagePathDir.erase(imagePathDir.rfind('\\')); + + // + // Get current 'DLL' version + // + int majorVersion = (ICE_INT_VERSION / 10000); + int minorVersion = (ICE_INT_VERSION / 100) - majorVersion * 100; + ostringstream os; + os << majorVersion * 10 + minorVersion; + + int patchVersion = ICE_INT_VERSION % 100; + if(patchVersion > 50) + { + os << 'b'; + if(patchVersion >= 52) + { + os << (patchVersion - 50); + } + } + string version = os.str(); + + string result = imagePathDir + '\\' + "ice" + version + ".dll"; + + if(fileExists(result)) + { + return result; + } + else + { + result = imagePathDir + '\\' + "ice" + version + "d.dll"; + if(fileExists(result)) + { + return result; + } + else + { + throw string("Could not find Ice DLL"); + } + } +} diff --git a/cpp/src/iceserviceinstall/Makefile.mak b/cpp/src/iceserviceinstall/Makefile.mak new file mode 100644 index 00000000000..e20442869b6 --- /dev/null +++ b/cpp/src/iceserviceinstall/Makefile.mak @@ -0,0 +1,56 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ..\.. + +TOOL = $(top_srcdir)\bin\iceserviceinstall.exe + +TARGETS = $(TOOL) + +OBJS = Install.obj + +SRCS = $(OBJS:.obj=.cpp) + +!include $(top_srcdir)\config\Make.rules.mak + +CPPFLAGS = $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN + +!if "$(CPP_COMPILER)" != "BCC2006" && "$(OPTIMIZE)" != "yes" +PDBFLAGS = /pdb:$(TOOL:.exe=.pdb) +!endif + + +$(TOOL): $(OBJS) + $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(OBJS) $(SETARGV) $(PREOUT)$@ $(PRELIBS)$(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest security.manifest -outputresource:$@;#1 && del /q $@.manifest + +clean:: + del /q $(TOOL:.exe=.*) + +install:: all + copy $(TOOL) $(install_bindir) + +!if "$(OPTIMIZE)" != "yes" + +!if "$(CPP_COMPILER)" == "BCC2006" + +install:: all + copy $(TOOL:.exe=.tds) $(install_bindir) + +!else + +install:: all + copy $(TOOOL:.exe=.pdb) $(install_bindir) + +!endif + +!endif + +!include .depend diff --git a/cpp/src/iceserviceinstall/security.manifest b/cpp/src/iceserviceinstall/security.manifest new file mode 100755 index 00000000000..a683e40afe4 --- /dev/null +++ b/cpp/src/iceserviceinstall/security.manifest @@ -0,0 +1,11 @@ +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel + level="requireAdministrator" + uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> |