CNTService logoCNTService v2.09

Welcome to CNTService, a collection of freeware C++ classes which provide a class framework for developing NT services.

For detailed information about NT services, how to develop them and their relationship to other NT subsystems, I would suggest you thoroughly read the relevant documentation which comes with the Windows SDK.

 

Features
Usage
Copyright
History
Class Framework Reference
References
Contacting the Author

 

Features

 

 

 

Usage

 

 

 

Copyright

 

 

 

History

v2.09 (28 March 2024)

v2.08 (23 September 2023)

v2.07 (10 May 2023)

v2.06 (5 February 2022)

v2.05 (15 January 2022)

v2.04 (9 January 2022)

30 July 2021

v2.03 (26 July 2020)

v2.02 (12 April 2020)

v2.01 (5 January 2020)

v2.0 (28 December 2019)

v1.99 (6 November 2019)

v1.98 (3 November 2019)

v1.97 (26 October 2019)

v1.96 (17 September 2019)

v1.95 (13 August 2019)

v1.94 (28 July 2019)

v1.93 (2 June 2019)

v1.92 (1 September 2018)

v1.91 (29 August 2018)

v1.90 (2 June 2018)

v1.89 (26 May 2018)

v1.88 (16 September 2017)

v1.87 (27 April 2017)

v1.86 (16 April 2017)

v1.85 (9 April 2017)

v1.84 (15 November 2016)

v1.83 (1 June 2016)

v1.82 (19 April 2016)

v1.81 (18 December 2015)

v1.80 (1 January 2014)

v1.79 (10 November 2012)

v1.78 (3 September 2010)

v1.77 (1 August 2010)

v1.76 (1 June 2008)

v1.75 (12 January 2008)

v1.74 (19 November 2007)

v1.73 (22 March 2007)

v1.72 (2 February 2007)

20 November 2006

v1.71 (21 September 2006)

v1.70 (1 August 2006)

v1.69 (27 July 2006)

v1.68 (2 July 2006)

v1.67 (25 June 2006)

v1.66 (24 June 2006)

v1.65 (13 June 2006)

v1.64 (9 June 2006)

v1.63 (7 June 2006)

v1.62 (3 June 2006)

v1.61 (31 May 2006)

v1.60 (18 May 2006)

v1.59 (12 May 2006)

v1.58 (27 April 2006)

v1.57 (13 January 2006)

v1.56 (11 January 2006)

v1.55 (14 August 2005)

v1.54 (31 July 2005)

v1.53 (21 April 2005)

v1.52 (26 March 2005)

v1.51 (11 February 2005)

v1.50 (11 November 2004)

v1.49 (18 October 2004)

v1.48 (15 October 2004)

v1.47 (24 June 2004)

v1.46 (20 June 2004)

v1.45 (20 June 2004)

v1.44 (5 May 2004)

v1.43 (12 April 2004)

v1.42 (9 April 2004)

v1.41 (18 March 2004)

21 February 2004

v1.40 (22 January 2004)

13 January 2004

v1.39 (26 November 2003)

v1.38 (23 November 2003)

v1.37 (19 November 2003)

v1.36 (14 November 2003)

v1.35 (12 November 2003)

v1.34 (5 October 2003)

v1.33 (4 October 2003)

v1.32 (8 September 2003)

v1.31 (15 August 2003)

v1.30 (3 August 2003)

v1.29 (22 May 2003)

v1.28 (17 May 2003)

v1.27 (8 May 2003)

v1.26 (12 March 2003)

v1.25 (20 November 2002)

v1.24 (20 September 2002)

v1.23 (28 August 2002)

v1.22 (27 August 2002)

v1.21 (27 November 2001)

v1.20 (9 August 2001)

v1.19 (18 July 2001)

v1.18 (15 July 2001)

v1.17 (27 May 2001)

v1.16 (16 May 2001)

v1.15 (8 January 2001)

v1.14 (21 December 2000)

v1.13 (28 July 2000)

v1.12 (21 June 2000)

v1.11 (19 June 2000)

v1.1 (21 May 2000)

v1.07 (10 April 2000)

v1.06 (24 January 2000)

v1.05 (10 October 1999)

v1.04 (5 October 1999)

v1.03 (3 October 1999)

v1.02 (5 September 1999)

v1.01 (17 May 1999)

24 August 1998

v1.0 (17 July 1998)

 

 

 

Class Framework Reference

The framework consists of the following classes:

 

CNTServiceCommandLineInfo
CNTEventLogSource
CNTService
CNTScmService
CNTServiceControlManager
CEventLogRecord
CNTEventLog

 

 

CNTServiceCommandLineInfo

The CNTServiceCommandLineInfo class aids in parsing the command line at application start-up. It is based almost exactly upon the way that the  CCommandLineInfo class in MFC works.

A service application will typically create a local instance of this class in your main/wmain or InitInstance function. This object is then passed to CNTService::ParseCommandLine, which fills the CNTServiceCommandLineInfo object. The CNTServiceCommandLineInfo object is then passed to CNTService::ProcessShellCommand to handle the command-line arguments and flags.

You can use this object to encapsulate the following command-line options and parameters:

Command-line argument

Command executed

/install

Installs the service.

/remove | /uninstall

Uninstalls the service.

/help [ /?]

Calls the virtual CNTService::OnHelp function.

/debug | /app | /Application Using this setting bypasses the service SCM start-up code and instead runs your code as a standard application.
/start Starts the service.
/stop Stops the service.
/pause Pauses the service.
/continue Continues the service.
/auto Installs the service as an automatic start-up service, as opposed to a manual start-up service which is the default (should be used in conjunction with the /install argument)
/T:value A timeout value in milliseconds to use when uninstalling, starting, stopping, pausing and continuing the service.
/SCL:XYZ Provides the command line which the code should use when running as a service by the SCM. (The use of this value on the command line is dependent upon CNTService::m_bAllowCommandLine).
/SD:WYZ Provides the service description to use. (The use of this value on the command line is dependent upon CNTService::m_bAllowDescriptionChange).
/SDN:PRQ Provides the service display name to use. (The use of this value on the command line is dependent upon CNTService::m_bAllowDisplayNameChange).
/SN:STU Provides the service name to use. (The use of this value on the command line is dependent upon CNTService::m_bAllowNameChange).
/silent Use this command line in conjunction with other command line arguments to suppress any message boxes or console output which the framework generates.
/U:ABC Allows you to configure the username account under which the service runs.
/P:DEF Allows you to configure the password for the associated username account under which the service runs.
/EnableServiceLogonRight Will cause the "SeServiceLogonRight" privilege for the specified account to be enabled using the LsaAddAccountRights API (should be used in conjuction with the /install and /P arguments)

Derive a new class from CCommandLineInfo to handle other flags and parameter values.

Please note that Install / Uninstall support via the CNTServiceCommandLineInfo class and the framework in general is considered self-registration. Installation best practices for Windows says that you should use the declarative approach provided by Windows Installer to install / uninstall your service. Please pick the MSI approach if you can.

 

CNTEventLogSource

CNTEventLogSource provides a wrapper class for writing events to the NT event log. You could consider this as the server side to the Event log APIs. Please note that CNTEventLogSource class uses the pre Vista API's for writing to the Windows Event Log. If you are targetting Windows Vista or later, then you should use the new APIs documented at https://msdn.microsoft.com/en-us/library/windows/desktop/aa385772%28v=vs.85%29.aspx. All that is required to support the new Vista API's is to generate an XML manifest file with your event log entries and then pass this file through the MC.exe SDK utility and a header file will be generated with inline code which you can call to write your event log entries without the need for any support classes.

 

