Access Control:
Licencing and Registration Control:
Additional Features:
Note: in Secwin 4, all the File driver DLLs are included in the main install, so you will not require any additional install files for other driver support.
Why is Capesoft charging for an upgrade from Secwin 3 to Secwin 4?
How do I upgrade from Secwin 3 to Secwin 4?
What do we need to change in order to upgrade from Secwin3 to Secwin4?
This is a quick way to get going implementing the Licensing and Registration features. It's by no means all the power available to you, but it's enough to get you up and running. we recommend reading the items in the Secwin User Guide related to Licensing and Registration for more information on what is available.
| TIP : At this point a lot of developers get easily confused. You need to register your own program on your own computer. Any registration type error messages you get do not apply to Secwin itself, but rather illustrate that the Secwin features in your application are in fact working. |
To register your product - which is what your client will need to do when, or before, it expires, use the supplied Register Application or use Secwin Online Server to supply activation codes on line.
The manual registration application is shipped
as one of the Secwin examples, and can be modified to suit your needs. It can
be found in the \clarion\3rdparty\examples\secwin\register directory.
In it's simplest form Register application allows you to capture:
| TIP : For a full description of the Register example see the Secwin Examples Reference manual. |
| TIP : To the right of all alpha-numeric fields on the window is a Check number. This number will be visible to the client while typing the details in. If his number does not match the supplied number then a spelling mistake has occurred. |
| TIP : Read the sections in the User Guide which cover the Licensing and Registration features and options to learn more about what is, and isn't possible using the Registration features. |

2. Add Secwin's Activate Security Global extension
to your Application.
For the Options on the Extension
a) Enter the Unique Application Name. For Multi-DLL applications, read up on
the Using Secwin In MultiDLL Apps
section of the docs on what to enter here.
b) On the Files tab set the Allow Program to create Security Files
on, and set the Position to Exe directory.
| Tip : This method of creating files is not very secure if you aren't using the licensing features. If you aren't using licensing then read about Creating the Security File soon. For now though continue the QuickStart. |
c) On the Options tab, set the Function Overrides as follows (for Multi-DLL users, this will be in your data dll only):
Note: SetAccess must be set to SecwinSetAccess NOT SecwinSetAllAccess.
Note: For Multi-DLL users, you'll want to compile the security dll (normally the data dll) now, and then switch over to your main exe at this point. Repeat steps 1 and 2 in the EXE application. In step 1, make sure you check the 'Import the procedures as external' checkbox on the template utility.
For Multi-DLL users, in other applications (not the security dll) check the Functions are in another application checkbox and type in the external procedure names of the procedures that you will require in this application (typically the SetAccess window only for most apps, except the one that you log in with - then you'll need all the procedure names).
3. Go to the Frame, or Main Menu, procedure. Add Secwin's
User Login Here Extension template (if it's not there
already).
For the Options on the Extension
a) On the General tab, set the Unique Area Name as Main.
b) If you don't want AccessControl to be optional for the end
user, then make sure that the Make Login Optional to End User is
unchecked.
4. Continuing in the Frame procedure, add Secwin's Create Secwin Menu extension template. If it was already there, then make sure that the Disable Access Control Items checkbox is unchecked, and that the following procedures are set correctly:
5. For Multi-DLL applications, you need to follow the Using Secwin In MultiDLL Apps guide in this document.
The first time the program is run you will be asked to add the first user. A User's
information is made up of a First Name, Last Name and Login code. When you add
a user the password is automatically set to be the same as the Login code.
After you have finished entering the first user, then you can use the Login code,
and Password (which will be the same at this point) to log in.
After you have logged in you can add more users using the Browse Users item
in the Security menu created by the
Create Secwin Menu extension template.
You can also change your own password using the Change
Password item created by the
Create Secwin Menu extension template.
| TIP : We get lots of questions about passwords. For most of the answers see the section in the Secwin User Guide entitled Logins and Passwords. |

| User Guide | ||
| Access Control Features | Licensing Features | Other Features |
| Overview of Access Control | Overview of Licensing | Creating the Security File |
| Logins and Password Access Control | Some Activation Code Secrets | Locating the Security File |
| Operator Browse and Form | Branding on Reports | Security-File Driver |
| Screen Security Access Control | Branding Using Logo Screens | Changing the Logo |
| Set Access Rights Screen | Hardware Copy Protection | Making your own Secwin Windows |
| Ancillary User Functions | Using Levels | Secwin Error Messages |
| User Groups | Automatic Temporary Licenses | Using Secwin in Multi-DLL Apps |
| Work Groups | Using Optional Modules | Converting from Secwin 2.x |
| Bypassing Access Control | Using Network Copies | Secwin Examples |
| Using Expiry Dates | Super Users | |
| Using Counters | Translating Secwin Windows | |
| When the License Fails | Pin Numbers | |
| Advanced Programmer Functions | ||
| ClarioNet / WebBuilder Compatibility | ||
| IP Driver Compatibility | ||
If you're not wanting Access Control, but just wanting to use the Licensing and Registration part of Secwin, then take a look at the Bypassing Access Control section.
| Lost a password?
The password itself is not available to either the programmer, or any other
user in the system. Because Secwin has been designed to span across applications,
and networks, it would constitute a major security flaw for one user to
be able to find out the password for another user. This means effectively,
that if a password is forgotten, there is no way to retrieve it. If the
password can't be remembered, then the user will have to be deleted and
re-added. ( Tip : You can use User Groups to handle folk who are
continually forgetting passwords. See the section in the User Guide entitled
User Groups.) Alternatively, take a look at Using an encryption key for details on an alternative method of access control, which enables you to retrieve the password. |
| TIP : If you have a Multiple-Exe product, then you can consider each Application to be it's own area. However it is possible for all the EXEs to have the same Area definition, and hence have the same access rights apply to all the EXEs. This is done by setting the Unique Application Name (on the Secwin Global Extension) and the Unique Area Name (on the Secwin User Login Here Extension) to be the same across all the Applications. |
Definitions:
When a user logs in they can be classified into one of 3 possible Levels.
Supervisor: This level has all the power -
the supervisor has access to the whole application (or area) - and has the power
to add users and user groups and limit those users and groups.
No Access: This Level has no power (in fact they
will be denied access). These users will not appear in the list of operators
that the SuperVisor can assign access to (for security areas in the application).
Operator: This level is in between - he does not
have the power to add or update users, or their access points, but he is in the
list of operators that the supervisor can grant or deny access to (areas of) the
application.
The difference between a Supervisor, and an Operator is obviously a significant one. Simply put, a Supervisor is allowed to change the security access rights of other Users. An Operator can not change either their own, or anyone else's, Access rights.
Each Operator can be assign an initial access of either All Access or No Access. This is the default access for any particular security access point in your application for that operator. The Supervisor can change that default access to any of the security points. An operator with an initial access of No Access will need to be assigned access by the supervisor before they will have access to a security area.
Note: The difference between a user that is an operator with an initial access of No Access and a user that has a level of No Access, is that the supervisor will be able to grant access to the operator to particular areas of the program, but the No Access user will not appear on the list of users that the supervisor can give access to. The supervisor must change a No Access user to an operator if they are to be given access into your application.
| TIP : For programmatic access to the Users list see the ds_InsertUserEx , ds_ChangeUser, ds_DeleteUser and ds_UsersEx functions in the Secwin Technical Reference. |
Note: an Operator can now be part of more than one User Group.
| Tip : When you create a new user or user group, you can set it to have an existing user or user group's access rights (when it's created). You can diverge the two groups (i.e. if you wanted more options for the one than the other). |
| Tip : If a user is always forgetting their password, and you get tired of resetting their access rights every time you have to delete, and re-add them, then make a user group for that person. The access rights will be stored with the Group, not the User, so it's easier to delete, and re-add the user. |
What happens about access rights when a user gets added to a usergroup:
Example:
If ds_GetProperty(AppNum,,'WorkGroup') = 2
!Allow user into this routine
end
So to summarize: In order to use a WorkGroup for an operator, you need to programmatically set the access rights in your application (for the area that you want to limit access to), and then at runtime, assign that operator to the WorkGroup Number you used in code.
There're a couple of reasons why you may like to bypass the Access control part of Secwin (a bit like disabling Access Control - but technically it's working around it). The primary reason for doing this, is for demo purposes - i.e. you want your program to run without forcing the user to login. Alternatively, you may not require Access control for your program period, you might like to just use the Licencing and Registration features.
There're 2 ways of Bypassing Access Control this:
1. Check the Make Login Optional to End User (on the User_Login template - Login Options tab). You won't need to ship a
dssw4.tps file (although you can if you want to use Access Control later). This means that access control is bypassed.
This is typically for people you don't require Access Control or would like to
make access control optional.
2. Check the Allow default login values (on the User_Login template - Login Options tab) use a default Login code and password and ship a
dssw4.tps file that contains the default user (if you want access control at a later stage, but not in the demo application).
This is typically for people who require access control (either now or at a
later stage), but not in the demo application.
Note: When shipping a dssw4.tps file, you need to make sure that dssw4.tps file does not overwrite the one that already exists there (for people downloading a program
update who have already set up all their user settings).
When you add an operator and set his default access to 'All Access', this will only be for the application that he is added to. For other applications, his default access is set to 'No Access'. This is because it would pose a major security flaw if you could create a user in a Secwin enabled application and get all access rights to a completely unrelated application. In order to allow cross-pollination of operators in a Multi-DLL environment (IOW across multiple apps which are essentially the same application) - you need to set the app name the same for each application (you need to do this in the Secwin Global Extension template). See the Definitions section of this doc for more details.
![]()
This code should be written into your application that generates registration
codes. There is a default registry code generation app that ships with SecWin
as an example (3rdparty\examples\secwin\register\register.app), which you can
modify to suit your needs.
| Tip : Many users upgrade their computers every 2 years or so. Network administrators change network drives more often then that. Each time the hard disk is changed the user will have to get a new activation code from you. If you're expecting a large number of installations then DO NOT use this feature. Use only in very select situations. |

SecLoc:xmlFile = DropID()
Do ImportXMLFile
if SecLoc:AdditionalString1 = FunctionToGetID() !This could be
ds_GetDriveSerialNumber
post(event:accepted,?Sec:RegisterButton)
else
disable(?Sec:RegisterButton)
!Warn on mismatched ID here
post(event:closewindow)
end
You also need to turn off the Automatically register when an XML file is dropped checkbox (on the RegisterProduct control template on the SecwinRegisterProduct window).
When loading the application you need to test the hardware to a saved licence:
LicenceDetails group(ProductDetailsGroupType),pre(LD) .
code
LicenceDetails = ds_CurrentLicenceDetails()
if LD:AdditionalString1 = FunctionToGetID()
else
!Invalid hardware for registered licence code.
end
When the user runs your program on his machine for the first time you can set your application up that he can automatically get a temporary license for running your program. You can switch on this feature by going to the User Login Here template, on the Licensing tab, and turning on the Issue temporary licence when first run? switch. The length of the demo is set in the next option called Valid for (days). You can set the automatic license level in the Level drop down list.

This feature also cause much grief to Secwin developers because they find it difficult
to test. Secwin will only issue ONE demo license for your program on any one machine.
If the user registers the program then they will not get a 30 day temporary
activation at any time after that. Also if they install your program, and get their temporary license,
they will never get another for your program.
Automatic temporary licenses are issued with all modules enabled (see
Using Optional Modules for more details on
modules).
| Tip 1 : Deleting the Security File (dssw4.Tps) is not sufficient to overcome this feature, so please don't complain when you can't make it work on your development machine a second time. |
| Tip 2 : If during the 30 day period, the PC date goes backwards, then the license will automatically, immediately, expire. |
If the user sets the date back to the last date of the license, runs you program and then resets the date, then it is possible to bypass the Secwin date checking. Probably the best solution in this case would be to put a timer on the frame that checks the date is before the expiry date every few seconds, and shuts the program down as soon as the date goes past the expiry date. The function to call is ds_CurrentExpiryDate
If the user is really desperate, and resets the date in order to keep your program running (and keeps the PC date reset), then you could build a system that checks an internet date (you could use NetTalk to do this) and if the difference is > 1 day, then force the PC date to that date, and redo the license check. They would need to be connected to the internet at the time of the check though, so it might only take a short time for them to figure out the check is in place. What you could do is do the check once on startup - if there is no internet connection, then retrying every 30 seconds or so until one is established and you can then check the date. Of course, the user could always disconnect from the internet while they run your program - but eventually it gets so inconvenient for the user, that they eventually purchase an extended license.
For table restrictions, you need to:


In your program you can specify, using the Screen Security extension template, that a
procedure Decrements the counter. When the counter reaches 0 then any procedure
trying to decrement the counter will result in a License fail.
This could be used when your program is being evaluated, for example when you
want to allow the user a fixed number of program runs before they have to purchase.
Alternatively it's possible to sell your program based on the number of times
it is used. For example data applications can be sold by the number of reports
that can be generated. You user can buy 10 reports, when they run out you simply
issue another activation code, and they get 10 more.
To set a procedure to decrement a counter, go to the User Screen Security
extension for that procedure, click on the License Check and Restrictions
button, go to the Counter tab, and select the option Decrement Counter
here. You need to specify which counter Secwin must decrement by a label
(which must match the label of the counter in the registration window as well as
that in the registration program issuing the activation code). This means that
there is technically no limit to the number of counters your application can
make use of.
It is also possible to deduct multiple "credits" from the counter field at one time. Use the ds_DecrementCounterEx function to do this.
For Secwin3 upgrade users:
If you made use of the counter in Secwin3, then the counter to resume using
is the 'Default Counter'. If you need additional counters, then you can either
make use of the Table Restrictions limit functionality, or else you can use
other labels and add additional procedural counters to your registration window.
The Serial Number field is a string field which you are able to use for Serial Number purposes. It is not required for licensing purposes - but is provided for your convenience. You can use the Company name to make the license unique.
In Secwin4 you have the ability to use additional fields in the licence. The licence details group contains Other2, Other3, OtherLong, ExtraLong and ExtraString additional user-definable fields that you can make use of for additional parameters.
In your RegisterProduct window (check the Creating the Register Product section of the docs, if you have not created the SecwinRegisterProduct window in your application yet) you can add an additional field (up to 5 - 2 longs and 3 strings) for the additional items you would like to store.
These additional fields come already on the SecwinRegisterProduct window, but by default are hidden. You can unhide the Additional fields group, and then hide the controls that you don't require (unless you require all 5 additional fields). You can edit the field prompts to be something descriptive, and make sure that the Additional fields are populated on both the Register application (or Secwin Online Server) - as well as in your application when registering the licence, otherwise the activation code will not work.
Note: If you're using the built in xml file mechanism to transfer the licence details in an xml file, then you will not need to do anything extra to support this.
By far the easiest way to transfer a licence details manually is via an XML file. This removes all possible user-entry error and makes it very simple for the user to enter licence details. Simply send them an email, include the XML file, and they can drag the xml file and drop it straight onto the RegisterProduct window in order to register the product.
You will need to create the xml file in your registration application. For an example of this, take a look at the RegisterABC application, in your Secwin Examples folder. This does not include a method of transporting the application, but using a product like NetTalk, will make emailing the XML file as an attachment very straight forward.
Some tips on creating a registration (using the registerabc application). Run the registerabc application - and to create a registration:

![]() Showing Table Restrictions |
![]() |
|
![]() Showing a procedural counter |
||
| R# = ds_CheckCounter
('Default Counter',1) Showing a hand-coded counter |
What you need to change in your application:
Nothing - except Creating the Register Product window in your application. Once this is accomplished, you will notice the following region on the SecwinRegisterProduct window:

