SoftwareShield System Feature Guide > Testing and Debugging Support > Controlling Debug Output

Controlling Debug Output


When using the SoftwareShield System, you may need to get debug feedback from the ClientProtector COM server about what is happening "under the hood" in order to help you developing licensing solutions and especially - debugging. The ClientProtector provides you with two mechanisms for controlling debug output:

  1. The Debug ClientProtector Server and Debug Flags.

  2. The ReturnCodeToMessage function.

ClientProtector Debug Server and "DebugFlags"

The ClientProtector component is contained in an in-proc COM server dll. That dll ships in two versions (a release version: SSCProt.dll and a debug version: SSCProtD.dll). While debugging your applications, you can register the debug server and by using a bit-field of debug flags, control a great deal of debugging information output from the ClientProtector. The debug flag values themselves are a set of enumerated constants which the server exposes (in enumeration CPDEBUGFLAGS).

Only the debug server supports outputting debug messages using debug flags. Although the "DebugFlags" parameter in the StartUp function is identical in the release server - the DebugFlags parameter value is simply ignored in the release server. While the interfaces have been designed to be completely interchangeable, allowing you to simply switch which server is registered on a machine without making changes to your code, we recommend that prior to your final release, you ensure that the parameter your code passes in "DebugFlags" is set to zero.

The messages that are output using DebugFlags are simply descriptive messages that tell you what is happening, about to happen or what important logical conditions have just occurred. This helps you understand why your licensing function is behaving in a certain way. When used by the developer in conjunction with the ClientProtector Control Flow-Charts it becomes much easier to understand.

Debug Output Methods

The debug flags are divided into three categories which allow you to control the method of debug output. These methods are not mutually exclusive and may be combined with a bit-wise OR applied to the flags representing the methods you want to include. While the methods control the channels for the output messages - the messages themselves are identical, regardless of method or methods used.

  1. Output Debug String. This method allows the ClientProtector to output is debug messages to an IDE which supports the Windows API OutputDebugString function (most modern IDEs support this, check your IDEs documentation). In many IDEs this is called the "Event Log". When the ClientProtector needs to output a message using this method, it simply does so, posting it to the IDE and continues processing. The messages will appear inline with any other messages that may be logged there.

  2. Output Log File. This method creates a log file (simple ASCII text file) in the host applications directory named SSLOGFILE_1.txt. It will use this log file for the life of the ClientProtector object which created it. It will not overwrite a log file that already exists and will successively name log files SSLOGFILE_2.txt, SSLOGFILE_3.txt etc for subsequent instances of the ClientProtector when outputting to a log file is enabled. The log file will have a header noting the date and time of creation and the host applications name. When the ClientProtector needs to output a message using this method, it simply does so, posting it to the log file and continues processing.

  3. Output Debug Dialogs. This method shows a modal dialog with the debug message. This method is thread-blocking and will show the modal dialog and not continue processing until you dismiss the dialog. This method may be useful if you need very fine control and need to observe step-by-step what is happening on your system. This also allows you to easily follow along with the logical flow in the ClientProtector Control Flow-Chart as the COM server actually executes function calls internally one-by-one.

Debug Output Level

For each method above, the debug flags are further divided into two levels which allow you to control the amount of debug output. Levels for different methods are not mutually exclusive and may be combined with a bit-wise OR applied to the flags representing the methods and levels you want to include. The two levels are:

  1. Coarse. This level will generally only output messages when a condition occurs inside the ClientProtector that causes the flow of control to move toward a false state (or an unexpected state).

  2. Detailed. This level will output messages in numerous locations. It will output a descriptive message at the beginning of almost every step in the processing, as well as at any point where a "coarse" message would be output. As each step in the ClientProtector Control Flow Chart commences, this level will generally output a descriptive message.

DBG_SUPPRESS_WARNING_DLG

DBG_SUPPRESS_WARNING_DLG is a special debug flag that may be combined with any of the other flags you may need to use when you are debugging a non-interactive application (such as an NT service) or a web-application (server side).  Non-interactive applications may hang or crash if a COM component created from inside them attempts to show a dialog.  The Debug ClientProtector server shows a warning dialog by default when it is accessed to remind you that you are linking to the debug version (see: Controlling Debug Output) Use this flag to suppress this warning dialog.

ReturnCodeToMessage function

Both versions of the ClientProtector server expose the function ReturnCodeToMessage. The behaviour is the same in both versions, but should only be used for debugging purposes. It is different from using debug flags though in that it only provides a small string equivalent of a return_code identifier back to your code. It is your choice if you wish to output this string or not.

Using the ReturnCodeToMessage function can be very helpful in debugging your applications communication with the ClientProtector component - even when using the release server version. However, we suggest you use it inside a conditional define that you use only for debugging purposes. This allows you to simply change the conditional and without changing the code recompile, so that the messages do not show to your user.

Note that in most cases when responding to a Return Code from the ClientProtector you can handle just a few of the possibilities and group the rest together for simplicity. For example, in the Simple Copy Protection Example License And Application, we use a relatively small switch statement to handle the Return Codes from the ClientProtector because the license is so simple. We don't have to explicitly handle every possibility separately.

However, the more complex your licenses are you may have to separately handle many different return codes and possibly handle them differently depending on the context. This is where the ReturnCodeToMessage function becomes quite handy.

More Information

For help on actually using the DebugFlags, see CPDEBUGFLAGS in the SoftwareShield ClientProtector Reference.

For help on actually using the StartUp function to control debug output, see StartUp in the SoftwareShield ClientProtector Reference.

For the ClientProtector Control Flow-Charts, see ClientProtector Control Flow-Charts in the SoftwareShield ClientProtector Reference.

For help on actually using the ReturnCodeToMessage function, see ReturnCodeToMessage in the SoftwareShield ClientProtector Reference.

For help on registering and un-registering the release ClientProtector server and the debug ClientProtector server, see Registering / Un-registering ClientProtector Servers in this reference.

Related Topics