Functions this class provides include:

CNTEventLogSource
~CNTEventLogSource
operator HANDLE
Attach
Detach
Register
Report
Deregister
Install
Uninstall

 

CNTEventLogSource::CNTEventLogSource

CNTEventLogSource();

CNTEventLogSource(LPCTSTR pUNCServerName, LPCTSTR pSourceName);

Remarks

This is the constructor which just initializes all internal variables to a safe state.

See Also ~CNTEventLogSource

 

CNTEventLogSource::~CNTEventLogSource

~CNTEventLogSource();

Remarks

This is the standard destructor for the class. Internally it will call Deregister to ensure that any handle that is opened by this instance is closed

See Also
CNTEventLogSource Deregister

 

CNTEventLogSource::operator HANDLE

operator HANDLE() const;

Return Value:

The underlying SDK handle representing this event log source.

Remarks

This function exposes the underlying handle which the CNTEventLogSource class wraps. This function is provided for integration with legacy code which uses the handle directly

 

CNTEventLogSource::Attach

void Attach(HANDLE hEventSource);

Parameters

hEventSource An SDK event log source handle returned from ::RegisterEventSource

Remarks

Use this member function to attach an existing SDK handle to a CNTEventLogSource.

See Also
Detach

 

CNTEvenLogSource::Detach

HANDLE Detach();

Return Value

The SDK event log source handle

Remarks

Call this function to detach m_hEventLogSource from the CNTEventLogSource object and  set m_hEventLogSource to nullptr.

See Also
Attach

 

CNTEventLogSource::Register

BOOL Register(LPCTSTR pUNCServerName, LPCTSTR pSourceName);

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

pUNCServerName Pointer to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which this operation is to be performed. If this parameter is nullptr, the operation is performed on the local computer.

pSourceName Pointer to a null-terminated string that specifies the name of the source referenced by the returned handle. The source name must be a sub key of a log file entry under the EventLog key in the registry. For example, "WinApp" is a valid source name if the registry has the following key:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
        EventLog
          Application
            WinApp
          Security
          System
Remarks

Use this function to register a source of logging into the event log. Internally the CNTService class contains a member variable (m_EventLogSource) of type CNTEventLogSource which calls this function in its construction.

See Also
Deregister

 

CNTEventLogSource::Report

BOOL Report(WORD wType, WORD wCategory, DWORD dwEventID, PSID pUserSid, WORD wNumStrings, DWORD dwDataSize, LPCTSTR* pStrings, LPVOID pRawData) const;

BOOL Report(WORD wType, DWORD dwEventID);

BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR pszString);

BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR pszString1, LPCTSTR pszString2);

BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR pszString1, LPCTSTR pszString2, DWORD dwCode, BOOL bReportAsHex = TRUE);

BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR pszString, DWORD dwCode, BOOL bReportAsHex = TRUE);

BOOL Report(WORD wType, DWORD dwEventID, DWORD dwCode, BOOL bReportAsHex = TRUE);

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

wType Specifies the type of event being logged.

wCategory Specifies the event category. This is source-specific information; the category can have any value.

dwEventID Specifies the event. The event identifier specifies the message that goes with this event as an entry in the message file associated with the event source.

pUserSid Pointer to the current user's security identifier. This parameter can be nullptr if the security identifier is not required.

wNumStrings Specifies the number of strings in the array pointed to by the lpStrings parameter. A value of zero indicates that no strings are present.

dwDataSize Specifies the number of bytes of event-specific raw (binary) data to write to the log. If this parameter is zero, no event-specific data is present.

pStrings Pointer to a buffer containing an array of null-terminated strings that are merged into the message from the message file before Event Viewer displays the string to the user. This parameter must be a valid pointer (or nullptr), even if wNumStrings is zero.

pRawData Pointer to the buffer containing the binary data. This parameter must be a valid pointer (or nullptr), even if the dwDataSize parameter is zero.

pszString, pszString1, pszString2 Specifies a single string which will be merged into the message from the message file before Event Viewer displays the string to the user.

dwCode A DWORD value to be put into the event log. Internally the code will convert it to an appropriate string representation.

bReportAsHex Whether or not "dwCode" should be displayed as a hex representation or decimal.

Remarks

These 7 versions of Report, report a message to the event log. The versions are provided to allow the programmer to use the one most suitable for the particular situation at hand.

 

CNTEventLogSource::Deregister

BOOL Deregister();

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Remarks

Call this function to close the handle to the event log. This function will be called in the destructor in case you forget to close the handle yourself.

See Also
Register

 

CNTEventLogSource::Install

static bool Install(LPCTSTR pszLogName, LPCTSTR pSourceName, LPCTSTR pEventMessageFile, LPCTSTR pszEventCategoryMessageFile, LPCTSTR pszParameterMessageFile, DWORD dwTypesSupported, DWORD dwCategoryCount);

static bool Install(LPCTSTR pSourceName, LPCTSTR pEventMessageFile, LPCTSTR pszEventCategoryMessageFile, LPCTSTR pszParameterMessageFile, DWORD dwTypesSupported, DWORD dwCategoryCount);

Return Value

true if the function was successful, otherwise false. To get extended error information, call GetLastError

Parameters

pszLogName The name of the event log to install to. Normally you would use "Application".

pSourceName The name of the service which you want to install an event log source as.

pEventMessageFile The location of the binary where the Message table resource can be located. This can be a standard exe or dll.

pEventCategoryMessageFile Path to the category message file. A category message file contains language-dependent strings that describe the categories.

pEventParameterMessageFile Path to the parameter message file. A parameter message file contains language-independent strings that are to be inserted into the event description strings. This value can be of type REG_SZ or REG_EXPAND_SZ.

dwTypesSupported Specifies a bitmask of supported types.

dwCategoryCount Number of event categories supported

Remarks

Call this function to setup the necessary entries in the registry so that the Event Viewer can correctly locate the message file for messages displayed in the event log. This function is called as part of CNTService::Install using appropriate values.

See Also
Uninstall

 

CNTEventLogSource::Uninstall

static bool Uninstall(LPCTSTR pSourceName);

Return Value

true if the function was successful, otherwise false. To get extended error information, call GetLastError

Remarks

Call this function to remove the entries from the registry which were setup by the method Install.

See Also
Install

 

 

 

CNTService

CNTService is the class which provides a C++ framework upon which you can develop your own C++ based services. The class makes heavy use of virtual functions which your service class should override.

 

Functions this class provides include:

CNTService
~CNTService
WriteProfileString
WriteProfileInt
WriteProfileBinary
WriteProfileStringArray
GetProfileString
GetProfileInt
GetProfileBinary
GetProfileStringArray
ParseCommandLine
ProcessShellCommand
ReportStatus
RegisterCtrlHandler
ServiceCtrlHandler
ServiceMain
OnStop
OnPause
OnContinue
OnInterrogate
OnShutdown
OnUserDefinedRequest
OnParamChange
OnHardwareProfileChange
OnPowerEvent
OnNetBindAdd
OnNetBindRemove
OnNetBindEnable
OnNetBindDisable
OnDeviceEvent
Run
Install
Uninstall
Debug
ShowHelp

EnumerateInstances

 

CNTService::CNTService

CNTService();

CNTService(LPCTSTR pszServiceName, LPCTSTR pszDisplayName, DWORD dwControlsAccepted, LPCTSTR pszDescription = nullptr);

Parameters

pszServiceName Pointer to a null-terminated string that is the internal name of the service.

pszDisplayName Pointer to a null-terminated string that is to be used by user interface programs to identify this service.

dwControlsAccepted Specifies the control codes that the service will accept and process. Any of the standard NT service codes as specified in the Platform SDK can be specified.