Dropping the xml license file onto this region will automatically populate all the fields with the correct licence values. The user then simply has to click the register button and he's done.
If you want to support manual entry into the Register Product window as well as via the XML file (manual is by default disabled) - then you can do this by enabling the ?Sheet1 control in the Window Formatter of the Secwin_RegisterProduct window that you imported into your application.
Secwin supports different licence types (at this stage there are 2 types - Permanent and Temporary). This feature enables your existing users to try out certain additional functionality for a demo period, without losing their Permanent Licence. Once a Permanent licence is issued, the Licence will always fall back to that permanent licence (after an issued temporary licence expires).
You can issue as many temporary codes as you would like your customer to have (each subsequent one will replace the previous temporary code). When the temporary licence expires, the licence will always revert back to the permanent licence that they had previously (unless the permanent licence expires in the interim). Issuing another Permanent licence will replace the existing Permanent licence (as will issuing another Temporary licence will replace an existing temporary licence). The licence type is set on the Registration window - and must match in both the Registration program and on the RegisterProduct window in your application.
The temporary licence (by nature) - will contain more features than your permanent licence. The reason for a temporary licence is to try out temporary features. Once the temporary licence expires, the licence will fall back to the permanent one - IOW the temporary licence is at a higher level to the permanent one. Temporary Licences are Level 2 licences, while Permanent Licences are Level 1 licences.
Because temporary licences should be temporary, the expiry period should be a short period (say 30 days) in order to avoid the following issue:
Warning Note: The temporary licence will always supersede the Permanent licence. This means that if you assign your client a new Permanent licence, while the temporary licence has not yet expired, it will not be used until the temporary licence expires. If you don't want this feature, then hide the Type drop down in the registration application, and always assign the licences to permanent. If you want to assign more features in a permanent licence (than in a currently unexpired temporary licence) - then you need to issue both the temporary and the permanent licences (so that the current temporary licence will be replaced by the new temporary licence with the new features).
Note: Don't confuse a temporary licence with a demo licence. A demo licence is a permanent licence type - a temporary licence is only issued to an existing permanent licensee to try out new features (so the licensee is still registered).
Use the ds_CurrentLicenceDetails function to return the Licence type (as well as other licence details).
In order for Licencing to work correctly, each instance of your program must be set to create and/or use the Licence file in the same place as all the other instances. This is set on the Files tab of the Secwin Global Extension template of your application. If your application is opening more times simultaneously than you have issued licenses for, then it almost certainly means that each instance running is using a different path for the license files. For more details on locating the Security file, peruse the Locating The Security File section of this document.
For handcoders that care - take a look at the Secwin Data Types section of this doc for more details on the data structures required for licensing and registration (in particular the ProductDetailsGroupType and the LimitsQueueType data structures).
| Tip : If you used the QuickStart settings to get going then you program is creating it's own security files. This is not a problem if you are using Licensing, but if you aren't using licensing the strongly consider changing to one of the options below. |
| Tip : Secwin ships with an example called Cresec which creates the security file (\clarion\3rdparty\examples\secwin\cresec.) For your convenience this is also shipped as a pre-compiled Exe into your \clarion\3rdparty\bin directory. |
For Flat file systems (like TPS): By default the Security file will be placed in the Windows directory.
This makes it harder for people to simply copy your program from one machine
to another. However in network situations this approach doesn't work because
typically the users need to share the same security file. If the the file is
shared they can use the program, with their login, from any machine. Security
administration is also much easier if the file is shared.
There are ways to set the location of the security files.
Secwin.Ini
Win.Ini
For SQL files: The security files are located in the database and/or schema specified in the connection string. See the Security-File Driver section of this document for more details on connecting to the server. Secwin will create a handful of data files prefixed with Secwin_ which it will use to store the necessary security data in.
Secwin supports storing the security file using a variety of different drivers. These
include support for Oracle, Microsoft SQL, PervasiveSQL, IPDriver and ODBC drivers, which
means you can use a variety of different databases such as Interbase or MySql.
You can select from the list of supported drivers on the
Global Extension, on the Files tab. Some drivers may have different options.
These are discussed in detail below. If you would like a new driver added to
the list then contact Support@CapeSoft.com
.
All the following drivers are included in the Secwin
install (unlike Secwin 3 which required an additional install for each driver
required).
If you are using a file driver other than the Topspeed or Btrieve drivers then you will need to enter the owner string in the Owner field. This is the Owner attribute as it would normally appear in your dictionary. The owner format for the different drivers is as follows:
User/pwd@sn where User is the username, pwd is the
password, and sn is the Service Name or SID of your Oracle Database.
Host,db,user,pwd where Host is the IP or
Host name of the Database server, db is the Microsoft SQL database name,
user is the username, and pwd is the password.
Host|db,user where Host is the IP or Host name of the Database server, db is the database name, and user is the username. Please note the pipe "|" character used between Host and db.
Dsn,user,pwd where Dsn is the Data Source Name, user is the username, and pwd is the password. Alternatively, use www.connectionstrings.com to assemble a connection string that can be used to connect to the database.
If you would like to use a different schema other than the default, you can set this in the template entry prompt on the Files tab of the Secwin Global Extension template.
| Tip : The ODBC driver comes with special support for MySql, Ingress and Firebird. On the Global Extension Files tab, first select ODBC file driver, and then MySql (or Ingress) Database type. For all other ODBC connections, use the Other option. |
Via ODBC, Secwin explicitly supports: MySQL, Ingress, Interbase and PostgreSQL. You may have success with other databases, if so - please let us know so that we can add these to the confirmed list.
Peruse the IPDriver Compatibility section of this
document to include IPDriver support for Secwin.
| Tip : See the various examples for these drivers in your clarion\3rdparty\examples\secwin directory. Read more about these Secwin Examples. |
If you are using the Topspeed or Btrieve driver, then you can leave the Owner
field blank, and the default one will be used. However you can enter your
own Owner field here if you want to.
| Tip : If you set an owner here for Topspeed or Btrieve then the security file you create will not be compatible with other applications that use a different owner. Therefore if you set the Owner field yourself then you must set the position of the file to be in the Application, or Data directories. (See Locating the Security File.) |
Of course if you set the owner, then you're able to import the security files
into your dictionary, and manipulate the files directly in the code. We obviously
can't stop you doing this, but we advise against it. By altering the files directly
you run the risk of bypassing the validity checking that Secwin would normally
do. For example Secwin doesn't allow you to delete Super
Users, although in your own code this would be a trivial thing to do.
Note: If you are using Multi-Proj's Driver Substitution, then peruse the Using Secwin in a Multi-Proj application section of this doc for details.
On all of the Built-In Secwin windows is a little padlock logo. This logo can
be replaced by your own logo, or removed completely, using the
ds_SetLogo
function.
As from version 3.1 all of the Secwin windows can be replaced with your own Windows. This allows you more creative control over how the windows look, and it's also an important part of making the program compatible with Web Builder and ClarioNet.
Open your application in the Clarion IDE and use the "Create RegisterProduct window" (ABC or Legacy) to import a default SecwinRegisterProduct window (in Multi-DLL apps, it's probably best to do this in the DataDLL):
Open the window formatter for the SecwinRegisterProduct procedure, you can now hide controls that are not required (if you are not using all the Licence features). If you don't use an entire tab, you can modify the accepted code in the Back and Next buttons to skip that particular tab. Don't delete controls in case you require those features at a later stage. Have a look at the Including additional Fields in the Licence if you require the use of additional fields in your licence.
Right-click on one of the controls, and you be able to set the following:

Automatically register when an XML file is dropped. Checking this will load the XML and attempt to register when the XML file is dropped onto the XML region in the Register Window. Otherwise, the settings will simply be loaded and the user will need to manually click the register button.
Activation code can only be used once. The activation code is stored in history, and may not be used on the same PC a second time.
Dealer field in the licence. Detext in XML: if the dealer field is included in the XML file, then the activation code checker will assume that the Dealer field was included when generating the activation code. Force use: will include the dealer code in the activation code. No Dealer: will not include the dealer in the activation code checker (whether the code is in the XML or not).
On the Messages tab you will be able to set the text of Registration success and failure:

On the Counters/Limits tab you can enter any limits/counters that are used in the activation code.

These must match those in the application issuing activation codes (although these are case insensitive). If you are using table limits, then these will be automatically added to the list from the Global Extension template, and will only be displayed here. You will need to add the procedure counters manually though. Peruse the Using Counters section of this doc for more details.
Note: If you're wanting to use Secwin Online Server to manage your Product Registrations online, then you can add the Secwin Online Server controls now.
Included in Secwin is the ability to create a Global SetAccess window. You can create one window to SetAccess rights throughout the entire application for each user. Here are the steps in order to do this:
The SetAccess window that is added to your application has two list boxes: one for users and one for the AccessPoints.

Selecting a User in the Users list, will show the AccessPoints that this user has access to in the AccessPoints list (the ones that are checked, he has access to and the ones that aren't he does not have access to). You can edit a user's access rights by Double-Clicking the relevant AccessPoint's checkbox in the Access Points list.
To view the users that have access to a specific Access Point, use the Access Points tab:

Selecting an Access Point from the AccessPoints list will show which users have access to that point highlighted. You can edit a user's access rights by Double-Clicking the relevant User's checkbox in the Users list.
You can add users and user groups using the respective buttons on the window.
Note: Only supervisors have access to this window.
The way to do this is to use the Create AccessControl windows Template Utility to make a set of AccessControl windows (including the User Browse and forms).
The way to do this is to use the
Create AccessControl windows Template Utility to make a set of AccessControl windows (including the Login
Window)
The way to do this is to use the
Create AccessControl windows Template Utility to make a set of AccessControl windows (including the
ChangePassword window)
The easiest way to do this is to use the
Create AccessControl windows Template Utility to make a set of AccessControl windows (including the
ChangeLogin window)
Use the Create AccessControl windows
Template Utility to make a set of AccessControl windows (including the
SecwinSetAccess window). You are now free to examine the SecwinSetAccess procedure, and to tweak the
visual look & behaviour as you like.
![]()
For and example of a MultiDLL application using Secwin, and the ABC templates,
see the \clarion\3rdparty\examples\secwin\MultiABC directory.
There are 2 kinds of Application in a Multi-DLL project. The first kind is the
Root, or Data application. This typically contains all your file structures.
The second kind is any of the other APP files, other DLLs and EXEs that make
use of this Data DLL.
Note: Follow the
Jumpstart for adding support to your multi-dll application.
In addition to that, you need to do the following:
If this is the Root Application then
1. go to the Global Extension, to the Multi-DLL tab.
2. Click on This is part of a Multi-DLL Application.
3. Click on Export Secwin data.
If this is Not the Root Application then
1. go to the Global Extension, to the Multi-DLL tab.
2. Click on This is part of a Multi-DLL Application.
3. Click off Export Secwin data.
In the global extension on each application:
For some assistance with additional settings, check out the Global Extension template
One of the goals when creating Secwin 3.0 was to keep it as compatible as possible
with Secwin 2.x. There are very few issues to worry about when converting,
but known issues are described here.
The Secwin DLL names HAVE CHANGED! See the
Distribution section, in the Other Information
section for specifics.
Multi-DLL support has been simplified a lot, but this means that there will
be a few things for you to remove from your existing apps.
1. In your Root DLL remove the
QAdd, QGet and QDelete functions.
2. In your Root DLL go to the Global Data button and remove
AppNameDesc and AppNum.
Support is being added for a number of different file drivers. The old Use Btrieve
switch has fallen away, and been replaced by a drop-down. This can be found
on the Global Extension, on the File
Tab.
Secwin ships with quite a few examples, so sometimes it's difficult to find the example you're looking for. Here is a list of all the examples, and what they're trying to show you. Al the examples are found in the \Clarion\3rdparty\Examples\Secwin directory.
| Demo_AccessControl | Demonstrates the access control features in a simple application. This uses an EncryptionKey - and demonstrates the use of the ds_GetUserPassword and ds_ResetUserPassword functions. |
| Demo_Licence | Demonstrates a program with the Licensing and AccessControl features activated. This is the most complete functioning Secwin Demo. |
| MultiABC | Demonstrates a Multi-Dll program based on the ABC templates |
| MultiDLL | Demonstrates a Multi-Dll program based on the Legacy templates |
| MultiEXE | Demonstrates a Multi-Exe project which shares a Secwin Login. |
| Non_TPS_Examples\Interbase | Demonstrates the use of the ODBC driver for Secwin with Interbase. We have called this one Westwind. You will have to set up a datasource name called Westwind_dsn. The customizable procedure in the global embed will need to be edited to suit your database setup. |
| Non_TPS_Examples\IPDriver | Demonstrates the use of the IP driver for Secwin.
Steps to get going: |
| Non_TPS_Examples\ IPDriverMultiDLL |
Demonstrates the use of the IP driver for Secwin in a MultiDLL application.
Follow the steps above, using the IP_Country.app for the IPServer DLL. |
| Non_TPS_Examples\MsSQL | Demonstrates using the MsSQL driver. This example uses
the Northwind example database that ships with MsSQL. You will have to make
a small adjustment in the Global Embed to set the machine name for your database. |
| Non_TPS_Examples\MySQL | Demonstrates using the ODBC driver with a MySql database. We decided to stick to the theme initiated by MsSQL and name our example database Southwind. You will have to set up a datasource name called Southwind_dsn, and fill in your datasource name, username, and password in the global embed. |
| Register | This is an example of a Activation Code database. It allows you to create customers, products and registrations, and link them all together. This program can be used as a start to developing your own Activation Code database. |
| WebServer | Coming soon - Secwin4 controls the access rights of your NetTalk4 web server application. |
Note : They are probably not what you think.
Read the next bit carefully to understand them.
The need for Super Users arises where you, as the developer, need to maintain
a permanent ability to access the program at your client's site. While this
may seem like a defacto requirement of all programs, it is often not ideal.
While it may be common for developers to have 'back doors' into their own programs,
these back doors provide a substantial security risk (Anyone seen the movie
War Games recently ?)
Of course on some sites you do need to make sure that your login rights are
preserved, because your users are likely to do things like lock themselves out,
or forget their own passwords. Secwin offers a SuperUser feature for coping
with these situations.
Firstly - what a Super User is NOT. It is not a Back Door which will always
let you in.
Essentially a Super User is simply a user who cannot be Deleted. The user still
needs to be added in the Normal Way. The Super User code is normally set to
be a Supervisor, although he can also be set to be an Operator, or even set
to No Access. The Super User can be seen by the customer, but cannot be deleted
by the customer.
The User Login template has been modified
to support this feature. There is a special tab containing the Login Code for
the Super User. Remember the User must be created in the normal way, setting
the code here will not automatically add the user.
As with most features, this feature is optional and should not be used on sites
requiring a high level of security.
Secwin allows you to translate any of the windows into any language.
First one or two bits of terminology.
A language file (note the small letters) is a text file containing a
list of translations, from the original English into whatever language you like.
The exact format of the file will be discussed later.
LanguageFile (note the big letters, and the lack of a space) is a SecWin.INI
file parameter, containing a DOS file name (including drive and path) of a valid
language file. This file normally uses the .IRF extension.
LanguagePath is a SecWin.Ini parameter that is used with the
ds_SetLanguage function to change languages on the fly. It contains a valid
drive and path.
Secwin allows you to choose your language using two methods, the first is via
the use of an INI file, and the second is via a function (ds_SetLanguage) at runtime.
When your Secwin enable App is started Secwin looks for two parameters namely
LanguageFile and LanguagePath. Secwin looks first in the Application directory,
in the Secwin.Ini file, in the [Secwin] section. If either, or both are not
there then it looks in the Windows directory, in the Win.Ini file, in the [Secwin]
section. If LanguageFile is still not present then it defaults to a file called
Secwin.Irf, in the Windows directory. If LanguagePath hasn't been found then
it defaults to the Windows directory. If LanguagePath is set to 'Here' (no quotes)
then it will be set to the application directory.
LanguageFile is a full path- and filename to a valid Secwin language file. The
exact format of a valid Secwin language file is discussed a little later on.
Secwin uses LanguageFile as the default language file containing the required
language phrases. If this file does not exist, then Secwin uses the normal English
phrases on the screen.
During the running of your application you can set, or change, the language
file being used by calling the ds_SetLanguage function. This function takes
one parameter, the name of a language file. This parameter is added to the LanguagePath
parameter (discussed above), and then used as the current language file.
Inside the Secwin.Ini file...
[Secwin]
LanguageFile=c:\Windows\Spanish.Irf
LanguagePath=c:\Lang
Using the above Secwin will default to using the Spanish.Irf language file in
the Windows directory, on the C Drive.
At runtime the application could call the ds_SetLanguage function, like this...
ds_SetLanguage('Russian.Irf')
Which would change Secwin to use the Russian.Irf file, in the Lang subdirectory on the C Drive.
The last point to discuss is the structure of the Language file itself.
The format of a Secwin language file is very simple. It is made even simpler
by the fact that a sample language file (English.Irf) ships with Secwin, and
thus simply copying this sample file and translating the English terms is all
you really need to do. Note that Secwin (by default) doesn't use the English.Irf
file, it is only included as an example.
Inside the file there are a
number of Sections, each one enclosed in a set of square brackets, like this...
[spLevel Text]
Inside each section are a number of field equates that identify each visible
text field on the screen. On the right of the equals sign is the actual text
that would be displayed. For example the following.
[spLevel Text]
Level:Unknown=Desconocido
AccessLevel:2=Operador
AccessLevel:0=Sin acceso
AccessLevel:3=Supervisor
AccessLevel:-3=Todos Acceso
AccessLevel:-10=Acceso
By replacing the text to the right of the equals sign, you can get the
translated text to be displayed as anything you like.
At the top of the file is a section called [Intl], and this has a single entry
called sLanguage. eg
[Intl]
sLanguage=sp
This is used to find the correct section later on. You'll have noticed above
that the function name (e.g. ds_OperatorBrowse) is prefixed with this. This
is a requirement of the way the support works. If you change the value in the
Intl section, then you must change the prefix in all the other sections as well.
At the bottom of the file is a section called [enuMessages]. This section contains
the messages that appear when SecWin needs to communicate with the user. You
will need to translate these messages as well.
Note: Because by default the Secwin windows are included in your application, only the MessageText and level text will require translation. The old DLL windows will still be supported for Secwin3 applications using the Secwin 4 DLL.
Using a different date picture:
To set the different date picture, then you need to enter the following in to the language file:
[engMessages]
datepic=@d6
Using alternative licence level notifications:
You can use alternatives to the default licence level indicators in Secwin (i.e. Demo, Lite, Standard, Professional and Enterprise). Setup translation in the normal manner (as indicated above) , and "translate" the licence level text to display what you would rather display.
[engLevelText]
Level:0=None
Level:1=Demo
Level:2=Lite
Level:3=Standard
Level:4=Professional
Level:5=Enterprise
| Note : PIN numbers are only necessary if the Licencing and Registration features have not been enabled. If you are using the Licencing and Registration features then you should set the PIN number to 0 and not worry about it |
One of the only current methods of compromising SecWin Access Control (where
licencing and registration aren't used) is through the replacement of the
dssw4 security file by an empty dssw4 file. PIN numbers prevent this from being effective
by requiring that a dssw4 file be "stamped" with a PIN number before
the Application will accept the dssw4 file as valid.
The PIN number system introduces two new functions, and their associated templates.
ds_SetPin is used to stamp a PIN number into a DSSW file.
If you choose to make use of the PIN number system, then you will need some
way of stamping the dssw4 file with the pin number. This can be done in a number
of ways, some of which are laid out below!
1. Use another EXE program, over which 100% physical control can be maintained.
It should not be accessible to un-authorised users, and should be treated as
a physical key. The PIN number itself is hard-coded into the program, and can
be run by anyone with access to it. An example of such a program ships with
SecWin and is called HARDPIN. This can be found in the \Clarion\3rdparty\Examples\Secwin\UsingPin
directory. The advantage of this method is that a person doesn't need to remember
the pin number - they simply need to run the program.
2. Use the enclosed SETPIN program which ships with SecWin. (This program can
be found in the \Clarion\3rdparty\Examples\Secwin\UsingPin
directory.)
This program requires that the PIN number be entered by the user. The user will
then need to know the correct PIN number in order to properly stamp the dssw4
file.
You can use your own encryption key to essentially encode the secwin_operators table so that it is unique to your application. This means that no other application (that doesn't use the same unique encryption key that your application uses) can access the secwin_operator's table that your application uses. This means that, because your secwin_operator's table is closed to the outside world and completely in your control, you are able to use the ds_ResetUserPassword and ds_GetUserPassword functions in Secwin - to enable a supervisor to reset a user's password (or get it and send them the password using a transport mechanism of your choice).
For handcoders, you'll need to call the ds_SetEncryptionKey function before initializing secwin (or template users - there's a setting in the template that you can set to do this). You cannot use the ds_ResetUserPassword and ds_GetUserPassword functions without using a unique EncryptionKey.
Note: Once the ds_SetEncryptionKey function has been used by your application, and your application has been run on the Secwin data tables, then only your application will be able to read the secwin operators table. There's no going back to default encryption again.
You can take a look at the example application in the Demo_AccessControl folder that uses these functions.
This utility is provided in order to generate an Security code that will enable Secwin to internally repair corrupted AccessControl tables. If your user's tables have been altered by an application other than Secwin, then the encrypted CRC will not match the CRC of the fields in the table. Your user will be confronted with the following message:

If you have entered an email address in the Secwin Global Extension template (on the Options tab), then your user will be able to easily generate an email requesting an activation code in order to easily acquire a Security Code to copy and past into the entry field provided. The must simply click the "Create Request Email" hyperlink. If you have not entered a valid email address, they will need to enter the Unique Identifier into an email (or over the phone) - which you can use to create a Security code.
The file fixer utility is located in the Clarion\3rdparty\bin directory (called SecwinFileFixer.exe) - and is used to generate the necessary Security code to repair the AccessControl tables.
In order to generate a valid Security code that the user can enter to get the program going again, you need to do the following:
Secwin now supports full compatability with both the standard Web Builder templates
included with Clarion, as well as the ClarionNet
add on. For the sake of simplicity in this section I'll refer to WB compatability.
This includes both the Web Builder and ClarioNet products.
The only thing you need to do to make your program WB compatible is to create
your own versions of the Secwin screens. (You may have already done this anyway
for design reasons.) For information on creating your own Secwin windows see
the section called
Making your own Secwin Windows.
Secwin is completely compatible with a Multi-Proj application - however you may need to tweak some settings in order to get the two templates to operate correctly. Typically you'll need to do this if you are using the Driver Substitution feature in Multi-Proj. If you are creating an IPDriver project (for example), then you'll need to make the following changes:


For a list of the matching drivers to their Secwin projects, see the Distribution section of this document.
![]()
Installing
[ TIP : when deploying your application, i.e. deploying the ClarionDataServer, then you will need to do steps (1) and (2) as part of your deployment ]
Changes required to your application
The SV IPDriver Client Global Extension is active in your app then Secwin will use the IP Driver connection (so you must have the SV IPDriver Client Global Extension added to your application).
Note: If you are adding Secwin to an IPDriver application (Multi-DLL or single EXE), then you can follow the steps in the JumpStart as per a normal application, with the above amendments to the JumpStart instructions.
Using a sub-directory within the ClarionDataServer
The IPDriver supports multiple database driver DLLs, which means that you can have a number of Secwin IPDriver DLLs running on the same server, each with it's own set of security files that it is maintaining. This is what you need to do in order to use a subdirectory within the ClarionDataServer:
1. Create the subdirectory within the ClarionDataServer directory (let's
call it MyDatabase)
2. Copy the IP_S4TPS6.DLL to this directory (i.e. c:\ClarionDataServer\MyDatabase)
3. In your application, go to the Files tab of the Secwin Global Extension
template, and in the Security File - Position group, select the 'Data
Directory' option and enter 'MyDatabase\' (including the quotes). You could
use a variable here as well (without quotes) if you wanted to load the
directory at runtime. The important thing to remember is that the path entered
is with respect to the ClarionDataServer directory (normally c:\ClarionDataServer\)
4. If you are not allowing your program to create security files, then you
need to copy the dssw4.tps file to the
c:\ClarionDataServer\MyDatabase
directory.
You can alternatively have the secwin data files residing in a different sub-directory to where the ip_s4tps6.dll resides. By adding the following to the Program Setup embed - immediately before the Secwin - After SetOwner and SetPath embed point. Note that the template setting in the position group still indicates where the ip_s4tps6.dll resides.
ds_SetPath(GLO:IPServerSubSir) !GLO:IPServerSubSir must contain the sub dir containing the dssw4 file.
Limitations
1) Only support for the TPS driver (i.e. dssw4.TPS) is currently available. Support
for other drivers will be made available on a demand basis.
Note: An example ships with Secwin (see Secwin Examples in this doc for details). If you are having difficulties getting your IPDriver enabled application to work, try this example t test where the problem lies.
This section describes some of the advanced functions available to you the programmer,
and where you might use them.
ds_BuildKeys
This function can be used to rebuild the keys stored inside the security file.
The primary reason for using this function is when you want to change the Locale
settings for your program. In Clarion if the Locale settings change then keys
need to be rebuilt.
ds_Crypt
This is a simple function for doing simply text encryption. Pass the string
to the function to encrypt it, and pass the encrypted string to the function
to decrypt it.
ds_InsertUserEx,
ds_ChangeUser, ds_DeleteUser
These functions allow you to add to and edit the list of users.
ds_UsersEx
and ds_UsersUserGroups
This function returns a Queue containing all the users currently in the file.
The Queue contains their First name, Surname, Login Code, and User Group setting.
ds_SetPath
The most common way to set the location of the Security file (dssw4) is to use
the Secwin.Ini file. However you can also set the path in code using this function.
|
Secwin Template Reference |
|
| Extension Templates | Code Templates |
| Global Extension : Activate Secwin features | Code : Call Current (Various) |
| Extension : Make Logo Screen | Code : Calling Current Counter |
| Extension : Run Logo Screen | Code : Calling Current Expiry Date |
| Extension : User Login Here | Code : Calling Set Pin |
| Extension : User Screen Security | Code : Calling CurrentlyLoggedIn |
| Extension : User Workgroup Filtering | Code : Calling Change Login |
| Control : Register Product Controls | Code : Calling Change Password |
| Extension: AutoPopulateUserScreenSecurity | Code : Calling Run Another Exe |
| Extension: CreateSecwinMenu | Code : Calling Lock Screen |
| Code : Calling Operator Browse | |
| Code : Calling SetLanguage | |
This is a Global Extension template which needs to be added to the Global area
in order for the Secwin features to work.
1. Open your App in the usual fashion
2. Choose Global Properties from the Edit menu ( You can also click
on the Global button to get here )
3. Click on Extensions
4. Click on
Insert
5. Choose Activate Secwin Features




If you add this extension to a screen then the screen will be displayed, but
only in the background. this template is used in conjunction with the
RunLogoScreen Extension
This is an Extension template which can be added to a screen to make it a background
screen. This background screen is ideal for displaying the application's current
user, current license etc. This effect only works on MDI applications, and the
screen must be an MDI child window screen. The best way to run this procedure
is by using the supplied RunLogoScreen extension
in your Main procedure.
Tip : If you have the MDI attribute clicked
off by mistake then the window will float on top of all your other windows instead
of going to the back.
Tip : Setting the border of the screen to
None, and the Caption to blank and ensuring that the System attribute is off,
improve the screen's look. You can also use the Center attribute on the Position
tab when designing the screen to have the screen automatically center itself.
1. Open your App in the usual fashion
2. Click on the Window procedure that you want to make a "background" window
3. Click on Extensions
4. Click on Add
5. ChooseMakeLogoScreen
| Do not Call ds_GetCurrent | Click on this if you do not want the Logo Screen to automatically load the current license details. |
| Level Names | If you want to change the names of the different levels then enter them here. |
This template calls your logo window, which makes the logo window visible.
This template starts a thread with your MDI logo window.
1. Open your App in the usual fashion
2. Click on your Main function
3. Click onExtensions
4. Click on Add
5. Choose RunLogoScreen Extension
| Logo Procedure | This is the name of the Logo Procedure to use. The Logo procedure should use the MakeLogo Extension. |
The user must enter a valid user code and password here before the screen will
open. If you are not using AccessControl, you will still need...
Use this extension wherever you want password protection. In the usual case,
where the user logs in before running the Application, use this template extension
on your 'main' function.
You can include any number of these extensions throughout your program. Each
time one is encountered the user will be required to enter a valid user code
and password in order to continue. In each section you can reset which users
are operators, and which are supervisors.
When the function, in which you use this extension, is completed then the user
is automatically logged out. The user then returns to the level, and accesses,
they had before entering the function.
You can tell the program to activate licensing support at this time, and "get"
a valid license.
You can include a "Super User" at this point. This user, although
deletable, will re-appear in the browse users list every time a user logs in.
1. Open the App in the normal fashion
2. Click on the procedure where you wish the login screen to appear
3. Click on theProperties button.
4. Click on Extensions
5. Click onAdd
6. Choose User Login Here from the list of available extensions
| Login Options Tab | Unique Area Name | This is the name for this login area. A program can have multiple login areas (each one with a unique name). If you have only one login area (as is probably the case) then you can just use the word Main. |
| Allow Case Insensitive Password | If this is ticked then passwords will be case insensitive. If this is off, then passwords will be case sensitive. | |
| Make Login Optional to End User | If this option is ticked, and there are NO users defined then the login screen will not be displayed. If this option is not ticked, and no users exist, then the user will be prompted to add the first user. | |
| Allow only 3 tries | If this is ticked, and the login fails 3 times, then the program will close. | |
| Allow Automatic Login from other EXEs | If this option is ticked on then you'll be able to automatically log into this program from other Secwin enabled programs, using the ds_Run template, or function. | |
| Allow Default Login values | If this is on, then you can set default login and password values. This allows you to 'auto-login' as well as supporting your own Login window. | |
| Default Login Code | Set this to a fixed value in 'quotes' - or a variable name. | |
| Default Password | Set this to a fixed value in 'quotes' - or a variable name. | |
| Don't show screen if default fails | If the default login fails, and this is ticked on, then the Secwin Login window will not be displayed. Otherwise the Secwin Login window will be displayed with the primed values. | |
| Force Password change every 30 days | If this is on the user will be asked to change their password every 30 days. | |
| Force Long password | If this is on then the user will be forced to have a password containing at least 6 alpha characters and 3 numeric characters. | |
| Display Login After Window Displays | If this is on, then your Frame will display before the login window. Normally the login window displays before the Frame window. | |
| Licensing Tab | Activate Licensing Support | Click this on to activate the licensing for this login. Typically you'll click this on for a single login in your application, usually the one on the frame. (Remember you app could have multiple login screens.) |
| Default to demo license | If you ship a security file with No license, and this option is on, then the user will automatically get a demo level license the first time the program is run. Note they will ONLY get 1 demo license. Deleting the dssw4 file will NOT result in another license. | |
| Valid for (days) | Active if the Default to Demo License is on. Default is 30 days. Set the length of time (in days) that you want the demo to last for. | |
| Level | Allows you to set what Level will be set when the Demo License is made. In the past this had to be Level Demo, now you can choose | |
| Disable Network Licensing | If this option is ticked on then the Concurrent Network Copies feature will not be enforced. | |
| Unique License Code | Enter a 4 character (no spaces) code here. This, along with a 4 digit number, will be used to name the .LIC files used for network copies. | |
| Super User Tab | Enable Super User | Tick this option on to enable Super Users. |
| Super User Login Code | Enter the Super User's Login code here. Note Super Users are probably not what you think they are See the section in the User Guide for more information. |
At runtime a supervisor can press a hotkey ( Ctrl F8 by default ), on this screen,
and get a list of operators, along with the list of restrictions. By using the
mouse he can toggle access rights to individual operators. Only users designated
as Operators for this area of the App who are not in groups, and user group
names, will be displayed on the list.
Include this extension in a function if you wish to restrict operators, on an
individual basis, from all, or part of, the function. This will automatically
check each operator as he enters the function to check if access to the screen
is permitted, and also to check if access to controls on the screen are allowed.
You can specify up to 30 other controls, apart from the actual access to the
screen, that the operator can be restricted from. The controls that are not
accessible can be either disabled, hidden or set to read-only.
1. Open the App in the normal fashion.
2. Point to the function you wish to protect.
3. Click on theProperties button.
4. Click on Extensions
5. Click onAdd
6. Choose User Screen Security from the list of available extensions
- OR -
Add the AutoPopulateUserScreenSecurity Global Extension template to your
application.
| General Tab | This Procedure Doesn't have a window | This is used when you are adding licensing support to a procedure which doesn't have a window - like a report. |
| Control Restrictions Button | Contains all the restrictions for the Access Control features. See below for more information. | |
| License Check and Restrictions Button | Contains all the restrictions for the Licensing features. See below for more information. | |
| Disable Screen Security Here | Click on this option to disable all the Secwin Screen Security in this procedure. In other words this is like deleting the extension, except that all your current settings are kept. This is useful if you suspect that this extension is causing a problem in your window. | |
| Control Restrictions Button | Unique Bit Position | You are allowed up to 30 groups of controls per window. Each group (a group may be just 1 control) needs a unique, unchanging number, from 1 to 30. Enter that number here. |
| Name | Enter the name of the group here. This name will be used on the Set Access window. | |
| Use Equate | Enter the equate label for the first control in the group here. (Most groups will probably have just this primary control). You can select the control from the drop down list box. | |
| Column | If the control set in the previous setting is a list box, then you can protect just a single column of the list box if you like. (If you leave this as 0 then the whole list box will be protected.). Enter a column number in here if you want to protect just a single column. | |
| Action | This determines what happens if the user does not have access to the control. For buttons and menu items Disable is recommended, for entry controls you probably want to Hide the controls. Occasionally (mostly with text-boxes) it's useful to set the control to Read-Only. This allows the user to cut & paste the entry, but not change it. This is useful for address fields and things like that. | |
| Attach other Controls | I mentioned above that you can apply the settings to a group of controls. By clicking on this button you can add more controls to the group | |
| License Restrictions Button | Disable all License checking here | Click this on if you want to bypass all the license checks here. Typically you'd do this if the extension has been added for the Access security above, but you want to prevent license checks. |
| Disable Valid License File Check here | This overrides the global extension option (see the global extension template help for details). | |
| Disable Valid Date Check here | This overrides the global extension option (see the global extension template help for details). | |
| Expiry Tab NEW | Warn of Impending Expiry | Click this on if you want Secwin to automatically warn the user when their program is nearing an expiry date. |
| Warning Period | This sets the length of the warning period in days. For example, if set to 14, then the program will start warning the customer 14 days before it expires. | |
| Action : Display Message | This allows you to specify the text of the message that will be displayed. | |
| Action : Call Procedure | This allows you to specify a procedure that mst be called. You can then create your own window procedure to display whatever you like. | |
| Levels Tab | Level Required for this screen. | If you set this to say Standard, and the user only has level Demo, or Lite, then this will cause the License to fail. |
| NEW | Control Restrictions | This allows you to restrict access to individual controls based on the Level. You can add as many controls as you like, and you can set the option to either hide, or disable, the control if the license fails. |
| Modules Tab | Optional modules required for this screen. | If you set any of the options on here, then the user will require the same module to be set, or the license will fail. For example if this procedure belongs to your General Ledger module (module 1) then you would click on optional module 1 here. If the user doesn't have the General Ledger then the license will fail. |
| NEW | Control Restrictions | This allows you to restrict access to individual controls based on the Optional Modules that are activated. You can add as many controls as you like, and you can set the option to either hide, or disable, the control if the license fails. |
| Action Tab | Action to take if License fails | If the user doesn't have the correct level, or the correct optional modules, or the license has expired, or the license is invalid, or the user has run out of network copies, then the license will fail. Exactly what happens when the license fails is up to you. |
| Show Warning and return to caller : This is the most common action. The user will see an error message and the procedure will close. | ||
| Return to caller without showing warning : Use this if you're going to show your own warning. | ||
| Disable all controls except.... : This option allows the window to continue opening, but all of the controls will be disabled (except for the ones you specify). This is useful on a frame so that the user can still run certain items (like Help | About) but not get into the bulk of the program. | ||
| Call Procedure : If you have your own Product Registration window, then you might want to call it directly (especially if the license on the Frame failed). | ||
| Counter Tab | Decrement Counter Here | If you click this option on then the counter will be decremented when this procedure runs. If the counter is already at 0 then the license will fail. Use this feature when you want to limit your program by number of runs, or number of reports etc. |
This template will auto-populate the UserScreenSecurity template to all your procedures in your application (except source and process procedures). Once added to your application, do not remove from the application, otherwise all the UserScreenSecurity templates will be removed (from their respective procedures).
This template is not recommended for small single-EXE applications - but can be very useful in Multi-DLL applications.
Note: This template can only be added to a frame with the UserLoginHere template added there.
This template will create a Security menu with the necessary Secwin menu items to enable the user to access Access Control and Registration windows, where applicable. It can only be added to a Frame procedure.
This template will control what items are visible (depending on what features you've selected). For example: If you have disabled licencing and registration, then the RegisterProduct item will not be displayed in the menu list. If you have selected to make Access Control optional, then only the Create First User item will be displayed. If you are not wanting to use Access Control at all, then you can disable the Create First User item.

Allows you to use the CWG variable in your browse filtering.
This allows you to filter records from the browse based on the current user's
workgroup. You can set the User's workgroup on the User Details Form, which
is called from the Browse Users Screen. This template will create a variable
called CWG (a long) which stores the current users workgroup. You can then use
this variable in your browse filtering.
1. Open the App in the normal fashion.
2. Point to the browse function you wish to filter.
3. Click on the Properties button.
4. Click on Extensions.
5. Click on Add.
6. Choose User Workgroup Filtering from the list of available extensions.
7. Click on the OK button.
8. Add your desired filter in the normal fashion.
Note : No actual filtering is done by this
template. You are free to implement filtering in the normal fashion. This template
simply defines, binds, and primes the CWG variable for your use.
This allows you to create a Register product window inside your application
(as apposed to using the deprecated RegisterProduct window inside the Secwin DLL).
Use the Template Utility provided to create a SecwinRegisterProduct window in your application.
See the Creating your own Product Registration window section for more details.
Allows the user to call the ds_CurrentName,
ds_CurrentLogin
or ds_CurrentLevel function and place the result on the status bar.
By using this template is is easy to see, on the status bar, the currently logged
in user. You can use any one of the user name, user login code or user level.
You can also prefix your own text or variable before the result of the function
call.
1. Go to the Properties screen of your Main Menu procedure
2. ChooseEmbeds
3. Choose After Opening Window
4. Choose the Call_Current code template
| Position in Status Bar | Enter the position in the status bar here. |
| Text | Enter any text here you want to appear before the variable part. For example if you're displaying the user's name then enter 'User Name' here. Use quotes for literal text, or a variable (without any !) |
| Call | Select the variable you want to display. Use Name for the user's name, Login for their Login code, or Level for their level |
![]()
Allows the developer to display the current value left in the counter.
Allows the developer to display the current value left in the counter. This
is useful if you have a counter based license. the result is stored in a field,
and you can display the field on a Window or a report. It makes use of the
ds_CurrentCounter function.
1. Add the Code template to an embed in your program. You can call this function
from just about any local (not global) embed point.
| Put the result in | Enter a field which will contain the result. The field should be a Long. |
![]()
Allows the developer to display the current value currently in the Expiry Date in the License
This is useful if you want to display to the user the date on which the license
will expire. It uses the ds_CurrentExpiryDate
function.
1. Add the Code template to an embed in your program. You can call this function
from just about any local (not global) embed point.
| Put the result in | Enter a Long field to contain the date. |
Used to Brand Windows and Reports with the name of the user who is the current
owner of this copy of the program. You can also use the
Call Get License Details template to get all the license details.
This code template is designed to be attached to a report, or window. It creates
a variable called ds_RegisteredCompany. It puts the name of the current License
owner into the variable for you. You can then put the string onto your window,
or report, and format it any way you like. It uses the function
ds_CurrentLicence.
1. Go to the Procedure you want to display the License name in
2. Click onEmbeds for the procedure
3. Choose an embed that is near the beginning of the procedure. The exact spot
will vary depending on your template, but any embed that happens before the
report starts printing is fine.
4. Click on the Insert button
5. Choose theCall_CurrentLicence code template.
6. Close the windows in the normal fashion.
Then go to your Report or Window structure and populate the new Local Data variable
called ds_RegisteredCompany
Allows the user to see the list of all the users currently logged into the system.
Note that the network licensing features must be activated in order for this to work.
This code template is designed to be attached to a menu item or button. It calls
the ds_CurrentlyLoggedInEx function.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. ChooseEmbeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose the
Call_CurrentlyLoggedIn code template.
6. Close the windows in the normal fashion.
Allows the user to call the Change Login Screen.
This code template is designed to be attached to a menu item or button. It calls
the ds_ChangeLoginEx function. If you're going
to use the built-in Secwin window then typically this would be called from a
menu item. If you are going to make your own Change Login window then you would
add this to the Ok button on your Change Login window.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. ChooseEmbeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose theCall_ChangeLogin code template.
6. Close the windows in the normal fashion.
| 1. This is CALLING the Secwin Change Login window | Click this option if you want the menu item to call Secwin's built-in Change Login window. OR |
| 2. This is calling Your Own Change Login window. | Click this if you want the menu item to call your own Change Login window. OR |
| 3. This IS the Ok button on your Change Login window. | Use this if this is the OK button attached to Your Change Login window. |
| Login | Enter a field name here which contains the Login code that the user just entered. (Only used if Option 3 above is chosen) |
| Password | Enter a field name here which contains the Password code that the user just entered. (Only used if Option 3 above is chosen) |
| Your Procedure | If you chose Option 2 above, then enter the name of your Change Login procedure here. |
| Parameters | If you chose option 2 above, then you can optionally enter your parameters to your procedure here. This is included for your convenience if you decide to make a procedure that accepts parameters. |
Allows the user to call the Change Password Screen.
This code template is designed to be attached to a menu item or button. It calls
the ds_ChangePasswordEx function. If you're
going to use the built-in Secwin window then typically this would be called
from a menu item. If you are going to make your own Change Password window then
you would add this to the Ok button on your Change Password window.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. ChooseEmbeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose theCall_ChangePassword code template.
6. Close the windows in the normal fashion.
| This is your own Change Password Window | If you've added this template to your own Change Password window, to the Ok button, then click this option on here. |
| Old Password | Enter a field name here which contains the Old Password that the user just entered. |
| New Password | Enter a field name here which contains the New Password that the user just entered. |
| Verify Password | Enter a field name here which contains the second copy of the new password that the user just entered. |
| Suppress Warnings | If this option is on then Secwin will not display any warnings if the request failed. This is usually done when you want to display your own warnings. See the ds_ChangePasswordEx docs for information on the possible error codes. |
![]()
Allows you to load all the current existing license details.
This is typically used when you are creating your own Product Registration screen.
It allows you to prime all your variables with the current values. It calls
several of the functions including ds_CurrentLicence,
ds_CurrentSerialNumber,
ds_CurrentCopies,
ds_CurrentCounter,
ds_CurrentAppLevel,
ds_CurrentExpiryDate and
ds_CurrentOptional
1. Add this to the Init method (in ABC templates) or to the After Opening Window
embed point if you are using the Legacy templates.
| Company | Enter the company field here. This should be a String(40). |
| Serial Number | Enter the serial number field here. This should be a String(20). |
| Copies | Enter the copies field here. This should be a Long. |
| Counter | Enter the counter field here. This should be a Long. |
| Level | Enter the level field here. This should be a Byte. |
| Expiry Date | Enter the expiry date field here. This should be a Long. |
| Optional Modules | Enter the optional modules field here. This should be an Array of bytes. The array should have at least 30 items. If you select the name from the lookup, then Clarion will automatically populate the field with a subscript. e.g. Modules[1]. You should remove the subscript part. e.g. Modules. |
Allows the user to call the Lock Screen Screen.
This code template is designed to be attached to a menu item or button. It calls
the ds_LockScreen function
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. ChooseEmbeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose theCall_LockScreen code template.
6. Close the windows in the normal fashion.
Allows the user to call the Operator Browse Screen.
This code template is designed to be attached to a menu item or button. It calls
the ds_OperatorBrowse function with the appropriate parameters.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button. This control should be visible from all the security areas
within your App, so you may need to add more than one control.
2. Click onActions for the control.
3. Choose Embeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose theCall_OperatorBrowse code template.
6. Close the windows in the normal fashion.
Allows the user to call the Register Product Screen.
This code template is designed to be attached to a menu item or button. It calls
the ds_RegisterProductEx function with the
appropriate parameters.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or a toolbar button.
2. Click on Actions for the control.
3. Choose Embeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose the Call_RegisterProduct code template.
| General Tab | This is your own Register screen | Click this option on if you're using this embed on the Ok button of your own Product Registration screen. Click this option off if you are calling the default Product Registration window. The rest of the options you see will depend on this option. |
| Levels Tab | Allow the following Levels | Allows you to control what Levels appear on the default Secwin window. Select the Levels you want Secwin to offer. |
| Optional Modules Tab | Allow the following optional modules | Allows you to control which Optional Modules appear on the default Secwin Window. Select the modules you want Secwin to offer. |
| Fields Tab | Company | This is set if this is your own Register Product screen. Set the field to match the Company field that the user just typed in. |
| Serial Number | This is set if this is your own Register Product screen. Set the field to match the Serial Number field that the user just typed in, or that you've set in your code. | |
| Copies | This is set if this is your own Register Product screen. Set the field to match the Copies field that the user just typed in, or that you've set in your code. | |
| Counter | This is set if this is your own Register Product screen. Set the field to match the Counter field that the user just typed in, or that you've set in your code. | |
| Level | This is set if this is your own Register Product screen. Set the field to match the Level field that the user just typed in, or that you've set in your code. | |
| Optional Modules | This is set if this is your own Register Product screen. Set the field to match the Optional Modules field that the user just typed in, or that you've set in your code. | |
| Activation Code | This is set if this is your own Register Product screen. Set the field to match the Serial Number field that the user just typed in. | |
| Advanced | Counter is Relative | The counter setting will be added to the existing counter value. |
| Activation code used once. | Prevents the same activation code being entered multiple times. Use when issuing relative counters to prevent multiple entry. |
Allows the user to run another Secwin program, using the currently logged in
user. The program being run must have the Allow Automatic Logins from other
EXE's option clicked on.
This code template is designed to allow you to run other programs, from within
the current program, at the same time automatically logging in to the new program
using the existing user's details. This template uses the ds_Run
function.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. Choose Embeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose the Call_RunAnotherExe code template.
| Program Name | Enter the program name to run here. This name can include the path if necessary. |
| Parameters | Enter any command line parameters, which will be sent to the new program, here. |
6. Set the name of the program to run as well as any other parameters that the program may need.
![]()
International language support.
Allows you to change the language file which will be used when displaying any
of the default Secwin windows. Makes use of the ds_SetLanguage function.
1. Add a control somewhere in your program. Usually this control would take
the form of a menu item in your main menu, but it could also be a button, or
a toolbar button.
2. Click on Actions for the control.
3. Choose Embeds
4. Choose Control Event Handling , after generated code, Accepted.
5. Choose the Call_SetLanguage code template.
| Language File Name | Enter the name of the language file here. Use 'Quotes' if this is a fixed name, or enter a variable if you want the name of the file to be stored in a variable. |
None
This function is not designed to be added to your main application - rather
it is used on the developer machine to stamp dssw4 files with PIN numbers.
This code template stamps the dssw4 file with an Application PIN number. Pin
numbers enhance application security be ensuring that only correctly "stamped"
dssw4 files will be considered valid for the application. A full description
of the PIN number concept, and when you would use this function, can be found
in the User Guide in the section entitled Application PIN numbers. It uses the
ds_SetPin function.
1. Remember this function would not be used inside the Application you are intending
to protect. Rather you need to create a separate utility. 2 examples of such
utilities are shipped with Secwin. They can be found in the \Clarion\3rdparty\Examples\Secwin\UsingPin
directory.
2. Add a control somewhere in your utility. This control could be a menu item
in your main menu, or a button, or a toolbar button.
3. Click on Actions for the control.
4. ChooseEmbeds
5. Choose Control Event Handling , after generated code, Accepted.
6. Choose theCall_SetPin code template.
| Application Name | Enter the name of the application here. You can use a variable, or 'quotes' for a fixed value. |
| Application PIN number | Enter the application Pin number in here. |
None
This function is not designed to be added to your main application - rather
it is used on the developer machine to generate Activation Codes. This template
makes use of the ds_GetActivationCode function.
Used in registration programs, like the included Register example application.
You feed the template the variables it needs and it returns a valid activation
code. You can find the Register example in the \clarion\3rdparty\secwin\register
directory
1. Add the code template to a button.
See Secwin Data Types for the Secwin Specific data types required by some of these functions.
| Access Control Functions | Licencing Functions | Miscellaneous Functions |
| ds_Allowed | ds_CheckCounter | ds_BuildKeys |
| ds_ChangeLoginEx | ds_CheckEncryptedActivationCodeEx | ds_CreSec |
| ds_ChangePassword | ds_CurrentAppLevel | ds_Crypt |
| ds_ChangePasswordEx | ds_CurrentCopies | ds_ExportTables |
| ds_ChangeUser | ds_CurrentCounter | ds_ImportTables |
| ds_ChangeUserEmailAddress | ds_CurrentExpiryDate | ds_Run |
| ds_ChangeUserPassword | ds_CurrentLicence | ds_SecwinMessage |
| ds_CountUsers | ds_CurrentLicenceDetails | ds_SetDefaultFontEx |
| ds_CurrentLastPasswordChange | ds_CurrentLimits | ds_SetLanguage |
| ds_CurrentLevel | ds_CurrentlyLoggedIn | ds_SetLogo |
| ds_CurrentLogin | ds_CurrentlyLoggedInEx | ds_SetOwner |
| ds_CurrentName | ds_CurrentOptional | ds_SetPath |
| ds_CurrentOperatorNumber | ds_CurrentSerialNumber | ds_SetPin |
| ds_CurrentUserGroup | ds_DecrementCounter | ds_SetSuperUser |
| ds_CurrentWorkGroupEx | ds_GenerateActivationCode | ds_UsePin |
| ds_GetAccessEx | ds_GetActivationCode | ds_InitFileCallback |
| ds_GetProperty | ds_GetCRCandLen | ds_GetSecwinFileHandles |
| ds_GetWorkGroupEx | ds_GetDriveSerialNumber | ds_OpenSecwinFile |
| ds_LoginText | ds_GetEncryptedActivationCode | ds_CloseSecwinFile |
| ds_LoginUser | ds_GetLevelText | ds_SetEncryptionKey |
| ds_Logout | ds_LicenceOk | ds_MakeValidFileName |
| ds_LogoutUser | ds_LoadLicenceFromXML | |
| ds_LockScreen | ds_RegisterProductEx | |
| ds_OperatorBrowse | ds_SaveLicenceToXMLEx | |
| ds_ModifyAccessEx | ds_SetMaxTableRecords | |
| ds_SetAccess | ds_TableMaxRecords | |
| ds_SetAccessEx | ds_UseLicence (change to Ex) | |
| ds_UpdateUser | ||
| ds_Users | ||
| ds_UserAllowed | ||
| ds_UsersEx | ||
| ds_UsersUserGroups | ||
| ds_UpdateUsersUserGroups | ||
| ds_ResetUserPassword | ||
| ds_GetUserPassword | ||
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| Calledby | String | This is the name of the function to which the user is requesting access. This parameter is not case sensitive. |
| Override | Long | This is an attribute that contains any overrides that the program may use to override the users access levels. This is not currently used and should be set to 0. |
| pUser | Long | The user number (if 0 then uses the current user). Required for NetWebserver applications (with multiple users logged in simultaneously). |
| pUserSite | string(4) | The user's site id (for Replicate enabled applications). |
This function enables the application to get the access rights for a specific
user for a specific part of the program ( usually a screen.) The function is
called using the ApplicationNumber as well as the FunctionName. The function
returns a string, in
which each character signifies that access has been granted or denied to a particular
section. If the bit is set the access has been granted, if it is not set then
access has been denied.
These accesses only apply to users designated as 'Operators' on the Operator
Browse screen. You cannot limit the access of an user designated as a 'Supervisor'.
A string which can be character tested to determine the access rights that
the user has been granted. These access rights are set by calling
ds_ModifyAccessEx
ds_LoginUser,
ds_ModifyAccessEx
ViewVideo Procedure
window WINDOW('Caption'),AT(-1,2,185,92),SYSTEM,RESIZE,MDI
BUTTON('Delete'),AT(68,28,,),USE(?DeleteButton)
BUTTON('Change'),AT(127,35,,),USE(?ChangeButton)
BUTTON('Cancel'),AT(74,53,,),USE(?CancelButton)
BUTTON('Ok'),AT(17,25,,),USE(?OkButton)
BUTTON('Print'),AT(19,51,,),USE(?PrintButton)
END
ThisAllowedString
string(252)
CODE
ThisAllowedString = ds_UserAllowed (Application Number,'ViewVideo',0,0)
if ThisAllowedString[1]
<> '1' then return.
OPEN(window)
WindowOpened=True
if ThisAllowedString[2]
<> '1' then hide(?OkButton).
if ThisAllowedString[3]
<> '1' then hide(?ChangeButton).
alert(DS_SECURITYKEY)
ACCEPT
| Parameter Name | Type | Description |
| Locale | String | Optional. A string suitable for passing to the Clarion LOCALE statement. |
Use this function to rebuild the keys in the Security file. Actually the main
reason for this function is to allow you to change the LOCALE settings for the
file. When you change your LOCALE settings then you need to rebuild the keys
in order for the new Locale to take effect.
Nothing
NewLogin String(12)
NewPassword String(12)
Code
ds_BuildKeys ()
ds_BuildKeys ('My.Env')
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
| FunctionName | String | This is the name of the function to which the user is requesting access. This parameter is not case sensitive. |
| Override | Long | This is an attribute that contains any overrides that the program may use to override the users access levels. This is not currently used and should be set to 0. |
This function enables the application to get the access rights for a specific
user for a specific part of the program ( usually a screen.) The function is
called using the ApplicationNumber as well as the FunctionName. The function
returns a long ( although currently only the low 8 bits are supported ), in
which each bit signifies that access has been granted or denied to a particular
section. If the bit is set the access has been granted, if it is not set then
access has been denied.
These accesses only apply to users designated as 'Operators' on the Operator
Browse screen. You cannot limit the access of an user designated as a 'Supervisor'.
A Long which can be bitwise tested to determine the access rights that
the user has been granted. These access rights are set by calling ds_SetAccess
ViewVideo Procedure
window WINDOW('Caption'),AT(-1,2,185,92),SYSTEM,RESIZE,MDI
BUTTON('Delete'),AT(68,28,,),USE(?DeleteButton)
BUTTON('Change'),AT(127,35,,),USE(?ChangeButton)
BUTTON('Cancel'),AT(74,53,,),USE(?CancelButton)
BUTTON('Ok'),AT(17,25,,),USE(?OkButton)
BUTTON('Print'),AT(19,51,,),USE(?PrintButton)
END
ThisAllowed long
CODE
ThisAllowed = ds_allowed (Application Number,'ViewVideo',0)
if ~band(ThisAllowed,1) then return.
OPEN(window)
WindowOpened=True
if ~band(ThisAllowed,2) then hide(?OkButton).
if ~band(ThisAllowed,4) then hide(?ChangeButton).
if ~band(ThisAllowed,8) then hide(?DeleteButton).
if ~band(ThisAllowed,16) then hide(?PrintButton).
alert(DS_SECURITYKEY)
ACCEPT
![]()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| Login | String | Optional. A default value for the Login. |
| Password | String | Optional. A default value for the Password. |
| Options | Long | Optional. Explained below |
This allows another user to Login without quitting the application. The login
screen will behave using the same options as was last passed to ds_LoginUser.
This function behaves the same as the ds_LoginUser function and uses the Login
and Password parameters in the same way.
If Options is set to 1 then the default Secwin screen will not be displayed.
This is used when you have your own ChangeLogin screen.
Note that you can create your own ChangeLogin window to collect the Login and
Password from the user, and pass them on to this function. In this way you can
bypass the built-in Secwin window.
A Byte containing 0 if the operation was successful, or 1 if the login was unsuccessful.
NewLogin String(12)
NewPassword String(12)
Code
ds_ChangeLoginEx (AppNum,NewLogin,NewPassword)
ds_LoginUser, Code
: Change Login, Making your own Secwin windows
| Parameter Name | Type | Description |
| App | Long | This is the Application number returned by ds_LoginUser. |
| pUser | long | The user number (as set in the ds_LoginUser function) |
| pUserSite | String(4) | Optional - for Replicate purposes, contains the SiteID of the user. |
| pPassword | String(252) | Contains the user's password. |
| pEmailAddress | String(252) | Contains the new Email Address. |
| Options | Long | A bit loaded flag: DS_DONTWARN: if added will not display warning messages. |
Allows a user to change their email address. Note: that only the person currently logged in can change their
EmailAddress. In other words the Password field must match the password that
the person currently logged in.
If Option is set to 1 then the Secwin warning messages will be suppressed.
A long containing 0 if the operation was successful, or one of the following error codes;
ds_InvalidUser - the user is not currently
logged in.
ds_InvalidPassword - incorrect password supplied.
ds_CannotBeBlank - the EmailAddress supplied is blank (if the ds_CannotBeBlank
is set in the options flag).
case ds_ChangeUserEmailAddress(AppNum,GLO:CurrentUser,,Loc:Password,Loc:EmailAddress,ds_CannotBeBlank)
of ds_InvalidUser
orof ds_CannotBeBlank
orof ds_InvalidPassword
!Error changing email address. The Email address was not changed for this
user.
else
message('EmailAddress changed successfully')
end
Note: You must use the UserID (a number) not the login (see ds_GetUserProperty).
ds_LoginUser, ds_GetUserProperty
Allows the user who is currently logged in to change his or her password. The
user will be required to enter his existing password, and then his new password
twice. There is only one password per user, regardless of the number of
applications or security areas.
To build your own password window, use
the
ds_ChangePasswordExfunction.
Nothing
NewPassword String(20)
OldPassword String(20)
Code
ds_ChangePassword(OldPassword,NewPassword)
ds_ChangePasswordEx, Code : Calling Change Password,Making your own Secwin windows
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| OldPassword | String(12) | The users old password |
| NewPassword | String(12) | Contains the new password |
| VerifyPassword | String(12) | Contains a copy of the new password. |
| Options | Long | Described below |
Allows a programmer to use his own
ChangePassword screen, and call this function to update the password stored
in the database. Note that only the person currently logged in can change their
password. In other words the OldPassword field must match the password that
the person currently logged in.
If Option is set to 1 then the Secwin warning messages will be suppressed.
A Byte containing 0 if the operation was successful, or one of the following error codes;
1 Incorrect Old Password
2 New password cannot be the same as old password
3 New Password and Verify Password don't match.
4 Password cannot be blank
6 Password must contain 6 Alpha and 3 Numeric Characters
This last requirement is enforced if the Force Long Password option on
the Login extension is set.
OldPassword STRING(12)
NewPassword STRING(12)
VerifyPassword STRING(12)
window WINDOW('Change Password'),AT(,,209,75),SYSTEM,GRAY,AUTO
PROMPT('Old Password:'),AT(34,6),USE(?OldPassword:Prompt)
ENTRY(@s12),AT(103,6,60,10),USE(OldPassword)
PROMPT('New Password:'),AT(34,22),USE(?NewPassword:Prompt)
ENTRY(@s12),AT(103,22,60,10),USE(NewPassword),PASSWORD
PROMPT('Verify Password:'),AT(34,38),USE(?VerifyPassword:Prompt)
ENTRY(@s12),AT(103,38,60,10),USE(VerifyPassword),PASSWORD
BUTTON('&Ok'),AT(56,55,45,14),USE(?Ok)
BUTTON('&Cancel'),AT(109,55,45,14),USE(?Cancel)
END
Code
open(window)
accept
if field() = ?Ok and Event() = Event:Accepted
if ds_ChangePassword(AppNum,OldPassword,NewPassword,VerifyPassword,0) = 0
post(event:closewindow)
end
end
end
close(window)
ds_ChangePassword, Code: Calling Change Password, Making your own Secwin windows
| Parameter Name | Type | Description |
| pActivationCode | string | The activation code to be verified |
| pProductDetails | ProductDetailsGroupType | A Secwin group (see Secwin Data Types for details) containing all the licence information used to verify the activation code add/change/delete the user. |
| pSeedCode | string | Contains the seedcode for the product (entered on the Licence Tab of the Secwin Global Extension template). |
| pAppNumber | long | Contains the AppNumber returned from the ds_LoginUser function. |
| pLimitsQueue | Queue | Contains the list of the counters and/or limits used in the activation code (see Secwin Data Types for details). |
| pOptions | long | A bit loaded flag: ds_OneTime - means that the activation code can only be used once. |
This function allows you to verify an activation code (generated by the ds_GetEncryptedActivationCode function) - against a set of licence information. The set of licence information must match that set used by the ds_GetEncryptedActivationCode function exactly.
The ExpiryDate of the licence (if the Activation Code
check is successful).
-1 = Activation code has expired.
-2 = Activation code failure (the Activation code does not match the details in
the ProductDetails and/or LimitsQueue)
-3 = Incorrect product (the Activation code is correct, but the product does not
match the one that the Activation code was issued for).
See the ds_GetEncryptedActivationCode example to set the details of the licence. These must match those that are used to generate the activation code.
case
ds_CheckEncryptedActivationCodeEx(ActivationCode,MyDetailsGroup,'MySeedCode',MyLimitsQueue,ds_OneTime)
of 0 to ds_SecwinLastDate
!Success - restart your application for the licence to
take effect.
of -1
!The activation code is no longer valid.
of -2
!Activation code failure. The Activation code does not
match the details specified. Please ensure that the details match exactly for
the code to take effect.
of -3
!In correct product. The activation code used is not
for this product.
of -4
!Activation code already used.
else
!Unknown activation code error.
end
See also ds_GetEncryptedActivationCode
This is a Registration related function. It allows the programmer to get the
current Application Level ( e.g. Demo, Lite, Standard etc) set in the current
license. Don't confuse this function with ds_CurrentLevel which is an Access
Control related function, and returns the Users current level.
A long containing the current Application Level. Valid values are 1 to 5. 1
is the lowest level (Demo) while 5 is the highest (Enterprise).
Result Long
Code
Result = ds_CurrentAppLevel()
Code : Get License Details, Using Levels
![]()
Allows the programmer to get the number of Copies set in the current license.
A long containing the current number of copies.
Result Long
Code
Result = ds_CurrentCopies()
Code : Get License Details, Using Network Copies
![]()
Allows the programmer to get the Counter set in the current license. This Counter
is set when the activation code is generated, and used.
A long containing the current Counter value.
Result Long
Code
Result = ds_CurrentCounter()
Code : Get License Details, Using Counters
This function generates an activation code to be used to licence your application at your user's site. This function would typically not be in your application, but in a separate application that you keep locally to generate activation codes. An example ships with Secwin that you can use to generate activation codes, or as this basis for your own application.
| Parameter Name | Type | Description |
| pActivationExpires | Long | The date the Activation Code expires (0 for unlimited - this will give a date limit of 12/31/9999). The maximum date is 08/20/2084. After this date the activaction code generated will be out of date, and unusable. |
| pLicenceExpires | Long | The date the Licence expires (0 for unlimited - this will give a date limit of 12/31/9999). The maximum date is 08/20/2084. This date is when the licence will fail, and the application will no longer be licenced. |
| pProductDetails | ProductDetailsGroupType | A handle to the ProduceDetailsGroup. (see Secwin Data Types for details) This contains all the necessary details to store in the activation code. |
| pSeedCode | string | A string containing a seedcode that your application uses. This seedcode must match the one used in your application. |
| pLimitsQueue | Queue | For Users: pass the equate InsertRecord to add, ChangeRecord to change and DeleteRecord to delete. You can add the ds_NoMessages Secwin equate to the request to disable internal error messages from being displayed. |
A string containing the activation code to register the application at the clients site (using the ds_CheckEncryptedActivationCode function).
MyDetailsGroup group(ProductDetailsGroupType),pre()
.
MyLimitsQueue queue(LimitsQueueType),pre().
ActivationCode string(20)
code
MyDetailsGroup.SiteLimiter = '$$$$'
MyDetailsGroup.CompanyName = 'Paying Company'
MyDetailsGroup.Product = 'MyProduct'
MyDetailsGroup.LicenceType = 0
!Permanent
MyDetailsGroup.Copies = 5
MyDetailsGroup.Level =
ds_ProfessionalLevel
MyDetailsGroup.SerialNumber = '12345'
MyDetailsGroup.OptionalModules = 0
MyLimitsQueue.Description = 'Default Counter'
!The old Secwin3 counter
MyLimitsQueue.Limit
= 100
MyLimitsQueue.LimitIsRelative = 1
!Counter is relative - so add 100 to the existing number in the licence.
add(MyLimitsQueue)
MyLimitsQueue.Description = 'Customers'
!Limit the customers entries to 100
MyLimitsQueue.Limit
= 100
MyLimitsQueue.LimitIsRelative = 0
add(MyLimitsQueue)
ActivationCode =
ds_GetEncryptedActivationCode(today()+31,today()+365,MyDetailsGroup,'MySeedCode',MyLimitsQueue)
See also ds_CheckEncryptedActivationCode
Note: This function has replaced the superannuated functions: ds_ChangeUser, ds_InsertUser and ds_DeleteUser
| Parameter Name | Type | Description |
| App | Long | The application number of the current application as returned by the ds_LoginUser function. |
| pUserDetails | ds_UserDetailsType | A Secwin group (see Secwin Data Types for details) containing all the information used to add/change/delete the user. Not all the fields are required (when changing a record) - although the user's login or number must be set (in order to retrieve the correct record). Also - you cannot use this function to change the password or email address of the user. |
| pRequest | long | For Users: pass the equate InsertRecord to add, ChangeRecord to change and DeleteRecord to delete. You can add the ds_NoMessages Secwin equate to the request to disable internal error messages from being displayed. |
Lets you insert a user, change a user's (or user group's) details, or delete a user in source code.
| 0 | Success |
| ds_ErrorInvalidUser | Invalid User (change/delete: the user is not in the data file, insert: required data is not complete) |
| ds_ErrorSuperUser | You are trying to delete a superuser. |
| ds_ErrorUsedElsewhere | The user you are trying to delete is used in another application |
| ds_ErrorLastSupervisor | You are trying to delete the last supervisor. |
| -errorcode() | An error occured while trying to save the data changes. |
MyDetailsGroup group(ds_UserDetailsType),pre()
.
code
MyDetailsGroup.Number = UserNumber
MyDetailsGroup.SiteLow = NewSiteLow
!We'll leave the other fields
blank, as they don't need to be changed.
case ds_UpdateUser(App,MyDetailsGroup,ChangeRecord + ds_NoMessages)
!We'll display our own message for errors that occur
of 0 !Success
of ds_ErrorInvalidUser
message('Operator Not Found')
of ds_ErrorUsedElsewhere orof ds_ErrorLastSupervisor orof ds_ErrorSuperUser
!Not valid for ChangeRecord - only for deleterecord
else
!Negative value means a file error occured
message('Error('&errorcode()&') Writing Record: ' & Error())
end
This function is included in the
docs for backward-compatibility reasons. It should be considered as obsolete.
The ds_UsersEx function should be used.
| Parameter Name | Type | Description |
| UserQueue | ds_UserQueueType | This is a queue defined in your application using the ds_UserQueueType queue structure. the queue you pass must have this structure. An example of such a queue is |
Structure
ds_UserQueue Queue,pre(_dsq)
Name string(20)
Surname string(20)
Login string(12)
UserGroup Long
end
This function fills in a queue all the users currently in the database. In other
words by using this function you can get the logins and names of all existing
users.
Nothing. The queue you passed now contains all the user details.
ds_UserQueue Queue,pre(_dsq)
Name string(20)
Surname string(20)
Login string(12)
UserGroup Long
end
code
ds_Users (ds_UserQueue)
ds_InsertUserEx, ds_ChangeUser, ds_DeleteUser, ds_CurrentOperatorNumber
| Parameter Name | Type | Description |
| SecurityAreaName | String | This is the name of the area being protected. Each name must be unique, even across applications, so by convention, this name is normally made up of the application name and the area name, separated by a pipe ( | ) symbol. The maximum length of this parameter is 43 characters, and it is not case sensitive. This is the same as the SecurityAreaName parameter from the ds_LoginUser function. |
Counts the number of users that have access to this Area. If you create your
own login screen, then you will probably want to create your own FirstUser screen
as well. This procedure lets you determine if the FirstUser fuinction needs
to be called.
long containing the number of users with Supervisor or Operator access.
code
if ds_CountUsers(Clip(AppNameDesc) & ' | Main') = 0
myFirstUser(Clip(AppNameDesc) & ' | Main')
end
This function creates the security file. Typically it's called from inside a
separate utility, but it can be called from inside your program.
Care should be taken if you add this to your application as it can mean a serious
breech of the security is possible. For example a user might overcome
the security simply by deleting the security file and running the program again.
This is less of a problem if the Licensing features are enabled as the program
will have to be re-activated before it will run.
| Tip : If you are using a file driver other than Topspeed to store your security file, then you must call ds_SetOwner before calling ds_Cresec. |
The function won't empty, or overwrite, any security file which might exist already.
Nothing
code
ds_SetOwner ('bobbybrown', 'washere')
ds_CreSec( )
Creating the Security File,
Activate
Security Extension, ds_SetOwner
| Parameter Name | Type | Description |
| TextString | String | This is the string to encrypt or decrypt. |
Allows you to perform simple encryption on a string. To decrypt the string you
pass the encrypted string to ds_Crypt. This doesn't provide a very high level
of encryption as no key is used, but it does prevent unsophisticated users from
finding sensitive text on the disk.
A String containing the encrypted or decrypted string.
Test String(12)
Code
test = ds_Crypt('hello') ! now test contains the encrypted string
test = ds_Crypt(test) ! now test contains the decrypted string
Exports the Secwin tables to a portable format. Useful when you need to move the tables from one storage system to another (for example TPS to MSSQL). The encrypted file is called dssw4.BIN and it will be created in the "Current directory". Use the ds_ImportFiles function to import the file.
| Parameter Name | Type | Description |
| pSelectDir | byte | If this is 0 or omitted, then the select file dialog box is not displayed and the exported table is merely created in the current directory. If 1 is passed, then a select file dialog box is displayed that allows you to select the file to export the data to. |
Tip : It is recommended that this function is only called After the call to ds_LoginUser.
Tip : Use SETPATH to set the current directory, however it is recommended that you restore the current directory to the previous value after the export.
Nothing
Code
ds_ExportTables()
Exports the Secwin tables to a portable format. Useful when you need to move the tables from one storage system to another (for example TPS to MSSQL). The encrypted file is called dssw4.BIN and it will be created in the "Current directory". Use the ds_ImportFiles function to import the file.
| Parameter Name | Type | Description |
| pSelectDir | byte | If this is 0 or omitted, then the select file dialog box is not displayed and the imported table is used in the current directory. If 1 is passed, then a select file dialog box is displayed that allows you to select the file to import the data from. |
Tip : It is recommended that this function is only called After the call to ds_LoginUser.
Tip : Use SETPATH to set the current directory, however it is recommended that you restore the current directory to the previous value after the export.
Tip : Data from the import is added to the existing Secwin data. Duplicate records are automatically discarded. However this function is designed primarily to move complete Secwin data, and is not designed to merge Secwin data. While merges of multiple data files may be successful, no guarantee is offered in this regard.
Nothing
Code
ds_ImportTables()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the date on which the password, for the logged
in user, was last change. Useful for implementing your own "Force Password
Change" feature when the built-in version is not flexible enough.
A long containing the date of the last password change in a Clarion standard date format.
Result Long
Code
Result = ds_CurrentLastPasswordChange(AppNum)
If Today()-Result > 7
ds_ChangePassword(AppNum)
End
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the Level of the user who is currently logged on.
This can be useful for displaying the login of the current user on the status
bar etc.
A long containing the level of the user currently logged on. The returned value
will be either DS_SUPERVISOR or DS_OPERATOR.
CurrentLevel Long
Code
CurrentLevel = ds_CurrentLevel(AppNum)
ds_CurrentLogin, ds_CurrentName,
ds_CurrentOperatorNumber,
Code : Calling Current
| Parameter Name | Type | Description |
| ApplicationNumber | Long | The application number (as returned by ds_LoginUser) |
| pUserNumber or pUserLogin | String | Either the user number (with the ds_GetProperty) or the user's login (with ds_GetUserProperty). If blank (for ds_GetUserProperty) or 0 (for ds_GetProperty), then the requested detail pertaining to the current user is returned). |
| pUserSite | String | The site ID of the User (for Replicate purposes) - may be omitted for non-Replicate applications. |
| pProperty | String | The name of the property to return: DefaultAccess - returns the Default access for the user. Level - returns the user's operator level Login - returns the user's login Number - returns the user's number (or ID). FirstName - returns the user's firstname LastName or Surname - returns the user's lastname/surname EmailAddress - returns the user's email address. WorkGroup - returns the workgroup that the user belongs to. LastPasswordChange - returns the date of the last password change. ExtraString - returns the contents of the extra string field (which you can use to store additional information in) ExtraLong - returns the contents of the extra long field (which you can use to store additional information in) FingerPrint1 - a CString that you can use to store a fingerprint or other data FingerPrint2 - a CString that you can use to store an additional fingerprint or other data |
These function returns information pertaining to a user (or the current user). Depending on the property passed, will depend on the value returned (see the pProperty parameter).
ReturnValue string(252)
!For Login, FirstName, LastName, EmailAddress, ExtraString
ReturnValue long
!For DefaultAccess, Level, Number, WorkGroup, LastPasswordChange, ExtraLong
ReturnValue cstring(1024) !For FingerPrint1
and FingerPrint2
Note: If the user does not exist or there is an file error in obtaining the user's details, then a blank string (equates to 0 for a long) is returned.
ReturnValue = ds_GetProperty(AppNum,0,,'FirstName')
& ' ' & ds_GetProperty(AppNum,0,,'LastName')
ReturnValue = ds_GetUserProperty(AppNum,Login,,'FirstName')
& ' ' & ds_GetUserProperty(AppNum,Login,,'LastName'
case ds_GetUserProperty(AppNum,Login,,'Level')
of ds_Operator
!This is an operator
of ds_Supervisor
!This is a Supervisor
of ds_NoAcccess
!This user is disallowed from the
application
end
case ds_GetUserProperty(AppNum,Login,,'DefaultAccess')
of ds_AllAccess
!This is user has all access to security
areas by default, unless restricted.
of ds_NoAcccess
!This user is disallowed from the security
ares by default, unless allowed.
end
Allows the programmer to get the current Expiry Date set in the current
license. This Date is set when the activation code is generated, and used.
A long containing the current date in a Clarion standard date format.
Result Long
Code
Result = ds_CurrentExpiryDate()
Code : Get License Details, Using Expiry Dates
Allows the programmer to get the name that this program has been licensed to
as set in the current license. This value can be used in the product as a "Branding"
technique. For example this value could appear on reports, on the MDI screen etc.
A string containing the company, or person, name of the registered user. This
string can be a maximum of 40 characters long.
result string(40)
code
result = ds_CurrentLicence()
Code : Get License Details,
Branding on Reports,
Branding Using Logo screens
This function returns all the licence details of the current licence used by the application.
A group containing the current licence information as follows:
| ProductDetailsGroupType | group,pre(_dsPDGT),type | |
| SiteLimiter | string(4) | !For Replicate - reserved for later use. |
| CompanyName | string(252) | !The name of the Company that the licence is valid for |
| Product | string(252) | !The licence name for this application (see the Licensing Tab on the Global Extension template) |
| Dealer | string(252) | !The label of the dealer selling the license (optional) |
| LicenceType | long | !The level of the licence type (see Using Different Licence Types for details) |
| Copies | long | !The number of users in the current license that can run this application concurrently (not valid for SQL applications) |
| Level | long | !The licence level of the current licence(equates: ds_DemoLevel, ds_LiteLevel, ds_StandardLevel, ds_ProfessionalLevel and ds_EnterpriseLevel) |
| SerialNumber | string(252) | !The serial number contained in the current licence |
| OptionalModules | long | !A bit loaded flag indicating the modules that the current license contains. |
| AdditionalString1 | string(252) | !Additional information contained in the licence |
| AdditionalString2 | string(252) | |
| AdditionalLong1 | long | |
| AdditionalLong2 | long | |
| AdditionalString3 | string(252) | |
| end |
LicenceDetails
group(ProductDetailsGroupType),pre(LD) .
code
LicenceDetails = ds_CurrentLicenceDetails()
message('Current licence details are:|' & |
' Company: '
& LD:CompanyName & '|' & |
' LicenceType:
' & LD:LicenceType & '|' & |
' Copies: ' &
LD:Copies & '|' & |
' Level: ' &
LD:Level & '|' & |
'
SerialNumber: ' & LD:SerialNumber & '|' & |
' Dealer: ' &
LD:Dealer)
| Parameter Name | Type | Description |
| Options | Long | Valid options are DS_DONTSHOWSCREEN. |
This function requires the registration features to be active. Allows the user
to see who else is logged on to the system. This is useful when you wish to
ask people to quit the program because of insufficient licenses, or if you need
to update the program on the server.
If the DS_DONTSHOWSCREEN option is used then the function will not open a screen
showing the list of users.
Irrespective of the parameter, a comma delimited list of User Names is passed
back from the function.
A comma delimited string containing the list of User Names currently on the system.
List string(255)
Code
ds_CurrentlyLoggedIn()
list = ds_CurrentlyLoggedIn (DS_DONTSHOWSCREEN)
Code : Calling Currently Logged In,
Using Network Copies,
ds_CurrentlyLoggedInEx
| Parameter Name | Type | Description |
| LoggedInQueue |
ds_LoggedInQueue | This is a queue defined in your application using the ds_LoggedInQueue queue structure. the queue you pass must have this structure. An example of such a queue is... |
LoggedInQueue
QUEUE,PRE(_dsqex)
Name
STRING(255)
Reserved
STRING(255)
END
This function requires the registration features to be active. It fills the
supplied Queue with the names of all the other users who are logged onto the
system. This is useful when you wish to ask people to quit the program
because of insufficient licenses, or if you need to update the program on the
server.
In addition to the Queue being populated, a comma delimited list of User Names
is passed back from the function.
This function is not designed to replace
ds_CurrentlyLoggedIn,
but rather to provide a method for getting the list of names in a Queue format.
This is particularly useful if large numbers of users will be connected, and
the string is not large enough for the whole list.
A comma delimited string containing the list of User Names currently on the system.
Note: The first item in the queue/string is the current user. This will mean that the user is duplicated in the queue of users. Don't forget to free the queue before calling the function, as the function will simply add to the queue.
UserQueue
QUEUE,PRE(_dsqex)
Name
STRING(255)
Reserved
STRING(255)
END
s
STRING(255)
code
s = ds_CurrentlyLoggedInEx (UserQueue)
Code : Calling Currently Logged In,
Using Network Copies,
ds_CurrentlyLoggedIn
Allows the programmer to get the optional modules that this program has been
licensed to as set in the current license.
A long, where each bit represents an optional module. You can test for a specific
optional module by BANDing the result with one of the DS_OM1 to DS_OM30 equates.
result long
Optionalmodule1 byte
OptionalModule2 byte
code
result = ds_CurrentOptional()
if band(result,DS_OM1) then OptionalModule1 =1.
if band(result,DS_OM2) then OptionalModule2 =1.
Code : Get License Details,
Using Optional Modules
Allows the programmer to get the Serial number as set in the current license.
A String (20) containing the Serial Number.
SerialNumber String(20)
code
SerialNumber = ds_CurrentSerialNumber()
Removes pDecrementBy (normally 1) from the value stored in the License. This is used when selling your
program by number of runs, or number of reports, or something like that.
0 if successful. 1 if failed. The function will fail if the counter is already set to 0.
Result Long
Code
result = ds_DecrementCounterEx(1)
If result = 0 then return.
Using Counters
ds_CheckCounter
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the Login Code of the user who is currently logged
on. This can be useful for displaying the login of the current user on the status
bar etc.
A string containing the login code of the user currently logged on. The maximum
length of the string is 12 characters.
CurrentLogin string(12)
Code
CurrentLogin = ds_CurrentLogin (AppNum)
ds_CurrentLevel, ds_CurrentName, ds_CurrentOperatorNumber, Code : Calling Current
![]()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
Allows the programmer to get the Name of the user who is currently logged on.
This can be useful for displaying the name of the current user on the status
bar etc.
A string containing the name of the user currently logged on. The maximum length
of the string is 40 characters.
currentname string(40)
code
currentname = ds_CurrentName(AppNum)
ds_CurrentLevel,
ds_CurrentOperatorNumber,
ds_CurrentLogin, Code : Calling Current
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the Operator Number of the user who is currently
logged on. This matches the number returned in the ds_UsersEx function.
You can use this number (which is unique for each operator) to link your own
user file to the Secwin user file.
A long containing the operator number of the user currently logged on.
CurrentOperator Long
Code
CurrentLevel = ds_CurrentOperatorNumber(AppNum)
ds_UsersEx, ds_CurrentLevel, ds_CurrentLogin, ds_CurrentName, Code : Calling Current
![]()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
This function has been deprecated in Secwin 4 for the following reason:
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the Workgroup of the user who is currently logged
on. The users' Workgroup is set on the users form by a Supervisor. Workgroups
are a way of grouping users for browse filter purposes.
A long. The number returned is the number entered in on the User form.
CWG long
code
CWG = ds_CurrentWorkGroup (AppNum)
Work Groups, ds_GetWorkGroupEx
![]()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
| CalledBy | String | This is a unique string for this procedure. Usually the procedure name. |
| OperatorNumber | Long | This is the number for the current Operator as returned by ds_CurrentOperatorNumber or in the users Queue returned by ds_UsersEx. |
This function returns the access rights for a particular user, for a particular
procedure in the application. If the CalledBy parameter is set to LEVEL then
it returns the user's Level. This function is provided primarily so you
can build your own SetAccess window.
A Long, containing the access rights for that user, for that particular screen.
This is basically the number that has been set using the ds_SetAccessEx function.
If the CalledBy parameter is set to LEVEL then it returns one of DS_NOACCESS,
DS_OPERATOR or DS_SUPERVISOR.
See the included Splash example for an example of a SetAccess window.
![]()
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
Allows the programmer to get the Name of the user who is currently logged on.
This can be useful for displaying the name of the current user on the status bar etc.
A string containing the name of the user currently logged on. The maximum length
of the string is 40 characters.
currentname string(40)
code
currentname = ds_CurrentName(AppNum)
ds_CurrentLevel, ds_CurrentOperatorNumber, ds_CurrentLogin, Code : Calling Current
| Parameter Name | Type | Description |
| pCounter | String | This is the Label of the Counter to Check or decrement. |
| pDecrementBy | Long | The number to decrement the existing value by. |
| pOptions | long | A bit loaded flag. DS_DONTWARN if added will not warn if the counter has reached 0. |
Removes pDecrementBy from the pCounter value stored in the License. This is used when selling your program by number of runs, or number of reports, or something like that. If the pCounter is blank, then the Default Counter will be used.
This function replaces the old ds_DecrementCounterEx and ds_DecrementCounter functions.
The Counter value before decrementing if successful. 0 if the Counter is 0 and
therefore no more records/reports/procedures are permitted on this licence. If the function fails then nothing
is removed from the counter. If pDecrementBy is 0, then the Counter
is not altered, but simply returned as is.
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| Login | String | The login code of the operator being deleted. |
Allows the programmer to delete a user in Source code. Users that are used in
other applications which share this file cannot be deleted. (Rather set their
Level to NoAccess using the ds_ChangeUser function). If the user is the last
Supervisor for an application, and other Operators exist, then he can't be deleted.
0 if successful.
1 if the operator doesn't exist.
2 if he's the last Supervisor.
3 if the user is used in another application
4 if some file-access-error prevented the delete. Use ERRORCODE() to get the actual error.
code
execute ds_DeleteUser(App,LoginCode)
message('Operator Not Found')
message('Can''t delete last supervisor')
message('Operator used by another program')
message('Unable to delete operator: ' & error())
end
ds_InsertUserEx, ds_ChangeUser
| Parameter Name | Type | Description |
| App | Long | This is the Application number returned by ds_LoginUser. |
| CalledBy | String | This is a unique string for this procedure. Usually the procedure name. |
| User | Long | This is the number for the current Operator as returned by ds_CurrentOperatorNumber or in the users Queue returned by ds_UsersEx. |
| UserSite | string(4) | This is the site id of the operatory (for Replicate applications). |
This function returns the access rights for a particular user, for a particular
procedure in the application. If the CalledBy parameter is set to LEVEL then
it returns the user's Level.
A Long, containing the access rights for that user, for that particular screen.
This is basically the number that has been set using the ds_ModifyAccessEx function.
If the CalledBy parameter is set to LEVEL then it returns one of DS_NOACCESS,
DS_OPERATOR or DS_SUPERVISOR.
if ds_GetAccess4(App,'Level',UserNumber,'$$$$')
= DS_OPERATORString then
!Do stuff for operators in here.
end
Access = ds_GetAccess4(App,CalledBy,UserNumber,'$$$$')
ds_UserAllowed, ds_ModifyAccessEx
Opens a screen that lets you generate an activation code. You wouldn't normally
include this function in an application. The Register.App example calls this
function so that you can generate unique activation codes based on your clients
name etc. The example can be found in the \Clarion\3rdParty\Examples\Secwin\Register
directory.
Nothing
code
ds_GenerateActivationCode()
ds_GetActivationCode,
Some Activation Code Secrets
![]()
| Parameter Name | Type | Description |
| Product | String | The name of your product as specified in the Secwin Global Extension. |
| Company | String | The name of the company which has bought the software. |
| SerialNumber | String | The serial number you have issued the company mentioned above. |
| Copies | Long | The number of concurrent network copies they are allowed to run. |
| Level | Long | The level they have purchased. 1 = Demo, 2 = Lite etc. ( Valid 1- 5 ) |
| Optional | Long | A bit mask of the optional modules they have purchased. 1 is module 1, 2 is module 2, 4 is module 3, 8 is module 4 etc. So to activate modules 2 and 4 this would be set to 10 ( 2+8 ). |
| ExpiryDate | Long | The date when the user's license will expire. This is a standard clarion date. |
| Counter | Long | The counter field. |
| SeedCode | Long | The seed code of the application as specified on the Secwin Global Extension. |
Takes all the required parameters and returns an activation code. This function
is provided so that you can design your own activation code generation procedures.
For an example of using this function see the Register.App demo application
This example is in the \clarion\3rdparty\examples\secwin\register directory.
This function is not typically called in the programs that you distribute.
A String of length 20 containing the Activation code.
AC String(20)
Code
AC = ds_GetActivationCode ('App','Comp','001',5,3,0,today()+30,0,1234)
ds_GenerateActivationCode,
Some Activation Code Secrets
| ParameterName | Type | Description |
| Drive | String | Optional. Contains the Root directory of the drive to check. If omitted then the Current Path will be used. |
Used to get the Serial Number of the Hard Drive. This can then be used as the
program's serial number. By comparing the two numbers you can detect when the
data has been moved from one hard drive to another.
Ulong containing the Serial Number
Code
If ds_GetDriveSerialNumber() <> ds_CurrentSerialNumber()
message('I'm an unhappy program.')
return
End
![]()
Obsolete.
Use ds_GetWorkGroupEx instead. ds_GetWorkGroup returns a Short not a Long.
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| OperatorNumber | Long | This is the number for the current Operator as returned by ds_CurrentOperatorNumber or in the users Queue returned by ds_UsersEx. |
Allows the programmer to get the Workgroup of another user. The users' Workgroup
is set on the users form by a Supervisor. Workgroups are a way of grouping users
for browse filter purposes.
A long. The number returned is the number entered in on the User form.
CWG short
code
CWG = ds_GetWorkGroup (AppNum,1)
Work Groups, ds_CurrentWorkGroup
![]()
| Parameter Name | Type | Description |
| SecurityAreaName | String | This is the name of the area being protected. Each name must be unique, even across applications, so by convention, this name is normally made up of the application name and the area name, separated by a pipe ( | ) symbol. The maximum length of this parameter is 43 characters, and it is not case sensitive. This is the same as the SecurityAreaName parameter from the ds_LoginUser function. |
| FirstName | String | Firstname of the user being added. Ignored if Number <> 0. |
| LastName | String | Lastname of the user being added. Ignored if Number <> 0 |
| LoginCode | String | The code the user will use when he logs in. His initial password will also be set to this value. Ignored if Number <> 0. |
| Number | Long | The User Number of an existing User to be granted First User rights to this area. If 0 then a new user (using the above parameters) will be created. |
If the login to your program is not optional, then an issue arises if no user
has access to the program. At this point Secwin insists that either an existing
user (who currently has No Access) is granted access to the system, or a new
user is created. In either case the user will be granted Supervisor status.
0 = Success. Otherwise Failure.
Code
If choice(?list1) < 0
get(q,choice(?list1))
ds_InsertFirstUser(AppName,FirstName,LastName,LoginCode,q.Number)
Else
ds_InsertFirstUser(AppName,FirstName,LastName,LoginCode,0)
End
This function is obsolete. It's exactly the same
as calling ds_InsertUserEx with the UserGroup
parameter set to 0. It is included here for backward compatability reasons.
| Parameter Name | Type | Description |
| AppNum | Long | The application number of the current application as returned by the ds_LoginUser function. |
| FirstName | String | Obvious (for Users). If the UserGroup parameter is set to -1 then this contains the UserGroup Name. |
| LastName | String | Obvious (for Users). If the UserGroup parameter is set to -1 then this contains a space followed by the UserGroup Name. |
| LoginCode | String | The code the user will use when he logs in. His initial password will also be set to this value. |
| InitialAccess | Long | 1 = All Access otherwise No Access. |
| WorkGroup | Long | The users Workgroup number. this is the same as the Workgroup field on the usual operator form. |
| Level | Long | One of DS_SUPERVISOR, DS_OPERATOR or DS_NOACCESS |
| UserGroup | Long | User Group Number. If this is set to -1 then this is a UserGroup (not a User) being added. |
Lets you add a user (or user group) to the system in source code. As in the
screen version the user's initial password is set the same as his login code.
If the user exists, or if one of the parameters is blank, then the function
will fail.
If you are adding a User Group then the WorkGroup field is ignored, and the
FirstName field contains the User Group Name (eg Sales). The LastName parameter
should contain a space and the FirstName value. The Login code should be blank.
0 = successful.
1 = Either No FirstName, no LastName, no LoginCode, or InitialAccess not set to 0 or 1.
2 = An error adding the operator to the File (use Error() and ErrorCode() for details)
Code
ds_InsertUserEx (AppNum, 'Bill', 'Gates', 'BG',1,0,DS_OPERATOR,0)
ds_InsertUserEx (AppNum, 'Sales', ' Sales','',1,0,DS_OPERATOR,-1)
ds_UsersEx, ds_ChangeUser,
ds_DeleteUser
| Parameter Name | Type | Description |
| RqdLevel | Long | The license level required at this point. Valid values are 1 to 5. Invalid values are automatically set to 3. |
| RqdModules | Long | The optional modules required at this point. Valid values are 0 or a combination of the DS_OM1 through DS_OM30 equates. |
| Options | Long | Various options that modify the behaviour of the function. |
Checks the users current license and returns a value to tell you if it passed
or failed the check. Equates have been defined for the different optional modules,
namely DS_OM1 thru DS_OM30. You can modify the behaviour by using the options
parameter with one or more of the following values.
DS_NOWARN : By default Secwin displays a warning to the user when one of these
checks fails. By including this option no warning is displayed.
DS_NODATECHECK : This ignores the checks for errors 3 and 4.
DS_NONETWORKCHECK : This ignores the check which could return error 5.
DS_MULTIDATA : This ignores the check that could return error 7.
0 if successful.
1 if the current license level is not sufficient.
2 if the current license has expired
3 if the current PC date is less than the date of a previous use of the license.
4 if the current Pc date is more than 2 years later than the previous use of the license.
5 if too many network users are logged in.
6 if the current licence's optional modules are not sufficient.
7 if the date and time of the
dssw4 file goes backwards. (suppress this check with DS_MULTIDATA)
Result long
Code
Result = ds_LicenceOk(1,0,0)
Result = ds_LicenceOk(3,DS_OM1,DS_NOWARN)
Result = ds_LicenceOk(5,DS_OM1 + DS_OM8,DS_NOWARN + DS_NODATECHECK)
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
Allows the user who is currently logged in to lock the application while being
away from the terminal temporarily. The screen is blacked out and the user must
enter their password before the application will continue. Note that the machine
is not locked as the Windows task manager is still active. The application can
also be terminated using the task manager.
Nothing
Code
ds_LockScreen (AppNum)
Ancillary User Functions,
Code : Calling Lock Screen
| Parameter Name | Type | Description |
| pUserLoginOptions
|
ds_UserLoginOptions | This is a group containing: AreaName: the name of the area being protected. Each name must be unique, even across applications, so by convention, this name is normally made up of the application name and the area name, separated by a pipe ( | ) symbol. The maximum length of this parameter is 252 characters, and it is not case sensitive. Options: This parameter governs the behaviour of the Login function. Multiple options can be added together. Possible values are listed below. Login: This is the Login code. If blank - returned with an invalid login. Password: This is the Password. If blank - returned with an invalid login. |
| pUser | long | A handle to a long to return the user that is logged in (to store locally - particularly for WebServer applications). If 0, then the user is invalid. |
DS_DEFAULT (0) : Default behaviour. A login is definitely required, and the
password is case sensitive. Automatic logins are not allowed, and unlimited
login tries are accepted.
DS_CASESENSITIVITYOFF : If this flag is present then the User password is not
case sensitive.
DS_THREETRIES : Limits the number of login attempts to 3 before the program
automatically aborts the login attempt.
DS_USECURRENTLOGON : Allows this application to accept automatic login attempts,
using the ds_Run function.
Allows a user to login to the program, or program area. A window will be opened
allowing the user to enter a user code and a password. If there are no users
defined for this application then one of the following two actions will occur.
1. If security is not optional then you will be asked to either assign an existing
user to this area as a Supervisor, or to add a new user as a Supervisor. If
you add a new user then the initial password is the login code.
2. If security is optional then no window will be opened and the user will automatically
be given the Supervisor level.
If the DS_USECURRENTLOGON flag is set then the function will attempt to log
the user in using the same login code and password of the calling program. The
calling program uses the ds_Run function (or template) to run this program.
The Application Number (long).
This number is used by other functions so it must be stored, a global, non-threaded
long is the perfect storage vessel. If the number returned is 0 then the login
was unsuccessful and appropriate action should be taken.
If you have multiple login areas within one application then store the application
number (AppNum) in a queue, adding the new AppNum to the top of the queue when
successfully logging in, and removing it when logging out. This ensures that
AppNum always points to the current user area.
Calling ds_LoginUser automatically logs out the existing user for this instance
of the area, if one exists. In other words calling ds_LoginUser (SecurityAreaName,
x) causes an implicit ds_LogoutUser (ApplicationNumber) - i.e. a logout of the same
area - to be called before ds_LoginUser. If no user is logged in then ds_LogoutUser
ignores the request.
AppNum long
MyUserLoginOptions
group
AreaName
string(252)
User
string(252)
Password
string(252)
Options
long
end
MyUser
long
Code
MyUserLoginOptions.AreaName = 'MyApplication | Main'
MyUserLoginOptions.User =
'Geoff'
MyUserLoginOptions.Password = 'MyPassword'
MyUserLoginOptions.Options = 0 !Use the equates listed
above.
AppNum =
ds_LoginUser (MyUserLoginOptions
, MyUser)
if AppNum = 0
! login was unsuccessful
return
End
ds_Logout, Extension
: User Login Here, Login and Password Access
Control, Making your own Secwin windows
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| pUser | Long | This is the user ID as set by ds_LoginUser. |
Allows a user to logout of an application, or application area. The user will
have to re-enter his login code and password before he can re-enter the part
of the application protected by the password.
It is not necessary to Logout if the program is being terminated.
0 if successful. 1 if unsuccessful.
If the function returns 1, then the user was not logged in to the application.
AppNum long
Result long
code
AppNum =
ds_LoginUser ('Video.Exe', ds_DEFAULT,'','')
if AppNum = 1
! login was unsuccessful
return
End
< function code goes here >
result = ds_LogOut (AppNum)
return
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
Allows you to Browse the users for this Application or Security area. Only Supervisors
have access to this screen. A Supervisor must use this function to add, edit
or remove other Supervisors or Operators.
Nothing
AppNum long
code
ds_OperatorBrowse (AppNum)
Operator Browse and Form, User Groups, Work Groups
| Parameter Name | Type | Description |
| Product | String | The name of the product. |
| Seed | Long | The developer's seed code. |
| Options | Long | Various options, described below. |
| Company | String | The name of the company the product is licensed to. |
| SerialNumber | String | The serial number of the product. |
| Copies | Long | The number of copies that the user may simultaneously run on a network. |
| Level | Long | The level that the user is licensed to. |
| Modules | Long | The optional modules that the user has access to. |
| Activation Code | String | The activation code as returned by ds_GenerateActivationCode. |
| Counter | Long | The number that the Counter must be set to. |
This function is used to change the users current license levels.
NOTE: This function relies on the existance of a licence already. It
merely changes the existing licence. If you are handcoding the call, then you
need to first call ds_UseLicence in order to
create an initial licence.
The product parameter is set with the name of the product. This is usually hard
coded into an application, and cannot be changed on this screen.
The seed code is used so that other developers cannot generate activation codes
for your applications. This is normally hard coded into the application, and
isn't seen by the end user.
The options parameter allows you to change the way the screen behaves.
If it contains any of the DS_LVL equates (DS_LVL1 to DS_LVL5) then that level
will not be displayed on the screen. So you can hide the Professional and Enterprise
options by including DS_LVL4 + DS_LVL5 in the options parameter.
If it contains any of the DS_OM equates (DS_OM1 to DS_OM15) then those optional
modules will not appear. So to hide optional modules 13 thru 15 you would include
DS_OM13 + DS_OM14 + DS_OM15 in the options parameter. If this parameter includes
DS_OM16 then all optional modules from 16 to 30 are hidden.
If it contains the DS_DONTSHOWSCREEN parameter then the screen will not be opened.
In this case you MUST pass all the correct values, including the activation
code, to the function. This is available so that you can draw your own RegisterProduct
screen. You should then check the value returned to make sure the call was successful.
If it contains DS_RELATIVECOUNTER then any value in the Counter field will be
ADDED to the user's current Counter value. Use this in situations where you
are basically trying simply to increment the number stored in the counter at
the client.
If it contains DS_ONETIME then the activation code can only be entered once.
If it is entered a second time it will fail. This prevents a user from entering
a code, using up the Counter, and re-entering the same code (within the 7 day
window).
Using the company, serial number, copies, level, modules and activation code
parameters you can prime each of the values on the screen. If you omit any of
these parameters then they will default to their current value.
0 if successful, 1 if Invalid Activation code.
code
ds_RegisterProduct('Wonderprog',12345678,0)
ds_RegisterProduct('Wonderprog',12345678,DS_LVL4+LVL5)
ds_RegisterProduct('Wonderprog',12345678,DS_LVL4+LVL5+DS_OM15)
Code : Calling Register Product,
Overview of Licensing,
Making your own Secwin Windows
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| pUser | Long | The user's login number. |
Allows you to launch another Secwin enabled EXE, performing an automatic login
using the currently logged in user.
In other words, App A can use this function to run App B, at the same time passing
App B the login code and password of the current user. App B will automatically
log the person in.
In order for this to occur App B MUST have the login option DS_AUTOLOGON bit
set. On the Login User Here template this option is referred to as "Allow
automatic login's from other EXEs".
A string which needs to be included as a parameter in the Clarion "Run" statement.
code
run ('ProgName ProgParam ' & ds_Run (AppNum))
Code : Run Another Exe,
Secwin Examples
| Parameter Name | Type | Description |
| pDetailsGroup | ProductDetailsGroupType Handle | A reference to a group containing all the Licence details. The group must be declared as type: ProductDetailsGroupType |
| pLimitsQueue | queue | A queue containing the table limits and counters contained in the licence. |
| pXMLFile | string | Contains the name of the XML file to save the licence details to (if saving to file) - otherwise contains the actual XML string (if pXMLStringLen is not omitted) |
| pXMLStringLen | long | A long containing the length of the xml string. If omitted, then pXMLFile is the name of an XML file to load. |
This procedure allows Secwin to import licence details from either an XML file or a string in XML format (if the data is already loaded into a string).
long - 0 for success, otherwise an error occurred.
| Parameter Name | Type | Description |
| pDetailsGroup | ProductDetailsGroupType Handle | A reference to a group containing all the Licence details. The group must be declared as type: ProductDetailsGroupType |
| pLimitsQueue | queue | A queue containing the table limits and counters to be contained in the licence. |
| pXMLFile | string | Contains the name of the XML file to save the licence details to (if saving to file). This must not contain a path as well as the name will be converted to a valid filename (i.e. invalid filename chars will be converted to '_'). See ds_MakeValidFileName for details. |
| pSecwinXMLString | ds_SecwinXMLString | A Secwin data type to contain the licence details in a string (in XML format) - rather than saving to a file. |
| pOptions |
SaveLicenceToXMLOptionsGroupType |
A Secwin data type to contain the Options in a group
passed to the function: EncodingType - should be either 'URLEncoded' (default if blank) or the old 'ISO-8859-1'. |
This procedure allows Secwin to export licence details to either an XML file or a string in XML format (if not required to save directly to a file).
Note: If you are saving to an XML string, then you must dispose the string after using it (see the example code below)
long - 0 for success, otherwise an error occurred.
SecwinXMLString
group(ds_SecwinXMLString) .
code
!Here's an example of how
you would create an XML licence string:
if
ds_SaveLicenceToXML(REG:CodeGroup,Queue:Browse,,SecwinXMLString) .
!Do code using XML string such as:
MyString = SecwinXMLString.bin !The
bin item in the group contains the contents of the string.
MyStringLen = SecwinXMLString.len !The len item in the
group contains the length of the string
dispose(SecwinXMLString.bin)
!You must dispose the string after using it.
!Here's an example of how you would create an XML
licence file:
if
ds_SaveLicenceToXML(REG:CodeGroup,Queue:Browse,clip(REG:CompanyName) & '_' &
clip(REG:Product) &'.xml') .
See Secwin Data Types ; ds_MakeValidFileName
![]()
| Parameter Name | Type | Description |
| pfileName | string | The name of the file that must be stripped of it's invalid characters. |
This procedure returns a valid filename that the ds_SaveLicenceToXML function will use to create the xml file for the licence details. You can then use this filename to handle the file that the ds_SaveLicenceToXML function creates.
string - contains the pFileName with invalid dos filename characters replaced with '_'
if ds_SaveLicenceToXML(REG:CodeGroup,Queue:Browse,ds_MakeValidFileName(clip(REG:CompanyName) & '_' & clip(REG:Product) &'.xml')) .
See Secwin Data Types ; ds_SaveLicenceToXML
| Parameter Name | Type | Description |
| MakeoverObject | Makeover | A reference to a Makeover objected created in the Exe. This would typically be ThisMakeover |
This procedure allows the Secwin screens to support CapeSoft's
Makeover
accessory. The Makeover object is created by the Exe, and then this function
is used to pass a pointer to the object, to the Secwin DLL. Note that
Makeover is not required in order for Secwin to work properly.
Nothing.
code
ds_SecWinMakeover(ThisMakeover)
| Parameter Name | Type | Description |
| MessageName | String | This is one of the Standard Secwin Message Names. |
This function gets, translates, and displays one of the common Secwin error messages.
Valid message names are
| MessageName | Default Message |
| activationfailed | Incorrect Activation Code. Please consult your application supplier. |
| activationsuccessful | Activation Successful !! Please quit the application for new settings to take effect. |
| accessrestricted | Your access to this part of the program has been restricted. |
| cantdeletelast | You cannot delete the last supervisor before deleting all the other users, or setting their access to ''No Access''. |
| cantdeletesuperuser | This is a super user created by the developer and cannot be deleted. |
| featurenotavaliable | This feature is not available in your Level of the program. Consult your application supplier for more information |
| productexpired | Your product has expired. Consult your application supplier. |
| toomanyusers | Too many people are already running the system. People already logged in include ... |
| notlicenced | You are not licensed to use this module. |
| filecorrupted | Your Security file has become corrupted. Consult your application supplier for a new activation code. |
| badoldpassword | Incorrect Old Password |
| cantbesame | New password cannot be the same as old password |
| passwordsmustmatch | New passwords must match. Please try again. |
| cantbeblank | Password cannot be blank |
| cantbesimple | Password must contain 6 Alpha and 3 Numeric characters |
| invalidpassword | Invalid Password |
| invalidlogin | Invalid Login |
| licensenotloaded | Call to ds_LicenceOk, but License Not Loaded by ds_UseLicence |
Nothing.
code
ds_SecWinMessage('AccessRestricted')
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. |
| ScreenName | String | This is the name of the screen or function. This name must be unique within an application. |
| Options | String | This string contains all the access options for this function. Each item in the string is separated by a pipe (|) character. There may be up to 8 items in the string. Each item must be 6, or fewer, characters long. These items then appear on the Set Access screen in different columns. |
This screen is normally called from within a specific function in order to change
the access levels for the different operators, for that screen. Only Supervisors
have access to this function. The access levels are retrieved using the ds_UserAllowed
function. ds_ModifyAccessEx is normally invoked by pressing a hotkey. This hotkey
is normally stored in the DS_SECURITYKEY equate. By default this key is Ctrl-F8.
The function can however be called in almost any manner, for example by using
a button on the window.
The Options parameter string contains all of the access options for the calling
function, as you want them to be displayed on the ds_ModifyAccessEx browse box.
Nothing
ViewVideo procedure
code
< normal opening window code etc goes here >
alert(DS_SECURITYKEY)
accept
if keycode() = DS_SECURITYKEY
ds_ModifyAccessEx (AppNum,'ViewVideo','Access|Delete|Print')
End
< rest of accept handling goes here >
End
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
| ScreenName | String | This is the name of the screen or function. This name must be unique within an application. |
| Options | String | This string contains all the access options for this function. Each item in the string is separated by a pipe (|) character. There may be up to 8 items in the string. Each item must be 6, or fewer, characters long. These items then appear on the Set Access screen in different columns. |
This screen is normally called from within a specific function in order to change
the access levels for the different operators, for that screen. Only Supervisors
have access to this function. The access levels are retrieved using the ds_Allowed
function. ds_SetAccess is normally invoked by pressing a hotkey. This hotkey
is normally stored in the DS_SECURITYKEY equate. By default this key is Ctrl-F8.
The function can however be called in almost any manner, for example by using
a button on the window.
The Options parameter string contains all of the access options for the calling
function, as you want them to be displayed on the ds_SetAccess browse box.
Nothing
ViewVideo procedure
code
< normal opening window code etc goes here >
alert(DS_SECURITYKEY)
accept
if keycode() = DS_SECURITYKEY
ds_SetAccess (AppNum,'ViewVideo','Access|Delete|Print')
End
< rest of accept handling goes here >
End
| Parameter Name | Type | Description |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginText. |
| CalledBy | String | This is a unique string for this procedure. Usually the procedure name. |
| OperatorNumber | Long | This is the number for the current Operator as returned by ds_CurrentOperatorNumber or in the users Queue returned by ds_UsersEx. |
| Rights | Long | These is the rights for this operator, for this window. Each bit represents a different right. This is matched to the number |
This function sets the access rights for a particular user, for a particular
procedure in the application. This function is provided primarily so you
can build your own SetAccess window.
Nothing
See the included Splash example for an example of a SetAccess window.
![]()
| Parameter Name | Type | Description |
| App | Long | This is the Application number returned by ds_LoginUser. |
| CalledBy | String | This is a unique string for this procedure. Usually the procedure name. |
| User | Long | This is the number for the current Operator as returned by ds_CurrentOperatorNumber or in the users Queue returned by ds_UsersEx. |
| UserSite | string(4) | This is the operator's site (for Replicate applications). |
| Rights | string | These is the rights for this operator, for
this window (dependant on the Operation).
Each character represents a access area right. Obsolete: Each bit represents a different right. This is matched to the number (Secwin 3 functionality). |
| Operation | Long | An equate, governing how
the existing access rights are modified: ds_ReplaceExistingAccess - the Rights string replaces the existing rights of the user. ds_ClearAccessChars - Merges the Rights parameter with the existing Access rights, by clearing the existing access chars, in the positions that are set to 1 in the Rights parameter. Ignores characters in the existing access where 0 exists in those corresponding positions in the Rights parameter. ds_SetAccessChars - Merges the Rights parameter with the existing Access rights, by setting the existing access chars, in the positions that are set to 1 in the Rights parameter. Ignores characters in the existing access where 0 exists in those corresponding positions in the Rights parameter. |
| AccessIsString | Long | Set if the Rights is a string, otherwise clear (if it represents an old Secwin 3 bit flagged long). |
This function sets the access rights for a particular user, for a
particular procedure in the application.
Nothing
ds_ModifyAccessEx(App,CalledBy,UserNumber,'$$$$',
NewAccessString,,1)
!Replace the existing access rights
ds_ModifyAccessEx(App,CalledBy,UserNumber,UserSite,4,1,-1)
!Force the user's access to be on for group 4 of the CalledBy area.
ds_ModifyAccessEx(App,CalledBy,UserNumber,UserSite,all('1',252),0,1)
!Force the user's access for all groups on this CalledBy area to NO ACCESS.
| Parameter Name | Type | Description |
| Face | String | The name of the font to use. |
| Size | Long | The size of the font to use. |
| Color | Long | The color of the font to use. Valid colors, such as Color:Black, are in the Equates.Clw file. |
| Style | Long | The style of the font to use. Valid styles, such as Font:Regular, are in the Equates.Clw file. |
| Charset | Long | The Charset to use. |
This function allows you to set the font that Secwin will use on it's screens.
If you call the function with no parameters then the standard Windows Font Dialog
box will be called so that the user can select the font.
Note: that only versions of Clarion 5.5 and later support CharSets. In the previous
versions of Clarion, the Charset will be ignored.
Nothing
code
ds_SetDefaultFont('Arial',10,Color:Black,Font:Regular)
| Parameter Name | Type | Description |
| LanguageFileName | String | This is the name of the language file to use. If this name is invalid, or the file cannot be found, then Secwin will default to English. |
Allows you to adjust the text which appears on the Secwin screens. This is used
to translate the native English of the Secwin screens into other languages.
Note that this can be called from before or after the user logs in. If this
is called before the user logs in then the settings for the language file in
the various ini files will be ignored.
Nothing
User Guide : Internationalization support
AppNum long
code
ds_SetLanguage ('Spanish.Irf')
Code : Calling Set Language,
Translating Secwin Windows
| Parameter Name | Type | Description |
| LogoFileName | String | This is the name of the logo file to use. |
| CallbackFunctionAddress | Long | This parameter is reserved for future use. You should set this to 0. If this is set to -1 then the Secwin about screen will not appear if a user clicks on the Logo. |
Allows you to change the logo that appears on all of the Secwin screens.
Nothing
code
ds_SetLogo('c:\logo.ico',0) ! use logo in root directory
ds_SetLogo('logo.ico',0) ! use logo in current directory
| Parameter Name | Type | Description |
| Owner1 | String | This is the Owner attribute of the Security files. (dssw4) |
| Owner2 | String | This is the Owner attribute of the License files. (.LIC) (for flat files). If the backend selected is a SQL backend, then this will be used for the DriverString. |
This function allows you to set the Owner attributes for the Security, and License
Files. This function is required to support the alternative file drivers. when
you use the Topspeed driver (the default setting) then the owner variables are
set internally, and this function has no effect. If you are using one of the
other drivers, then set the owner using this function.
Nothing
code
ds_SetOwner ('bobbybrown','washere')
!For flat files
ds_SetOwner ('SQLConnection,SQLDataBase,SQLUser,SQLPassword','/MultipleActiveResultSets=1')
!For SQL files
ds_CreSec, Activate
Secwin Extension
| Parameter Name | Type | Description |
| Path | String | A specific path where the dssw4 file can be found. |
| LanguageFile | String | A specific name for the language file to use. |
| LanguagePath. | String | A specific path for the language file. |
Allows you to programmatically set the location of the Secwin support files,
including the dssw4 file and the language file or language path. They specifically
override the PATH, LANGUAGEFILE and LANGUAGEPATH settings as they appear in
the Secwin.Ini file.
If any of the above parameters are omitted then the usual methods (ie INI file
& defaults) are used to determine the position of those files.
For more information on the Language files and paths read the section in the
User Guide on Translating Secwin Windows
.
Note : This function can only be called once, and must be called Before
any other Secwin functions. Therefore it is recommended that you add this function,
if required, to your Global Program Setup embed point.
| Tip : Use the word HERE to indicate the current directory, and the word EXEDIR to indicate the Application(Exe) Directory |
Nothing
code
ds_SetPath('c:\')
ds_SetPath('HERE')
ds_SetPath('HERE','Dutch.Irf','EXEDIR')
| Parameter Name | Type | Description |
| SecurityAreaName | String | This is the name of the security area, as used by the ds_UsePin function. |
| PinNumber | Long | This is the Pin number to stamp into the file. |
Used to stamp the dssw4 file with a valid pin number. You would not normally
do this from inside an application. The SetPin and HardPin examples use this
function. The examples can be found in the \Clarion\3rdparty\Examples\Secwin\UsingPin directory.
Nothing
code
ds_SetPin('Bobs App',12345678)
ds_UsePin, Pin Numbers,
Extension : Activate Secwin Features
| Parameter Name | Type | Description |
| LoginCode | String | This is the Login Code of the user to make a Super User |
Use this function to set a user as a Super User. Note that this does NOT add
a user, if the user doesn't exist then the function does nothing.
Nothing
code
ds_SetSuperUser ('demo')
ds_UsersEx, ds_InsertUserEx, ds_ChangeUser,
ds_DeleteUser, Extension : User Login Here,
Super Users
| Parameter Name | Type | Description |
| ProductName | String | This is the name of the product. This name is used when generating activation codes. |
| ApplicationNumber | Long | This is the Application number returned by ds_LoginUser. If you are not using a login then set this number to 0. |
| LicenseName | String | This is a unique, 4 character, string containing the unique license name for this product. You may use alphanumeric characters only. It is case insensitive. |
| Options | Long | A long number containing a number of different bit settings.
This variable can contain either (or both) of the following options; DS_NODEMO DS_NONETWORKCHECK The 3rd byte in the long (ie options/65536) contains the length of the demo license. The default is 30 days. ds_CaseInsensitiveProductName - use this flag if the product name must be insensitive. |
In order to enable the copy protection, and remote activation, features which
Secwin can add to your application, you use Licenses. Somewhere near the beginning
of your application (usually just after calling the ds_LoginUser function) you
make a call to ds_UseLicence. A license is then sought, and held for the duration
of the program. The license is automatically released when the program terminates
(in whatever manner) or if the computer is switched off.
If no licenses exist then one will automatically be created. This created license
will have a level of 'Demo' (level 1) and an automatic expiry period of 30 days.
Your user can then change this license to their requirements when you supply
hem with the necessary activation code. If you do not want the 30 day demo period
then include the DS_NODEMO switch in the options parameter.
Although you can call this function at any time it is best to do it just after
the call to ds_LoginUser as you will then be able to supply the ApplicationNumber
parameter. This allows Secwin to put the name of the current user inside the
license file so that others can see which users are currently using the program.
You can override the default behavior of checking network licenses (i.e. the
user will have an effective "site license") by using the DS_NONETWORKCHECK
switch in the options parameter.
Note: that no checking of the license occurs at this point. To check the license,
especially the Expiry dates or application level, use the ds_LicenceOk function.
Nothing
AppNumQueue Queue
AppNum Long
End
Code
AppNum = ds_LoginUser('Video.Exe',DS_DEFAULT,'','')
if AppNum = 0
! login was unsuccessful
Return
End
Add(AppNumQueue,1)
ds_UseLicecnce('Amazing Wonderful Program',AppNum,'AWP',DS_NODEMO)
| Parameter Name | Type | Description |
| SecurityAreaName | String | This is the name of the application. This is the same name as you'd use with the ds_LoginUser function. |
| AppPinNumber | Long | This is the unique pin number for this application. Only dssw4 files containing this pin number will be valid. |
This function allows you to "stamp" a dssw4 file as being valid. Without
a pin number the user can simply delete the dssw4 file, and re-create an empty
one using CRESEC25. This use of Pin numbers requires however that the dssw4
file be stamped with the correct pin number before it will be considered valid.
Nothing
code
ds_UsePin (AppNameDesc,12345678)
ds_LoginUser( AppNameDesc, ds_Default,'','')
ds_SetPin, Pin Numbers,
Extension: Activate Secwin Features
| Parameter Name | Type | Description |
| AppNum | Long | This is the Application number returned by ds_LoginUser. |
| UserQueueEx |
ds_UserQueueEx | This is a queue defined in your application using the ds_UserQueueEx queue structure. the queue you pass must have this structure. An example of such a queue is... |
Note: In Secwin4 this function has changed somewhat, because a user can now belong to multiple user groups. In order to get a list of the user groups that a user belongs to, you need to use this function in conjunction with the ds_UsersUserGroups function. The UserGroup item in the queue will contain the first user group that the user belongs to (making sure that your existing code will not break when upgrading to Secwin 4) - but the user may belong to more than one group, in which case it will be necessary to call the additional function as well.
ds_UserQueueEx
QUEUE,PRE(_dsqex)
Name
STRING(40)
Surname
STRING(40)
Login
STRING(128)
UserGroup
LONG
Number
LONG
LastPasswordChangeDate LONG
Reserved1
LONG
Reserved2
STRING(12)
Reserved3
STRING(20)
end
This function fills into a queue, all the users and user groups currently in the database. In
other words by using this function you can get the logins and other details
of all existing users and user groups.
Nothing. The queue you passed now contains all the user details.
ds_UserQueueEx
QUEUE,PRE(_dsqex)
Name
STRING(40)
Surname
STRING(40)
Login
STRING(128)
UserGroup
LONG
Number
LONG
LastPasswordChangeDate LONG
Reserved1
LONG
Reserved2
STRING(12)
Reserved3
STRING(20)
end
code
ds_Users (Appnum,ds_UserQueueEx)
ds_UpdateUser, ds_UsersUserGroups
![]()
| Parameter Name | Type | Description |
| Appnum | Long | This is the Application number returned by ds_LoginUser. |
| pUser | Long | This is the user's ID number. |
| pUserSite | string | This is the user's SiteID field. |
| pUserGroupsQueue |
ds_UsersUserGroupsQType | This is a queue defined in your application using the ds_UsersUserGroupsQType queue structure (see Secwin Data Types). the queue you pass must have this structure. |
| pForce | long | If set, forces the UserGroup to be updated, otherwise only the usergroups with the activeicon flag <> active+1 flag. |
This function updates all the usergroups that this user belongs to from a previously populated UserGroup Queue (which you use ds_UsersUserGroups function to populate this queue with).
You can remove or add the user specified in the pUser field to any number of usergroups in the user group, as follows:
UsersUserGroups.ActiveIcon = 2 !Adds the user to the user group.
UsersUserGroups.ActiveIcon = 1 !Removes the user from the user group.
Similarly, if you have other users that must be associated with the usergroups of another user, you can retrieve the UserGroups using the ds_UsersUserGroups function (using the user id of the "from" user) and send the pUser to the user that you want to associate the same usergroups to.
Note: When adding/removing a user from a user group - leave the Active flag in the state it was in (when it was returned from the ds_UsersUserGroups function) - and only change the ActiveIcon flag. Secwin will comppare the flags to see where the changes have occured (rather than applying a change to every record that is in the queue - which is really inefficient).
Indicates whether a add to or remove from Usergroup failed:
0 - No error
1 - Removing the user from one or more usergroup(s) failed.
2 - Adding the user to one or more usergroup(s) failed.
3 - Adding to and removing from failed.
You can loop through the queue and see which records failed by testing (see example code for details).
UsersUserGroups QUEUE(ds_UsersUserGroupsQType),PRE(SecLocUUGQ)
!
END
UserNumber long
!The ID of the user
code
UserNumber = ds_GetUserProperty(AppNum,Login,,'UserNumber')
!This gets the usernumber for the user
if ds_UsersUserGroups(AppNum,UserNumber,'',UsersUserGroups,0)
. !Load the Users usergroups list
!First retrieve the user group
you are wanting to alter
Get(UsersUserGroups,<UserGroupToGet>)
!Code in here to toggle the
group that the user belongs to as follows:
if UsersUserGroups.ActiveIcon = 1
UsersUserGroups.ActiveIcon = 2
!The user is part of the UserGroup
else
UsersUserGroups.ActiveIcon = 1
!The user is not part of a UserGroup
end
put(UsersUserGroups)
if
ds_UpdateUsersUserGroups(Appnum,UserNumber,'',UsersUserGroups)
loop Counter = 1 to records(UsersUserGroups)
get(UsersUserGroups,Counter)
if ~errorcode() and
UsersUserGroups.ActiveIcon
<> UsersUserGroups.Active + 1
!What to do if the
changed didn't take
end
end
end
ds_UsersUserGroups , ds_GetUserProperty
| Parameter Name | Type | Description |
| Appnum | Long | This is the Application number returned by ds_LoginUser. |
| pUser | Long | This is the user's ID number returned by ds_LoginUser. |
| pUserSite | string | This is the user's SiteID field (leave blank if not used). |
| pUGQueue |
ds_UsersUserGroupsQType | This is a queue defined in your application using the ds_UsersUserGroupsQType queue structure (see Secwin Data Types). the queue you pass must have this structure. |
| pOptions (Optional) |
long | A bit loaded flag: Bit0: If set, then pUGQueue will be populated with a list of the UserGroups that the user belongs to. Otherwise, all the UserGroups will be added to the queue, with the Active flag set for those UserGroups that the User belongs to. |
| pChangeAccess (Optional) |
*string | A pointer to a string containing the access bits of a user (mainly for internal use). Must be a string(252) |
| pHash (Optional) |
long | A ID containing the area to assess the users' access rights (set to 0 to check their level). (mainly for internal use) |
ds_UserSUserGroups
QUEUE(ds_UsersUserGroupsQType ),pre(UUG) .
!You must have a prefix - otherwise you'll get compile warnings on this line
This function populates a queue with all the user groups that a user belongs to. You can either use it to populate an exhaustive list of UserGroups and highlight the user group using the active flag (like with a style or Icon in a list) or only return a list of the user groups that the user belongs to (depending on the pOptions flag passed to the function). For example, if you have the following usergroups in this application:
StockControl
Accounts
Invoicing
OrderEntry
Receiving
And you would like to display all 5 with a checkbox next
to the UserGroups that a particular user belongs to, then you would set the
pOptions to 0 (or omit the parameter). The Active element of the queue will be
set for those entries that the user belongs to. To just return the UserGroups
that a user belongs to (without returning all of the possible UserGroups) - set
the pOptions to 1.
Nothing. The queue you passed now contains all the usergroup details.
!This goes in your local
data section
ds_UsersUserGroupsQ
QUEUE(ds_UsersUserGroupsQType),pre(UUG) .
MyUser
long
code
ds_UsersUserGroups(AppNum,MyUser,'',ds_UsersUserGroupsQ)
!The Queue will contain all UserGroups with the Active Flag set for the ones that the
User belongs to.
ds_UsersUserGroups(AppNum,MyUser,'',ds_UsersUserGroupsQ,1)
!Contains just the UserGroups that the user belongs to
See Secwin Data Types for more details on the Queue structure.
See also: ds_LoginUser, ds_GetProperty . This function essentially replaces the obsolete ds_CurrentUserGroup function.
To change from using the ds_CurrentUserGroup function, you might have had something like:
if ds_CurrentUserGroup (Appnum)= 'MyUserGroup'
!Some functionality in here
end
Now, you need to declare the Queue as shown above (in your local data), and replace the code with the following:
ds_UsersUserGroups(AppNum,MyUser,'',ds_UsersUserGroupsQ,1)
loop x# = 1 to records(ds_UsersUserGroupsQ)
get(ds_UsersUserGroupsQ,x#)
if UUG:GroupName = 'MyUserGroup'
!Somefunctionality in here
break
end
end
| Parameter Name | Type | Description |
| pUser | Long | This is the user's ID number returned by ds_LoginUser. |
| pUserSite | string | This is the user's SiteID field (leave blank if not used). |
This function returns the user's password (specified by the pUser parameter). This must be used in conjunction with the use of the ds_SetEncryptionKey (see Using an encryption key for details)
A string containing the user's password.
UsersPassword string(128)
code
UsersPassword = ds_GetUserPassword(MyUser,'')
See also: ds_SetEncryptionKey , ds_ResetUserPassword . To get the user number, use the ds_GetUserProperty function.
| Parameter Name | Type | Description |
| pUser | Long | This is the user's ID number returned by ds_LoginUser. |
| pUserSite | string | This is the user's SiteID field (leave blank if not used). |
This function resets the user's password (specified by the pUser parameter) to the default (i.e. their login). This must be used in conjunction with the use of the ds_SetEncryptionKey (see Using an encryption key for details)
A long indicating pass (0) or failure (non-zero).
ReturnValue long
code
ReturnValue
= ds_ResetUserPassword(MyUser,'')
See also: ds_SetEncryptionKey , ds_GetUserPassword . To get the user number, use the ds_GetUserProperty function.
| Parameter Name | Type | Description |
| pEncryptionKey | string | This is the unique encryption key to use for your application to access the operator's table. |
This function sets the encryption key used to encrypt the necessary fields in the Secwin operators table (see Using an encryption key for details). Once this function has been used, and your application has been run on the Secwin data tables, then only your application will be able to read the secwin operators table.
Nothing.
ReturnValue long
code
ds_SetEncryptionKey('MyEncryptionKey')
See also: ds_ResetUserPassword , ds_GetUserPassword
![]()
The following data types are used by some of the functions and may be used in your application as well from time to time:
The complete data structures of these types may be found in the secequ15.clw file in your clarionx\3rdparty\libsrc directory.
| DataType | Use |
| ds_SecwinXMLString group | Used for saving licence in XML format to a string (rather than an actual XML file). |
| LimitsQueueType queue | A queue to contain the counters/table limits licensed for your application. This will contain the description of the counter as well as the value of each counter/limit. |
| ProductDetailsGroupType group | This group is used for saving and retrieving the licence details of the licence for your application. |
| ds_UserDetailsType group | Used to load and save a users details. |
| ds_UsersUserGroupsQType Queue | Used to load and save a user's user groups. |
| LimitsQueueType | queue,pre(_dsLQT) | |
| Description | string(252) | !The counter label |
| Limit | long | !The numeric limit |
| LimitIsRelative | long | !Set if the limit is relative (i.e. the Limit must be added to the current Limit) - or clear to replace an existing current limit |
| MinLevel | long | !The minimum level that the limit applies to (if > ds_DemoLevel then the limit will be 0 for levels less than the Minimum level) |
| MaxLevel | long | !The maximum level that the limit applies to (if not 0 then there will be no limit for levels greater than the Maximum level) |
| ExtraString | string(252) | !For additional user defined information you want to store with the limit. |
| end |
| ProductDetailsGroupType | group,pre(_dsPDGT) | |
| SiteLimiter | string(4) | !For Replicate - the ID of the site adding the user. Internally primed |
| CompanyName | string(252) | !The name of the Company that the licence is valid for |
| Product | string(252) | !The product name used for the application. |
| Dealer | string(252) | !The name of the dealer selling the licence (optional) |
| LicenceType | long | !The licence type (see |
| Copies | long | !The number of instances of the application that can run simultaneously. |
| Level | long | !The licence level |
| SerialNumber | string(252) | !A user field to store a serial number, or unique identifier. |
| OptionalModules | long | !A bit loaded flag which can be used to activate up to 30 modules |
| AdditionalString1 | string(252) | !Additional inforation you can store in the licence |
| AdditionalString2 | string(252) | !Additional inforation you can store in the licence |
| AdditionalLong1 | long | !Additional inforation you can store in the licence |
| AdditionalLong2 | long | !Additional inforation you can store in the licence |
| AdditionalString3 | string(252) | !Additional inforation you can store in the licence |
| end |
| ds_UserDetailsType | GROUP | !Insert has some required fields as noted. The only fields required for
change/delete are indicated !When changing a user, prime the Fields to change, otherwise leave blank. |
| Login | STRING(252) | !Required for insert, optional for change/delete (either use login or number) |
| FirstName | STRING(252) | !Required for insert - firstname of the user |
| Surname | STRING(252) | !Required for insert - surname/lastname of the user |
| Password | STRING(252) | !Not used. |
| Number | LONG | !Not used for insert (will be populated by Secwin), optional for change/delete (either use login or number). This number is a unique ID that Secwin uses to identify a user. |
| LastPasswordChangeDate | LONG | !Not used for insert - can be used to set the date that the password was last changed. |
| Hook1 | LONG | !Reserved - ignored if primed |
| Hook2 | STRING(252) | !Reserved - ignored if primed |
| EmailAddress | STRING(252) | !Only used for insert. The email address of the user. |
| FingerPrint1 | CSTRING(1024) | !Used for additional information like fingerprint info |
| FingerPrint2 | CSTRING(1024) | !Used for additional information like fingerprint info |
| Site | STRING(4) | !For Replicate - the ID of the site adding the user. Internally primed |
| SiteLow | STRING(4) | !For Replicate - site range for the user, use $$$$ for all sites |
| SiteHi | STRING(4) | !For Replicate - site range for the user, use $$$$ for all sites |
| ExtraLong | LONG | !Use this field for additional info |
| ExtraString | STRING(252) | !Use this field for additional info |
| Level | LONG | !Required for Insert - use the ds_Operator,ds_Supervisor or ds_NoAccess equate to set the correct level |
| InitialAccess | LONG | !Required for Insert - use ds_AllAccess,ds_NoAccess or ds_CopyAccess |
| CopyUserAccess | LONG | !The user to copy the access from (their Number) (if InitialAccess is set to ds_CopyAccess) |
| WorkGroup | LONG | !Indicates the WorkGroup that this user belongs to. |
| UserGroup | LONG | !Indicates whether this is a usergroup(1) or a user(0). |
| END |
| ds_UsersUserGroupsQType | Queue,pre(_dsUUGQ) | |
| GroupName | string(252) | !The name of the user group |
| ActiveIcon | long | !This flag is used to indicate the icon to display the icon (1 for unchecked, 2 for checked). It is also used to indicate a change in the status of the user's addition to this particular group. If Active is 1, and ActiveIcon is 1, then the user has changed from being part of the group, to being removed from the group. Similarly if Active is 0 and ActiveIcon is2, then the user is now added to the group. |
| Active | long | !Indicates whether the user is part of this group or not (1 if part of the group, 0 if not part of it) |
| Number | long | !The user group's number |
| Site | string(4) | !The site id of the user group (for Replicate purposes). |
| Login | string(252) | !The Login of the UserGroup (not used - except for display purposes, and retain the uniqueness of the key) |
| Level | string(252) | !The Level that the UserGroup is (ds_Operator or ds_NoAccess) |
![]()
| Other Information | |||||
| Installation | Distribution | Copyright & License | Limitation of Liability | Technical Support | Release History |
Run the Supplied Installation file.
You are free to distribute the Secwin DLLs with any of your Applications without extra charge.
You are free to distribute the CRESEC.EXE or any of the Example programs should you want to.
The DLLs your program require will depend on your version of Clarion and the
Secwin File Driver you are using. Note that programs compiled in Local Mode
do not use DLLs and therefore there is nothing extra for you to distribute.
| Clarion 6 | Clarion 5.5 | Clarion 7 | |
| Topspeed Driver | S6TPSX.DLL | S55TPSX.DLL | S70TPS.DLL |
| Btrieve Driver | S6BTRX.DLL | S55BTRX.DLL | S70BTR.DLL |
| SQL Anywhere Driver | S6SQAX.DLL | S55SQAX.DLL | S70SQA.DLL |
| MsSQL Driver | S6MSSX.DLL | S55MSSX.DLL | S70MSS.DLL |
| ODBC Driver | S6ODBCX.DLL | S55ODBCX.DLL | S70ODB.DLL |
| IPDriver | s6IPDx.DLL | ||
| Pervasive SQL Driver | s6SCAx.DLL | s55SCAx.DLL | s70SCA.DLL |
| Oracle Driver | s6ORAx.DLL | s55ORAx.DLL | s70ORA.DLL |
![]()
I'm getting Runtime and/or Compile Errors
1.1. I want to remove the license for a client on one machine. How do I do this?
1.2. How I define the activation code's expiry date?
1.3. Can more than one person run my Secwin app with one demo licence?
1.4. I want to ship a dssw4.tps file (with access control setup) -
but using that file gives me a license error when installing it at the client side.
1.5. I have issued 5 licences, but more than 5 users can run the application simultaneously.
1.6. I have issued a new code to my client, but the features
are not activated. They are still able to use the application though.
1.7. My activation code that I'm generating in the Register
application is failing to activated my program.
1.8. I'm adding additional features and generating an
activation code - but when restarting the program, the features aren't available.
1.9. I don't want Secwin to display an
error message when the Licence fails.
1.10. I want to encode some of the licence fields.
1.11. I drop my xml file into the register window, but it
always comes up with "Failure..."
1.12. I have issued 5 licences, but only 2 users can run
the application simultaneously.
1.13. I want to allow my users to enter their registration
details manually like in Secwin 3. How do I do this?
1.14. When I upgraded to the latest Secwin, the XML License
files generated now contain %20 for spaces?
2.1. When I send the app to my clients the users have to
be re-entered for the security to work.
2.3. Will Secwin allow me to refuse access to a report?
2.4. Not all my Access Points are showing on the Global Set
Access window?
3.1. Can I see who is logged into the program on all the clients?
3.2. I don't want to use the Access Control
features of Secwin, only the Licence and Registration.
3.3. I don't want the login screen appearing
in my demo application.
3.4. How do I reset a user's password?
3.5. I need to prevent the last SecWin User from switching
from supervisor to operator. How this can be done?
3.6. How do I force the user to change his password the first
time he logs on?
3.7. How can I set the default access to all
access when adding an operator (in a Multi-DLL/Multi-EXE scenario)?
3.8. How can I override AccessRights for
insert/change/deletion specific functionality?
3.9. How do I filter records in a browse based on the user logged in?
3.10. I see duplicate entries in the Operator Browse screen.
3.11. How do I print out a user's AccessRights?
3.12. I need to store extra information in
the Secwin operator table. How do I do this?
3.14. I want to hide and unhide controls based on my own
conditions - but Secwin is overriding my hide commands.
3.15. I only see 31 control groups on the access rights
screen when I press Ctrl-F8.
3.16. On the operator form, the Initial Access of each
operator always shows as 'No Access'.
3.17. Why can't I change the InitialAccess of an operator?
3.18. Why can't I change a UserGroup's level from NoAccess to Operator?
3.19. How do a select or de-select a user from all user
groups?
3.20. How do I copy a User's access settings to another user?
4.1. My Text for Cut and Paste has an incorrect CRC check in the Activation code. What must I do?
5.2. What settings must I do in my various apps in a Multi-DLL application?
5.3. How do I get my PowerToolbar application to work with
Secwin?
6.1. How can I rename the dssw4.tps file?
6.2. My app was running fine in Windows XP - but in Vista, it
does not find the security file?
6.3. I'm using Secwin with MSSQL and I cannot get my
application to create the security tables.
6.4. I would like to make the SQL connection before Secwin does. Where must I
put my connection code?
6.5. I'm changing from TPS to SQL, and would like to export
the user's access control settings to SQL. How do I do this?
6.6. how do I remove Secwin from my application?
6.7. My app takes a long time to load after the login screen
7.1. Why should I upgrade from Secwin 3 to Secwin 4?
7.2. What do we need to change in order to upgrade from
Secwin3 to Secwin4?
7.3. How do I upgrade from Secwin 3 to Secwin 4?
7.4. How do I cater for existing clients using the old
application when issuing activation codes?
7.5. Why is Capesoft charging for an upgrade from Secwin 3 to Secwin 4?
7.6. My saf password does not work on
the latest Secwin install. Where do I get a new password?
7.7. After upgrading from Secwin 4 to
Secwin 4, none of my users can log in.
1.1. Question: I want to remove the license for a client on one machine. How do I do this?
Answer: Call ds_RegisterProductEx with an already expired date.
1.2. Question: How I define the activation code's expiry date?
Answer: In Secwin 4 - this expiry date goes in the activation code itself. You can set the expiry date of the activation code when you generate it.
1.3. Question: Can more than one person run my Secwin app with one demo licence?
Answer: By default the demo licence will be a 30day, demo, 1 user licence (if you've enabled that in the Secwin Templates). This means that you can make any number of shortcuts to the application, but one person at a time will be able to access the application. However you can send them a (demo) code which allows multiple users at the same time. This code can be entered on any workstation.
1.4. Question:I want to ship a dssw4.tps file (with access control setup) - but using that file gives me a license error when installing it at the client side.
Answer: Basically what you're wanting to do is create a dssw4.tps file without licensing included in the file. Normally you'd want to do this to create a SuperUser and ship the SuperUser in the dssw4.tps file. This is a bit tricky - but here's basically how you do it:
a) Go to your app and turn OFF licensing. You can do this on the Secwin
Global Extension Template.
b) Compile (don't run yet.)
c) Delete the dssw4.tps that your program will use. (so that a new one will be created.)
d) Now run the program.
e) Doing as little in the program as possible, go to the Browse users screen,
and add the Super User. (if the system forces you to do this before the Login,
then add the user but DON'T login - just cancel when you get there.)
f) Now save the dssw4 file in a safe place, so you have a copy for the future.
This "virgin" dssw4 file is the one you ship.
g) Back to the app, turn licensing back on. Compile. Ship (make sure you include
the dssw4.tps file that you created earlier in your install). In your install,
make sure that you don't overwrite the dssw4.tps file that may already existing
at the client site as they will lose their security settings.
1.5. Question: I have issued 5 licences, but more than 5 users can run the application simultaneously.
Answer: Your application is not setup to use the same licence file location. For more details, peruse The mechanics of the Licencing section of this document.
1.6. Question: I have issued a new code to my client, but the features are not activated. They are still able to use the application though.
Answer: You're assigning a permanent licence to a client that already has a temporary licence, that has not yet expired. For more details on Licence Types check the Using Different Licence Types section of the docs.
1.7. Question: My activation code that I'm generating in the Register application is failing to activated my program.
Answer:
1.8. Question: I'm adding additional features and generating an activation code - but when restarting the program, the features aren't available.
Answer: Almost certainly you have an unexpired temporary code that is being used instead of the permanent code. Read up on Using Different Licence Types for more details.
1.9.Question: I don't want Secwin to display an error message when the Licence fails.
Answer: You need to set the action when the licence fails to "Return to caller without showing warning". This is set in the UserScreen Security extension template on that particular window. Then you can handle the return using the values returned by the ds_LicenceOK function.
1.10. Question: I want to encode some of the licence fields stored in the Security tables.
Answer: The key is to get both the Registration application encoding the fields before the XML generation.
A couple of changes you need to make to the registrabc.app:
1. Use a different field for the SerialNumber and AdditionalString1 (maybe a local variable). Just before the generate activation code routine, encode them to the variables that are currently used (when generating an activation code).
2. You'll need to decode it on the way in to the form, so that the original value is displayed in your custom fields.
What you need to do in your application:
1. When reading the licence details, you need to call your decode routine. www.capesoft.com/docs/secwin/secwin.htm#ds_CurrentLicenceDetails is the function to use for obtaining the licence details.
1.11. Question: I drop my xml file into the register window, but it always comes up with "Failure..."
Answer: This is normally one of the following:
1.12. Question: I have issued 5 licences, but only 2 users can run the application simultaneously.
Answer: A couple of things to check:
1.13. Question: I want to allow my users to enter their registration details manually like in Secwin 3. How do I do this?
Answer: You can enable the sheet control on the SecwinRegisterProduct window.
1.14. Question: When I upgraded to the latest Secwin, the XML License files generated now contain %20 for spaces?
Answer: in order to support HTML packets (for web activation codes) - the XML packet generated needed to be HTML compliant. Unfortunately this may mean that some of your old applications my be expecting the old format of XML file. You can force a non-HTML compliant XML registration packet, by using the following code in your registration code application (see the registerabc.app that ships with Secwin):
if UseOldXMLEncodingType = 1
!You'll need to add a switch on your screen to turn this on/off
SaveLicenceToXMLOptions.EncodingType = 'ISO-8859-1'
else
SaveLicenceToXMLOptions.EncodingType = ''
end
if ds_SaveLicenceToXMLEx(REG:CodeGroup,Queue:Browse,ds_MakeValidFileName(clip(REG:CompanyName)
& '_' & clip(REG:Product) &'.xml'),,SaveLicenceToXMLOptions) <> 0
You'll need to create the options groups as well (in your procedure data):
SaveLicenceToXMLOptions group(SaveLicenceToXMLOptionsGroupType) .
2.1. Question: When I send the app to my clients the users have to be re-entered for the security to work.
Answer: Maybe you're _shipping_ the dssw4 file. And the
"install" of the update is overwriting the existing dssw4 file?
If this is the case then set the file in the installer to be "preserve existing".
Alternatively, you've changed the setting for where the dssw4.tps file is stored? This is a setting on the Activate Security Global extension template.
2.3. Question: Will Secwin allow me to refuse access to a report?
2.4. Question: Not all my Access Points are showing on the Global Set Access window?
Answer: If this is a multi-dll application, then you need to compile your dll with the Secwin windows (normally the data dll) after adding an access point to your procedures. You also need to ensure that your .sac file is being re-generated after the compile of the dll with the updated security settings (access points or a new User Screen Security template addition).
3.1. Question: Can I see who is logged into the program on all the clients?
Answer: You can use the ds_CurrentlyLoggedInEx() function to return a queue of the users currently logged in.
3.4. Question: How do I reset a user's password?
Answer: You will need to use your own encryption key - in order to make the Secwin operator's table unique to your application. See Using an encryption key for details.
3.5. Question: I need to prevent the last SecWin User from switching from supervisor to operator. How this can be done?
Answer:
ds_UsersEx (Appnum,ds_UserQueueEx)
if records(ds_UserQueueEx) < 2
disable(?UserLevelGroup)
end
3.6. Question: How do I force the user to change his password the first time he logs on?
Answer:
3.8. Question: How can I override AccessRights for insert/change/deletion specific functionality?
Answer: There are probably 3 categories of users: 1 - those who have
complete rights (i.e. able to change and insert), 2. those who have insert
rights (not able to change), 3. those that are not able to insert or change.
Category 3: Place the restriction on the calling window (IOW they will not be
able to access the form to insert/change).
Category 2: Place the restriction on the form (either make all controls readonly,
or disable the OK button). These users that you are wanting to restrict - the
restriction will be overridden when inserting to allow insertion.
Category 1: Remove all restrictions for these users.
Probably the best way to do this, is the following mod in the 'After Get Allowed' embed point:
If self.Request = InsertRecord
ThisAllowed = DS_ACCESSALL
end
This will override the restriction for catagory 2 users to allow them to insert the record.
3.9. Question: How do I filter records in a browse based on the user logged in?
Answer: There's a couple of things you need to do:
3.10. Question: I see duplicate entries in the Operator Browse screen.
Answer: You need to create the AccessControl windows using the template utility provided, rather than use the old Secwin 3 internal DLL windows. These are not optimized for SQL - but are merely there for backward compatibility.
3.11. Question: How do I print out a user's AccessRights?
Answer: The easiest way is to add a SendTo button (www.capesoft.com\accessories\SendTosp.htm) to the SecwinSetAllAccess window. Use the following setup:

You will then be able to go to the Set All Access window in your application, select the user and send the access to the output of your choice.
3.12. Question: I need to store extra information in the Secwin operator table. How do I do this?
Answer: There are additional fields available in the user table:
FingerPrint1 CSTRING(1025)
FingerPrint2 CSTRING(1025)
ExtraLong LONG
ExtraString STRING(252)
You can edit these properties using the ds_UpdateUser procedure, and retrieve these properties using the ds_GetProperty method.
3.14. Question: I want to hide and unhide controls based on my own conditions - but Secwin is overriding my hide commands.
Answer: You can override the Secwin control of a specific screen control, in the RestrictAccess and GrantAccess routines generated by the Secwin UserScreenSecurity template. You must place your code after the Secwin generated code in order to have the desired effect.
3.15. Question: I only see 31 control groups on the access rights screen when I press Ctrl-F8.
Answer: You must follow all the steps for upgrading to Secwin 4 (including importing the security windows into your application and setting these procedures in the Global Extension template).
3.16 Question: On the operator form, the Initial Access of each operator always shows as 'No Access'.
Answer:
3.17 Question: Why can't I change the InitialAccess of an operator?
Answer: The initial access (or default access) only pertains to screens not visited/accessed. Once an operator visits a screen for the first time, their access to that screen is solidified. If the InitialAccess for an operator is not correct (IOW it was not initially set correctly) - then it's pointless changing the access after that particular user has visited a number of screens (or the supervisor has set access for those screens while that user has been present on the system) - as their access would have been solidified for only those screens. The operator must rather be deleted and re-added with the correct InitialAccess to ensure that this is set correctly.
3.18. Question: Why can't I change a UserGroup's level from NoAccess to Operator?
3.19. Question: How do a select or de-select a user from all user groups?
Answer: In your SecwinOperatorForm (where you update the user) - you can add a select and/or de-select button with the following code:
!Select All
loop x = 1 to records(UsersUserGroups)
get(UsersUserGroups,x)
UsersUserGroups.ActiveIcon = 2
put(UsersUserGroups)
end
Like wise for de-select all:
!De-Select All
loop x = 1 to records(UsersUserGroups)
get(UsersUserGroups,x)
UsersUserGroups.ActiveIcon = 1
put(UsersUserGroups)
end
3.20. Question: How do I copy a User's access settings to another user?
Answer: This option is only available when you insert a new user. Besides the normal values that should be set in the ds_UpdateUser method call, you need to set the following:
SecLocLDG:InitialAccess = ds_CopyAccess
SecLocLDG:CopyUserAccess = LOC:UserNumberFrom
ds_updateuser(appnum,userdetailsgroup,InsertRecord)
Note: you must specify a valid secwin user id to copy from.
4.1. Question: My Text for Cut and Paste has an incorrect CRC check in the Activation code. What must I do?
Answer: There's a small change you need to make to your Registration App:
Open the UpdateRegistrations window in the source editor and paste the following line of code in the CopyIn routine:
do calccrc
immediately before the following code line:
TextField = 'Company : ' & clip(REG:Company) & ' (' & crc1 & ')<13,10>' & |
5.2. Question: What settings must I do in my various apps in a Multi-DLL application?
Answer: Check out the Using Secwin in MultiDLL applications section of this document.
5.3. Question: How do I get my PowerToolbar application to work with Secwin?
Answer: You to associate a normal clarion control with each powertoolbar. You can then use the template to setup the access groups. You'll need to mimick the hide/disable controls for the powertoolbar ones in handcode in the RestrictAccess routine. There's a button on the User Security Template that will get you straight there for each control. For example:
RestrictAccess Routine
If ThisAllowedString[2] <> '1'
if ?Insert:2{prop:Disable} = 0 then
?Insert:2{prop:Disable} = 1
end
!In here. Disable the PowerToolbar
control group no 1 here
End
6.1. Question: How can I rename the dssw4.tps file?
Answer: We have not made this programmer/user configurable and do not plan to do so in the future.
6.2. Question: My app was running fine in Windows XP - but in Vista, it does not find the security file?
Answer: It's almost certainly got to do with the location of your
dssw4 file. See the Secwin Global Extension, Files tab.
Under XP it's ok to place the dssw4 file in the windows directory. In Vista this
isn't going to work. Recommended practice is setting the dssw4 file to be the
same location as the rest of the data.
6.3. Question: I'm using Secwin with MSSQL and I cannot get my application to create the security tables.
Answer: Are you using a trusted connection? Don't supply a user name and password in the connect string.
6.4. Question: I would like to make the SQL connection before Secwin does. Where must I put my connection code?
Answer: You need to make the connection in the MainEXE (If this is a Multi-DLL application or a single-EXE application) in the Program Setup embeds before the Secwin - Initialize template generated code. This will be done by FM3 for you in the correct place, but if you are not using FM3, then this is where you need to connect to the database.

6.5. Question: I'm changing from TPS to SQL, and would like to export the user's access control settings to SQL. How do I do this?
Answer: There are 2 functions included in the Secwin libraries: ds_ExportTables, and ds_ImportTables. You can call these in the respective applications (the export function to export, and the import function to perform the import). The ds_ImportTables function must be called before the call for the user to login (i.e. the ds_LoginUser or ds_LoginText function calls) if an import is required.
6.6. Question: How do I remove Secwin from my application?
Answer:
Note: Multi-DLL users must do this from the exe downwards - finishing at the data dll.
6.7. Question: My app takes a long time to load after the login screen
Suggestions:
7.1. Question: Why should I upgrade from Secwin 3 to Secwin 4?
Answer: Besides Secwin 3 being "sooo last century" you'll miss out on all the incredibly cool new features: What's new in Secwin 4? . We will continue building Secwin 3 for later new releases of Clarion, but the door is officially closed on fixes/tweaks/changes to the old version of Secwin.
7.2. Question: What do we need to change in order to upgrade from Secwin3 to Secwin4?
Answer:
- Cater for Counter/Limit Queue functionality (CreateLimitsQueue)
- Cater for Secwin 3 codes and Secwin 4 codes
See also: How do I cater for existing clients using the old application when issuing activation codes?
7.3. Question: How do I upgrade from Secwin 3 to Secwin 4?
Answer:
7.4. Question: How do I cater for existing clients using the old application when issuing activation codes?
Answer: You can still issue old Secwin3 activation codes with the new registration application. This means that you are not forced to upgrade everyone to the new Secwin4 activation code system. They can each move over to the new application gradually if that is the method you prefer.
The new register.dct has been formulated in such a way that if you were using the old register application exactly out the box, then a simple matter of running the conversion application will move the data from the old format to the new one. Your products (moved over from the old database) will be considered Secwin3 applications - so you can either create a new application (which will use the Secwin4 activation code system) and then move over clients as they upgrade to the new system, or you can move the entire product over to use Secwin4 and force an upgrade when the users next require an activation code.
7.5. Question: Why is Capesoft charging for an upgrade from Secwin 3 to Secwin 4?
Answer:
7.6. Question: My saf password does not work on the latest Secwin install. Where do I get a new password?
Answer: In Secwin version 4.00 Capesoft introduced a paid-for upgrade, which means that the unlock code changed. You can continue using Secwin 3 and downloading the necessary install files with your existing Secwin 3 saf code, or you can upgrade to Secwin 4 (and make the most of all the functionality offered in the Secwin 4 package). To find out more ab