pszDescription The textual description of the service. This appears in the new service's MMC snapin in Windows 2000 as the "Description" column. Using this value just means that administrators will see a comment associated with your service. The default value is nullptr which will not insert a description into the registry.

Remarks

This is the standard constructor which initializes a number of internal variables based on the parameters sent in.

See Also
~CNTService

 

CNTService::~CNTService

~CNTService();

Remarks

Standard destructor for the class

See Also
CNTService

 

CNTService::WriteProfileString

bool WriteProfileString(LPCTSTR pszSection, LPCTSTR pszEntry, LPCTSTR pszValue);

bool WriteServiceProfileString(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, LPCTSTR pszValue, BOOL bFlush, DWORD* pLastError);

Return Value

true if successful; otherwise false.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry. If the section does not exist, it is created. The name of the section is case independent; the string may be any combination of uppercase and lowercase letters.

pszEntry Points to a null-terminated string that contains the entry into which the value is to be written. If the entry does not exist in the specified section, it is created.

pszValue Points to the string to be written. If this parameter is nullptr, the entry specified by the pszEntry parameter is deleted.

Remarks

Call this member function to write the specified string into the registry where Services are meant to store their configuration setting i.e. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters.

 

CNTService::WriteProfileInt

bool WriteProfileInt(LPCTSTR pszSection, LPCTSTR pszEntry, int nValue);

bool WriteServiceProfileInt(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, int nValue, bool bFlush, DWORD* pLastError);

Return Value

TRUE if successful; otherwise FALSE.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry. If the section does not exist, it is created. The name of the section is case independent; the string may be any combination of uppercase and lowercase letters.

pszEntry Points to a null-terminated string that contains the entry into which the value is to be written. If the entry does not exist in the specified section, it is created.

nValue Contains the value to be written.

Remarks

Call this member function to write the specified value into the registry where Services are meant to store their configuration setting i.e. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters.

 

CNTService::WriteProfileBinary

bool WriteProfileBinary(LPCTSTR pszSection, LPCTSTR pszEntry, const BYTE* pData, UINT nBytes);

bool WriteServiceProfileBinary(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, const BYTE* pData, UINT nBytes, bool bFlush, DWORD* pLastError = nullptr);

Return Value

true if successful; otherwise false.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry. If the section does not exist, it is created. The name of the section is case independent; the string may be any combination of uppercase and lowercase letters.

pszEntry Points to a null-terminated string that contains the entry into which the value is to be written. If the entry does not exist in the specified section, it is created.

pData Points to the binary data to be written.

nBytes The size of "pData" in bytes.

Remarks

Call this member function to write the specified binary data into the registry where Services are meant to store their configuration setting i.e. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters.

 

CNTService::WriteProfileStringArray

bool WriteProfileStringArray(LPCTSTR pszSection, LPCTSTR pszEntry, const CNTServiceStringArray& array);

bool WriteServiceProfileStringArray(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, const CNTServiceStringArray& array, bool bFlush, DWORD* pLastError = nullptr);

Return Value

true if successful; otherwise false.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry. If the section does not exist, it is created. The name of the section is case independent; the string may be any combination of uppercase and lowercase letters.

pszEntry Points to a null-terminated string that contains the entry into which the value is to be written. If the entry does not exist in the specified section, it is created.

array The CNTServiceStringArray to be written.

Remarks

Call this member function to write the specified string array into the registry where Services are meant to store their configuration setting i.e. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters. The value will be stored as a MULTI_SZ string in the registry.

 

CNTService::GetProfileString

CNTServiceString GetProfileString(LPCTSTR pszSection, LPCTSTR pszEntry, LPCTSTR lpszDefault = nullptr, DWORD* pdwLastError = nullptr);

CNTServiceString GetServiceProfileString(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, LPCTSTR lpszDefault = nullptr, DWORD* pLastError = nullptr);

Return Value

The return value is the string from the registry or pszDefault if the string cannot be found. The maximum string length supported by the framework is _MAX_PATH. If pszDefault is nullptr, the return value is an empty string.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry.

pszEntry Points to a null-terminated string that contains the entry whose string is to be retrieved. This value must not be nullptr.

lpszDefault Points to the default string value for the given entry if the entry cannot be found in the registry.

pdwLastError If this value is non-null, then upon return it will contain the value from the function GetLastError. This allows code to distinguish between a default value which is returned because it is actually stored as opposed to returning a default value because some of the registry API's failed.

Remarks

Call this member function to retrieve the string associated with an entry within the specified section in the registry.

 

CNTService::GetProfileInt

UINT GetProfileInt(LPCTSTR pszSection, LPCTSTR pszEntry, int nDefault, DWORD* pdwLastError = nullptr);

UINT GetServiceProfileInt(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, int nDefault, DWORD* pLastError = nullptr);

Return Value

The integer value of the string that follows the specified entry if the function is successful. The return value is the value of the nDefault parameter if the function does not find the entry.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry.

pszEntry Points to a null-terminated string that contains the entry whose value is to be retrieved.

nDefault Specifies the default value to return if the framework cannot find the entry.

pdwLastError If this value is non-null, then upon return it will contain the value from the function GetLastError. This allows code to distinguish between a default value which is returned because it is actually stored as opposed to returning a default value because some of the registry API's failed.

Remarks

Call this member function to retrieve the value of an integer from an entry within a specified section in the registry.

This member function is not case sensitive, so the strings in the pszSection and pszEntry parameters may differ in case.

 

CNTService::GetProfileBinary

bool GetProfileBinary(LPCTSTR pszSection, LPCTSTR pszEntry, std::vector<BYTE>& data);

bool GetServiceProfileBinary(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, std::vector<BYTE>& data, DWORD* pLastError = nullptr);

Return Value

true if successful; otherwise false.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry.

pszEntry Points to a null-terminated string that contains the entry whose binary data is to be retrieved. This value must not be nullptr.

data Upon successful return, this pointer will contain the binary data read from the registry.

Remarks

Call this member function to set a binary value associated with an entry within the specified section in the registry. Internally the data is stored in the registry as a REG_BINARY value. Note that the caller of the function is responsible for freeing the memory associated with the data in "ppData". This can be achieved using: "delete [] *ppData".

 

CNTService::GetProfileStringArray

bool GetProfileStringArray(LPCTSTR pszSection, LPCTSTR pszEntry, CNTServiceStringArray& array);

bool GetServiceProfileStringArray(LPCTSTR pszService, LPCTSTR pszSection, LPCTSTR pszEntry, CNTServiceStringArray& array, DWORD* pLastError = nullptr);

Return Value

true if successful; otherwise false.

Parameters

pszService Points to a null-terminated string that specifies the service containing the entry.

bFlush Should the setting be flushed to the registry

pLastError If provided this parameter will contain the last error upon return

pszSection Points to a null-terminated string that specifies the section containing the entry.

pszEntry Points to a null-terminated string that contains the entry whose string array is to be retrieved. This value must not be nullptr.

array Upon successful return this will contain the CNTServiceStringArray.

Remarks

Call this member function to retrieve a string array associated with an entry within the specified section in the registry. The value is stored as a MULTI_SZ string in the registry.

 

CNTService::ParseCommandLine

void ParseCommandLine(CNTServiceCommandLineInfo& rCmdInfo);

Parameters

rCmdInfo A reference to a CNTServiceCommandLineInfo object.

Remarks

Call this member function to parse the command line and send the parameters, one at a time, to CNTServiceCommandLineInfo::ParseParam.

 

CNTService::ProcessShellCommand

DWORD ProcessShellCommand(CNTServiceCommandLineInfo& rCmdInfo);

Return Value

The Win32 error code if the shell command fails, otherwise ERROR_SUCCESS (0) if successful.

Parameters

rCmdInfo A reference to a CNTServiceCommandLineInfo object.

Remarks

This member function is called by your InitInstance, main or wmain to accept the parameters passed from the CNTServiceCommandLineInfo object identified by rCmdInfo, and perform the indicated action.

The "m_nShellCommand" data member of the CNTServiceCommandLineInfo object is of the following enumerated type, which is defined within the CNTServiceCommandLineInfo class.

enum class ShellCommand 
{
    RunAsService,
    StartTheService,
    PauseService,
    ContinueService,
    StopService,
    InstallService,
    UninstallService,
    DebugService,
    ShowServiceHelp
};

Please note that prior to v1.39, the return value from this function was a BOOL. Please ensure you review your code to make sure it correctly handles this change.

 

CNTService::ReportStatus

BOOL ReportStatus(DWORD dwCurrentState, std::optional<DWORD> dwCheckPoint = std::optional<DWORD>{}, std::optional<DWORD> dwWaitHint = std::optional<DWORD>{}, std::optional<DWORD> dwControlsAccepted = std::optional<DWORD>{});

BOOL ReportStatus();

Return Value

TRUE if the SCM was notified successfully of this services state otherwise FALSE. To get extended error information, call GetLastError

Parameters

dwCurrentState Indicates the current state of the service.

dwWin32ExitCode Specifies an Win32 error code that the service uses to report an error that occurs when it is starting or stopping. To return an error code specific to the service, the service must set this value to ERROR_SERVICE_SPECIFIC_ERROR to indicate that the dwServiceSpecificExitCode member contains the error code. The service should set this value to NO_ERROR when it is running and on normal termination.

dwServiceSpecificExitCode Specifies a service specific error code that the service returns when an error occurs while the service is starting or stopping. This value is ignored unless the dwWin32ExitCode member is set to ERROR_SERVICE_SPECIFIC_ERROR.

dwCheckPoint Specifies a value that the service increments periodically to report its progress during a lengthy start, stop, pause, or continue operation. For example, the service should increment this value as it completes each step of its initialization when it is starting up. The user interface program that invoked the operation on the service uses this value to track the progress of the service during a lengthy operation. This value is not valid and should be empty when the service does not have a start, stop, pause, or continue operation pending.

dwWaitHint Specifies an estimate of the amount of time, in milliseconds, that the service expects a pending start, stop, pause, or continue operation to take before the service makes its next call to the SetServiceStatus function with either an incremented dwCheckPoint value or a change in dwCurrentState. If the amount of time specified by dwWaitHint passes, and dwCheckPoint has not been incremented, or dwCurrentState has not changed, the service control manager or service control program can assume that an error has occurred.

dwControlsAccepted Specifies the control codes that the service will accept and process. Any of the standard NT service codes as specified in the Platform SDK can be specified. These are the same codes as specified in the CNTService constructor.

Remarks

These two functions report the current state of the service back to the service control manager. The first version uses the parameters specified to report to the SCM. The second version uses the existing state of the service when reporting to the SCM.

 

CNTService::RegisterCtrlHandler

BOOL RegisterCtrlHandler();

Return Value

TRUE if the Control handler for this service was successfully registered otherwise FALSE. To get extended error information, call GetLastErrorr

Remarks

This function is called automatically for you prior to the framework calling your ServiceMain code, so there is normally no need to call this function yourself. This function setups up the function on which the SCM will callback on when making requests to the service. Internally when a request is made it will be routed to the appropriate virtual function.

See Also
ServiceCtrlHandler

 

CNTService::ServiceCtrlHandler

DWORD ServiceCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID pEventData)

Parameters

dwControl Specifies the requested control code.

dwEventType The type of event that has occurred. pEventData Additional device information, if required

 

Remarks

This function is called into by the SCM and internally it delegates to the appropriate virtual function. For example if a  SERVICE_CONTROL_STOP request arrives then this function will call the virtual OnStop function. This function will not normally have to be overridden in your derived class. Please bear in mind that this function will be called in the context on the main thread on your service and not the thread in which your service does it main work (its ServiceMain handler).

 

CNTService::ServiceMain

virtual void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* pszArgv);

Parameters

dwArgc Specifies the number of arguments in the lpszArgv array.

pszArgv Pointer to an array of pointers that point to null-terminated argument strings. The first argument in the array is the name of the service, and subsequent arguments are any strings passed to the service by the process that called the CScmService::Start function to start the service.

Remarks

In your derived class you are responsible for writing your own ServiceMain function for your service

When a service control program requests that a new service run, the SCM starts the service and sends a start request to the control dispatcher. The control dispatcher creates a new thread to execute the ServiceMain function for the service.

The ServiceMain function should perform the following tasks:

  1. Perform initialisation. If the execution time of the initialisation code is expected to be very short (less than one second), initialisation can be performed directly in ServiceMain, if not you should report back to the SCM using the state START_PENDING. Check the sample service for the details on how this is done.
  2. When initialisation is complete, call SetServiceStatus, specifying the SERVICE_RUNNING state in the SERVICE_STATUS structure.
  3. Perform the service tasks, or, if there are no pending tasks, return. Any change in the state of the service warrants a call to ReportStatusToSCM to report new status information.
  4. If an error occurs while the service is initializing or running, the service should call ReportStatusToSCM specifying the SERVICE_STOP_PENDING state, if cleanup will be lengthy. Once cleanup is complete, call ReportStatusToSCM from the last thread to terminate, specifying SERVICE_STOPPED in the SERVICE_STATUS structure. Be sure to set the dwServiceSpecificExitCode and dwWin32ExitCode members of the SERVICE_STATUS structure to identify the error.

 

CNTService::OnStop

virtual void OnStop();

Remarks

This function will be called whenever a SERVICE_CONTROL_STOP request comes in from the SCM. Your derived class should do whatever is necessary to cause your service to stop.

 

CNTService::OnPause

virtual void OnPause();

Remarks

This function will be called whenever a SERVICE_CONTROL_PAUSE request comes in from the SCM. Your derived class should do whatever is necessary to cause your service to pause.

 

CNTService::OnContinue

virtual void OnContinue();

Remarks

This function will be called whenever a SERVICE_CONTROL_CONTINUE request comes in from the SCM. Your derived class should do whatever is necessary to cause your service to continue.

 

CNTService::OnInterrogate

virtual void OnInterrogate();

Remarks

This function will be called whenever a SERVICE_CONTROL_INTERROGATE request comes in from the SCM. The default implementation just calls ReportStatusToSCM to inform the SCM.

 

CNTService::OnShutdown

virtual void OnShutdown();

Remarks

This function will be called whenever a SERVICE_CONTROL_SHUTDOWN comes in from the SCM.  Your derived class should do whatever is necessary to cause your service to shutdown.

 

CNTService::OnUserDefinedRequest

virtual void OnUserDefinedRequest(DWORD dwControl);

Remarks

This function will be called whenever a user defined request comes in from the SCM.  Your derived class should do whatever is appropriate for its service. In the example service provided, it simply changes the frequency of beeps emitted by the service.

 

CNTService::OnParamChange

virtual void OnParamChange();

Remarks

Notifies the service that service-specific startup parameters have changed. The service should reread its startup parameters. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnHardwareProfileChange

virtual DWORD OnHardwareProfileChange(DWORD dwEventType, LPVOID pEventData);

Return Value

return NO_ERROR to grant the request and an error code to deny the request.

Parameters

dwEventType this parameter can be one of the following values: DBT_CONFIGCHANGED, DBT_QUERYCHANGECONFIG, or DBT_CONFIGCHANGECANCELED.

pEventData Additional device information, if required. The format of this data depends on the value of dwEventType parameter.

Remarks

Notifies the service that the computer's hardware profile has changed. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnPowerEvent

virtual DWORD OnPowerEvent(DWORD dwEventType, LPVOID pEventData);

Return Value

return NO_ERROR to grant the request and an error code to deny the request.

Parameters

dwEventType this parameter can be one of the values specified in the wParam value of the WM_POWERBROADCAST message.

pEventData This data corresponds to the lParam value that applications receive as part of a WM_POWERBROADCAST message.

Remarks

Notifies the service of system power events. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnNetBindAdd

virtual void OnNetBindAdd();

Remarks

Notifies a network service that there is a new component for binding. The service should bind to the new component. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnNetBindRemove

virtual void OnNetBindRemove();

Remarks

Notifies a network service that a component for binding has been removed. The service should reread its binding information and unbind from the removed component. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnNetBindEnable

virtual void OnNetBindEnable();

Remarks

Notifies a network service that a disabled binding has been enabled. The service should reread its binding information and add the new binding. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnNetBindDisable

virtual void OnNetBindDisable();

Remarks

Notifies a network service that one of its bindings has been disabled. The service should reread its binding information and remove the binding. This is only called when the service is running on Windows 2000 or later.

 

CNTService::OnDeviceEvent

virtual DWORD OnDeviceEvent(DWORD dwEventType, LPVOID pEventData);

Return Value

return NO_ERROR to grant the request and an error code to deny the request.

Parameters

dwEventType this parameter can be one of the following values: DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE, DBT_DEVICEQUERYREMOVE, DBT_DEVICEQUERYREMOVEFAILED, DBT_DEVICEREMOVEPENDING, or DBT_CUSTOMEVENT

pEventData This data corresponds to the lParam value that applications receive as part of a WM_DEVICECHANGE message.

Remarks

Notifies the service of device events. The service must register to receive these notifications by using the RegisterDeviceNotification function. This is only called when the service is running on Windows 2000 or later.

 

CNTService::Run

virtual bool Run();

Remarks

Calling this function will cause a service to start running. Internally it will set up an appropriate SERVICE_TABLE_ENTRY array and call StartServiceCtrlDispatcher to kick of the service. You would normally call this in your main, wmain or InitInstance. If you are using the CNTServiceCommandLineInfo class and ParseCommandLine and ProcessShellCommand member functions of CNTService then there is no need to call this function.

 

CNTService::Install

virtual bool Install(CNTServiceString& sErrorMsg, DWORD& dwError);

Remarks

This will install a service. Internally it will call into the SCM API to set this service up as an On demand service with no dependencies. It will also install the service so that it can report events to the event log as well as letting Event Viewer filter using the friendly name of the service. This function will be called internally by the CNTServiceCommandLineInfo if "/install" is specified on the command line.

 

CNTService::Uninstall

virtual bool Uninstall(CNTServiceString& sErrorMsg, DWORD& dwError, DWORD dwTimeToWaitForStop);

Remarks

The is the corollary function of Install and will remove the service from the SCM database and unregister its' event log registry entries. Please bear in mind that once this is done, event viewer will no longer be able to correctly display any messages the service generated while it was installed. the CNTServiceCommandLineInfo if "-uninstall" or "-remove" is specified on the command line.

 

CNTService::Debug

virtual void Debug();

Remarks

This will run a service without interacting with the SCM, in effect a "debug" or "Application" mode. This helps when testing your application as it will stop the SCM from timing out your service as it is being debugged. Internally this function will just call the ServiceMain function of your class. Remember that in this case your service code will be running in the same thread as the main thread so it may mask problems which only arise when the code is executed as a real service. This function will be called internally by CNTServiceCommandLineInfo if "/debug", /Application or /App is specified on the command line.

 

CNTService::ShowHelp

virtual void ShowHelp();

Remarks

This function will be called internally by CNTServiceCommandLineInfo if "-help" or "-?" is specified on the command line. It is up to you to either print some message to the console if you are developing a console mode service or display some helpful window if its a GUI app. The sample service simply displays a message using AfxMessageBox as it was developed using the GUI subsystem.

 

CNTService::EnumerateInstances

virtual bool EnumerateInstances(CNTServiceStringArray& ServiceNames, DWORD& dwError);

Return Value

true if successful; otherwise false.

Parameters

ServiceNames Upon return will contain all the service name instances for this service.

dwError Will contain the last error code upon return.

Remarks

Call this member function to enumerate all instances of the service. This could prove useful where you are writing configuration type applets which configure the settings for all the instances of your installed service.

 

 

 

CNTScmService

CNTScmService is a class which encapsulates a service as returned from the Service Control Manager, in effect a SC_HANDLE. An instance of a CNTScmService is usually acquired by a call to CNTServiceControlManager::Open. Once retrieved the class allows you to control the service, change its configuration and query a service's state.

 

Functions this class provides include:

CNTScmService
~CNTScmService
Close
operator SC_HANDLE
Attach
Detach
ChangeConfig
Control
Stop
Pause
Continue
Interrogate
Start
QueryStatus
QueryConfig
Create
Delete
EnumDependents
QueryObjectSecurity
SetObjectSecurity
ChangeDescription
QueryDescription
QueryFailureActions
ChangeFailureActions

ChangeDelayAutoStart
QueryDelayAutoStart
ChangeFailureActionsFlag
QueryFailureActionsFlag
ChangeSidType
QuerySidType
ChangeRequiredPrivileges
QueryRequiredPrivileges
ChangePreShutdown
QueryPreShutdown
ChangeTrigger
QueryTrigger
ChangePreferredNode
QueryPreferredNode
NotifyStatusChange

SubscribeChangeNotifications
UnsubscribeChangeNotifications
WaitState

 

 

CNTScmService::CNTScmService

CNTScmService();

Remarks

This is the default constructor which just initializes all internal variables to a safe state.

See Also
~CNTScmService

 

CNTScmService::~CNTScmService

~CNTScmService();

Remarks

This is the standard destructor for the class. Internally it will call Close to ensure that any handle that is opened by this instance is closed

See Also
CNTScmService Close

 

CNTScmService::Close

void Close();

Remarks

This frees the SC_HANDLE by internally calling CloseServiceHandle which this class encapsulates.

 

CNTScmService::operator SC_HANDLE

operator SC_HANDLE() const;

Return Value:

The underlying SDK service handle representing this class.

Remarks

This function exposes the underlying handle which the CNTScmService class wraps. This function is provided for integration with legacy code which uses the handle directly.

 

CNTScmService::Attach

void Attach(SC_HANDLE hService);

Parameters

hService An SDK service handle returned from SDK calls to the SCM APIs

Remarks

Use this member function to attach an existing SDK handle to a CNTScmService.

See Also
Detach

 

CNTScmService::Detach

SC_HANDLE Detach();

Return Value

The SDK service handle

Remarks

Call this function to detach m_hService from the CNTScmService object and  set m_hService to nullptr.

See Also
Attach

 

CNTScmService::ChangeConfig

BOOL ChangeConfig(DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR pBinaryPathName, LPCTSTR pLoadOrderGroup, LPDWORD pdwTagId, LPCTSTR pDependencies, LPCTSTR pServiceStartName, LPCTSTR pPassword, LPCTSTR pDisplayName) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig. See the SDK for full details on this function.

 

CNTScmService::Control

BOOL Control(DWORD dwControl);
DWORD Control(DWORD
dwControl, DWORD dwInfoLevel, PVOID pControlParams)

Parameters

dwControl Specifies the control code to send to this service.

Remarks

This is a simple wrapper for the SDK call ControlService. The version which has three parameters is a simple wrapper for the SDK call COntrolServiceEX.

 

CNTScmService::Stop

BOOL Stop() const;

Remarks

This is a simple wrapper for calling Control with the parameter SERVICE_CONTROL_STOP

 

CNTScmService::Pause

BOOL Pause() const;

Remarks

This is a simple wrapper for calling Control with the parameter SERVICE_CONTROL_PAUSE

 

CNTScmService::Continue

BOOL Continue() const;

Remarks

This is a simple wrapper for calling Control with the parameter SERVICE_CONTROL_CONTINUE

 

CNTScmService::Interrogate

BOOL Interrogate() const;

Remarks

This is a simple wrapper for calling Control with the parameter SERVICE_CONTROL_INTERROGATE

 

CNTScmService::Start

BOOL Start(DWORD dwNumServiceArgs, LPCTSTR* pServiceArgVectors) const;

Parameters

dwNumServiceArgs Specifies the number of argument strings in the lpServiceArgVectors array. If lpServiceArgVectors is nullptr, this parameter can be zero.

pServiceArgVectors Pointer to an array of pointers that point to null-terminated argument strings passed to a service. Driver services do not receive these arguments. If no arguments are passed to the service being started, this parameter can be nullptr.

Return Values

TRUE If the function succeeds otherwise FALSE. To get extended error information, call GetLastError.

Remarks

Starts this service with the specified parameters.

 

CNTScmService::QueryStatus

BOOL QueryStatus(SERVICE_STATUS& ServiceStatus) const;

BOOL QueryStatus(SERVICE_STATUS_PROCESS& ssp) const;

Parameters

ServiceStatus Upon a successful return from this function, ServiceStatus will contain the current status of this service.

ssp Upon a successful return from this function, ssp will contain detailed info about the current status of this service.

Return Values

TRUE If the function succeeds otherwise FALSE. To get extended error information, call GetLastError.

Remarks

Queries this service for its current status. The overridden version which takes a SERVICE_STATUS_PROCESS structure is only available on Windows 2000.

 

CNTScmService::QueryConfig

BOOL QueryConfig(CNTServiceConfig& config) const;

Parameters

config Upon a successful return from this function, this will contain the current configuration of this service accessible via an operator LPQUERY_SERVICE_CONFIG() method.

Return Values

TRUE If the function succeeds otherwise FALSE. To get extended error information, call GetLastError.

Remarks

Queries this service for its current configuration.

 

CNTScmService::Create

BOOL Create(CNTServiceControlManager& Manager, LPCTSTR pServiceName, LPCTSTR pDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR pBinaryPathName, LPCTSTR pLoadOrderGroup, LPDWORD pdwTagId, LPCTSTR pDependencies, LPCTSTR pServiceStartName, LPCTSTR pPassword);

Remarks

This is a simple wrapper for the SDK call CreateService. See the SDK for full details on this function.

 

CNTScmService::Delete

BOOL Delete() const;

Remarks

This is a simple wrapper for the SDK call DeleteService. See the SDK for full details on this function.

 

CNTScmService::EnumDependents

BOOL EnumDependents(DWORD dwServiceState, DWORD dwUserData, ENUM_SERVICES_PROC pEnumServicesFunc) const;

Parameters

dwServiceState Specifies the services to enumerate based on their running state.

dwUserData Any user defined DWORD which you want to send to the callback function.

pEnumServicesFunc pointer to a callback function to use to enumerate the dependent services

Remarks

This function allows you to enumerate the services upon which this service is dependent. Internally this calls EnumDependentServices and calls the callback function for each service. The format of the callback function is:

BOOL CALLBACK ENUM_SERVICES_PROC(DWORD dwData, ENUM_SERVICE_STATUS& ServiceStatus);

dwData This is the value as send into the Enumeration function

ServiceStatus Contains the information related to the enumerated service. See the SDK documentation for further details.

Return TRUE from the function to continue enumeration and FALSE to stop enumeration

 

CNTScmService::QueryObjectSecurity

BOOL QueryObjectSecurity(SECURITY_INFORMATION dwSecurityInformation, CNTServiceSecurityDescriptor& securityDescriptor) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceObjectSecurity. See the SDK for full details on this function.

 

CNTScmService::SetObjectSecurity

BOOL SetObjectSecurity(SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR& pSecurityDescriptor) const;

Remarks

This is a simple wrapper for the SDK call SetServiceObjectSecurity. See the SDK for full details on this function. Bear in mind that since the PSECURITY_DESCRIPTOR is a variable sized structure, internally this function will allocate the required memory for pSecurityDescriptor, It is the responsibility of the client to delete this structure. This can be done as follows:

PSECURITY_DESCRIPTOR pDescriptor = nullptr;
service.QueryObjectSecurity(whatever, pDescriptor);
delete [] reinterpret_cast<BYTE*>(pDescriptor);

 

CNTScmService::ChangeDescription

BOOL ChangeDescription(const CNTServiceString& sDescription);

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_DESCRIPTION. See the SDK for full details on this function.

 

CNTScmService::QueryDescription

BOOL QueryDescription(CNTServiceString& sDescription) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_DESCRIPTION. See the SDK for full details on this function.

 

CNTScmService::ChangeFailureActions

BOOL ChangeFailureActions(LPSERVICE_FAILURE_ACTIONS* pFailureActions);

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_FAILURE_ACTIONS. See the SDK for full details on this function.

 

CNTScmService::QueryFailureActions

BOOL QueryFailureActions(CNTServiceFailureActions& actions) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_FAILURE_ACTIONS. See the SDK for full details on this function.

 

CNTScmService::ChangeDelayAutoStart

BOOL ChangeDelayAutoStart(BOOL bDelayedAutoStart) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_DELAYED_AUTO_START_INFO. See the SDK for full details on this function.

 

CNTScmService::QueryDelayAutoStart

BOOL QueryDelayAutoStart(BOOL& bDelayedAutoStart) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_DELAYED_AUTO_START_INFO. See the SDK for full details on this function.

 

CNTScmService::ChangeFailureActionsFlag

BOOL ChangeFailureActionsFlag(BOOL bFailureActionsOnNonCrashFailure) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_FAILURE_ACTIONS_FLAG. See the SDK for full details on this function.

 

CNTScmService::QueryFailureActionsFlag

BOOL QueryFailureActionsFlag(BOOL& bFailureActionsOnNonCrashFailure) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_FAILURE_ACTIONS_FLAG . See the SDK for full details on this function.

 

CNTScmService::ChangeSidType

BOOL ChangeSidType(DWORD dwServiceSidType) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_SERVICE_SID_INFO. See the SDK for full details on this function.

 

CNTScmService::QuerySidType

BOOL QuerySidType(DWORD& dwServiceSidtype) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_SERVICE_SID_INFO. See the SDK for full details on this function.

 

CNTScmService::ChangeRequiredPrivileges

BOOL ChangeRequiredPrivileges(const CNTServiceStringArray& privileges) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO. See the SDK for full details on this function.

 

CNTScmService::QueryRequiredPrivileges

BOOL QueryRequiredPrivileges(CNTServiceStringArray& dwServiceSidtype) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO. See the SDK for full details on this function.

 

CNTScmService::ChangePreShutdown

BOOL ChangePreShutdown(DWORD dwPreShutdownTimeout) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_PRESHUTDOWN_INFO. See the SDK for full details on this function.

 

CNTScmService::QueryPreShutdown

BOOL QueryPreShutdown(DWORD& dwPreShutdownTimeout) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_PRESHUTDOWN_INFO. See the SDK for full details on this function.

 

CNTScmService::ChangeTrigger

BOOL ChangeTrigger(PSERVICE_TRIGGER_INFO* pTriggerInfo);

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_TRIGGER_INFO. See the SDK for full details on this function.

 

CNTScmService::QueryTrigger

BOOL QueryTrigger(CNTServiceTriggerInfo& triggerInfo) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_TRIGGER_INFO. See the SDK for full details on this function.

 

CNTScmService::ChangePreferredNode

BOOL ChangePreferredNode(USHORT usPreferredNode, BOOL bDelete) const;

Remarks

This is a simple wrapper for the SDK call ChangeServiceConfig2 using the info level SERVICE_CONFIG_PREFERRED_NODE. See the SDK for full details on this function.

 

CNTScmService::QueryPreferredNode

BOOL QueryPreShutdown(USHORT& usPrefrredNode, BOOL& bDelete) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceConfig2 using the info level SERVICE_CONFIG_PREFERRED_NODE. See the SDK for full details on this function.

 

CNTScmService::NotifyStatusChange

BOOL NotifyStatusChange(DWORD udwNotifyMask, BPSERVICE_NOTIFY pNotifyBuffer) const;

Remarks

This is a simple wrapper for the SDK call NotifyServiceStatusChange. See the SDK for full details on this function.

 

CNTScmService::SubscribeChangeNotifications

DWORD SubscribeServiceChangeNotifications(SC_EVENT_TYPE eEventType, PSC_NOTIFICATION_CALLBACK pCallback, PVOID pCallbackContext, PSC_NOTIFICATION_REGISTRATION* pSubscription) const;

Remarks

This is a simple wrapper for the SDK call SubscribeServiceChangeNotifications. See the SDK for full details on this function.

 

CNTScmService::UnsubscribeChangeNotifications

BOOL UnsubscribeChangeNotifications(PSC_NOTIFICATION_REGISTRATION pSubscription) const;

Remarks

This is a simple wrapper for the SDK call UnsubscribeServiceChangeNotifications. See the SDK for full details on this function.

 

CNTScmService::WaitStatus

BOOL WaitStatus(DWORD dwNotify, DWORD dwTimeout, HANDLE hCancelEvent) const;

Remarks

This is a simple wrapper for the SDK call WaitServiceStatus. See the SDK for full details on this function.

 

 

CNTServiceControlManager

CNTServiceControlManager is a class which encapsulates a connection to a Service Control Manager (SCM) on some machine. Functionality provided includes enumeration, database locking and service access.

 

Functions this class provides include:

CNTServiceControlManager
~CNTServiceControlManager
operator HANDLE
Attach
Detach
Open
Close
QueryLockStatus
EnumServices
OpenService
Lock
Unlock

 

CNTServiceControlManager::CNTServiceControlManager

CNTServiceControlManager();

Remarks

This is the default constructor which just initializes all internal variables to a safe state.

See Also
~CNTServiceControlManager

 

CNTServiceControlManager::~CNTServiceControlManager

~CNTServiceControlManager();

Remarks

This is the standard destructor for the class. Internally it will call Close to ensure that any handle that is opened by this instance is closed

See Also
Close

 

CNTServiceControlManager::operator HANDLE

operator SC_HANDLE() const;

Return Value:

The underlying SDK service handle representing this class.

Remarks

This function exposes the underlying handle which the CNTServiceControlManager class wraps. This function is provided for integration with legacy code which uses the handle directly.

 

CNTServiceControlManager::Attach

void Attach(SC_HANDLE hSCM);

Parameters

hSCM An SDK service control manager handle returned from SDK calls to the SCM APIs

Remarks

Use this member function to attach an existing SDK handle to a CNTServiceControlManager.

See Also
Detach

 

CNTServiceControlManager::Detach

SC_HANDLE Detach();

Return Value

The SDK service control manager handle

Remarks

Call this function to detach m_hSCM from the CNTServiceControlManager object and  set m_hSCM to nullptr.

See Also
Attach

 

CNTServiceControlManager::Open

BOOL Open(LPCTSTR pszMachineName, DWORD dwDesiredAccess);

Remarks

This is a simple wrapper for the SDK call OpenSCManager. See the SDK for full details on this function.

 

CNTServiceControlManager::Close

void Close();

Remarks

This frees the SC_HANDLE by internally calling CloseServiceHandle which this class encapsulates.

 

CNTServiceControlManager::QueryLockStatus

BOOL QueryLockStatus(CNTServiceControlManagerLockStatus& lockStatus) const;

Remarks

This is a simple wrapper for the SDK call QueryServiceLockStatus. See the SDK for full details on this function.

 

CNTServiceControlManager::EnumServices

BOOL EnumServices(DWORD dwServiceType, DWORD dwServiceState, void* pUserData, ENUM_SERVICES_PROC pEnumServicesFunc) const;

BOOL EnumServices(DWORD dwServiceType, DWORD dwServiceState, LPCTSTR pszGroupName, void* pUserData, ENUM_SERVICES_PROC2 pEnumServicesFunc) const;

Parameters

dwServiceType Specifies the type of services to enumerate.

dwServiceState Specifies the services to enumerate based on their running state.

pUserData Any user defined void* which you want to send to the callback function.

pszGroupName Specifies a load-order group name. If this parameter is a string, the only services enumerated are those that belong to the group that has the name specified by the string. If this parameter is an empty string, only services that do not belong to any group are enumerated. If this parameter is nullptr, group membership is ignored and all services are enumerated.

pEnumServicesFunc pointer to a callback function to use to enumerate the dependent services

Remarks

This function allows you to enumerate the services which in the SCM. Internally this calls EnumServicesStatus or (EnumServicesStatusEx) and calls the callback function for each service. The format of the callback functions are:

typedef BOOL CALLBACK ENUM_SERVICES_PROC(void* pData, const ENUM_SERVICE_STATUS& ServiceStatus);

typedef BOOL CALLBACK ENUM_SERVICES_PROC2(void* pData, const ENUM_SERVICE_STATUS_PROCESS& ssp);

pData This is the value as send into the enumeration function

ServiceStatus Contains the information related to the enumerated service. See the SDK documentation for further details.

ssp Contains the information related to the enumerated service. See the SDK documentation for further details.

Return TRUE from the function to continue enumeration and FALSE to stop enumeration

 

CNTServiceControlManager::OpenService

BOOL OpenService(LPCTSTR pServiceName, DWORD dwDesiredAccess, CNTScmService& service) const;

Remarks

This is a simple wrapper for the SDK call of the same name. See the SDK for full details on this function.

 

CNTServiceControlManager::Lock

BOOL Lock();

Remarks

This is a simple wrapper for the SDK call LockServiceDatabase. See the SDK for full details on this function.

 

CNTServiceControlManager::Unlock

BOOL Unlock();

Remarks

This is a simple wrapper for the SDK call UnlockServiceDatabase. See the SDK for full details on this function.

 

 

CEventLogRecord

CEventLogRecord is a C++ wrapper class for the EVENTLOGRECORD structure as provided in the SDK. For anyone who has had to use this class using raw SDK calls, you will appreciate the easier access which the class provides.

 

Functions and members this class provides include:

CEventLogRecord
operator=
m_dwRecordNumber
m_dwTimeGenerated
m_dwTimeWritten
m_dwEventID
m_wEventTypes
m_wEventCategory
m_UserSID
m_Strings
m_Data
m_sSourceName
m_sComputerName

 

CEventLogRecord::CEventLogRecord

CEventLogRecord();

CEventLogRecord(const CEventLogRecord& record);

CEventLogRecord(const EVENTLOGRECORD* pRecord);

Parameters

record An existing CEventLogRecord

pRecord An existing SDK EVENTLOGRECORD structure

 

CEventLogRecord::operator=

CEventLogRecord& operator=(const CEventLogRecord& record);

Remarks

The standard copy constructor

 

CEventLogRecord::m_dwRecordNumber

DWORD m_dwRecordNumber;

Remarks

Contains the record number for this event log entry

 

CEventLogRecord::m_dwTimeGenerated

DWORD m_dwTimeGenerated;

Remarks

The number of seconds since 1/1/1970 UCT since this entry was submitted.

 

CEventLogRecord::m_dwTimeWritten

DWORD m_TimeWritten;

Remarks

The number of seconds since 1/1/1970 UCT since this entry was written to the event log.

 

CEventLogRecord::m_dwEventID

DWORD m_dwEventID;

Remarks

Specifies the event. This is specific to the source that generated the event log entry, and is used, together with SourceName, to identify a message in a message file that is presented to the user while viewing the log.

 

CEventLogRecord::m_wEventTypes

WORD m_wEventType;

Remarks

Specifies the type of event.

 

CEventLogRecord::m_wEventCategory

WORD m_wEventCategory;

Remarks

Specifies a subcategory for this event. This subcategory is source specific.

 

CEventLogRecord::m_UserSID

std::vector<BYTE> m_UserSID;

Remarks

A byte array representation of the security identifier of the active user at the time this event was logged.

 

CEventLogRecord::m_Strings

CNTServiceStringArray m_Strings;

Remarks

A CNTServiceStringArray representation of the strings which are merged into the message before it is displayed to the user.

 

CEventLogRecord::m_Data

std::vector<BYTE> m_Data;

Remarks

A byte array representation of the event-specific information within this event record.

 

CEventLogRecord::m_sSourceName

CNTServiceString m_sSourceName;

Remarks

Contains the string specifying the name of the source (application, service, driver, subsystem) that generated the entry.

 

CEventLogRecord::m_sComputerName

CNTServiceString m_sComputerName;

Remarks

Contains the string specifying the name of the computer that generated this event.

 

 

 

CNTEventLog

CNTEventLog is a C++ wrapper class for accessing the NT Event Logs. You can consider this as the client side to the Event Log APIs.

 

Functions this class provides include:

CNTEventLog
~CNTEventLog
operator HANDLE
Attach
Detach
Open
OpenBackup
OpenApplication
OpenSystem
OpenSecurity
Close
Backup
Clear
GetNumberOfRecords
GetOldestRecord
NotifyChange
ReadNext
ReadPrev

GetFullInformation

 

CNTEventLog::CNTEventLog

CNTEventLog();

Remarks

This is the default constructor which just initializes all internal variables to a safe state.

See Also
~CNTEventLog

 

CNTEventLog::~CEventLog

~CNTEventLog();

Remarks

This is the standard destructor for the class. Internally it will call Close to ensure that any handle that is opened by this instance is closed

See Also
Close

 

CNTEventLog::operator HANDLE

operator HANDLE() const;

Return Value:

The underlying SDK event log handle representing this class.

Remarks

This function exposes the underlying handle which CNTEventLog class wraps. This function is provided for integration with legacy code which uses the handle directly.

 

CNTEventLog::Attach

void Attach(HANDLE hEventLog);

Parameters

hEventLog An SDK event log handle returned from SDK calls to the Event log APIs

Remarks

Use this member function to attach an existing SDK handle to a CNTEventLog.

See Also
Detach

 

CNTEventLog::Detach

HANDLE Detach();

Return Value

The SDK event log handle

Remarks

Call this function to detach m_hEventLog from the CNTEventLog object and  set m_hEventLog to nullptr.

See Also
Attach

 

CNTEventLog::Open

BOOL Open(LPCTSTR pUNCServerName, LPCTSTR pSourceName);

Remarks

This is a simple wrapper for the SDK call OpenEventLog. See the SDK for full details on this function.

 

CNTEventLog::OpenBackup

BOOL OpenBackup(LPCTSTR pUNCServerName, LPCTSTR pFileName);

Remarks

This is a simple wrapper for the SDK call OpenBackupEventLog. See the SDK for full details on this function.

 

CNTEventLog::OpenApplication

BOOL OpenApplication(LPCTSTR pUNCServerName);

Remarks

This is a sample wrapper for opening the "Application" event log on the specified computer, Internally it just calls Open with the appropriate string "Application".

 

CNTEventLog::OpenSystem

BOOL OpenSystem(LPCTSTR pUNCServerName);

Remarks

This is a sample wrapper for opening the "system" event log on the specified computer, Internally it just calls Open with the appropriate string "System".

 

CNTEventLog::OpenSecurity

BOOL OpenSecurity(LPCTSTR pUNCServerName);

Remarks

This is a sample wrapper for opening the "Security" event log on the specified computer, Internally it just calls Open with the appropriate string "Security".

 

CNTEventLog::Close

BOOL Close();

Remarks

This frees the HANDLE by internally calling CloseEventLog which this class encapsulates.

 

CNTEventLog::Backup

BOOL Backup(LPCTSTR pBackupFileName) const;

Remarks

This is a simple wrapper for the SDK call BackupeventLog. See the SDK for full details on this function.

 

CNTEventLog::Clear

BOOL Clear(LPCTSTR pBackupFileName) const;

Remarks

This is a simple wrapper for the SDK call ClearEventLog. See the SDK for full details on this function.

 

CNTEventLog::GetNumberOfRecords

BOOL GetNumberOfRecords(DWORD& dwNumberOfRecords) const;

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

dwNumberOfRecords Upon successful return this will contain the number of records in the event log.

Remarks

This is a simple wrapper for the SDK call GetNumberOfEventLogRecords. See the SDK for full details on this function.

 

CNTEventLog::GetOldestRecord

BOOL GetOldestRecord(DWORD& dwOldestRecord) const;

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

dwOldestRecord Upon successful return this will contain the record number of the oldest record in the event log.

Remarks

This is a simple wrapper for the SDK call GetOldestEventLogRecord. See the SDK for full details on this function.

 

CNTEventLog::NotifyChange

BOOL NotifyChange(HANDLE hEvent) const;

Remarks

This is a simple wrapper for the SDK call NotifyChangeEventLog. See the SDK for full details on this function.

 

CNTEventLog::ReadNext

BOOL ReadNext(CEventLogRecord& record) const;

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

record Upon successful return this will contain the next record in the event log

Remarks

Reads the next record in forward chronological order from the event log. When this function returns successfully, the read position is incremented by one ready for the next read to occur.

 

CNTEventLog::ReadPrev

BOOL ReadPrev(CEventLogRecord& record) const;

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

record Upon successful return this will contain the previous record in the event log

Remarks

Reads the next record in reverse chronological order from the event log. When this function returns successfully, the read position is decremented by one ready for the next read to occur.

 

CNTEventLog::GetFullInformation

BOOL GetFullInformation(DWORD& dwFull) const;

Return Value

TRUE if the function was successful, otherwise FALSE. To get extended error information, call GetLastError

Parameters

dwFull Indicates whether the event log is full. If the log is full, this member is TRUE. Otherwise, it is FALSE.

Remarks

This is a simple wrapper for the SDK call GetEventLogInformation using the InfoLevel of EVENTLOG_FULL_INFO. See the SDK for full details on this function.

 

 

 

References

 

 

 

Contacting the Author

PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
28 March 2024